[{"data":1,"prerenderedAt":1325},["ShallowReactive",2],{"\u002Fguides\u002Fadd-a-news-filter-to-your-mt4-expert-advisor":3,"\u002Fguides\u002Fadd-a-news-filter-to-your-mt4-expert-advisor-surround":1315},{"id":4,"title":5,"authors":6,"badge":12,"body":14,"date":1303,"description":1304,"draft":1305,"extension":1306,"image":1307,"meta":1309,"navigation":256,"path":1310,"seo":1311,"stem":1312,"updated":1313,"__hash__":1314},"posts\u002F3.guides\u002F41.add-a-news-filter-to-your-mt4-expert-advisor.md","How to Add a News Filter to Your MT4 Expert Advisor",[7],{"name":8,"to":9,"avatar":10},"ShowMyTrades Team","https:\u002F\u002Fshowmytrades.com",{"src":11},"\u002Ficon-512.png",{"label":13},"Automation",{"type":15,"value":16,"toc":1292},"minimark",[17,27,40,45,56,140,144,159,165,176,180,195,952,958,962,965,1031,1042,1053,1057,1060,1122,1126,1176,1180,1188,1192,1203,1209,1219,1225,1235,1246,1250,1277,1280,1288],[18,19,20,21,26],"p",{},"An ",[22,23,25],"a",{"href":24},"\u002Fglossary\u002Fwhat-is-an-expert-advisor","Expert Advisor"," that trades through Non-Farm Payrolls or a rate decision is not trading its strategy: it is flipping a coin with a wide spread. A news filter fixes that. It pauses new entries for a few minutes before and after the releases that move the market, and lets the strategy do its job the rest of the time.",[18,28,29,30,34,35,39],{},"MetaTrader 5 has a calendar built in. ",[31,32,33],"strong",{},"MetaTrader 4 does not",", so the EA has to fetch the news from somewhere. This guide uses the free ",[22,36,38],{"href":37},"\u002Fdocs\u002Fapi\u002Feconomic-calendar","ShowMyTrades economic calendar API",": no account, no API key, one URL to allow in the terminal, and an include file you can paste into any EA.",[41,42,44],"h2",{"id":43},"what-you-are-building","🧭 What You Are Building",[46,47,52],"pre",{"className":48,"code":50,"language":51},[49],"language-text","every 15 minutes          every tick\n┌───────────────────┐     ┌────────────────────────────────┐\n│ download the next │ ──► │ is a release within            │\n│ 2 days of news    │     │ [-30 min, +30 min] of now?     │\n│ (CSV, one request)│     │   yes → no new entries         │\n└───────────────────┘     │   no  → run the strategy       │\n                          └────────────────────────────────┘\n","text",[53,54,50],"code",{"__ignoreMap":55},"",[57,58,59,75],"table",{},[60,61,62],"thead",{},[63,64,65,69,72],"tr",{},[66,67,68],"th",{},"Decision",[66,70,71],{},"Default in the code",[66,73,74],{},"Why",[76,77,78,92,108,119,129],"tbody",{},[63,79,80,84,89],{},[81,82,83],"td",{},"Which currencies",[81,85,86],{},[53,87,88],{},"EUR,USD",[81,90,91],{},"The two sides of the pair you trade. Empty means all nine majors",[63,93,94,97,102],{},[81,95,96],{},"Which impact",[81,98,99],{},[53,100,101],{},"high",[81,103,104,107],{},[53,105,106],{},"high,medium"," for a more cautious filter",[63,109,110,113,116],{},[81,111,112],{},"Pause before",[81,114,115],{},"30 minutes",[81,117,118],{},"Spreads widen and liquidity thins before the number",[63,120,121,124,126],{},[81,122,123],{},"Pause after",[81,125,115],{},[81,127,128],{},"The first reaction and the reversal both happen here",[63,130,131,134,137],{},[81,132,133],{},"Download interval",[81,135,136],{},"15 minutes",[81,138,139],{},"The calendar changes a few times a day; the API caches for 15 minutes anyway",[41,141,143],{"id":142},"step-1-allow-the-address-in-metatrader","🔑 Step 1: Allow the Address in MetaTrader",[18,145,146,149,150,153,154,158],{},[53,147,148],{},"WebRequest()",", the MQL4 function that downloads from the internet, only talks to addresses you have approved. In the terminal open ",[31,151,152],{},"Tools → Options → Expert Advisors",", tick ",[155,156,157],"em",{},"Allow WebRequest for listed URL"," and add:",[46,160,163],{"className":161,"code":162,"language":51,"meta":55},[49],"https:\u002F\u002Fshowmytrades.com\n",[53,164,162],{"__ignoreMap":55},[18,166,167,168,171,172,175],{},"Skip this and the download returns ",[53,169,170],{},"-1"," with error ",[53,173,174],{},"4060",". The include file prints a reminder in the Experts tab when that happens, so you will not wonder why the filter is silent.",[41,177,179],{"id":178},"step-2-save-the-include-file","📄 Step 2: Save the Include File",[18,181,182,183,186,187,190,191,194],{},"Save the following as ",[53,184,185],{},"SMT_NewsFilter.mqh"," in the ",[53,188,189],{},"MQL4\\Include"," folder of your terminal (File → Open Data Folder). It is the same file documented in the ",[22,192,193],{"href":37},"API reference",", and it also compiles in MQL5 unchanged.",[46,196,200],{"className":197,"code":198,"filename":185,"language":199,"meta":55,"style":55},"language-cpp shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F+------------------------------------------------------------------+\n\u002F\u002F| SMT_NewsFilter.mqh - news filter for MT4 and MT5                 |\n\u002F\u002F| Data: https:\u002F\u002Fshowmytrades.com\u002Fapi\u002Fpublic\u002Fcalendar\u002Fv1 (free)     |\n\u002F\u002F| Docs: https:\u002F\u002Fshowmytrades.com\u002Fdocs\u002Fapi\u002Feconomic-calendar        |\n\u002F\u002F| Setup: Tools > Options > Expert Advisors > Allow WebRequest for  |\n\u002F\u002F|        https:\u002F\u002Fshowmytrades.com                                  |\n\u002F\u002F+------------------------------------------------------------------+\n#property strict\n\ninput string SMT_Currencies     = \"EUR,USD\"; \u002F\u002F News: currencies (comma-separated, empty = all)\ninput string SMT_Impact         = \"high\";    \u002F\u002F News: impact (high | high,medium | all)\ninput int    SMT_MinutesBefore  = 30;        \u002F\u002F News: pause before a release (minutes)\ninput int    SMT_MinutesAfter   = 30;        \u002F\u002F News: pause after a release (minutes)\ninput int    SMT_RefreshMinutes = 15;        \u002F\u002F News: download interval (minutes, min 15)\n\ndatetime smt_eventTime[];\nstring   smt_eventTitle[];\ndatetime smt_nextDownload = 0;\nlong     smt_serverTime   = 0;     \u002F\u002F server UTC (Unix seconds) at the last download\nuint     smt_syncTick     = 0;     \u002F\u002F GetTickCount() at that moment\nbool     smt_clockSynced  = false;\n\n\u002F\u002F--- the real UTC time: the server's clock plus the milliseconds elapsed since the\n\u002F\u002F--- download, counted with GetTickCount(), which ignores time zones, daylight saving\n\u002F\u002F--- and clock corrections on the computer (the uint subtraction survives its wrap).\n\u002F\u002F--- Before the first download it falls back to TimeGMT(). Never TimeCurrent(): the\n\u002F\u002F--- broker's GMT offset is unknown and jumps with daylight saving.\ndatetime SMT_Now()\n{\n   if(!smt_clockSynced) return TimeGMT();\n   uint elapsedMs = GetTickCount() - smt_syncTick;\n   return (datetime)(smt_serverTime + elapsedMs \u002F 1000);\n}\n\n\u002F\u002F--- how far the broker's clock is from UTC, in seconds (7200 = GMT+2). Handy on its\n\u002F\u002F--- own: most EAs never know it. TimeCurrent() is the time of the last tick, so read\n\u002F\u002F--- this while the market is open, not over the weekend.\nint SMT_BrokerGmtOffsetSeconds()\n{\n   return (int)(TimeCurrent() - SMT_Now());\n}\n\n\u002F\u002F--- everything after the n-th comma (the CSV title, which may itself contain commas)\nstring SMT_AfterComma(const string line, const int n)\n{\n   int pos = -1;\n   for(int i = 0; i \u003C n; i++)\n   {\n      pos = StringFind(line, \",\", pos + 1);\n      if(pos \u003C 0) return \"\";\n   }\n   string rest = StringSubstr(line, pos + 1);\n   StringReplace(rest, \"\\\"\\\"\", \"\\\"\");\n   if(StringLen(rest) >= 2 && StringGetCharacter(rest, 0) == '\"')\n      rest = StringSubstr(rest, 1, StringLen(rest) - 2);\n   return rest;\n}\n\n\u002F\u002F--- downloads the next 2 days (the window also covers the last 6 hours)\nbool SMT_Download()\n{\n   string url = \"https:\u002F\u002Fshowmytrades.com\u002Fapi\u002Fpublic\u002Fcalendar\u002Fv1?format=csv&days=2&impact=\" + SMT_Impact;\n   if(StringLen(SMT_Currencies) > 0) url += \"&currency=\" + SMT_Currencies;\n\n   char   post[], result[];\n   string headers;\n   ResetLastError();\n   int status = WebRequest(\"GET\", url, \"\", NULL, 10000, post, 0, result, headers);\n   if(status != 200)\n   {\n      Print(\"[SMT] calendar download failed: HTTP \", status, \", error \", GetLastError(),\n            \". Is https:\u002F\u002Fshowmytrades.com in Tools > Options > Expert Advisors > Allow WebRequest?\");\n      smt_nextDownload = TimeCurrent() + 60; \u002F\u002F retry in a minute\n      return false;\n   }\n\n   string body = CharArrayToString(result, 0, WHOLE_ARRAY, CP_UTF8);\n   string lines[];\n   int n = StringSplit(body, '\\n', lines);\n\n   ArrayResize(smt_eventTime, 0);\n   ArrayResize(smt_eventTitle, 0);\n   for(int i = 1; i \u003C n; i++) \u002F\u002F line 0 is the header\n   {\n      \u002F\u002F last line \"# server_time=1760702400 server_time_iso=...\": the server's UTC clock\n      if(StringFind(lines[i], \"# server_time=\") == 0)\n      {\n         long serverTime = StringToInteger(StringSubstr(lines[i], 14, 10));\n         if(serverTime > 0)\n         {\n            smt_serverTime  = serverTime;\n            smt_syncTick    = GetTickCount();\n            smt_clockSynced = true;\n         }\n         continue;\n      }\n      string f[];\n      if(StringSplit(lines[i], ',', f) \u003C 8) continue;\n      int k = ArraySize(smt_eventTime);\n      ArrayResize(smt_eventTime, k + 1);\n      ArrayResize(smt_eventTitle, k + 1);\n      smt_eventTime[k]  = (datetime)StringToInteger(f[0]);      \u002F\u002F Unix seconds, UTC\n      smt_eventTitle[k] = f[2] + \" \" + f[3] + \": \" + SMT_AfterComma(lines[i], 7);\n   }\n   smt_nextDownload = TimeCurrent() + MathMax(SMT_RefreshMinutes, 15) * 60;\n   Print(\"[SMT] calendar: \", ArraySize(smt_eventTime), \" events loaded. UTC now \",\n         TimeToString(SMT_Now(), TIME_DATE|TIME_MINUTES), \", broker clock is GMT\",\n         (SMT_BrokerGmtOffsetSeconds() >= 0 ? \"+\" : \"\"), DoubleToString(SMT_BrokerGmtOffsetSeconds() \u002F 3600.0, 1));\n   return true;\n}\n\n\u002F\u002F--- true while a release is within the pause window; reason tells which one\nbool SMT_IsNewsTime(string &reason)\n{\n   reason = \"\";\n   if(MQLInfoInteger(MQL_TESTER)) return false;   \u002F\u002F no network in the tester\n   if(TimeCurrent() >= smt_nextDownload) SMT_Download();\n\n   datetime now = SMT_Now();\n   for(int i = 0; i \u003C ArraySize(smt_eventTime); i++)\n   {\n      if(now >= smt_eventTime[i] - SMT_MinutesBefore * 60 && now \u003C= smt_eventTime[i] + SMT_MinutesAfter * 60)\n      {\n         reason = smt_eventTitle[i];\n         return true;\n      }\n   }\n   return false;\n}\n","cpp",[53,201,202,210,216,222,228,234,240,245,251,258,264,270,276,282,288,293,299,305,311,317,323,329,334,340,346,352,358,364,370,376,382,388,394,400,405,411,417,423,429,434,440,445,450,456,462,467,473,479,485,491,497,503,509,515,521,527,533,538,543,549,555,560,566,572,577,583,589,595,601,607,612,618,624,630,636,641,646,652,658,664,669,675,681,687,692,698,704,710,716,722,728,734,740,746,752,758,764,770,776,782,788,794,800,806,811,817,823,829,835,841,846,851,857,863,868,874,880,886,891,897,903,908,914,919,925,931,936,941,947],{"__ignoreMap":55},[203,204,207],"span",{"class":205,"line":206},"line",1,[203,208,209],{},"\u002F\u002F+------------------------------------------------------------------+\n",[203,211,213],{"class":205,"line":212},2,[203,214,215],{},"\u002F\u002F| SMT_NewsFilter.mqh - news filter for MT4 and MT5                 |\n",[203,217,219],{"class":205,"line":218},3,[203,220,221],{},"\u002F\u002F| Data: https:\u002F\u002Fshowmytrades.com\u002Fapi\u002Fpublic\u002Fcalendar\u002Fv1 (free)     |\n",[203,223,225],{"class":205,"line":224},4,[203,226,227],{},"\u002F\u002F| Docs: https:\u002F\u002Fshowmytrades.com\u002Fdocs\u002Fapi\u002Feconomic-calendar        |\n",[203,229,231],{"class":205,"line":230},5,[203,232,233],{},"\u002F\u002F| Setup: Tools > Options > Expert Advisors > Allow WebRequest for  |\n",[203,235,237],{"class":205,"line":236},6,[203,238,239],{},"\u002F\u002F|        https:\u002F\u002Fshowmytrades.com                                  |\n",[203,241,243],{"class":205,"line":242},7,[203,244,209],{},[203,246,248],{"class":205,"line":247},8,[203,249,250],{},"#property strict\n",[203,252,254],{"class":205,"line":253},9,[203,255,257],{"emptyLinePlaceholder":256},true,"\n",[203,259,261],{"class":205,"line":260},10,[203,262,263],{},"input string SMT_Currencies     = \"EUR,USD\"; \u002F\u002F News: currencies (comma-separated, empty = all)\n",[203,265,267],{"class":205,"line":266},11,[203,268,269],{},"input string SMT_Impact         = \"high\";    \u002F\u002F News: impact (high | high,medium | all)\n",[203,271,273],{"class":205,"line":272},12,[203,274,275],{},"input int    SMT_MinutesBefore  = 30;        \u002F\u002F News: pause before a release (minutes)\n",[203,277,279],{"class":205,"line":278},13,[203,280,281],{},"input int    SMT_MinutesAfter   = 30;        \u002F\u002F News: pause after a release (minutes)\n",[203,283,285],{"class":205,"line":284},14,[203,286,287],{},"input int    SMT_RefreshMinutes = 15;        \u002F\u002F News: download interval (minutes, min 15)\n",[203,289,291],{"class":205,"line":290},15,[203,292,257],{"emptyLinePlaceholder":256},[203,294,296],{"class":205,"line":295},16,[203,297,298],{},"datetime smt_eventTime[];\n",[203,300,302],{"class":205,"line":301},17,[203,303,304],{},"string   smt_eventTitle[];\n",[203,306,308],{"class":205,"line":307},18,[203,309,310],{},"datetime smt_nextDownload = 0;\n",[203,312,314],{"class":205,"line":313},19,[203,315,316],{},"long     smt_serverTime   = 0;     \u002F\u002F server UTC (Unix seconds) at the last download\n",[203,318,320],{"class":205,"line":319},20,[203,321,322],{},"uint     smt_syncTick     = 0;     \u002F\u002F GetTickCount() at that moment\n",[203,324,326],{"class":205,"line":325},21,[203,327,328],{},"bool     smt_clockSynced  = false;\n",[203,330,332],{"class":205,"line":331},22,[203,333,257],{"emptyLinePlaceholder":256},[203,335,337],{"class":205,"line":336},23,[203,338,339],{},"\u002F\u002F--- the real UTC time: the server's clock plus the milliseconds elapsed since the\n",[203,341,343],{"class":205,"line":342},24,[203,344,345],{},"\u002F\u002F--- download, counted with GetTickCount(), which ignores time zones, daylight saving\n",[203,347,349],{"class":205,"line":348},25,[203,350,351],{},"\u002F\u002F--- and clock corrections on the computer (the uint subtraction survives its wrap).\n",[203,353,355],{"class":205,"line":354},26,[203,356,357],{},"\u002F\u002F--- Before the first download it falls back to TimeGMT(). Never TimeCurrent(): the\n",[203,359,361],{"class":205,"line":360},27,[203,362,363],{},"\u002F\u002F--- broker's GMT offset is unknown and jumps with daylight saving.\n",[203,365,367],{"class":205,"line":366},28,[203,368,369],{},"datetime SMT_Now()\n",[203,371,373],{"class":205,"line":372},29,[203,374,375],{},"{\n",[203,377,379],{"class":205,"line":378},30,[203,380,381],{},"   if(!smt_clockSynced) return TimeGMT();\n",[203,383,385],{"class":205,"line":384},31,[203,386,387],{},"   uint elapsedMs = GetTickCount() - smt_syncTick;\n",[203,389,391],{"class":205,"line":390},32,[203,392,393],{},"   return (datetime)(smt_serverTime + elapsedMs \u002F 1000);\n",[203,395,397],{"class":205,"line":396},33,[203,398,399],{},"}\n",[203,401,403],{"class":205,"line":402},34,[203,404,257],{"emptyLinePlaceholder":256},[203,406,408],{"class":205,"line":407},35,[203,409,410],{},"\u002F\u002F--- how far the broker's clock is from UTC, in seconds (7200 = GMT+2). Handy on its\n",[203,412,414],{"class":205,"line":413},36,[203,415,416],{},"\u002F\u002F--- own: most EAs never know it. TimeCurrent() is the time of the last tick, so read\n",[203,418,420],{"class":205,"line":419},37,[203,421,422],{},"\u002F\u002F--- this while the market is open, not over the weekend.\n",[203,424,426],{"class":205,"line":425},38,[203,427,428],{},"int SMT_BrokerGmtOffsetSeconds()\n",[203,430,432],{"class":205,"line":431},39,[203,433,375],{},[203,435,437],{"class":205,"line":436},40,[203,438,439],{},"   return (int)(TimeCurrent() - SMT_Now());\n",[203,441,443],{"class":205,"line":442},41,[203,444,399],{},[203,446,448],{"class":205,"line":447},42,[203,449,257],{"emptyLinePlaceholder":256},[203,451,453],{"class":205,"line":452},43,[203,454,455],{},"\u002F\u002F--- everything after the n-th comma (the CSV title, which may itself contain commas)\n",[203,457,459],{"class":205,"line":458},44,[203,460,461],{},"string SMT_AfterComma(const string line, const int n)\n",[203,463,465],{"class":205,"line":464},45,[203,466,375],{},[203,468,470],{"class":205,"line":469},46,[203,471,472],{},"   int pos = -1;\n",[203,474,476],{"class":205,"line":475},47,[203,477,478],{},"   for(int i = 0; i \u003C n; i++)\n",[203,480,482],{"class":205,"line":481},48,[203,483,484],{},"   {\n",[203,486,488],{"class":205,"line":487},49,[203,489,490],{},"      pos = StringFind(line, \",\", pos + 1);\n",[203,492,494],{"class":205,"line":493},50,[203,495,496],{},"      if(pos \u003C 0) return \"\";\n",[203,498,500],{"class":205,"line":499},51,[203,501,502],{},"   }\n",[203,504,506],{"class":205,"line":505},52,[203,507,508],{},"   string rest = StringSubstr(line, pos + 1);\n",[203,510,512],{"class":205,"line":511},53,[203,513,514],{},"   StringReplace(rest, \"\\\"\\\"\", \"\\\"\");\n",[203,516,518],{"class":205,"line":517},54,[203,519,520],{},"   if(StringLen(rest) >= 2 && StringGetCharacter(rest, 0) == '\"')\n",[203,522,524],{"class":205,"line":523},55,[203,525,526],{},"      rest = StringSubstr(rest, 1, StringLen(rest) - 2);\n",[203,528,530],{"class":205,"line":529},56,[203,531,532],{},"   return rest;\n",[203,534,536],{"class":205,"line":535},57,[203,537,399],{},[203,539,541],{"class":205,"line":540},58,[203,542,257],{"emptyLinePlaceholder":256},[203,544,546],{"class":205,"line":545},59,[203,547,548],{},"\u002F\u002F--- downloads the next 2 days (the window also covers the last 6 hours)\n",[203,550,552],{"class":205,"line":551},60,[203,553,554],{},"bool SMT_Download()\n",[203,556,558],{"class":205,"line":557},61,[203,559,375],{},[203,561,563],{"class":205,"line":562},62,[203,564,565],{},"   string url = \"https:\u002F\u002Fshowmytrades.com\u002Fapi\u002Fpublic\u002Fcalendar\u002Fv1?format=csv&days=2&impact=\" + SMT_Impact;\n",[203,567,569],{"class":205,"line":568},63,[203,570,571],{},"   if(StringLen(SMT_Currencies) > 0) url += \"&currency=\" + SMT_Currencies;\n",[203,573,575],{"class":205,"line":574},64,[203,576,257],{"emptyLinePlaceholder":256},[203,578,580],{"class":205,"line":579},65,[203,581,582],{},"   char   post[], result[];\n",[203,584,586],{"class":205,"line":585},66,[203,587,588],{},"   string headers;\n",[203,590,592],{"class":205,"line":591},67,[203,593,594],{},"   ResetLastError();\n",[203,596,598],{"class":205,"line":597},68,[203,599,600],{},"   int status = WebRequest(\"GET\", url, \"\", NULL, 10000, post, 0, result, headers);\n",[203,602,604],{"class":205,"line":603},69,[203,605,606],{},"   if(status != 200)\n",[203,608,610],{"class":205,"line":609},70,[203,611,484],{},[203,613,615],{"class":205,"line":614},71,[203,616,617],{},"      Print(\"[SMT] calendar download failed: HTTP \", status, \", error \", GetLastError(),\n",[203,619,621],{"class":205,"line":620},72,[203,622,623],{},"            \". Is https:\u002F\u002Fshowmytrades.com in Tools > Options > Expert Advisors > Allow WebRequest?\");\n",[203,625,627],{"class":205,"line":626},73,[203,628,629],{},"      smt_nextDownload = TimeCurrent() + 60; \u002F\u002F retry in a minute\n",[203,631,633],{"class":205,"line":632},74,[203,634,635],{},"      return false;\n",[203,637,639],{"class":205,"line":638},75,[203,640,502],{},[203,642,644],{"class":205,"line":643},76,[203,645,257],{"emptyLinePlaceholder":256},[203,647,649],{"class":205,"line":648},77,[203,650,651],{},"   string body = CharArrayToString(result, 0, WHOLE_ARRAY, CP_UTF8);\n",[203,653,655],{"class":205,"line":654},78,[203,656,657],{},"   string lines[];\n",[203,659,661],{"class":205,"line":660},79,[203,662,663],{},"   int n = StringSplit(body, '\\n', lines);\n",[203,665,667],{"class":205,"line":666},80,[203,668,257],{"emptyLinePlaceholder":256},[203,670,672],{"class":205,"line":671},81,[203,673,674],{},"   ArrayResize(smt_eventTime, 0);\n",[203,676,678],{"class":205,"line":677},82,[203,679,680],{},"   ArrayResize(smt_eventTitle, 0);\n",[203,682,684],{"class":205,"line":683},83,[203,685,686],{},"   for(int i = 1; i \u003C n; i++) \u002F\u002F line 0 is the header\n",[203,688,690],{"class":205,"line":689},84,[203,691,484],{},[203,693,695],{"class":205,"line":694},85,[203,696,697],{},"      \u002F\u002F last line \"# server_time=1760702400 server_time_iso=...\": the server's UTC clock\n",[203,699,701],{"class":205,"line":700},86,[203,702,703],{},"      if(StringFind(lines[i], \"# server_time=\") == 0)\n",[203,705,707],{"class":205,"line":706},87,[203,708,709],{},"      {\n",[203,711,713],{"class":205,"line":712},88,[203,714,715],{},"         long serverTime = StringToInteger(StringSubstr(lines[i], 14, 10));\n",[203,717,719],{"class":205,"line":718},89,[203,720,721],{},"         if(serverTime > 0)\n",[203,723,725],{"class":205,"line":724},90,[203,726,727],{},"         {\n",[203,729,731],{"class":205,"line":730},91,[203,732,733],{},"            smt_serverTime  = serverTime;\n",[203,735,737],{"class":205,"line":736},92,[203,738,739],{},"            smt_syncTick    = GetTickCount();\n",[203,741,743],{"class":205,"line":742},93,[203,744,745],{},"            smt_clockSynced = true;\n",[203,747,749],{"class":205,"line":748},94,[203,750,751],{},"         }\n",[203,753,755],{"class":205,"line":754},95,[203,756,757],{},"         continue;\n",[203,759,761],{"class":205,"line":760},96,[203,762,763],{},"      }\n",[203,765,767],{"class":205,"line":766},97,[203,768,769],{},"      string f[];\n",[203,771,773],{"class":205,"line":772},98,[203,774,775],{},"      if(StringSplit(lines[i], ',', f) \u003C 8) continue;\n",[203,777,779],{"class":205,"line":778},99,[203,780,781],{},"      int k = ArraySize(smt_eventTime);\n",[203,783,785],{"class":205,"line":784},100,[203,786,787],{},"      ArrayResize(smt_eventTime, k + 1);\n",[203,789,791],{"class":205,"line":790},101,[203,792,793],{},"      ArrayResize(smt_eventTitle, k + 1);\n",[203,795,797],{"class":205,"line":796},102,[203,798,799],{},"      smt_eventTime[k]  = (datetime)StringToInteger(f[0]);      \u002F\u002F Unix seconds, UTC\n",[203,801,803],{"class":205,"line":802},103,[203,804,805],{},"      smt_eventTitle[k] = f[2] + \" \" + f[3] + \": \" + SMT_AfterComma(lines[i], 7);\n",[203,807,809],{"class":205,"line":808},104,[203,810,502],{},[203,812,814],{"class":205,"line":813},105,[203,815,816],{},"   smt_nextDownload = TimeCurrent() + MathMax(SMT_RefreshMinutes, 15) * 60;\n",[203,818,820],{"class":205,"line":819},106,[203,821,822],{},"   Print(\"[SMT] calendar: \", ArraySize(smt_eventTime), \" events loaded. UTC now \",\n",[203,824,826],{"class":205,"line":825},107,[203,827,828],{},"         TimeToString(SMT_Now(), TIME_DATE|TIME_MINUTES), \", broker clock is GMT\",\n",[203,830,832],{"class":205,"line":831},108,[203,833,834],{},"         (SMT_BrokerGmtOffsetSeconds() >= 0 ? \"+\" : \"\"), DoubleToString(SMT_BrokerGmtOffsetSeconds() \u002F 3600.0, 1));\n",[203,836,838],{"class":205,"line":837},109,[203,839,840],{},"   return true;\n",[203,842,844],{"class":205,"line":843},110,[203,845,399],{},[203,847,849],{"class":205,"line":848},111,[203,850,257],{"emptyLinePlaceholder":256},[203,852,854],{"class":205,"line":853},112,[203,855,856],{},"\u002F\u002F--- true while a release is within the pause window; reason tells which one\n",[203,858,860],{"class":205,"line":859},113,[203,861,862],{},"bool SMT_IsNewsTime(string &reason)\n",[203,864,866],{"class":205,"line":865},114,[203,867,375],{},[203,869,871],{"class":205,"line":870},115,[203,872,873],{},"   reason = \"\";\n",[203,875,877],{"class":205,"line":876},116,[203,878,879],{},"   if(MQLInfoInteger(MQL_TESTER)) return false;   \u002F\u002F no network in the tester\n",[203,881,883],{"class":205,"line":882},117,[203,884,885],{},"   if(TimeCurrent() >= smt_nextDownload) SMT_Download();\n",[203,887,889],{"class":205,"line":888},118,[203,890,257],{"emptyLinePlaceholder":256},[203,892,894],{"class":205,"line":893},119,[203,895,896],{},"   datetime now = SMT_Now();\n",[203,898,900],{"class":205,"line":899},120,[203,901,902],{},"   for(int i = 0; i \u003C ArraySize(smt_eventTime); i++)\n",[203,904,906],{"class":205,"line":905},121,[203,907,484],{},[203,909,911],{"class":205,"line":910},122,[203,912,913],{},"      if(now >= smt_eventTime[i] - SMT_MinutesBefore * 60 && now \u003C= smt_eventTime[i] + SMT_MinutesAfter * 60)\n",[203,915,917],{"class":205,"line":916},123,[203,918,709],{},[203,920,922],{"class":205,"line":921},124,[203,923,924],{},"         reason = smt_eventTitle[i];\n",[203,926,928],{"class":205,"line":927},125,[203,929,930],{},"         return true;\n",[203,932,934],{"class":205,"line":933},126,[203,935,763],{},[203,937,939],{"class":205,"line":938},127,[203,940,502],{},[203,942,944],{"class":205,"line":943},128,[203,945,946],{},"   return false;\n",[203,948,950],{"class":205,"line":949},129,[203,951,399],{},[18,953,954,955],{},"What it does, in order: builds the request from the inputs, downloads the CSV, keeps one timestamp and one label per event, and answers the only question the EA cares about: ",[155,956,957],{},"is a release within the window right now?",[41,959,961],{"id":960},"step-3-call-it-before-every-entry","🔌 Step 3: Call It Before Every Entry",[18,963,964],{},"In your EA, include the file and ask before opening a position:",[46,966,969],{"className":197,"code":967,"filename":968,"language":199,"meta":55,"style":55},"#include \u003CSMT_NewsFilter.mqh>\n\nvoid OnTick()\n{\n   string news;\n   if(SMT_IsNewsTime(news))\n   {\n      Comment(\"News filter active: \", news);\n      return;                       \u002F\u002F no new entries during the news window\n   }\n   Comment(\"\");\n   \u002F\u002F ... your entry logic ...\n}\n","YourEA.mq4",[53,970,971,976,980,985,989,994,999,1003,1008,1013,1017,1022,1027],{"__ignoreMap":55},[203,972,973],{"class":205,"line":206},[203,974,975],{},"#include \u003CSMT_NewsFilter.mqh>\n",[203,977,978],{"class":205,"line":212},[203,979,257],{"emptyLinePlaceholder":256},[203,981,982],{"class":205,"line":218},[203,983,984],{},"void OnTick()\n",[203,986,987],{"class":205,"line":224},[203,988,375],{},[203,990,991],{"class":205,"line":230},[203,992,993],{},"   string news;\n",[203,995,996],{"class":205,"line":236},[203,997,998],{},"   if(SMT_IsNewsTime(news))\n",[203,1000,1001],{"class":205,"line":242},[203,1002,484],{},[203,1004,1005],{"class":205,"line":247},[203,1006,1007],{},"      Comment(\"News filter active: \", news);\n",[203,1009,1010],{"class":205,"line":253},[203,1011,1012],{},"      return;                       \u002F\u002F no new entries during the news window\n",[203,1014,1015],{"class":205,"line":260},[203,1016,502],{},[203,1018,1019],{"class":205,"line":266},[203,1020,1021],{},"   Comment(\"\");\n",[203,1023,1024],{"class":205,"line":272},[203,1025,1026],{},"   \u002F\u002F ... your entry logic ...\n",[203,1028,1029],{"class":205,"line":278},[203,1030,399],{},[18,1032,1033,1034,1037,1038,1041],{},"The five inputs (",[53,1035,1036],{},"SMT_Currencies",", ",[53,1039,1040],{},"SMT_Impact",", and the three minute values) appear in the EA's input dialog like any other setting, so each chart can have its own.",[18,1043,1044,1045,1048,1049,1052],{},"Recompile, attach the EA, and look at the Experts tab: the first line should be ",[53,1046,1047],{},"[SMT] calendar: N events loaded",". On a quiet day ",[53,1050,1051],{},"N"," can be zero, which is correct, not an error.",[41,1054,1056],{"id":1055},"️-times-clocks-and-the-tester","⏱️ Times, Clocks and the Tester",[18,1058,1059],{},"Three details decide whether the filter fires at the right minute.",[57,1061,1062,1070],{},[60,1063,1064],{},[63,1065,1066,1068],{},[66,1067],{},[66,1069],{},[76,1071,1072,1093,1110],{},[63,1073,1074,1079],{},[81,1075,1076],{},[31,1077,1078],{},"The API speaks UTC, and says what time it is",[81,1080,1081,1084,1085,1088,1089,1092],{},[53,1082,1083],{},"ts"," is Unix time in seconds, UTC. Every download ends with the server's own clock (",[53,1086,1087],{},"# server_time=…","), and ",[53,1090,1091],{},"SMT_Now()"," carries it forward with the computer's tick counter, which ignores time zones and daylight saving. Nothing depends on the broker's time zone, on daylight saving anywhere, or on the VPS being set to the right zone",[63,1094,1095,1103],{},[81,1096,1097],{},[31,1098,1099,1100],{},"Never ",[53,1101,1102],{},"TimeCurrent()",[81,1104,1105,1106,1109],{},"Broker time sits at an offset from UTC that the EA cannot know and that changes twice a year. ",[53,1107,1108],{},"SMT_BrokerGmtOffsetSeconds()"," measures it for you, which is useful on its own; the filter never relies on it",[63,1111,1112,1117],{},[81,1113,1114],{},[31,1115,1116],{},"The strategy tester has no internet",[81,1118,1119,1121],{},[53,1120,148],{}," is disabled there, so the function returns \"no news\" in backtests. Testing a news filter on history needs a local file of past events, which is a different project",[41,1123,1125],{"id":1124},"️-tuning-it","🎛️ Tuning It",[1127,1128,1129,1144,1157,1167],"ul",{},[1130,1131,1132,1135,1136,1139,1140,1143],"li",{},[31,1133,1134],{},"Open positions."," The code only blocks ",[155,1137,1138],{},"new"," entries. Whether to close, tighten stops or widen them before a release is a strategy decision; the same ",[53,1141,1142],{},"SMT_IsNewsTime()"," tells you when to do it.",[1130,1145,1146,1149,1150,1152,1153,1156],{},[31,1147,1148],{},"One side of the pair only."," Set ",[53,1151,1036],{}," to ",[53,1154,1155],{},"USD"," if only dollar news matters to you.",[1130,1158,1159,1162,1163,1166],{},[31,1160,1161],{},"Medium impact too."," ",[53,1164,1165],{},"SMT_Impact = \"high,medium\""," roughly triples the events. Good for scalpers, often too much for swing systems.",[1130,1168,1169,1162,1172,1175],{},[31,1170,1171],{},"Holidays.",[53,1173,1174],{},"impact=all"," includes market holidays as all-day events. Most filters do not want them; the default leaves them out.",[41,1177,1179],{"id":1178},"checking-the-data","🔍 Checking the Data",[18,1181,1182,1183,1187],{},"The same calendar is a page you can read: ",[22,1184,1186],{"href":1185},"\u002Ftools\u002Feconomic-calendar","economic calendar",". When the EA says it paused for \"USD high: Nonfarm Payrolls\", you can see the event there with its forecast and, after the release, its actual.",[41,1189,1191],{"id":1190},"faq","❓ FAQ",[18,1193,1194,1197,1198,1202],{},[31,1195,1196],{},"Does this need a ShowMyTrades account?","\nNo. The calendar API is free and open, with no key. Track your account on ShowMyTrades if you want the ",[22,1199,1201],{"href":1200},"\u002Fguides\u002Fhow-to-verify-your-account","verified public page",", but the news filter does not depend on it.",[18,1204,1205,1208],{},[31,1206,1207],{},"How much traffic does it generate?","\nOne request every 15 minutes per chart, a few kilobytes each. Ten EAs on one terminal are 40 requests an hour. The limit is 600 per minute per IP address.",[18,1210,1211,1214,1215,1218],{},[31,1212,1213],{},"Why not read Forex Factory directly?","\nYou can, and many EAs do. Its weekly file allows two downloads every five minutes per IP address, which breaks on a VPS running many terminals, and it has no ",[53,1216,1217],{},"actual"," values. The ShowMyTrades endpoint filters by currency and impact on the server, returns a few kilobytes and is built for polling.",[18,1220,1221,1224],{},[31,1222,1223],{},"My VPS clock or time zone is wrong. Does the filter still fire at the right minute?","\nYes. The server tells the EA what time it is in UTC with every download, and the EA keeps that clock running with its own. A VPS set to the wrong zone, or a few minutes off, changes nothing. Even a daylight-saving switch on the VPS changes nothing: the EA counts elapsed time with the tick counter, not with the clock.",[18,1226,1227,1230,1231,1234],{},[31,1228,1229],{},"What if the download fails?","\nThe filter keeps the last calendar it loaded and retries after a minute. If it never loaded one (fresh start, no internet) it reports \"no news\", so the EA trades: if that is not what you want, check ",[53,1232,1233],{},"ArraySize(smt_eventTime) == 0"," and decide.",[18,1236,1237,1240,1241,1245],{},[31,1238,1239],{},"Does the same file work in MT5?","\nYes, unchanged. MT5 also has a ",[22,1242,1244],{"href":1243},"\u002Fguides\u002Fnews-filter-mt5-expert-advisor-built-in-calendar-or-api","calendar of its own","; use whichever suits you.",[41,1247,1249],{"id":1248},"related","🔗 Related",[1127,1251,1252,1258,1263,1270],{},[1130,1253,1254,1257],{},[22,1255,1256],{"href":37},"Economic calendar API reference",": every parameter, the JSON format, the WebSocket for cTrader",[1130,1259,1260],{},[22,1261,1262],{"href":1243},"News filter in MT5: built-in calendar or API",[1130,1264,1265,1269],{},[22,1266,1268],{"href":1267},"\u002Fguides\u002Fadd-a-news-filter-to-a-ctrader-cbot","News filter for a cTrader cBot",": the same idea where HTTP is not available",[1130,1271,1272,1276],{},[22,1273,1275],{"href":1274},"\u002Fguides\u002Flive-ea-results-on-your-sales-page","Show live EA results on your sales page",": once the EA trades well, show it",[1278,1279],"hr",{},[18,1281,1282,1283,1287],{},"The filter is a page of code and a URL. If your EA is already ",[22,1284,1286],{"href":1285},"\u002Fsignup","tracked on ShowMyTrades",", the trades it skips around the news will show up as the drawdown it did not take.",[1289,1290,1291],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":55,"searchDepth":212,"depth":212,"links":1293},[1294,1295,1296,1297,1298,1299,1300,1301,1302],{"id":43,"depth":212,"text":44},{"id":142,"depth":212,"text":143},{"id":178,"depth":212,"text":179},{"id":960,"depth":212,"text":961},{"id":1055,"depth":212,"text":1056},{"id":1124,"depth":212,"text":1125},{"id":1178,"depth":212,"text":1179},{"id":1190,"depth":212,"text":1191},{"id":1248,"depth":212,"text":1249},"2026-10-17T00:00:00.000Z","MetaTrader 4 has no economic calendar for Expert Advisors. This guide adds one in ten minutes: a free calendar API, one include file, one function to call before every entry. Full MQL4 code, no API key.",false,"md",{"src":1308},"\u002Fimages\u002Fblog\u002Fadd-a-news-filter-to-your-mt4-expert-advisor-hero.svg",{},"\u002Fguides\u002Fadd-a-news-filter-to-your-mt4-expert-advisor",{"title":5,"description":1304},"3.guides\u002F41.add-a-news-filter-to-your-mt4-expert-advisor",null,"bZsSK0xUm3IscnPGzknUwaChppAIME8YQpkFFlOPMa8",[1316,1321],{"title":1317,"path":1318,"stem":1319,"description":1320,"children":-1},"How to Show Multiple Trading Accounts on One Page","\u002Fguides\u002Fshow-multiple-trading-accounts-on-one-page","3.guides\u002F40.show-multiple-trading-accounts-on-one-page","Several accounts, several EAs or several brokers on a single web page: a live comparison table with one row per account, side-by-side charts, or one combined curve. With the code.",{"title":1322,"path":1243,"stem":1323,"description":1324,"children":-1},"News Filter in MT5: the Built-in Calendar or an API?","3.guides\u002F42.news-filter-mt5-expert-advisor-built-in-calendar-or-api","MetaTrader 5 ships an economic calendar that Expert Advisors can read with no download. When it is enough, when it is not, and how to use a free calendar API instead, with MQL5 code for both.",1792249019790]