[{"data":1,"prerenderedAt":3500},["ShallowReactive",2],{"\u002Fdocs\u002Fapi\u002Feconomic-calendar":3,"docs-api-navigation":3389,"\u002Fdocs\u002Fapi\u002Feconomic-calendar-surround":3495},{"id":4,"title":5,"body":6,"description":3380,"extension":3381,"meta":3382,"navigation":3383,"path":3385,"seo":3386,"stem":3387,"__hash__":3388},"docs\u002F1.docs\u002F2.api\u002F6.economic-calendar.md","Economic calendar API",{"type":7,"value":8,"toc":3370},"minimark",[9,32,51,63,76,81,170,177,181,184,204,768,844,850,876,891,895,898,959,981,1015,1025,1028,1040,1079,1095,1099,1114,1140,1861,1864,1930,1933,1980,1984,1999,2006,2013,2019,2044,2060,2071,3033,3062,3066,3069,3124,3127,3195,3211,3247,3251,3270,3274,3363,3366],[10,11,16],"pre",{"className":12,"code":13,"language":14,"meta":15,"style":15},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","GET https:\u002F\u002Fshowmytrades.com\u002Fapi\u002Fpublic\u002Fcalendar\u002Fv1\n","bash","",[17,18,19],"code",{"__ignoreMap":15},[20,21,24,28],"span",{"class":22,"line":23},"line",1,[20,25,27],{"class":26},"sBMFI","GET",[20,29,31],{"class":30},"sfazB"," https:\u002F\u002Fshowmytrades.com\u002Fapi\u002Fpublic\u002Fcalendar\u002Fv1\n",[33,34,35,36,40,41,46,47,50],"p",{},"Scheduled macroeconomic releases, central-bank decisions and speeches, and market holidays for\n",[37,38,39],"strong",{},"USD, EUR, GBP, JPY, AUD, NZD, CAD, CHF and CNY",", with forecast, previous and actual values.\nThe same data as the ",[42,43,45],"a",{"href":44},"\u002Ftools\u002Feconomic-calendar","economic calendar page",", in a format made for\ncode: ",[37,48,49],{},"Unix timestamps, lowercase impact levels, JSON or CSV",".",[33,52,53,54,57,58,62],{},"It is ",[37,55,56],{},"free and needs no API key",". The typical use is a ",[59,60,61],"em",{},"news filter",": a trading robot that\npauses before and after high-impact news. This page has the endpoint, then working code for\nMetaTrader 4, MetaTrader 5 and cTrader that you can paste as it is.",[64,65,66],"note",{},[33,67,68,71,72,75],{},[37,69,70],{},"One request every 15 minutes is all a robot needs."," The calendar changes a few times a day,\nresponses are cached for 15 minutes on our side, and a request with ",[17,73,74],{},"If-None-Match"," costs\nnothing while the data is unchanged. The limit is 600 requests per minute per IP address, so\ndozens of terminals on one VPS can start at the same time without being refused.",[77,78,80],"h2",{"id":79},"query-parameters","Query parameters",[82,83,84,100,131,157],"field-group",{},[85,86,89],"field",{"name":87,"type":88},"currency","string",[33,90,91,92,95,96,99],{},"Comma-separated ISO codes among ",[17,93,94],{},"USD, EUR, GBP, JPY, AUD, NZD, CAD, CHF, CNY",". Example:\n",[17,97,98],{},"currency=EUR,USD",". Omit it for all nine.",[85,101,103],{"name":102,"type":88},"impact",[33,104,105,106,109,110,109,113,109,116,119,120,123,124,126,127,130],{},"Comma-separated levels among ",[17,107,108],{},"high",", ",[17,111,112],{},"medium",[17,114,115],{},"low",[17,117,118],{},"holiday",", or ",[17,121,122],{},"all",". Defaults to\n",[17,125,108],{},". ",[17,128,129],{},"impact=high,medium"," is the usual choice for a cautious filter.",[85,132,135],{"name":133,"type":134},"days","integer",[33,136,137,138,141,142,145,146,148,149,152,153,156],{},"How many days ahead, from ",[17,139,140],{},"1"," to ",[17,143,144],{},"30",". Defaults to ",[17,147,140],{},". The window always starts ",[37,150,151],{},"6 hours\nin the past",", so a filter that pauses ",[59,154,155],{},"after"," a release still sees the release.",[85,158,160],{"name":159,"type":88},"format",[33,161,162,165,166,169],{},[17,163,164],{},"json"," (default) or ",[17,167,168],{},"csv",". CSV is easier to parse in MQL.",[33,171,172,173,176],{},"Anything outside those lists is a ",[17,174,175],{},"400"," with a message that says what is allowed, so a\nmisconfigured robot notices on its first run instead of trading through the news.",[77,178,180],{"id":179},"example","Example",[33,182,183],{},"Today's high-impact news for the euro and the dollar:",[10,185,187],{"className":12,"code":186,"language":14,"meta":15,"style":15},"curl \"https:\u002F\u002Fshowmytrades.com\u002Fapi\u002Fpublic\u002Fcalendar\u002Fv1?currency=EUR,USD&impact=high&days=1\"\n",[17,188,189],{"__ignoreMap":15},[20,190,191,194,198,201],{"class":22,"line":23},[20,192,193],{"class":26},"curl",[20,195,197],{"class":196},"sMK4o"," \"",[20,199,200],{"class":30},"https:\u002F\u002Fshowmytrades.com\u002Fapi\u002Fpublic\u002Fcalendar\u002Fv1?currency=EUR,USD&impact=high&days=1",[20,202,203],{"class":196},"\"\n",[10,205,209],{"className":206,"code":207,"filename":208,"language":164,"meta":15,"style":15},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"server_time\": 1760685160,\n  \"server_time_iso\": \"2026-10-17T07:12:40Z\",\n  \"generated_at\": \"2026-10-17T07:12:40Z\",\n  \"from\": \"2026-10-17T01:12:40Z\",\n  \"to\": \"2026-10-18T07:12:40Z\",\n  \"count\": 2,\n  \"events\": [\n    {\n      \"ts\": 1760702400,\n      \"time\": \"2026-10-17T12:00:00Z\",\n      \"currency\": \"EUR\",\n      \"impact\": \"high\",\n      \"title\": \"ECB President Lagarde Speech\",\n      \"forecast\": \"\",\n      \"previous\": \"\",\n      \"actual\": \"\"\n    },\n    {\n      \"ts\": 1760704200,\n      \"time\": \"2026-10-17T12:30:00Z\",\n      \"currency\": \"USD\",\n      \"impact\": \"high\",\n      \"title\": \"Building Permits MoM\",\n      \"forecast\": \"1.33M\",\n      \"previous\": \"1.31M\",\n      \"actual\": \"\"\n    }\n  ],\n  \"attribution\": { \"required\": false, \"text\": \"Economic calendar by ShowMyTrades\", \"url\": \"https:\u002F\u002Fshowmytrades.com\u002Ftools\u002Feconomic-calendar\" },\n  \"docs\": \"https:\u002F\u002Fshowmytrades.com\u002Fdocs\u002Fapi\u002Feconomic-calendar\"\n}\n","Response",[17,210,211,216,239,260,280,301,322,339,354,360,378,399,419,438,459,476,492,507,513,518,534,554,574,593,613,633,653,666,672,678,743,762],{"__ignoreMap":15},[20,212,213],{"class":22,"line":23},[20,214,215],{"class":196},"{\n",[20,217,219,222,226,229,232,236],{"class":22,"line":218},2,[20,220,221],{"class":196},"  \"",[20,223,225],{"class":224},"spNyl","server_time",[20,227,228],{"class":196},"\"",[20,230,231],{"class":196},":",[20,233,235],{"class":234},"sbssI"," 1760685160",[20,237,238],{"class":196},",\n",[20,240,242,244,247,249,251,253,256,258],{"class":22,"line":241},3,[20,243,221],{"class":196},[20,245,246],{"class":224},"server_time_iso",[20,248,228],{"class":196},[20,250,231],{"class":196},[20,252,197],{"class":196},[20,254,255],{"class":30},"2026-10-17T07:12:40Z",[20,257,228],{"class":196},[20,259,238],{"class":196},[20,261,263,265,268,270,272,274,276,278],{"class":22,"line":262},4,[20,264,221],{"class":196},[20,266,267],{"class":224},"generated_at",[20,269,228],{"class":196},[20,271,231],{"class":196},[20,273,197],{"class":196},[20,275,255],{"class":30},[20,277,228],{"class":196},[20,279,238],{"class":196},[20,281,283,285,288,290,292,294,297,299],{"class":22,"line":282},5,[20,284,221],{"class":196},[20,286,287],{"class":224},"from",[20,289,228],{"class":196},[20,291,231],{"class":196},[20,293,197],{"class":196},[20,295,296],{"class":30},"2026-10-17T01:12:40Z",[20,298,228],{"class":196},[20,300,238],{"class":196},[20,302,304,306,309,311,313,315,318,320],{"class":22,"line":303},6,[20,305,221],{"class":196},[20,307,308],{"class":224},"to",[20,310,228],{"class":196},[20,312,231],{"class":196},[20,314,197],{"class":196},[20,316,317],{"class":30},"2026-10-18T07:12:40Z",[20,319,228],{"class":196},[20,321,238],{"class":196},[20,323,325,327,330,332,334,337],{"class":22,"line":324},7,[20,326,221],{"class":196},[20,328,329],{"class":224},"count",[20,331,228],{"class":196},[20,333,231],{"class":196},[20,335,336],{"class":234}," 2",[20,338,238],{"class":196},[20,340,342,344,347,349,351],{"class":22,"line":341},8,[20,343,221],{"class":196},[20,345,346],{"class":224},"events",[20,348,228],{"class":196},[20,350,231],{"class":196},[20,352,353],{"class":196}," [\n",[20,355,357],{"class":22,"line":356},9,[20,358,359],{"class":196},"    {\n",[20,361,363,366,369,371,373,376],{"class":22,"line":362},10,[20,364,365],{"class":196},"      \"",[20,367,368],{"class":26},"ts",[20,370,228],{"class":196},[20,372,231],{"class":196},[20,374,375],{"class":234}," 1760702400",[20,377,238],{"class":196},[20,379,381,383,386,388,390,392,395,397],{"class":22,"line":380},11,[20,382,365],{"class":196},[20,384,385],{"class":26},"time",[20,387,228],{"class":196},[20,389,231],{"class":196},[20,391,197],{"class":196},[20,393,394],{"class":30},"2026-10-17T12:00:00Z",[20,396,228],{"class":196},[20,398,238],{"class":196},[20,400,402,404,406,408,410,412,415,417],{"class":22,"line":401},12,[20,403,365],{"class":196},[20,405,87],{"class":26},[20,407,228],{"class":196},[20,409,231],{"class":196},[20,411,197],{"class":196},[20,413,414],{"class":30},"EUR",[20,416,228],{"class":196},[20,418,238],{"class":196},[20,420,422,424,426,428,430,432,434,436],{"class":22,"line":421},13,[20,423,365],{"class":196},[20,425,102],{"class":26},[20,427,228],{"class":196},[20,429,231],{"class":196},[20,431,197],{"class":196},[20,433,108],{"class":30},[20,435,228],{"class":196},[20,437,238],{"class":196},[20,439,441,443,446,448,450,452,455,457],{"class":22,"line":440},14,[20,442,365],{"class":196},[20,444,445],{"class":26},"title",[20,447,228],{"class":196},[20,449,231],{"class":196},[20,451,197],{"class":196},[20,453,454],{"class":30},"ECB President Lagarde Speech",[20,456,228],{"class":196},[20,458,238],{"class":196},[20,460,462,464,467,469,471,474],{"class":22,"line":461},15,[20,463,365],{"class":196},[20,465,466],{"class":26},"forecast",[20,468,228],{"class":196},[20,470,231],{"class":196},[20,472,473],{"class":196}," \"\"",[20,475,238],{"class":196},[20,477,479,481,484,486,488,490],{"class":22,"line":478},16,[20,480,365],{"class":196},[20,482,483],{"class":26},"previous",[20,485,228],{"class":196},[20,487,231],{"class":196},[20,489,473],{"class":196},[20,491,238],{"class":196},[20,493,495,497,500,502,504],{"class":22,"line":494},17,[20,496,365],{"class":196},[20,498,499],{"class":26},"actual",[20,501,228],{"class":196},[20,503,231],{"class":196},[20,505,506],{"class":196}," \"\"\n",[20,508,510],{"class":22,"line":509},18,[20,511,512],{"class":196},"    },\n",[20,514,516],{"class":22,"line":515},19,[20,517,359],{"class":196},[20,519,521,523,525,527,529,532],{"class":22,"line":520},20,[20,522,365],{"class":196},[20,524,368],{"class":26},[20,526,228],{"class":196},[20,528,231],{"class":196},[20,530,531],{"class":234}," 1760704200",[20,533,238],{"class":196},[20,535,537,539,541,543,545,547,550,552],{"class":22,"line":536},21,[20,538,365],{"class":196},[20,540,385],{"class":26},[20,542,228],{"class":196},[20,544,231],{"class":196},[20,546,197],{"class":196},[20,548,549],{"class":30},"2026-10-17T12:30:00Z",[20,551,228],{"class":196},[20,553,238],{"class":196},[20,555,557,559,561,563,565,567,570,572],{"class":22,"line":556},22,[20,558,365],{"class":196},[20,560,87],{"class":26},[20,562,228],{"class":196},[20,564,231],{"class":196},[20,566,197],{"class":196},[20,568,569],{"class":30},"USD",[20,571,228],{"class":196},[20,573,238],{"class":196},[20,575,577,579,581,583,585,587,589,591],{"class":22,"line":576},23,[20,578,365],{"class":196},[20,580,102],{"class":26},[20,582,228],{"class":196},[20,584,231],{"class":196},[20,586,197],{"class":196},[20,588,108],{"class":30},[20,590,228],{"class":196},[20,592,238],{"class":196},[20,594,596,598,600,602,604,606,609,611],{"class":22,"line":595},24,[20,597,365],{"class":196},[20,599,445],{"class":26},[20,601,228],{"class":196},[20,603,231],{"class":196},[20,605,197],{"class":196},[20,607,608],{"class":30},"Building Permits MoM",[20,610,228],{"class":196},[20,612,238],{"class":196},[20,614,616,618,620,622,624,626,629,631],{"class":22,"line":615},25,[20,617,365],{"class":196},[20,619,466],{"class":26},[20,621,228],{"class":196},[20,623,231],{"class":196},[20,625,197],{"class":196},[20,627,628],{"class":30},"1.33M",[20,630,228],{"class":196},[20,632,238],{"class":196},[20,634,636,638,640,642,644,646,649,651],{"class":22,"line":635},26,[20,637,365],{"class":196},[20,639,483],{"class":26},[20,641,228],{"class":196},[20,643,231],{"class":196},[20,645,197],{"class":196},[20,647,648],{"class":30},"1.31M",[20,650,228],{"class":196},[20,652,238],{"class":196},[20,654,656,658,660,662,664],{"class":22,"line":655},27,[20,657,365],{"class":196},[20,659,499],{"class":26},[20,661,228],{"class":196},[20,663,231],{"class":196},[20,665,506],{"class":196},[20,667,669],{"class":22,"line":668},28,[20,670,671],{"class":196},"    }\n",[20,673,675],{"class":22,"line":674},29,[20,676,677],{"class":196},"  ],\n",[20,679,681,683,686,688,690,693,695,698,700,702,705,707,710,712,714,716,719,721,724,726,729,731,733,735,738,740],{"class":22,"line":680},30,[20,682,221],{"class":196},[20,684,685],{"class":224},"attribution",[20,687,228],{"class":196},[20,689,231],{"class":196},[20,691,692],{"class":196}," {",[20,694,197],{"class":196},[20,696,697],{"class":26},"required",[20,699,228],{"class":196},[20,701,231],{"class":196},[20,703,704],{"class":196}," false,",[20,706,197],{"class":196},[20,708,709],{"class":26},"text",[20,711,228],{"class":196},[20,713,231],{"class":196},[20,715,197],{"class":196},[20,717,718],{"class":30},"Economic calendar by ShowMyTrades",[20,720,228],{"class":196},[20,722,723],{"class":196},",",[20,725,197],{"class":196},[20,727,728],{"class":26},"url",[20,730,228],{"class":196},[20,732,231],{"class":196},[20,734,197],{"class":196},[20,736,737],{"class":30},"https:\u002F\u002Fshowmytrades.com\u002Ftools\u002Feconomic-calendar",[20,739,228],{"class":196},[20,741,742],{"class":196}," },\n",[20,744,746,748,751,753,755,757,760],{"class":22,"line":745},31,[20,747,221],{"class":196},[20,749,750],{"class":224},"docs",[20,752,228],{"class":196},[20,754,231],{"class":196},[20,756,197],{"class":196},[20,758,759],{"class":30},"https:\u002F\u002Fshowmytrades.com\u002Fdocs\u002Fapi\u002Feconomic-calendar",[20,761,203],{"class":196},[20,763,765],{"class":22,"line":764},32,[20,766,767],{"class":196},"}\n",[82,769,770,787,806,811,825],{},[85,771,774],{"name":772,"type":773},"server_time \u002F server_time_iso","integer \u002F string",[33,775,776,779,780,782,783,50],{},[37,777,778],{},"What time it is now, in UTC",", as the server sees it: Unix seconds and ISO 8601. This is\nthe clock to compare ",[17,781,368],{}," against. It is fresh on every response, even when the rest of\nthe body comes from cache. See ",[42,784,786],{"href":785},"#clocks-which-time-to-trust","Clocks",[85,788,789],{"name":368,"type":134},[33,790,791,792,795,796,799,800,802,803,50],{},"The release time as ",[37,793,794],{},"Unix time in seconds, UTC",". In MQL it is a ",[17,797,798],{},"datetime"," as it is;\ncompare it with the clock derived from ",[17,801,225],{},", never with the broker's ",[17,804,805],{},"TimeCurrent()",[85,807,808],{"name":385,"type":88},[33,809,810],{},"The same instant in ISO 8601 UTC, for humans and for languages with a date parser.",[85,812,813],{"name":102,"type":88},[33,814,815,109,817,109,819,821,822,824],{},[17,816,108],{},[17,818,112],{},[17,820,115],{}," or ",[17,823,118],{},". A holiday is a closed market, not a release: its time\nis the start of the day.",[85,826,828],{"name":827,"type":88},"forecast \u002F previous \u002F actual",[33,829,830,831,109,834,109,837,840,841,843],{},"Strings exactly as published: ",[17,832,833],{},"\"0.3%\"",[17,835,836],{},"\"$70.5B\"",[17,838,839],{},"\"1.33M\"",". Empty when not available.\n",[17,842,499],{}," is empty until the release and is filled in minutes after it.",[33,845,846,847,231],{},"The same request with ",[17,848,849],{},"format=csv",[10,851,854],{"className":852,"code":853,"language":168,"meta":15,"style":15},"language-csv shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","ts,time,currency,impact,forecast,previous,actual,title\n1760702400,2026-10-17T12:00:00Z,EUR,high,,,,ECB President Lagarde Speech\n1760704200,2026-10-17T12:30:00Z,USD,high,1.33M,1.31M,,Building Permits MoM\n# server_time=1760685160 server_time_iso=2026-10-17T07:12:40Z\n",[17,855,856,861,866,871],{"__ignoreMap":15},[20,857,858],{"class":22,"line":23},[20,859,860],{},"ts,time,currency,impact,forecast,previous,actual,title\n",[20,862,863],{"class":22,"line":218},[20,864,865],{},"1760702400,2026-10-17T12:00:00Z,EUR,high,,,,ECB President Lagarde Speech\n",[20,867,868],{"class":22,"line":241},[20,869,870],{},"1760704200,2026-10-17T12:30:00Z,USD,high,1.33M,1.31M,,Building Permits MoM\n",[20,872,873],{"class":22,"line":262},[20,874,875],{},"# server_time=1760685160 server_time_iso=2026-10-17T07:12:40Z\n",[33,877,878,879,882,883,886,887,890],{},"The title is the ",[37,880,881],{},"last"," column because it is the only one that can contain a comma (it is then\nwrapped in double quotes, RFC 4180). Read the first seven columns with a split on commas and\ntake everything after the seventh comma as the title. The ",[37,884,885],{},"last line"," starts with ",[17,888,889],{},"#"," and\ncarries the server's clock; a parser that only looks at lines with eight fields skips it on\nits own.",[77,892,894],{"id":893},"clocks-which-time-to-trust","Clocks: which time to trust",[33,896,897],{},"The most common bug in a news filter is not the calendar, it is the clock. A robot has three\nof them and none says what it is:",[899,900,901,917],"table",{},[902,903,904],"thead",{},[905,906,907,911,914],"tr",{},[908,909,910],"th",{},"Clock",[908,912,913],{},"In MQL",[908,915,916],{},"What it really is",[918,919,920,933,946],"tbody",{},[905,921,922,926,930],{},[923,924,925],"td",{},"Broker time",[923,927,928],{},[17,929,805],{},[923,931,932],{},"The broker's server time, at an offset from UTC the robot does not know, which changes with daylight saving, and which stops moving over the weekend",[905,934,935,938,943],{},[923,936,937],{},"Computer time",[923,939,940],{},[17,941,942],{},"TimeLocal()",[923,944,945],{},"The VPS clock, in whatever time zone the VPS was set up in, possibly drifting",[905,947,948,951,956],{},[923,949,950],{},"\"GMT\"",[923,952,953],{},[17,954,955],{},"TimeGMT()",[923,957,958],{},"The computer clock converted by Windows: right only if the clock and the time zone are both right",[33,960,961,962,965,966,968,969,972,973,976,977,980],{},"This API removes the guesswork. ",[37,963,964],{},"Every response says what time it is",", in UTC, as the\nserver sees it, at the moment of the response: ",[17,967,225],{}," in the JSON, the ",[17,970,971],{},"# server_time=","\nline at the end of the CSV, and the ",[17,974,975],{},"X-Server-Time"," header on every HTTP response, the ",[17,978,979],{},"304","\nincluded. The recipe, which the code below implements:",[982,983,984,995,1008],"ol",{},[985,986,987,988,990,991,994],"li",{},"At every download remember ",[17,989,225],{}," and the computer's tick counter (",[17,992,993],{},"GetTickCount()",").",[985,996,997,998,1001,1002,1005,1006,50],{},"From then on, ",[59,999,1000],{},"now"," is ",[17,1003,1004],{},"server_time + elapsed ticks",". Compare that with ",[17,1007,368],{},[985,1009,1010,1011,1014],{},"As a bonus, ",[17,1012,1013],{},"TimeCurrent() − now"," is the broker's GMT offset, measured rather than guessed.",[33,1016,1017,1018,1021,1022,1024],{},"The tick counter ignores time zones, daylight saving and clock corrections on the VPS, and it\nis realigned at every download, so nothing can drift. ",[37,1019,1020],{},"Daylight saving never enters the\npicture at any level",": the release times come from the sources already in UTC for each date\n(Non-Farm Payrolls is 13:30 UTC in summer and 14:30 UTC in winter, and ",[17,1023,368],{}," says so), the\nbroker's clock is never used to compare, and the broker's offset is measured live, so its\nown switch is picked up at the next download.",[33,1026,1027],{},"If you only want the clock, without the calendar:",[10,1029,1031],{"className":12,"code":1030,"language":14,"meta":15,"style":15},"GET https:\u002F\u002Fshowmytrades.com\u002Fapi\u002Fpublic\u002Ftime\n",[17,1032,1033],{"__ignoreMap":15},[20,1034,1035,1037],{"class":22,"line":23},[20,1036,27],{"class":26},[20,1038,1039],{"class":30}," https:\u002F\u002Fshowmytrades.com\u002Fapi\u002Fpublic\u002Ftime\n",[10,1041,1043],{"className":206,"code":1042,"filename":208,"language":164,"meta":15,"style":15},"{ \"server_time\": 1760685160, \"server_time_iso\": \"2026-10-17T07:12:40Z\" }\n",[17,1044,1045],{"__ignoreMap":15},[20,1046,1047,1050,1052,1054,1056,1058,1060,1062,1064,1066,1068,1070,1072,1074,1076],{"class":22,"line":23},[20,1048,1049],{"class":196},"{",[20,1051,197],{"class":196},[20,1053,225],{"class":224},[20,1055,228],{"class":196},[20,1057,231],{"class":196},[20,1059,235],{"class":234},[20,1061,723],{"class":196},[20,1063,197],{"class":196},[20,1065,246],{"class":224},[20,1067,228],{"class":196},[20,1069,231],{"class":196},[20,1071,197],{"class":196},[20,1073,255],{"class":30},[20,1075,228],{"class":196},[20,1077,1078],{"class":196}," }\n",[33,1080,1081,1082,1085,1086,1088,1089,1091,1092,1094],{},"Never cached, no key, also on port 25345 (HTTP ",[17,1083,1084],{},"GET \u002Fapi\u002Fpublic\u002Ftime",", or the text ",[17,1087,385],{}," over\nthe WebSocket). ",[17,1090,225],{}," is the current time; ",[17,1093,267],{}," in the JSON is when the\ncalendar body was assembled, up to five minutes earlier, and is not a clock.",[77,1096,1098],{"id":1097},"metatrader-4-and-5-a-news-filter-in-one-include-file","MetaTrader 4 and 5: a news filter in one include file",[33,1100,1101,1102,1105,1106,1109,1110,1113],{},"The same file compiles in MQL4 and MQL5. Save it as ",[17,1103,1104],{},"SMT_NewsFilter.mqh"," in ",[17,1107,1108],{},"MQL4\\Include","\n(or ",[17,1111,1112],{},"MQL5\\Include","), then include it in your Expert Advisor.",[33,1115,1116,1119,1120,1123,1124,1127,1128,1131,1132,1135,1136,1139],{},[37,1117,1118],{},"Before it can download anything",", allow the address in the terminal: Tools → Options →\nExpert Advisors → tick ",[59,1121,1122],{},"Allow WebRequest for listed URL"," and add ",[17,1125,1126],{},"https:\u002F\u002Fshowmytrades.com",".\nWithout that line ",[17,1129,1130],{},"WebRequest()"," returns ",[17,1133,1134],{},"-1"," and error ",[17,1137,1138],{},"4060","; the file prints a reminder.",[10,1141,1145],{"className":1142,"code":1143,"filename":1104,"language":1144,"meta":15,"style":15},"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",[17,1146,1147,1152,1157,1162,1167,1172,1177,1181,1186,1192,1197,1202,1207,1212,1217,1221,1226,1231,1236,1241,1246,1251,1255,1260,1265,1270,1275,1280,1285,1289,1294,1299,1304,1309,1314,1320,1326,1332,1338,1343,1349,1354,1359,1365,1371,1376,1382,1388,1394,1400,1406,1412,1418,1424,1430,1436,1442,1447,1452,1458,1464,1469,1475,1481,1486,1492,1498,1504,1510,1516,1521,1527,1533,1539,1545,1550,1555,1561,1567,1573,1578,1584,1590,1596,1601,1607,1613,1619,1625,1631,1637,1643,1649,1655,1661,1667,1673,1679,1685,1691,1697,1703,1709,1715,1720,1726,1732,1738,1744,1750,1755,1760,1766,1772,1777,1783,1789,1795,1800,1806,1812,1817,1823,1828,1834,1840,1845,1850,1856],{"__ignoreMap":15},[20,1148,1149],{"class":22,"line":23},[20,1150,1151],{},"\u002F\u002F+------------------------------------------------------------------+\n",[20,1153,1154],{"class":22,"line":218},[20,1155,1156],{},"\u002F\u002F| SMT_NewsFilter.mqh - news filter for MT4 and MT5                 |\n",[20,1158,1159],{"class":22,"line":241},[20,1160,1161],{},"\u002F\u002F| Data: https:\u002F\u002Fshowmytrades.com\u002Fapi\u002Fpublic\u002Fcalendar\u002Fv1 (free)     |\n",[20,1163,1164],{"class":22,"line":262},[20,1165,1166],{},"\u002F\u002F| Docs: https:\u002F\u002Fshowmytrades.com\u002Fdocs\u002Fapi\u002Feconomic-calendar        |\n",[20,1168,1169],{"class":22,"line":282},[20,1170,1171],{},"\u002F\u002F| Setup: Tools > Options > Expert Advisors > Allow WebRequest for  |\n",[20,1173,1174],{"class":22,"line":303},[20,1175,1176],{},"\u002F\u002F|        https:\u002F\u002Fshowmytrades.com                                  |\n",[20,1178,1179],{"class":22,"line":324},[20,1180,1151],{},[20,1182,1183],{"class":22,"line":341},[20,1184,1185],{},"#property strict\n",[20,1187,1188],{"class":22,"line":356},[20,1189,1191],{"emptyLinePlaceholder":1190},true,"\n",[20,1193,1194],{"class":22,"line":362},[20,1195,1196],{},"input string SMT_Currencies     = \"EUR,USD\"; \u002F\u002F News: currencies (comma-separated, empty = all)\n",[20,1198,1199],{"class":22,"line":380},[20,1200,1201],{},"input string SMT_Impact         = \"high\";    \u002F\u002F News: impact (high | high,medium | all)\n",[20,1203,1204],{"class":22,"line":401},[20,1205,1206],{},"input int    SMT_MinutesBefore  = 30;        \u002F\u002F News: pause before a release (minutes)\n",[20,1208,1209],{"class":22,"line":421},[20,1210,1211],{},"input int    SMT_MinutesAfter   = 30;        \u002F\u002F News: pause after a release (minutes)\n",[20,1213,1214],{"class":22,"line":440},[20,1215,1216],{},"input int    SMT_RefreshMinutes = 15;        \u002F\u002F News: download interval (minutes, min 15)\n",[20,1218,1219],{"class":22,"line":461},[20,1220,1191],{"emptyLinePlaceholder":1190},[20,1222,1223],{"class":22,"line":478},[20,1224,1225],{},"datetime smt_eventTime[];\n",[20,1227,1228],{"class":22,"line":494},[20,1229,1230],{},"string   smt_eventTitle[];\n",[20,1232,1233],{"class":22,"line":509},[20,1234,1235],{},"datetime smt_nextDownload = 0;\n",[20,1237,1238],{"class":22,"line":515},[20,1239,1240],{},"long     smt_serverTime   = 0;     \u002F\u002F server UTC (Unix seconds) at the last download\n",[20,1242,1243],{"class":22,"line":520},[20,1244,1245],{},"uint     smt_syncTick     = 0;     \u002F\u002F GetTickCount() at that moment\n",[20,1247,1248],{"class":22,"line":536},[20,1249,1250],{},"bool     smt_clockSynced  = false;\n",[20,1252,1253],{"class":22,"line":556},[20,1254,1191],{"emptyLinePlaceholder":1190},[20,1256,1257],{"class":22,"line":576},[20,1258,1259],{},"\u002F\u002F--- the real UTC time: the server's clock plus the milliseconds elapsed since the\n",[20,1261,1262],{"class":22,"line":595},[20,1263,1264],{},"\u002F\u002F--- download, counted with GetTickCount(), which ignores time zones, daylight saving\n",[20,1266,1267],{"class":22,"line":615},[20,1268,1269],{},"\u002F\u002F--- and clock corrections on the computer (the uint subtraction survives its wrap).\n",[20,1271,1272],{"class":22,"line":635},[20,1273,1274],{},"\u002F\u002F--- Before the first download it falls back to TimeGMT(). Never TimeCurrent(): the\n",[20,1276,1277],{"class":22,"line":655},[20,1278,1279],{},"\u002F\u002F--- broker's GMT offset is unknown and jumps with daylight saving.\n",[20,1281,1282],{"class":22,"line":668},[20,1283,1284],{},"datetime SMT_Now()\n",[20,1286,1287],{"class":22,"line":674},[20,1288,215],{},[20,1290,1291],{"class":22,"line":680},[20,1292,1293],{},"   if(!smt_clockSynced) return TimeGMT();\n",[20,1295,1296],{"class":22,"line":745},[20,1297,1298],{},"   uint elapsedMs = GetTickCount() - smt_syncTick;\n",[20,1300,1301],{"class":22,"line":764},[20,1302,1303],{},"   return (datetime)(smt_serverTime + elapsedMs \u002F 1000);\n",[20,1305,1307],{"class":22,"line":1306},33,[20,1308,767],{},[20,1310,1312],{"class":22,"line":1311},34,[20,1313,1191],{"emptyLinePlaceholder":1190},[20,1315,1317],{"class":22,"line":1316},35,[20,1318,1319],{},"\u002F\u002F--- how far the broker's clock is from UTC, in seconds (7200 = GMT+2). Handy on its\n",[20,1321,1323],{"class":22,"line":1322},36,[20,1324,1325],{},"\u002F\u002F--- own: most EAs never know it. TimeCurrent() is the time of the last tick, so read\n",[20,1327,1329],{"class":22,"line":1328},37,[20,1330,1331],{},"\u002F\u002F--- this while the market is open, not over the weekend.\n",[20,1333,1335],{"class":22,"line":1334},38,[20,1336,1337],{},"int SMT_BrokerGmtOffsetSeconds()\n",[20,1339,1341],{"class":22,"line":1340},39,[20,1342,215],{},[20,1344,1346],{"class":22,"line":1345},40,[20,1347,1348],{},"   return (int)(TimeCurrent() - SMT_Now());\n",[20,1350,1352],{"class":22,"line":1351},41,[20,1353,767],{},[20,1355,1357],{"class":22,"line":1356},42,[20,1358,1191],{"emptyLinePlaceholder":1190},[20,1360,1362],{"class":22,"line":1361},43,[20,1363,1364],{},"\u002F\u002F--- everything after the n-th comma (the CSV title, which may itself contain commas)\n",[20,1366,1368],{"class":22,"line":1367},44,[20,1369,1370],{},"string SMT_AfterComma(const string line, const int n)\n",[20,1372,1374],{"class":22,"line":1373},45,[20,1375,215],{},[20,1377,1379],{"class":22,"line":1378},46,[20,1380,1381],{},"   int pos = -1;\n",[20,1383,1385],{"class":22,"line":1384},47,[20,1386,1387],{},"   for(int i = 0; i \u003C n; i++)\n",[20,1389,1391],{"class":22,"line":1390},48,[20,1392,1393],{},"   {\n",[20,1395,1397],{"class":22,"line":1396},49,[20,1398,1399],{},"      pos = StringFind(line, \",\", pos + 1);\n",[20,1401,1403],{"class":22,"line":1402},50,[20,1404,1405],{},"      if(pos \u003C 0) return \"\";\n",[20,1407,1409],{"class":22,"line":1408},51,[20,1410,1411],{},"   }\n",[20,1413,1415],{"class":22,"line":1414},52,[20,1416,1417],{},"   string rest = StringSubstr(line, pos + 1);\n",[20,1419,1421],{"class":22,"line":1420},53,[20,1422,1423],{},"   StringReplace(rest, \"\\\"\\\"\", \"\\\"\");\n",[20,1425,1427],{"class":22,"line":1426},54,[20,1428,1429],{},"   if(StringLen(rest) >= 2 && StringGetCharacter(rest, 0) == '\"')\n",[20,1431,1433],{"class":22,"line":1432},55,[20,1434,1435],{},"      rest = StringSubstr(rest, 1, StringLen(rest) - 2);\n",[20,1437,1439],{"class":22,"line":1438},56,[20,1440,1441],{},"   return rest;\n",[20,1443,1445],{"class":22,"line":1444},57,[20,1446,767],{},[20,1448,1450],{"class":22,"line":1449},58,[20,1451,1191],{"emptyLinePlaceholder":1190},[20,1453,1455],{"class":22,"line":1454},59,[20,1456,1457],{},"\u002F\u002F--- downloads the next 2 days (the window also covers the last 6 hours)\n",[20,1459,1461],{"class":22,"line":1460},60,[20,1462,1463],{},"bool SMT_Download()\n",[20,1465,1467],{"class":22,"line":1466},61,[20,1468,215],{},[20,1470,1472],{"class":22,"line":1471},62,[20,1473,1474],{},"   string url = \"https:\u002F\u002Fshowmytrades.com\u002Fapi\u002Fpublic\u002Fcalendar\u002Fv1?format=csv&days=2&impact=\" + SMT_Impact;\n",[20,1476,1478],{"class":22,"line":1477},63,[20,1479,1480],{},"   if(StringLen(SMT_Currencies) > 0) url += \"&currency=\" + SMT_Currencies;\n",[20,1482,1484],{"class":22,"line":1483},64,[20,1485,1191],{"emptyLinePlaceholder":1190},[20,1487,1489],{"class":22,"line":1488},65,[20,1490,1491],{},"   char   post[], result[];\n",[20,1493,1495],{"class":22,"line":1494},66,[20,1496,1497],{},"   string headers;\n",[20,1499,1501],{"class":22,"line":1500},67,[20,1502,1503],{},"   ResetLastError();\n",[20,1505,1507],{"class":22,"line":1506},68,[20,1508,1509],{},"   int status = WebRequest(\"GET\", url, \"\", NULL, 10000, post, 0, result, headers);\n",[20,1511,1513],{"class":22,"line":1512},69,[20,1514,1515],{},"   if(status != 200)\n",[20,1517,1519],{"class":22,"line":1518},70,[20,1520,1393],{},[20,1522,1524],{"class":22,"line":1523},71,[20,1525,1526],{},"      Print(\"[SMT] calendar download failed: HTTP \", status, \", error \", GetLastError(),\n",[20,1528,1530],{"class":22,"line":1529},72,[20,1531,1532],{},"            \". Is https:\u002F\u002Fshowmytrades.com in Tools > Options > Expert Advisors > Allow WebRequest?\");\n",[20,1534,1536],{"class":22,"line":1535},73,[20,1537,1538],{},"      smt_nextDownload = TimeCurrent() + 60; \u002F\u002F retry in a minute\n",[20,1540,1542],{"class":22,"line":1541},74,[20,1543,1544],{},"      return false;\n",[20,1546,1548],{"class":22,"line":1547},75,[20,1549,1411],{},[20,1551,1553],{"class":22,"line":1552},76,[20,1554,1191],{"emptyLinePlaceholder":1190},[20,1556,1558],{"class":22,"line":1557},77,[20,1559,1560],{},"   string body = CharArrayToString(result, 0, WHOLE_ARRAY, CP_UTF8);\n",[20,1562,1564],{"class":22,"line":1563},78,[20,1565,1566],{},"   string lines[];\n",[20,1568,1570],{"class":22,"line":1569},79,[20,1571,1572],{},"   int n = StringSplit(body, '\\n', lines);\n",[20,1574,1576],{"class":22,"line":1575},80,[20,1577,1191],{"emptyLinePlaceholder":1190},[20,1579,1581],{"class":22,"line":1580},81,[20,1582,1583],{},"   ArrayResize(smt_eventTime, 0);\n",[20,1585,1587],{"class":22,"line":1586},82,[20,1588,1589],{},"   ArrayResize(smt_eventTitle, 0);\n",[20,1591,1593],{"class":22,"line":1592},83,[20,1594,1595],{},"   for(int i = 1; i \u003C n; i++) \u002F\u002F line 0 is the header\n",[20,1597,1599],{"class":22,"line":1598},84,[20,1600,1393],{},[20,1602,1604],{"class":22,"line":1603},85,[20,1605,1606],{},"      \u002F\u002F last line \"# server_time=1760702400 server_time_iso=...\": the server's UTC clock\n",[20,1608,1610],{"class":22,"line":1609},86,[20,1611,1612],{},"      if(StringFind(lines[i], \"# server_time=\") == 0)\n",[20,1614,1616],{"class":22,"line":1615},87,[20,1617,1618],{},"      {\n",[20,1620,1622],{"class":22,"line":1621},88,[20,1623,1624],{},"         long serverTime = StringToInteger(StringSubstr(lines[i], 14, 10));\n",[20,1626,1628],{"class":22,"line":1627},89,[20,1629,1630],{},"         if(serverTime > 0)\n",[20,1632,1634],{"class":22,"line":1633},90,[20,1635,1636],{},"         {\n",[20,1638,1640],{"class":22,"line":1639},91,[20,1641,1642],{},"            smt_serverTime  = serverTime;\n",[20,1644,1646],{"class":22,"line":1645},92,[20,1647,1648],{},"            smt_syncTick    = GetTickCount();\n",[20,1650,1652],{"class":22,"line":1651},93,[20,1653,1654],{},"            smt_clockSynced = true;\n",[20,1656,1658],{"class":22,"line":1657},94,[20,1659,1660],{},"         }\n",[20,1662,1664],{"class":22,"line":1663},95,[20,1665,1666],{},"         continue;\n",[20,1668,1670],{"class":22,"line":1669},96,[20,1671,1672],{},"      }\n",[20,1674,1676],{"class":22,"line":1675},97,[20,1677,1678],{},"      string f[];\n",[20,1680,1682],{"class":22,"line":1681},98,[20,1683,1684],{},"      if(StringSplit(lines[i], ',', f) \u003C 8) continue;\n",[20,1686,1688],{"class":22,"line":1687},99,[20,1689,1690],{},"      int k = ArraySize(smt_eventTime);\n",[20,1692,1694],{"class":22,"line":1693},100,[20,1695,1696],{},"      ArrayResize(smt_eventTime, k + 1);\n",[20,1698,1700],{"class":22,"line":1699},101,[20,1701,1702],{},"      ArrayResize(smt_eventTitle, k + 1);\n",[20,1704,1706],{"class":22,"line":1705},102,[20,1707,1708],{},"      smt_eventTime[k]  = (datetime)StringToInteger(f[0]);      \u002F\u002F Unix seconds, UTC\n",[20,1710,1712],{"class":22,"line":1711},103,[20,1713,1714],{},"      smt_eventTitle[k] = f[2] + \" \" + f[3] + \": \" + SMT_AfterComma(lines[i], 7);\n",[20,1716,1718],{"class":22,"line":1717},104,[20,1719,1411],{},[20,1721,1723],{"class":22,"line":1722},105,[20,1724,1725],{},"   smt_nextDownload = TimeCurrent() + MathMax(SMT_RefreshMinutes, 15) * 60;\n",[20,1727,1729],{"class":22,"line":1728},106,[20,1730,1731],{},"   Print(\"[SMT] calendar: \", ArraySize(smt_eventTime), \" events loaded. UTC now \",\n",[20,1733,1735],{"class":22,"line":1734},107,[20,1736,1737],{},"         TimeToString(SMT_Now(), TIME_DATE|TIME_MINUTES), \", broker clock is GMT\",\n",[20,1739,1741],{"class":22,"line":1740},108,[20,1742,1743],{},"         (SMT_BrokerGmtOffsetSeconds() >= 0 ? \"+\" : \"\"), DoubleToString(SMT_BrokerGmtOffsetSeconds() \u002F 3600.0, 1));\n",[20,1745,1747],{"class":22,"line":1746},109,[20,1748,1749],{},"   return true;\n",[20,1751,1753],{"class":22,"line":1752},110,[20,1754,767],{},[20,1756,1758],{"class":22,"line":1757},111,[20,1759,1191],{"emptyLinePlaceholder":1190},[20,1761,1763],{"class":22,"line":1762},112,[20,1764,1765],{},"\u002F\u002F--- true while a release is within the pause window; reason tells which one\n",[20,1767,1769],{"class":22,"line":1768},113,[20,1770,1771],{},"bool SMT_IsNewsTime(string &reason)\n",[20,1773,1775],{"class":22,"line":1774},114,[20,1776,215],{},[20,1778,1780],{"class":22,"line":1779},115,[20,1781,1782],{},"   reason = \"\";\n",[20,1784,1786],{"class":22,"line":1785},116,[20,1787,1788],{},"   if(MQLInfoInteger(MQL_TESTER)) return false;   \u002F\u002F no network in the tester\n",[20,1790,1792],{"class":22,"line":1791},117,[20,1793,1794],{},"   if(TimeCurrent() >= smt_nextDownload) SMT_Download();\n",[20,1796,1798],{"class":22,"line":1797},118,[20,1799,1191],{"emptyLinePlaceholder":1190},[20,1801,1803],{"class":22,"line":1802},119,[20,1804,1805],{},"   datetime now = SMT_Now();\n",[20,1807,1809],{"class":22,"line":1808},120,[20,1810,1811],{},"   for(int i = 0; i \u003C ArraySize(smt_eventTime); i++)\n",[20,1813,1815],{"class":22,"line":1814},121,[20,1816,1393],{},[20,1818,1820],{"class":22,"line":1819},122,[20,1821,1822],{},"      if(now >= smt_eventTime[i] - SMT_MinutesBefore * 60 && now \u003C= smt_eventTime[i] + SMT_MinutesAfter * 60)\n",[20,1824,1826],{"class":22,"line":1825},123,[20,1827,1618],{},[20,1829,1831],{"class":22,"line":1830},124,[20,1832,1833],{},"         reason = smt_eventTitle[i];\n",[20,1835,1837],{"class":22,"line":1836},125,[20,1838,1839],{},"         return true;\n",[20,1841,1843],{"class":22,"line":1842},126,[20,1844,1672],{},[20,1846,1848],{"class":22,"line":1847},127,[20,1849,1411],{},[20,1851,1853],{"class":22,"line":1852},128,[20,1854,1855],{},"   return false;\n",[20,1857,1859],{"class":22,"line":1858},129,[20,1860,767],{},[33,1862,1863],{},"Using it in an Expert Advisor:",[10,1865,1868],{"className":1142,"code":1866,"filename":1867,"language":1144,"meta":15,"style":15},"#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 \u002F .mq5",[17,1869,1870,1875,1879,1884,1888,1893,1898,1902,1907,1912,1916,1921,1926],{"__ignoreMap":15},[20,1871,1872],{"class":22,"line":23},[20,1873,1874],{},"#include \u003CSMT_NewsFilter.mqh>\n",[20,1876,1877],{"class":22,"line":218},[20,1878,1191],{"emptyLinePlaceholder":1190},[20,1880,1881],{"class":22,"line":241},[20,1882,1883],{},"void OnTick()\n",[20,1885,1886],{"class":22,"line":262},[20,1887,215],{},[20,1889,1890],{"class":22,"line":282},[20,1891,1892],{},"   string news;\n",[20,1894,1895],{"class":22,"line":303},[20,1896,1897],{},"   if(SMT_IsNewsTime(news))\n",[20,1899,1900],{"class":22,"line":324},[20,1901,1393],{},[20,1903,1904],{"class":22,"line":341},[20,1905,1906],{},"      Comment(\"News filter active: \", news);\n",[20,1908,1909],{"class":22,"line":356},[20,1910,1911],{},"      return;                       \u002F\u002F no new entries during the news window\n",[20,1913,1914],{"class":22,"line":362},[20,1915,1411],{},[20,1917,1918],{"class":22,"line":380},[20,1919,1920],{},"   Comment(\"\");\n",[20,1922,1923],{"class":22,"line":401},[20,1924,1925],{},"   \u002F\u002F ... your entry logic ...\n",[20,1927,1928],{"class":22,"line":421},[20,1929,767],{},[33,1931,1932],{},"A few things worth knowing:",[1934,1935,1936,1956,1964,1970],"ul",{},[985,1937,1938,1941,1942,1944,1945,1948,1949,1952,1953,1955],{},[37,1939,1940],{},"Times."," ",[17,1943,368],{}," is UTC. The file compares it with ",[17,1946,1947],{},"SMT_Now()",", the server's clock carried\nforward with the computer's clock, so neither the VPS time zone nor the broker's offset\nmatters. ",[17,1950,1951],{},"SMT_BrokerGmtOffsetSeconds()"," tells you the broker's offset, measured. Broker time\n(",[17,1954,805],{},") is only used to space the downloads.",[985,1957,1958,1941,1961,1963],{},[37,1959,1960],{},"The tester.",[17,1962,1130],{}," does not work in the strategy tester, so the filter returns\n\"no news\" there. Backtesting a news filter needs historical data stored locally; that is a\ndifferent job.",[985,1965,1966,1969],{},[37,1967,1968],{},"Several charts."," Each chart downloads on its own. Ten EAs on one terminal are ten\nrequests every 15 minutes, well inside the limits.",[985,1971,1972,1975,1976,1979],{},[37,1973,1974],{},"MT5 has a built-in calendar."," The ",[17,1977,1978],{},"Calendar*"," functions of MQL5 work without any download\non most brokers, and that is a fine choice. Use this API when the broker does not provide the\nbuilt-in calendar, when you want one file for MT4 and MT5, or when you want the same data on\ncTrader.",[77,1981,1983],{"id":1982},"ctrader-a-news-filter-for-a-cbot-cloud-included","cTrader: a news filter for a cBot, cloud included",[33,1985,1986,1987,1990,1991,1994,1995,1998],{},"cTrader Cloud does not let a cBot make HTTP requests: ",[17,1988,1989],{},"Http.Get()"," fails with status ",[17,1992,1993],{},"503","\nthere. The only network it allows is a ",[37,1996,1997],{},"WebSocket on port 25345",". So the calendar is also\nserved on that port:",[10,2000,2004],{"className":2001,"code":2003,"language":709,"meta":15},[2002],"language-text","ws:\u002F\u002Fshowmytrades.com:25345\u002F\n",[17,2005,2003],{"__ignoreMap":15},[33,2007,2008,2009,2012],{},"Open the socket, send ",[37,2010,2011],{},"one line of text"," with the same parameters as the HTTP query, and read\none text frame back with the same JSON or CSV body:",[10,2014,2017],{"className":2015,"code":2016,"language":709,"meta":15},[2002],"→ currency=EUR,USD&impact=high&days=2&format=csv\n← ts,time,currency,impact,forecast,previous,actual,title\n  1760704200,2026-10-17T12:30:00Z,USD,high,1.33M,1.31M,,Building Permits MoM\n  ...\n",[17,2018,2016],{"__ignoreMap":15},[33,2020,2021,2024,2025,109,2028,2024,2030,2033,2034,2037,2038,2040,2041,2043],{},[17,2022,2023],{},"ping"," answers ",[17,2026,2027],{},"pong",[17,2029,385],{},[17,2031,2032],{},"{\"server_time\":…,\"server_time_iso\":…}",", an invalid\nrequest answers a line starting with ",[17,2035,2036],{},"Error:",", and the connection closes after a minute of\nsilence. The CSV and JSON bodies carry ",[17,2039,225],{}," exactly as over HTTP. The same port also answers a plain HTTP ",[17,2042,27],{},"\nwith the same path, which is convenient for a quick test from a terminal:",[10,2045,2047],{"className":12,"code":2046,"language":14,"meta":15,"style":15},"curl \"http:\u002F\u002Fshowmytrades.com:25345\u002Fapi\u002Fpublic\u002Fcalendar\u002Fv1?currency=USD&impact=high\"\n",[17,2048,2049],{"__ignoreMap":15},[20,2050,2051,2053,2055,2058],{"class":22,"line":23},[20,2052,193],{"class":26},[20,2054,197],{"class":196},[20,2056,2057],{"class":30},"http:\u002F\u002Fshowmytrades.com:25345\u002Fapi\u002Fpublic\u002Fcalendar\u002Fv1?currency=USD&impact=high",[20,2059,203],{"class":196},[33,2061,2062,2063,2066,2067,2070],{},"The cBot below works unchanged on the desktop and in the cloud, with ",[17,2064,2065],{},"AccessRights.None",", so it\ncan be published. It downloads the calendar at start and every 15 minutes, and\n",[17,2068,2069],{},"IsNewsTime()"," tells you whether to stay out.",[10,2072,2077],{"className":2073,"code":2074,"filename":2075,"language":2076,"meta":15,"style":15},"language-csharp shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F News filter for cTrader (desktop and cloud), data by ShowMyTrades, free, no key.\n\u002F\u002F Docs: https:\u002F\u002Fshowmytrades.com\u002Fdocs\u002Fapi\u002Feconomic-calendar\nusing System;\nusing System.Collections.Generic;\nusing cAlgo.API;\n\nnamespace cAlgo.Robots\n{\n    [Robot(AccessRights = AccessRights.None, TimeZone = TimeZones.UTC)]\n    public class SmtNewsFilterBot : Robot\n    {\n        [Parameter(\"News: currencies (comma-separated, empty = all)\", DefaultValue = \"EUR,USD\")]\n        public string NewsCurrencies { get; set; }\n\n        [Parameter(\"News: impact (high | high,medium | all)\", DefaultValue = \"high\")]\n        public string NewsImpact { get; set; }\n\n        [Parameter(\"News: minutes before\", DefaultValue = 30, MinValue = 0)]\n        public int MinutesBefore { get; set; }\n\n        [Parameter(\"News: minutes after\", DefaultValue = 30, MinValue = 0)]\n        public int MinutesAfter { get; set; }\n\n        private const string CalendarWs = \"ws:\u002F\u002Fshowmytrades.com:25345\u002F\";\n        private const string CalendarHttp = \"https:\u002F\u002Fshowmytrades.com\u002Fapi\u002Fpublic\u002Fcalendar\u002Fv1?\";\n        private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);\n\n        private readonly List\u003CKeyValuePair\u003CDateTime, string>> _events = new List\u003CKeyValuePair\u003CDateTime, string>>();\n        private WebSocketClient _ws;\n        private bool _received;\n\n        protected override void OnStart()\n        {\n            DownloadCalendar();\n            Timer.Start(TimeSpan.FromMinutes(15));\n        }\n\n        protected override void OnTimer()\n        {\n            DownloadCalendar();\n        }\n\n        protected override void OnTick()\n        {\n            string reason;\n            if (IsNewsTime(out reason))\n            {\n                \u002F\u002F No new entries during the news window. Manage open positions as you prefer.\n                return;\n            }\n\n            \u002F\u002F ... your entry logic ...\n        }\n\n        protected override void OnStop()\n        {\n            CloseSocket();\n        }\n\n        \u002F\u002F True while a release is inside the pause window; reason says which one.\n        \u002F\u002F Server.TimeInUtc is cTrader's own UTC clock: the platform knows the broker's offset,\n        \u002F\u002F so it is safe to compare with the calendar (ParseCsv checks it against the server).\n        public bool IsNewsTime(out string reason)\n        {\n            DateTime now = Server.TimeInUtc;\n            foreach (KeyValuePair\u003CDateTime, string> e in _events)\n            {\n                if (now >= e.Key.AddMinutes(-MinutesBefore) && now \u003C= e.Key.AddMinutes(MinutesAfter))\n                {\n                    reason = e.Value;\n                    return true;\n                }\n            }\n            reason = null;\n            return false;\n        }\n\n        private string Query()\n        {\n            string q = \"format=csv&days=2&impact=\" + NewsImpact;\n            if (!string.IsNullOrWhiteSpace(NewsCurrencies)) q += \"&currency=\" + NewsCurrencies.Replace(\" \", \"\");\n            return q;\n        }\n\n        private void DownloadCalendar()\n        {\n            if (RunningMode != RunningMode.RealTime) return; \u002F\u002F no network in the backtester\n\n            \u002F\u002F cTrader Cloud blocks HTTP from cBots and allows only a WebSocket on port 25345,\n            \u002F\u002F so the socket is the primary path everywhere; HTTP is the fallback on the desktop.\n            try\n            {\n                CloseSocket();\n                _received = false;\n                _ws = new WebSocketClient(new WebSocketClientOptions { Timeout = TimeSpan.FromSeconds(15) });\n                _ws.Connected += OnSocketConnected;\n                _ws.TextReceived += OnSocketText;\n                _ws.Disconnected += OnSocketDisconnected;\n                _ws.Connect(new Uri(CalendarWs));\n            }\n            catch (Exception ex)\n            {\n                Print(\"[SMT] calendar socket failed: {0}\", ex.Message);\n                DownloadOverHttp();\n            }\n        }\n\n        private void OnSocketConnected(WebSocketClientConnectedEventArgs args)\n        {\n            try { _ws.Send(Query()); }\n            catch (Exception ex) { Print(\"[SMT] calendar send failed: {0}\", ex.Message); }\n        }\n\n        private void OnSocketText(WebSocketClientTextReceivedEventArgs args)\n        {\n            _received = true;\n            if (args.Text.StartsWith(\"Error:\")) Print(\"[SMT] calendar: {0}\", args.Text);\n            else ParseCsv(args.Text);\n            CloseSocket();\n        }\n\n        private void OnSocketDisconnected(WebSocketClientDisconnectEventArgs args)\n        {\n            if (!_received) DownloadOverHttp(); \u002F\u002F desktop only: the cloud answers 503\n        }\n\n        private void DownloadOverHttp()\n        {\n            try\n            {\n                HttpResponse r = Http.Get(CalendarHttp + Query());\n                if (r.IsSuccessful) ParseCsv(r.Body);\n                else Print(\"[SMT] calendar HTTP failed: {0}\", r.StatusCode);\n            }\n            catch (Exception ex) { Print(\"[SMT] calendar HTTP failed: {0}\", ex.Message); }\n        }\n\n        private void CloseSocket()\n        {\n            WebSocketClient ws = _ws;\n            _ws = null;\n            if (ws == null) return;\n            try { ws.Connected -= OnSocketConnected; ws.TextReceived -= OnSocketText; ws.Disconnected -= OnSocketDisconnected; } catch (Exception) { }\n            try { if (ws.State == WebSocketClientState.Open) ws.Close(WebSocketClientCloseStatus.NormalClosure, \"done\"); } catch (Exception) { }\n            try { ws.Dispose(); } catch (Exception) { }\n        }\n\n        \u002F\u002F CSV: ts,time,currency,impact,forecast,previous,actual,title (title last, may be quoted),\n        \u002F\u002F then one last line \"# server_time=\u003Cunix> server_time_iso=\u003Ciso>\" with the server's UTC clock.\n        private void ParseCsv(string csv)\n        {\n            List\u003CKeyValuePair\u003CDateTime, string>> list = new List\u003CKeyValuePair\u003CDateTime, string>>();\n            foreach (string raw in csv.Split('\\n'))\n            {\n                string line = raw.TrimEnd('\\r');\n                if (line.Length == 0 || line.StartsWith(\"ts,\")) continue;\n                if (line.StartsWith(\"# server_time=\"))\n                {\n                    long serverTime;\n                    if (long.TryParse(line.Substring(14, 10), out serverTime))\n                    {\n                        double skew = (Server.TimeInUtc - Epoch.AddSeconds(serverTime)).TotalSeconds;\n                        if (Math.Abs(skew) > 60) Print(\"[SMT] warning: cTrader's UTC clock is {0:F0} s away from the calendar server\", skew);\n                    }\n                    continue;\n                }\n                string[] f = line.Split(',');\n                if (f.Length \u003C 8) continue;\n                long ts;\n                if (!long.TryParse(f[0], out ts)) continue;\n                DateTime at = Epoch.AddSeconds(ts);\n                string title = AfterComma(line, 7).Replace(\"\\\"\\\"\", \"\\\"\");\n                if (title.Length >= 2 && title[0] == '\"') title = title.Substring(1, title.Length - 2);\n                list.Add(new KeyValuePair\u003CDateTime, string>(at, f[2] + \" \" + f[3] + \": \" + title));\n            }\n            _events.Clear();\n            _events.AddRange(list);\n            Print(\"[SMT] calendar: {0} events loaded\", _events.Count);\n        }\n\n        private static string AfterComma(string line, int n)\n        {\n            int pos = -1;\n            for (int i = 0; i \u003C n; i++)\n            {\n                pos = line.IndexOf(',', pos + 1);\n                if (pos \u003C 0) return \"\";\n            }\n            return line.Substring(pos + 1);\n        }\n    }\n}\n","SmtNewsFilterBot.cs","csharp",[17,2078,2079,2084,2089,2094,2099,2104,2108,2113,2117,2122,2127,2131,2136,2141,2145,2150,2155,2159,2164,2169,2173,2178,2183,2187,2192,2197,2202,2206,2211,2216,2221,2225,2230,2235,2240,2245,2250,2254,2259,2263,2267,2271,2275,2280,2284,2289,2294,2299,2304,2309,2314,2318,2323,2327,2331,2336,2340,2345,2349,2353,2358,2363,2368,2373,2377,2382,2387,2391,2396,2401,2406,2411,2416,2420,2425,2430,2434,2438,2443,2447,2452,2457,2462,2466,2470,2475,2479,2484,2488,2493,2498,2503,2507,2512,2517,2522,2527,2532,2537,2542,2546,2551,2555,2560,2565,2569,2573,2577,2582,2586,2591,2596,2600,2604,2609,2613,2618,2623,2628,2632,2636,2640,2645,2649,2654,2658,2662,2667,2671,2675,2680,2686,2692,2698,2703,2709,2714,2719,2725,2730,2736,2742,2748,2754,2760,2766,2771,2776,2782,2788,2794,2799,2805,2811,2816,2822,2828,2834,2839,2845,2851,2857,2863,2869,2875,2881,2886,2892,2898,2904,2910,2916,2922,2928,2934,2939,2945,2951,2957,2962,2967,2973,2978,2984,2990,2995,3001,3007,3012,3018,3023,3028],{"__ignoreMap":15},[20,2080,2081],{"class":22,"line":23},[20,2082,2083],{},"\u002F\u002F News filter for cTrader (desktop and cloud), data by ShowMyTrades, free, no key.\n",[20,2085,2086],{"class":22,"line":218},[20,2087,2088],{},"\u002F\u002F Docs: https:\u002F\u002Fshowmytrades.com\u002Fdocs\u002Fapi\u002Feconomic-calendar\n",[20,2090,2091],{"class":22,"line":241},[20,2092,2093],{},"using System;\n",[20,2095,2096],{"class":22,"line":262},[20,2097,2098],{},"using System.Collections.Generic;\n",[20,2100,2101],{"class":22,"line":282},[20,2102,2103],{},"using cAlgo.API;\n",[20,2105,2106],{"class":22,"line":303},[20,2107,1191],{"emptyLinePlaceholder":1190},[20,2109,2110],{"class":22,"line":324},[20,2111,2112],{},"namespace cAlgo.Robots\n",[20,2114,2115],{"class":22,"line":341},[20,2116,215],{},[20,2118,2119],{"class":22,"line":356},[20,2120,2121],{},"    [Robot(AccessRights = AccessRights.None, TimeZone = TimeZones.UTC)]\n",[20,2123,2124],{"class":22,"line":362},[20,2125,2126],{},"    public class SmtNewsFilterBot : Robot\n",[20,2128,2129],{"class":22,"line":380},[20,2130,359],{},[20,2132,2133],{"class":22,"line":401},[20,2134,2135],{},"        [Parameter(\"News: currencies (comma-separated, empty = all)\", DefaultValue = \"EUR,USD\")]\n",[20,2137,2138],{"class":22,"line":421},[20,2139,2140],{},"        public string NewsCurrencies { get; set; }\n",[20,2142,2143],{"class":22,"line":440},[20,2144,1191],{"emptyLinePlaceholder":1190},[20,2146,2147],{"class":22,"line":461},[20,2148,2149],{},"        [Parameter(\"News: impact (high | high,medium | all)\", DefaultValue = \"high\")]\n",[20,2151,2152],{"class":22,"line":478},[20,2153,2154],{},"        public string NewsImpact { get; set; }\n",[20,2156,2157],{"class":22,"line":494},[20,2158,1191],{"emptyLinePlaceholder":1190},[20,2160,2161],{"class":22,"line":509},[20,2162,2163],{},"        [Parameter(\"News: minutes before\", DefaultValue = 30, MinValue = 0)]\n",[20,2165,2166],{"class":22,"line":515},[20,2167,2168],{},"        public int MinutesBefore { get; set; }\n",[20,2170,2171],{"class":22,"line":520},[20,2172,1191],{"emptyLinePlaceholder":1190},[20,2174,2175],{"class":22,"line":536},[20,2176,2177],{},"        [Parameter(\"News: minutes after\", DefaultValue = 30, MinValue = 0)]\n",[20,2179,2180],{"class":22,"line":556},[20,2181,2182],{},"        public int MinutesAfter { get; set; }\n",[20,2184,2185],{"class":22,"line":576},[20,2186,1191],{"emptyLinePlaceholder":1190},[20,2188,2189],{"class":22,"line":595},[20,2190,2191],{},"        private const string CalendarWs = \"ws:\u002F\u002Fshowmytrades.com:25345\u002F\";\n",[20,2193,2194],{"class":22,"line":615},[20,2195,2196],{},"        private const string CalendarHttp = \"https:\u002F\u002Fshowmytrades.com\u002Fapi\u002Fpublic\u002Fcalendar\u002Fv1?\";\n",[20,2198,2199],{"class":22,"line":635},[20,2200,2201],{},"        private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);\n",[20,2203,2204],{"class":22,"line":655},[20,2205,1191],{"emptyLinePlaceholder":1190},[20,2207,2208],{"class":22,"line":668},[20,2209,2210],{},"        private readonly List\u003CKeyValuePair\u003CDateTime, string>> _events = new List\u003CKeyValuePair\u003CDateTime, string>>();\n",[20,2212,2213],{"class":22,"line":674},[20,2214,2215],{},"        private WebSocketClient _ws;\n",[20,2217,2218],{"class":22,"line":680},[20,2219,2220],{},"        private bool _received;\n",[20,2222,2223],{"class":22,"line":745},[20,2224,1191],{"emptyLinePlaceholder":1190},[20,2226,2227],{"class":22,"line":764},[20,2228,2229],{},"        protected override void OnStart()\n",[20,2231,2232],{"class":22,"line":1306},[20,2233,2234],{},"        {\n",[20,2236,2237],{"class":22,"line":1311},[20,2238,2239],{},"            DownloadCalendar();\n",[20,2241,2242],{"class":22,"line":1316},[20,2243,2244],{},"            Timer.Start(TimeSpan.FromMinutes(15));\n",[20,2246,2247],{"class":22,"line":1322},[20,2248,2249],{},"        }\n",[20,2251,2252],{"class":22,"line":1328},[20,2253,1191],{"emptyLinePlaceholder":1190},[20,2255,2256],{"class":22,"line":1334},[20,2257,2258],{},"        protected override void OnTimer()\n",[20,2260,2261],{"class":22,"line":1340},[20,2262,2234],{},[20,2264,2265],{"class":22,"line":1345},[20,2266,2239],{},[20,2268,2269],{"class":22,"line":1351},[20,2270,2249],{},[20,2272,2273],{"class":22,"line":1356},[20,2274,1191],{"emptyLinePlaceholder":1190},[20,2276,2277],{"class":22,"line":1361},[20,2278,2279],{},"        protected override void OnTick()\n",[20,2281,2282],{"class":22,"line":1367},[20,2283,2234],{},[20,2285,2286],{"class":22,"line":1373},[20,2287,2288],{},"            string reason;\n",[20,2290,2291],{"class":22,"line":1378},[20,2292,2293],{},"            if (IsNewsTime(out reason))\n",[20,2295,2296],{"class":22,"line":1384},[20,2297,2298],{},"            {\n",[20,2300,2301],{"class":22,"line":1390},[20,2302,2303],{},"                \u002F\u002F No new entries during the news window. Manage open positions as you prefer.\n",[20,2305,2306],{"class":22,"line":1396},[20,2307,2308],{},"                return;\n",[20,2310,2311],{"class":22,"line":1402},[20,2312,2313],{},"            }\n",[20,2315,2316],{"class":22,"line":1408},[20,2317,1191],{"emptyLinePlaceholder":1190},[20,2319,2320],{"class":22,"line":1414},[20,2321,2322],{},"            \u002F\u002F ... your entry logic ...\n",[20,2324,2325],{"class":22,"line":1420},[20,2326,2249],{},[20,2328,2329],{"class":22,"line":1426},[20,2330,1191],{"emptyLinePlaceholder":1190},[20,2332,2333],{"class":22,"line":1432},[20,2334,2335],{},"        protected override void OnStop()\n",[20,2337,2338],{"class":22,"line":1438},[20,2339,2234],{},[20,2341,2342],{"class":22,"line":1444},[20,2343,2344],{},"            CloseSocket();\n",[20,2346,2347],{"class":22,"line":1449},[20,2348,2249],{},[20,2350,2351],{"class":22,"line":1454},[20,2352,1191],{"emptyLinePlaceholder":1190},[20,2354,2355],{"class":22,"line":1460},[20,2356,2357],{},"        \u002F\u002F True while a release is inside the pause window; reason says which one.\n",[20,2359,2360],{"class":22,"line":1466},[20,2361,2362],{},"        \u002F\u002F Server.TimeInUtc is cTrader's own UTC clock: the platform knows the broker's offset,\n",[20,2364,2365],{"class":22,"line":1471},[20,2366,2367],{},"        \u002F\u002F so it is safe to compare with the calendar (ParseCsv checks it against the server).\n",[20,2369,2370],{"class":22,"line":1477},[20,2371,2372],{},"        public bool IsNewsTime(out string reason)\n",[20,2374,2375],{"class":22,"line":1483},[20,2376,2234],{},[20,2378,2379],{"class":22,"line":1488},[20,2380,2381],{},"            DateTime now = Server.TimeInUtc;\n",[20,2383,2384],{"class":22,"line":1494},[20,2385,2386],{},"            foreach (KeyValuePair\u003CDateTime, string> e in _events)\n",[20,2388,2389],{"class":22,"line":1500},[20,2390,2298],{},[20,2392,2393],{"class":22,"line":1506},[20,2394,2395],{},"                if (now >= e.Key.AddMinutes(-MinutesBefore) && now \u003C= e.Key.AddMinutes(MinutesAfter))\n",[20,2397,2398],{"class":22,"line":1512},[20,2399,2400],{},"                {\n",[20,2402,2403],{"class":22,"line":1518},[20,2404,2405],{},"                    reason = e.Value;\n",[20,2407,2408],{"class":22,"line":1523},[20,2409,2410],{},"                    return true;\n",[20,2412,2413],{"class":22,"line":1529},[20,2414,2415],{},"                }\n",[20,2417,2418],{"class":22,"line":1535},[20,2419,2313],{},[20,2421,2422],{"class":22,"line":1541},[20,2423,2424],{},"            reason = null;\n",[20,2426,2427],{"class":22,"line":1547},[20,2428,2429],{},"            return false;\n",[20,2431,2432],{"class":22,"line":1552},[20,2433,2249],{},[20,2435,2436],{"class":22,"line":1557},[20,2437,1191],{"emptyLinePlaceholder":1190},[20,2439,2440],{"class":22,"line":1563},[20,2441,2442],{},"        private string Query()\n",[20,2444,2445],{"class":22,"line":1569},[20,2446,2234],{},[20,2448,2449],{"class":22,"line":1575},[20,2450,2451],{},"            string q = \"format=csv&days=2&impact=\" + NewsImpact;\n",[20,2453,2454],{"class":22,"line":1580},[20,2455,2456],{},"            if (!string.IsNullOrWhiteSpace(NewsCurrencies)) q += \"&currency=\" + NewsCurrencies.Replace(\" \", \"\");\n",[20,2458,2459],{"class":22,"line":1586},[20,2460,2461],{},"            return q;\n",[20,2463,2464],{"class":22,"line":1592},[20,2465,2249],{},[20,2467,2468],{"class":22,"line":1598},[20,2469,1191],{"emptyLinePlaceholder":1190},[20,2471,2472],{"class":22,"line":1603},[20,2473,2474],{},"        private void DownloadCalendar()\n",[20,2476,2477],{"class":22,"line":1609},[20,2478,2234],{},[20,2480,2481],{"class":22,"line":1615},[20,2482,2483],{},"            if (RunningMode != RunningMode.RealTime) return; \u002F\u002F no network in the backtester\n",[20,2485,2486],{"class":22,"line":1621},[20,2487,1191],{"emptyLinePlaceholder":1190},[20,2489,2490],{"class":22,"line":1627},[20,2491,2492],{},"            \u002F\u002F cTrader Cloud blocks HTTP from cBots and allows only a WebSocket on port 25345,\n",[20,2494,2495],{"class":22,"line":1633},[20,2496,2497],{},"            \u002F\u002F so the socket is the primary path everywhere; HTTP is the fallback on the desktop.\n",[20,2499,2500],{"class":22,"line":1639},[20,2501,2502],{},"            try\n",[20,2504,2505],{"class":22,"line":1645},[20,2506,2298],{},[20,2508,2509],{"class":22,"line":1651},[20,2510,2511],{},"                CloseSocket();\n",[20,2513,2514],{"class":22,"line":1657},[20,2515,2516],{},"                _received = false;\n",[20,2518,2519],{"class":22,"line":1663},[20,2520,2521],{},"                _ws = new WebSocketClient(new WebSocketClientOptions { Timeout = TimeSpan.FromSeconds(15) });\n",[20,2523,2524],{"class":22,"line":1669},[20,2525,2526],{},"                _ws.Connected += OnSocketConnected;\n",[20,2528,2529],{"class":22,"line":1675},[20,2530,2531],{},"                _ws.TextReceived += OnSocketText;\n",[20,2533,2534],{"class":22,"line":1681},[20,2535,2536],{},"                _ws.Disconnected += OnSocketDisconnected;\n",[20,2538,2539],{"class":22,"line":1687},[20,2540,2541],{},"                _ws.Connect(new Uri(CalendarWs));\n",[20,2543,2544],{"class":22,"line":1693},[20,2545,2313],{},[20,2547,2548],{"class":22,"line":1699},[20,2549,2550],{},"            catch (Exception ex)\n",[20,2552,2553],{"class":22,"line":1705},[20,2554,2298],{},[20,2556,2557],{"class":22,"line":1711},[20,2558,2559],{},"                Print(\"[SMT] calendar socket failed: {0}\", ex.Message);\n",[20,2561,2562],{"class":22,"line":1717},[20,2563,2564],{},"                DownloadOverHttp();\n",[20,2566,2567],{"class":22,"line":1722},[20,2568,2313],{},[20,2570,2571],{"class":22,"line":1728},[20,2572,2249],{},[20,2574,2575],{"class":22,"line":1734},[20,2576,1191],{"emptyLinePlaceholder":1190},[20,2578,2579],{"class":22,"line":1740},[20,2580,2581],{},"        private void OnSocketConnected(WebSocketClientConnectedEventArgs args)\n",[20,2583,2584],{"class":22,"line":1746},[20,2585,2234],{},[20,2587,2588],{"class":22,"line":1752},[20,2589,2590],{},"            try { _ws.Send(Query()); }\n",[20,2592,2593],{"class":22,"line":1757},[20,2594,2595],{},"            catch (Exception ex) { Print(\"[SMT] calendar send failed: {0}\", ex.Message); }\n",[20,2597,2598],{"class":22,"line":1762},[20,2599,2249],{},[20,2601,2602],{"class":22,"line":1768},[20,2603,1191],{"emptyLinePlaceholder":1190},[20,2605,2606],{"class":22,"line":1774},[20,2607,2608],{},"        private void OnSocketText(WebSocketClientTextReceivedEventArgs args)\n",[20,2610,2611],{"class":22,"line":1779},[20,2612,2234],{},[20,2614,2615],{"class":22,"line":1785},[20,2616,2617],{},"            _received = true;\n",[20,2619,2620],{"class":22,"line":1791},[20,2621,2622],{},"            if (args.Text.StartsWith(\"Error:\")) Print(\"[SMT] calendar: {0}\", args.Text);\n",[20,2624,2625],{"class":22,"line":1797},[20,2626,2627],{},"            else ParseCsv(args.Text);\n",[20,2629,2630],{"class":22,"line":1802},[20,2631,2344],{},[20,2633,2634],{"class":22,"line":1808},[20,2635,2249],{},[20,2637,2638],{"class":22,"line":1814},[20,2639,1191],{"emptyLinePlaceholder":1190},[20,2641,2642],{"class":22,"line":1819},[20,2643,2644],{},"        private void OnSocketDisconnected(WebSocketClientDisconnectEventArgs args)\n",[20,2646,2647],{"class":22,"line":1825},[20,2648,2234],{},[20,2650,2651],{"class":22,"line":1830},[20,2652,2653],{},"            if (!_received) DownloadOverHttp(); \u002F\u002F desktop only: the cloud answers 503\n",[20,2655,2656],{"class":22,"line":1836},[20,2657,2249],{},[20,2659,2660],{"class":22,"line":1842},[20,2661,1191],{"emptyLinePlaceholder":1190},[20,2663,2664],{"class":22,"line":1847},[20,2665,2666],{},"        private void DownloadOverHttp()\n",[20,2668,2669],{"class":22,"line":1852},[20,2670,2234],{},[20,2672,2673],{"class":22,"line":1858},[20,2674,2502],{},[20,2676,2678],{"class":22,"line":2677},130,[20,2679,2298],{},[20,2681,2683],{"class":22,"line":2682},131,[20,2684,2685],{},"                HttpResponse r = Http.Get(CalendarHttp + Query());\n",[20,2687,2689],{"class":22,"line":2688},132,[20,2690,2691],{},"                if (r.IsSuccessful) ParseCsv(r.Body);\n",[20,2693,2695],{"class":22,"line":2694},133,[20,2696,2697],{},"                else Print(\"[SMT] calendar HTTP failed: {0}\", r.StatusCode);\n",[20,2699,2701],{"class":22,"line":2700},134,[20,2702,2313],{},[20,2704,2706],{"class":22,"line":2705},135,[20,2707,2708],{},"            catch (Exception ex) { Print(\"[SMT] calendar HTTP failed: {0}\", ex.Message); }\n",[20,2710,2712],{"class":22,"line":2711},136,[20,2713,2249],{},[20,2715,2717],{"class":22,"line":2716},137,[20,2718,1191],{"emptyLinePlaceholder":1190},[20,2720,2722],{"class":22,"line":2721},138,[20,2723,2724],{},"        private void CloseSocket()\n",[20,2726,2728],{"class":22,"line":2727},139,[20,2729,2234],{},[20,2731,2733],{"class":22,"line":2732},140,[20,2734,2735],{},"            WebSocketClient ws = _ws;\n",[20,2737,2739],{"class":22,"line":2738},141,[20,2740,2741],{},"            _ws = null;\n",[20,2743,2745],{"class":22,"line":2744},142,[20,2746,2747],{},"            if (ws == null) return;\n",[20,2749,2751],{"class":22,"line":2750},143,[20,2752,2753],{},"            try { ws.Connected -= OnSocketConnected; ws.TextReceived -= OnSocketText; ws.Disconnected -= OnSocketDisconnected; } catch (Exception) { }\n",[20,2755,2757],{"class":22,"line":2756},144,[20,2758,2759],{},"            try { if (ws.State == WebSocketClientState.Open) ws.Close(WebSocketClientCloseStatus.NormalClosure, \"done\"); } catch (Exception) { }\n",[20,2761,2763],{"class":22,"line":2762},145,[20,2764,2765],{},"            try { ws.Dispose(); } catch (Exception) { }\n",[20,2767,2769],{"class":22,"line":2768},146,[20,2770,2249],{},[20,2772,2774],{"class":22,"line":2773},147,[20,2775,1191],{"emptyLinePlaceholder":1190},[20,2777,2779],{"class":22,"line":2778},148,[20,2780,2781],{},"        \u002F\u002F CSV: ts,time,currency,impact,forecast,previous,actual,title (title last, may be quoted),\n",[20,2783,2785],{"class":22,"line":2784},149,[20,2786,2787],{},"        \u002F\u002F then one last line \"# server_time=\u003Cunix> server_time_iso=\u003Ciso>\" with the server's UTC clock.\n",[20,2789,2791],{"class":22,"line":2790},150,[20,2792,2793],{},"        private void ParseCsv(string csv)\n",[20,2795,2797],{"class":22,"line":2796},151,[20,2798,2234],{},[20,2800,2802],{"class":22,"line":2801},152,[20,2803,2804],{},"            List\u003CKeyValuePair\u003CDateTime, string>> list = new List\u003CKeyValuePair\u003CDateTime, string>>();\n",[20,2806,2808],{"class":22,"line":2807},153,[20,2809,2810],{},"            foreach (string raw in csv.Split('\\n'))\n",[20,2812,2814],{"class":22,"line":2813},154,[20,2815,2298],{},[20,2817,2819],{"class":22,"line":2818},155,[20,2820,2821],{},"                string line = raw.TrimEnd('\\r');\n",[20,2823,2825],{"class":22,"line":2824},156,[20,2826,2827],{},"                if (line.Length == 0 || line.StartsWith(\"ts,\")) continue;\n",[20,2829,2831],{"class":22,"line":2830},157,[20,2832,2833],{},"                if (line.StartsWith(\"# server_time=\"))\n",[20,2835,2837],{"class":22,"line":2836},158,[20,2838,2400],{},[20,2840,2842],{"class":22,"line":2841},159,[20,2843,2844],{},"                    long serverTime;\n",[20,2846,2848],{"class":22,"line":2847},160,[20,2849,2850],{},"                    if (long.TryParse(line.Substring(14, 10), out serverTime))\n",[20,2852,2854],{"class":22,"line":2853},161,[20,2855,2856],{},"                    {\n",[20,2858,2860],{"class":22,"line":2859},162,[20,2861,2862],{},"                        double skew = (Server.TimeInUtc - Epoch.AddSeconds(serverTime)).TotalSeconds;\n",[20,2864,2866],{"class":22,"line":2865},163,[20,2867,2868],{},"                        if (Math.Abs(skew) > 60) Print(\"[SMT] warning: cTrader's UTC clock is {0:F0} s away from the calendar server\", skew);\n",[20,2870,2872],{"class":22,"line":2871},164,[20,2873,2874],{},"                    }\n",[20,2876,2878],{"class":22,"line":2877},165,[20,2879,2880],{},"                    continue;\n",[20,2882,2884],{"class":22,"line":2883},166,[20,2885,2415],{},[20,2887,2889],{"class":22,"line":2888},167,[20,2890,2891],{},"                string[] f = line.Split(',');\n",[20,2893,2895],{"class":22,"line":2894},168,[20,2896,2897],{},"                if (f.Length \u003C 8) continue;\n",[20,2899,2901],{"class":22,"line":2900},169,[20,2902,2903],{},"                long ts;\n",[20,2905,2907],{"class":22,"line":2906},170,[20,2908,2909],{},"                if (!long.TryParse(f[0], out ts)) continue;\n",[20,2911,2913],{"class":22,"line":2912},171,[20,2914,2915],{},"                DateTime at = Epoch.AddSeconds(ts);\n",[20,2917,2919],{"class":22,"line":2918},172,[20,2920,2921],{},"                string title = AfterComma(line, 7).Replace(\"\\\"\\\"\", \"\\\"\");\n",[20,2923,2925],{"class":22,"line":2924},173,[20,2926,2927],{},"                if (title.Length >= 2 && title[0] == '\"') title = title.Substring(1, title.Length - 2);\n",[20,2929,2931],{"class":22,"line":2930},174,[20,2932,2933],{},"                list.Add(new KeyValuePair\u003CDateTime, string>(at, f[2] + \" \" + f[3] + \": \" + title));\n",[20,2935,2937],{"class":22,"line":2936},175,[20,2938,2313],{},[20,2940,2942],{"class":22,"line":2941},176,[20,2943,2944],{},"            _events.Clear();\n",[20,2946,2948],{"class":22,"line":2947},177,[20,2949,2950],{},"            _events.AddRange(list);\n",[20,2952,2954],{"class":22,"line":2953},178,[20,2955,2956],{},"            Print(\"[SMT] calendar: {0} events loaded\", _events.Count);\n",[20,2958,2960],{"class":22,"line":2959},179,[20,2961,2249],{},[20,2963,2965],{"class":22,"line":2964},180,[20,2966,1191],{"emptyLinePlaceholder":1190},[20,2968,2970],{"class":22,"line":2969},181,[20,2971,2972],{},"        private static string AfterComma(string line, int n)\n",[20,2974,2976],{"class":22,"line":2975},182,[20,2977,2234],{},[20,2979,2981],{"class":22,"line":2980},183,[20,2982,2983],{},"            int pos = -1;\n",[20,2985,2987],{"class":22,"line":2986},184,[20,2988,2989],{},"            for (int i = 0; i \u003C n; i++)\n",[20,2991,2993],{"class":22,"line":2992},185,[20,2994,2298],{},[20,2996,2998],{"class":22,"line":2997},186,[20,2999,3000],{},"                pos = line.IndexOf(',', pos + 1);\n",[20,3002,3004],{"class":22,"line":3003},187,[20,3005,3006],{},"                if (pos \u003C 0) return \"\";\n",[20,3008,3010],{"class":22,"line":3009},188,[20,3011,2313],{},[20,3013,3015],{"class":22,"line":3014},189,[20,3016,3017],{},"            return line.Substring(pos + 1);\n",[20,3019,3021],{"class":22,"line":3020},190,[20,3022,2249],{},[20,3024,3026],{"class":22,"line":3025},191,[20,3027,671],{},[20,3029,3031],{"class":22,"line":3030},192,[20,3032,767],{},[1934,3034,3035,3044,3047],{},[985,3036,3037,3040,3041,3043],{},[17,3038,3039],{},"Server.TimeInUtc"," is the comparison clock: cTrader knows the broker's offset, so it is\nreliable. The parser still checks it against ",[17,3042,225],{}," and prints a warning if the two\ndisagree by more than a minute.",[985,3045,3046],{},"The backtester has no network: the filter is silent there, like in MetaTrader.",[985,3048,3049,3050,3053,3054,3057,3058,3061],{},"The socket has ",[37,3051,3052],{},"no TLS"," (",[17,3055,3056],{},"ws:\u002F\u002F",", not ",[17,3059,3060],{},"wss:\u002F\u002F","): that is what cTrader Cloud connects with.\nThe calendar is public and the request carries nothing about you or your account.",[77,3063,3065],{"id":3064},"python-javascript-and-everything-else","Python, JavaScript and everything else",[33,3067,3068],{},"Any HTTP client works. Python:",[10,3070,3074],{"className":3071,"code":3072,"language":3073,"meta":15,"style":15},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import requests\n\nevents = requests.get(\n    \"https:\u002F\u002Fshowmytrades.com\u002Fapi\u002Fpublic\u002Fcalendar\u002Fv1\",\n    params={\"currency\": \"EUR,USD\", \"impact\": \"high,medium\", \"days\": 7},\n    timeout=10,\n).json()[\"events\"]\n\nfor e in events:\n    print(e[\"time\"], e[\"currency\"], e[\"impact\"], e[\"title\"], e[\"forecast\"], e[\"actual\"])\n","python",[17,3075,3076,3081,3085,3090,3095,3100,3105,3110,3114,3119],{"__ignoreMap":15},[20,3077,3078],{"class":22,"line":23},[20,3079,3080],{},"import requests\n",[20,3082,3083],{"class":22,"line":218},[20,3084,1191],{"emptyLinePlaceholder":1190},[20,3086,3087],{"class":22,"line":241},[20,3088,3089],{},"events = requests.get(\n",[20,3091,3092],{"class":22,"line":262},[20,3093,3094],{},"    \"https:\u002F\u002Fshowmytrades.com\u002Fapi\u002Fpublic\u002Fcalendar\u002Fv1\",\n",[20,3096,3097],{"class":22,"line":282},[20,3098,3099],{},"    params={\"currency\": \"EUR,USD\", \"impact\": \"high,medium\", \"days\": 7},\n",[20,3101,3102],{"class":22,"line":303},[20,3103,3104],{},"    timeout=10,\n",[20,3106,3107],{"class":22,"line":324},[20,3108,3109],{},").json()[\"events\"]\n",[20,3111,3112],{"class":22,"line":341},[20,3113,1191],{"emptyLinePlaceholder":1190},[20,3115,3116],{"class":22,"line":356},[20,3117,3118],{},"for e in events:\n",[20,3120,3121],{"class":22,"line":362},[20,3122,3123],{},"    print(e[\"time\"], e[\"currency\"], e[\"impact\"], e[\"title\"], e[\"forecast\"], e[\"actual\"])\n",[33,3125,3126],{},"JavaScript, in a browser too (CORS is open):",[10,3128,3132],{"className":3129,"code":3130,"language":3131,"meta":15,"style":15},"language-js shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","const res = await fetch('https:\u002F\u002Fshowmytrades.com\u002Fapi\u002Fpublic\u002Fcalendar\u002Fv1?currency=USD&impact=high&days=1')\nconst { events } = await res.json()\n","js",[17,3133,3134,3168],{"__ignoreMap":15},[20,3135,3136,3139,3143,3146,3150,3154,3157,3160,3163,3165],{"class":22,"line":23},[20,3137,3138],{"class":224},"const",[20,3140,3142],{"class":3141},"sTEyZ"," res ",[20,3144,3145],{"class":196},"=",[20,3147,3149],{"class":3148},"s7zQu"," await",[20,3151,3153],{"class":3152},"s2Zo4"," fetch",[20,3155,3156],{"class":3141},"(",[20,3158,3159],{"class":196},"'",[20,3161,3162],{"class":30},"https:\u002F\u002Fshowmytrades.com\u002Fapi\u002Fpublic\u002Fcalendar\u002Fv1?currency=USD&impact=high&days=1",[20,3164,3159],{"class":196},[20,3166,3167],{"class":3141},")\n",[20,3169,3170,3172,3174,3177,3180,3183,3185,3188,3190,3192],{"class":22,"line":218},[20,3171,3138],{"class":224},[20,3173,692],{"class":196},[20,3175,3176],{"class":3141}," events ",[20,3178,3179],{"class":196},"}",[20,3181,3182],{"class":196}," =",[20,3184,3149],{"class":3148},[20,3186,3187],{"class":3141}," res",[20,3189,50],{"class":196},[20,3191,164],{"class":3152},[20,3193,3194],{"class":3141},"()\n",[33,3196,3197,3198,3201,3202,3204,3205,3207,3208,3210],{},"Polite polling with the ",[17,3199,3200],{},"ETag",": keep the value from the last response and send it back; a ",[17,3203,979],{},"\nmeans nothing changed and has no body. The ",[17,3206,975],{}," header is on the ",[17,3209,979],{}," too, so the\nclock stays synchronised even when the calendar does not change.",[10,3212,3214],{"className":12,"code":3213,"language":14,"meta":15,"style":15},"curl -i \"https:\u002F\u002Fshowmytrades.com\u002Fapi\u002Fpublic\u002Fcalendar\u002Fv1?impact=high\" \\\n  -H 'If-None-Match: \"a1b2c3d4e5f6a7b8c9d0\"'\n",[17,3215,3216,3233],{"__ignoreMap":15},[20,3217,3218,3220,3223,3225,3228,3230],{"class":22,"line":23},[20,3219,193],{"class":26},[20,3221,3222],{"class":30}," -i",[20,3224,197],{"class":196},[20,3226,3227],{"class":30},"https:\u002F\u002Fshowmytrades.com\u002Fapi\u002Fpublic\u002Fcalendar\u002Fv1?impact=high",[20,3229,228],{"class":196},[20,3231,3232],{"class":3141}," \\\n",[20,3234,3235,3238,3241,3244],{"class":22,"line":218},[20,3236,3237],{"class":30},"  -H",[20,3239,3240],{"class":196}," '",[20,3242,3243],{"class":30},"If-None-Match: \"a1b2c3d4e5f6a7b8c9d0\"",[20,3245,3246],{"class":196},"'\n",[77,3248,3250],{"id":3249},"for-ai-assistants","For AI assistants",[33,3252,3253,3254,109,3258,3261,3262,3265,3266,3269],{},"The same data is a tool of the ",[42,3255,3257],{"href":3256},"\u002Fdocs\u002Fapi\u002Fmcp","MCP server",[17,3259,3260],{},"get_economic_calendar",", with the\nsame three parameters and no key. An assistant asked to ",[59,3263,3264],{},"\"add a news filter to my EA\""," or\n",[59,3267,3268],{},"\"what news is out today\""," can call it directly, and should point the user to the code on this\npage for the robot itself.",[77,3271,3273],{"id":3272},"limits-and-terms","Limits and terms",[899,3275,3276,3284],{},[902,3277,3278],{},[905,3279,3280,3282],{},[908,3281],{},[908,3283],{},[918,3285,3286,3294,3301,3309,3324,3339,3349],{},[905,3287,3288,3291],{},[923,3289,3290],{},"Price",[923,3292,3293],{},"Free, no account, no key",[905,3295,3296,3299],{},[923,3297,3298],{},"Currencies",[923,3300,94],{},[905,3302,3303,3306],{},[923,3304,3305],{},"Window",[923,3307,3308],{},"From 6 hours ago to 30 days ahead at most",[905,3310,3311,3313],{},[923,3312,910],{},[923,3314,3315,3317,3318,3320,3321,3323],{},[17,3316,225],{}," in every response, ",[17,3319,975],{}," on every HTTP response, ",[17,3322,1084],{}," on its own",[905,3325,3326,3329],{},[923,3327,3328],{},"Rate limit",[923,3330,3331,3332,3335,3336],{},"600 requests per minute per IP (HTTP), 60 messages per minute per IP (WebSocket); a ",[17,3333,3334],{},"429"," carries ",[17,3337,3338],{},"Retry-After",[905,3340,3341,3344],{},[923,3342,3343],{},"Caching",[923,3345,3346,3347],{},"15 minutes, with ",[17,3348,3200],{},[905,3350,3351,3354],{},[923,3352,3353],{},"Credit",[923,3355,3356,3357,3359,3360],{},"Appreciated, not required: ",[59,3358,718],{},", linked to the ",[42,3361,3362],{"href":44},"calendar page",[33,3364,3365],{},"The calendar is assembled from public sources and served as-is, with no guarantee of\ncompleteness or timing; schedules change and some releases are moved or cancelled. It is\ninformation, not advice: whether to trade around a release is your decision.",[3367,3368,3369],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}",{"title":15,"searchDepth":218,"depth":218,"links":3371},[3372,3373,3374,3375,3376,3377,3378,3379],{"id":79,"depth":218,"text":80},{"id":179,"depth":218,"text":180},{"id":893,"depth":218,"text":894},{"id":1097,"depth":218,"text":1098},{"id":1982,"depth":218,"text":1983},{"id":3064,"depth":218,"text":3065},{"id":3249,"depth":218,"text":3250},{"id":3272,"depth":218,"text":3273},"Free economic calendar for Expert Advisors, cBots and any trading bot: upcoming news for the 9 major currencies as JSON or CSV, filtered by currency, impact and days. No API key. With ready-made news filter code for MT4, MT5 and cTrader (cloud included).","md",{},{"icon":3384},"i-lucide-calendar-clock","\u002Fdocs\u002Fapi\u002Feconomic-calendar",{"title":5,"description":3380},"1.docs\u002F2.api\u002F6.economic-calendar","0UHVOmprFnchodat88DMKfp31PSfMkbaHfSTfm4-UYI",[3390],{"title":3391,"path":3392,"stem":3393,"children":3394,"page":3413},"Docs","\u002Fdocs","1.docs",[3395,3414,3471],{"title":3396,"path":3397,"stem":3398,"children":3399,"icon":3413},"Getting Started","\u002Fdocs\u002Fgetting-started","1.docs\u002F1.getting-started\u002F1.index",[3400,3403,3408],{"title":3401,"path":3397,"stem":3398,"icon":3402},"Introduction","i-lucide-house",{"title":3404,"path":3405,"stem":3406,"icon":3407},"Installation","\u002Fdocs\u002Fgetting-started\u002Finstallation","1.docs\u002F1.getting-started\u002F2.installation","i-lucide-download",{"title":3409,"path":3410,"stem":3411,"icon":3412},"Usage","\u002Fdocs\u002Fgetting-started\u002Fusage","1.docs\u002F1.getting-started\u002F3.usage","i-lucide-sliders",false,{"title":3415,"path":3416,"stem":3417,"children":3418,"icon":3470},"API Reference","\u002Fdocs\u002Fapi","1.docs\u002F2.api\u002F1.index",[3419,3421,3426,3431,3436,3441,3446,3451,3456,3457,3462,3465],{"title":3401,"path":3416,"stem":3417,"icon":3420},"i-lucide-book-open",{"title":3422,"path":3423,"stem":3424,"icon":3425},"Show your trading results on your website","\u002Fdocs\u002Fapi\u002Fshow-trading-results-on-your-website","1.docs\u002F2.api\u002F1.show-trading-results-on-your-website","i-lucide-chart-line",{"title":3427,"path":3428,"stem":3429,"icon":3430},"Widget reference","\u002Fdocs\u002Fapi\u002Fwidgets","1.docs\u002F2.api\u002F1.widgets","i-lucide-layout-grid",{"title":3432,"path":3433,"stem":3434,"icon":3435},"Authentication","\u002Fdocs\u002Fapi\u002Fauthentication","1.docs\u002F2.api\u002F2.authentication","i-lucide-key",{"title":3437,"path":3438,"stem":3439,"icon":3440},"Attribution","\u002Fdocs\u002Fapi\u002Fattribution","1.docs\u002F2.api\u002F3.attribution","i-lucide-link",{"title":3442,"path":3443,"stem":3444,"icon":3445},"Conventions","\u002Fdocs\u002Fapi\u002Fconventions","1.docs\u002F2.api\u002F3.conventions","i-lucide-ruler",{"title":3447,"path":3448,"stem":3449,"icon":3450},"Accounts","\u002Fdocs\u002Fapi\u002Faccounts","1.docs\u002F2.api\u002F4.accounts","i-lucide-wallet",{"title":3452,"path":3453,"stem":3454,"icon":3455},"Trades & positions","\u002Fdocs\u002Fapi\u002Ftrades","1.docs\u002F2.api\u002F5.trades","i-lucide-arrow-left-right",{"title":5,"path":3385,"stem":3387,"icon":3384},{"title":3458,"path":3459,"stem":3460,"icon":3461},"Search","\u002Fdocs\u002Fapi\u002Fsearch","1.docs\u002F2.api\u002F6.search","i-lucide-search",{"title":3257,"path":3256,"stem":3463,"icon":3464},"1.docs\u002F2.api\u002F7.mcp","i-lucide-sparkles",{"title":3466,"path":3467,"stem":3468,"icon":3469},"Errors","\u002Fdocs\u002Fapi\u002Ferrors","1.docs\u002F2.api\u002F8.errors","i-lucide-triangle-alert","i-lucide-code-xml",{"title":3472,"path":3473,"stem":3474,"children":3475,"page":3413},"Essentials","\u002Fdocs\u002Fessentials","1.docs\u002F2.essentials",[3476,3481,3485,3490],{"title":3477,"path":3478,"stem":3479,"icon":3480},"Markdown Syntax","\u002Fdocs\u002Fessentials\u002Fmarkdown-syntax","1.docs\u002F2.essentials\u002F1.markdown-syntax","i-lucide-heading-1",{"title":3482,"path":3483,"stem":3484,"icon":3470},"Code Blocks","\u002Fdocs\u002Fessentials\u002Fcode-blocks","1.docs\u002F2.essentials\u002F2.code-blocks",{"title":3486,"path":3487,"stem":3488,"icon":3489},"Prose Components","\u002Fdocs\u002Fessentials\u002Fprose-components","1.docs\u002F2.essentials\u002F3.prose-components","i-lucide-component",{"title":3491,"path":3492,"stem":3493,"icon":3494},"Images and Embeds","\u002Fdocs\u002Fessentials\u002Fimages-embeds","1.docs\u002F2.essentials\u002F4.images-embeds","i-lucide-image",[3496,3498],{"title":3452,"path":3453,"stem":3454,"description":3497,"icon":3455,"children":-1},"Closed trades and currently open positions, paginated and filterable.",{"title":3458,"path":3459,"stem":3460,"description":3499,"icon":3461,"children":-1},"Search across every account published on ShowMyTrades.",1792249030670]