// SPDX-License-Identifier: MIT // Copyright (c) 2026 WickAtlas. MIT-licensed; provided "AS IS", without warranty. // Version 1.0.0 | Released 2026-08-13 | Platform: MetaTrader 4 / MQL4 build 600+ // Defaults: previous completed broker D1 and W1 high, low and close. Indicator only; no external access. #property strict #property copyright "WickAtlas" #property link "https://wickatlas.com/downloads" #property version "1.00" #property description "Previous completed broker-day and broker-week levels." #property description "Boundaries follow the broker's D1 and W1 candles." #property indicator_chart_window #property indicator_buffers 6 #property indicator_color1 clrMediumSeaGreen #property indicator_color2 clrTomato #property indicator_color3 clrSlateGray #property indicator_color4 clrSeaGreen #property indicator_color5 clrFireBrick #property indicator_color6 clrDarkSlateGray input bool InpShowDailyLevels = true; input bool InpShowWeeklyLevels = true; double PreviousDayHigh[]; double PreviousDayLow[]; double PreviousDayClose[]; double PreviousWeekHigh[]; double PreviousWeekLow[]; double PreviousWeekClose[]; void SetEmpty(const int index,const bool daily,const bool weekly) { if(daily) { PreviousDayHigh[index]=EMPTY_VALUE; PreviousDayLow[index]=EMPTY_VALUE; PreviousDayClose[index]=EMPTY_VALUE; } if(weekly) { PreviousWeekHigh[index]=EMPTY_VALUE; PreviousWeekLow[index]=EMPTY_VALUE; PreviousWeekClose[index]=EMPTY_VALUE; } } bool ReadCompletedPeriod(const int timeframe, const int shift, double &periodHigh, double &periodLow, double &periodClose) { if(shift<1 || iBars(NULL,timeframe)<=shift) return(false); ResetLastError(); double requestedHigh=iHigh(NULL,timeframe,shift); int highError=GetLastError(); ResetLastError(); double requestedLow=iLow(NULL,timeframe,shift); int lowError=GetLastError(); ResetLastError(); double requestedClose=iClose(NULL,timeframe,shift); int closeError=GetLastError(); if(highError!=0 || lowError!=0 || closeError!=0 || requestedHigh<=0.0 || requestedLow<=0.0 || requestedClose<=0.0) return(false); periodHigh=requestedHigh; periodLow=requestedLow; periodClose=requestedClose; return(true); } int OnInit() { if(!SetIndexBuffer(0,PreviousDayHigh) || !SetIndexBuffer(1,PreviousDayLow) || !SetIndexBuffer(2,PreviousDayClose) || !SetIndexBuffer(3,PreviousWeekHigh) || !SetIndexBuffer(4,PreviousWeekLow) || !SetIndexBuffer(5,PreviousWeekClose)) return(INIT_FAILED); ArraySetAsSeries(PreviousDayHigh,true); ArraySetAsSeries(PreviousDayLow,true); ArraySetAsSeries(PreviousDayClose,true); ArraySetAsSeries(PreviousWeekHigh,true); ArraySetAsSeries(PreviousWeekLow,true); ArraySetAsSeries(PreviousWeekClose,true); SetIndexStyle(0,DRAW_LINE,STYLE_DASH,1,clrMediumSeaGreen); SetIndexStyle(1,DRAW_LINE,STYLE_DASH,1,clrTomato); SetIndexStyle(2,DRAW_LINE,STYLE_DOT,1,clrSlateGray); SetIndexStyle(3,DRAW_LINE,STYLE_SOLID,2,clrSeaGreen); SetIndexStyle(4,DRAW_LINE,STYLE_SOLID,2,clrFireBrick); SetIndexStyle(5,DRAW_LINE,STYLE_DOT,1,clrDarkSlateGray); SetIndexLabel(0,"Previous day high"); SetIndexLabel(1,"Previous day low"); SetIndexLabel(2,"Previous day close"); SetIndexLabel(3,"Previous week high"); SetIndexLabel(4,"Previous week low"); SetIndexLabel(5,"Previous week close"); for(int plot=0;plot<6;plot++) SetIndexEmptyValue(plot,EMPTY_VALUE); IndicatorShortName("WickAtlas Previous D/W Levels"); IndicatorDigits(Digits); return(INIT_SUCCEEDED); } 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<2) return(0); ArraySetAsSeries(time,true); int first=(prev_calculated==0 || prev_calculated>rates_total) ? rates_total-1 : MathMin(rates_total-prev_calculated+1,rates_total-1); if(prev_calculated==0) { ArrayInitialize(PreviousDayHigh,EMPTY_VALUE); ArrayInitialize(PreviousDayLow,EMPTY_VALUE); ArrayInitialize(PreviousDayClose,EMPTY_VALUE); ArrayInitialize(PreviousWeekHigh,EMPTY_VALUE); ArrayInitialize(PreviousWeekLow,EMPTY_VALUE); ArrayInitialize(PreviousWeekClose,EMPTY_VALUE); } int cachedDayShift=-1; int cachedWeekShift=-1; double dayHigh=EMPTY_VALUE; double dayLow=EMPTY_VALUE; double dayClose=EMPTY_VALUE; double weekHigh=EMPTY_VALUE; double weekLow=EMPTY_VALUE; double weekClose=EMPTY_VALUE; for(int i=first;i>=0;i--) { if(InpShowDailyLevels) { int dayShift=iBarShift(NULL,PERIOD_D1,time[i],false); int previousDayShift=(dayShift>=0) ? dayShift+1 : -1; if(previousDayShift!=cachedDayShift) { cachedDayShift=previousDayShift; dayHigh=EMPTY_VALUE; dayLow=EMPTY_VALUE; dayClose=EMPTY_VALUE; ReadCompletedPeriod( PERIOD_D1,previousDayShift,dayHigh,dayLow,dayClose ); } PreviousDayHigh[i]=dayHigh; PreviousDayLow[i]=dayLow; PreviousDayClose[i]=dayClose; } else SetEmpty(i,true,false); if(InpShowWeeklyLevels) { int weekShift=iBarShift(NULL,PERIOD_W1,time[i],false); int previousWeekShift=(weekShift>=0) ? weekShift+1 : -1; if(previousWeekShift!=cachedWeekShift) { cachedWeekShift=previousWeekShift; weekHigh=EMPTY_VALUE; weekLow=EMPTY_VALUE; weekClose=EMPTY_VALUE; ReadCompletedPeriod( PERIOD_W1,previousWeekShift,weekHigh,weekLow,weekClose ); } PreviousWeekHigh[i]=weekHigh; PreviousWeekLow[i]=weekLow; PreviousWeekClose[i]=weekClose; } else SetEmpty(i,false,true); } return(rates_total); }