//+------------------------------------------------------------------+ //| GapStasts.mq5 | //| Copyright © 2021, EarnForex.com | //| https://www.earnforex.com/ | //+------------------------------------------------------------------+ #property copyright "www.EarnForex.com, 2021" #property link "https://www.earnforex.com/guides/forex-weekly-gap-statistics/" #property version "1.01" #property script_show_inputs #property description "Should be run on D1." #property description "Generates a CSV-file with weekly and daily data preceding and following a weekly gap." input int StartYear = 2010; //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { // Preparing the file. string period = EnumToString(_Period); StringReplace(period, "PERIOD", ""); string filename = "Gap" + _Symbol + period + ".csv"; if (FileIsExist(filename)) { if (!FileDelete(filename)) { Print("File " + filename + " already exists and cannot be delted: ", GetLastError(), "."); return; } } int file = FileOpen(filename, FILE_CSV | FILE_READ | FILE_WRITE); if (file == INVALID_HANDLE) { Print("Failed to create the output file " + filename + ": ", GetLastError(), "."); return; } int NumCandles = iBars(Symbol(), PERIOD_D1); int cnt = 0; // Start with the current day and go to the pre-oldest one. for (int i = 0; i < NumCandles - 1; i++) { MqlDateTime timestruct; TimeToStruct(iTime(Symbol(), PERIOD_D1, i), timestruct); // Skip old data. if (timestruct.year < StartYear) break; if (timestruct.day_of_week != 1) continue; // Monday of the post-gap week. double Open_Monday = iOpen(Symbol(), PERIOD_D1, i); double High_Monday = iHigh(Symbol(), PERIOD_D1, i); double Low_Monday = iLow(Symbol(), PERIOD_D1, i); double Close_Monday = iClose(Symbol(), PERIOD_D1, i); int friday_shift = 1; // Daily bar shift for Friday relative to Monday. // Check if this week has an active Sunday: MqlDateTime timestruct_sunday_check; TimeToStruct(iTime(Symbol(), PERIOD_D1, i + 1), timestruct_sunday_check); if (timestruct_sunday_check.day_of_week == 0) { // Need to append Sunday OHLC to the current Monday. Open_Monday = iOpen(Symbol(), PERIOD_D1, i + 1); High_Monday = MathMax(High_Monday, iHigh(Symbol(), PERIOD_D1, i + 1)); Low_Monday = MathMin(Low_Monday, iLow(Symbol(), PERIOD_D1, i + 1)); friday_shift++; // If there is Sunday, Friday's bar shift is 2 instead of 1. } // Ignore current week. if (TimeCurrent() - iTime(Symbol(), PERIOD_D1, i) < 5 * 24 * 60 * 60) continue; // A Monday with less than 5 days difference to current time. int w = iBarShift(Symbol(), PERIOD_W1, iTime(Symbol(), PERIOD_D1, i)); // Weekly bar shift for the post-gap week. if (w < 0) { Print("Failed to find the weekly timeframe shoft for " + TimeToString(iTime(Symbol(), PERIOD_D1, i)) + "."); return; } double ATR[1]; int myATR = iATR(Symbol(), Period(), 14); if (CopyBuffer(myATR, 0, iTime(Symbol(), PERIOD_D1, i + friday_shift), 1, ATR) != 1) { Print("ATR CopyBuffer() error: ", GetLastError(), "."); return; } // w + 1 = pre-gap week. // i + 1 = pre-gap Friday. // Gap. // i = post-gap Monday. // w = post-gap week. // ATR(14D). FileWrite(file, iOpen(Symbol(), PERIOD_W1, w + 1), iHigh(Symbol(), PERIOD_W1, w + 1), iLow(Symbol(), PERIOD_W1, w + 1), iClose(Symbol(), PERIOD_W1, w + 1), iOpen(Symbol(), PERIOD_D1, i + friday_shift), iHigh(Symbol(), PERIOD_D1, i + friday_shift), iLow(Symbol(), PERIOD_D1, i + friday_shift), iClose(Symbol(), PERIOD_D1, i + friday_shift), iOpen(Symbol(), PERIOD_W1, w) - iClose(Symbol(), PERIOD_W1, w + 1), Open_Monday, High_Monday, Low_Monday, Close_Monday, iOpen(Symbol(), PERIOD_W1, w), iHigh(Symbol(), PERIOD_W1, w), iLow(Symbol(), PERIOD_W1, w), iClose(Symbol(), PERIOD_W1, w), ATR[0] ); cnt++; } FileClose(file); Print(cnt, " lines written to ", filename, "."); } //+------------------------------------------------------------------+