Alert when bar breaks current daily high/low
Below is an example:
double close[]; //--- Sets indexing for the array like in timeseries if(!ArraySetAsSeries(close, true)) { Print(__FUNCTION__, " - Error indexing CLOSE array like in timeseries."); return; } //--- Sets the size of the array if(ArrayResize(close, 3) < 0) { Print(__FUNCTION__, " - Error setting CLOSE array size."); return; } //--- Gets historical data of the bar prices if(CopyClose(_Symbol, _Period, 0, 3, close) < 0) { Print(__FUNCTION__, " - Failed to copy data from CLOSE prices."); return; } //--- High and Low of the previous candle (D1) double HiD1 = iHigh(_Symbol, PERIOD_D1, 1); if(HiD1 == 0.0) { Print(__FUNCTION__, " - Error getting the previous day's high: ", GetLastError()); return; } double LoD1 = iLow(_Symbol, PERIOD_D1, 1); if(LoD1 == 0.0) { Print(__FUNCTION__, " - Error getting the previous day's low: ", GetLastError()); return; } //--- Checks whether there was a daily breakout upwards if(close[2] <= HiD1 && close[1] > HiD1) { // . . . } //--- Checks whether there was a daily breakout downwards if(close[2] >= LoD1 && close[1] < LoD1) { // . . . }
Ah, I see... In this case, you can use the iBarShift function to identify the index of the first candle of the day; then work with the iHighest and iLowest functions to identify the candle indices with the highest and lowest prices of the day; then iHigh and iLow... Try implementing it, if you have problems, show your attempt and describe the difficulty to get help.
#property strict #property indicator_chart_window #define _prcToStr(a) DoubleToString(a, _Digits) void OnDeinit(const int reason) { Comment(""); } int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { if(rates_total == prev_calculated) return(rates_total); #ifdef __MQL5__ ArraySetAsSeries(high, true); ArraySetAsSeries(low, true); ArraySetAsSeries(time, true); #endif int idxHigh, idxLow; if(!find(idxHigh, idxLow, high, low, time)) { Comment("Looks like today consists of one unformed bar"); return(rates_total); } Comment(StringFormat("High %s %s\nLow %s %s", _prcToStr(high[idxHigh]), TimeToString(time[idxHigh]), _prcToStr(low[idxLow]), TimeToString(time[idxLow]))); return(rates_total); } bool find(int &idxHigh, int &idxLow, const double &high[], const double &low[], const datetime &dt[]) { idxHigh = -1; idxLow = -1; MqlDateTime time; if(!dtToStruct(dt[0], time)) return(false); int dayOfYear = time.day_of_year; int limit = ArraySize(dt); for(int i = 1; i < limit; i++) { if(!dtToStruct(dt[i], time)) return(false); if(time.day_of_year != dayOfYear) break; if(idxHigh == -1 || high[i] > high[idxHigh]) idxHigh = i; if(idxLow == -1 || low[i] < low[idxLow]) idxLow = i; } return(idxHigh != -1 && idxLow != -1); // Although it is enough to check one of the variables } bool dtToStruct(datetime a_dt,MqlDateTime &var) { ResetLastError(); if(TimeToStruct(a_dt, var)) return(true); PrintFormat("%s error %i, value %I64i", __FUNCTION__, GetLastError(), a_dt); return(false); }
I can't stand either of them😄
[edit]
Especially in indicators. The terminal transfers already prepared prices to OnCalculate. Why do you need these terrible functions?
Rethink. If the current bar breaks the current daily, the current daily has changed.
Hello,
How can I, in an indicator, detect when the current bar closes and breaks the current daily high/low?
I need to check when a bar closes, if it breaks the daily high/low so far, from the first daily bar to the last bar (not counting the current bar).
If I use "
I will get the highest value of the current day including the current bar. But I need the highest value, up to the last bar, to check if the last bar has surpassed the level.
Thanks