[{"data":1,"prerenderedAt":1343},["ShallowReactive",2],{"\u002Fes\u002Fguides\u002Fadd-a-news-filter-to-your-mt4-expert-advisor":3,"\u002Fes\u002Fguides\u002Fadd-a-news-filter-to-your-mt4-expert-advisor-surround":1323,"\u002Fes\u002Fguides\u002Fadd-a-news-filter-to-your-mt4-expert-advisor-langs":1333},{"id":4,"title":5,"authors":6,"badge":12,"body":14,"date":1311,"description":1312,"draft":1313,"extension":1314,"image":1315,"meta":1317,"navigation":262,"path":1318,"seo":1319,"stem":1320,"updated":1321,"__hash__":1322},"posts\u002Fes\u002F3.guides\u002F41.add-a-news-filter-to-your-mt4-expert-advisor.md","Cómo agregar un filtro de noticias a tu Expert Advisor de MT4",[7],{"name":8,"to":9,"avatar":10},"ShowMyTrades Team","https:\u002F\u002Fshowmytrades.com",{"src":11},"\u002Ficon-512.png",{"label":13},"Automatización",{"type":15,"value":16,"toc":1300},"minimark",[17,27,40,45,56,140,144,159,165,176,180,195,958,964,968,971,1037,1048,1059,1063,1066,1129,1133,1184,1188,1196,1200,1211,1217,1227,1233,1243,1254,1258,1285,1288,1296],[18,19,20,21,26],"p",{},"Un ",[22,23,25],"a",{"href":24},"\u002Fglossary\u002Fwhat-is-an-expert-advisor","Expert Advisor"," que sigue operando en plena publicación de las nóminas no agrícolas (NFP) o de una decisión de tasas de interés ya no aplica su estrategia: está lanzando una moneda al aire, y con el spread bien abierto. Un filtro de noticias lo evita. Suspende las entradas nuevas durante unos minutos antes y después de las publicaciones que mueven el mercado, y el resto del tiempo deja que la estrategia haga su trabajo.",[18,28,29,30,34,35,39],{},"MetaTrader 5 trae un calendario integrado. ",[31,32,33],"strong",{},"MetaTrader 4, no",", así que el EA tiene que conseguir las noticias por su cuenta. Esta guía usa la ",[22,36,38],{"href":37},"\u002Fdocs\u002Fapi\u002Feconomic-calendar","API gratuita del calendario económico de ShowMyTrades",": sin cuenta ni clave de API, con una sola URL que autorizar en el terminal y un archivo include que puedes pegar en cualquier EA.",[41,42,44],"h2",{"id":43},"qué-vas-a-construir","🧭 Qué vas a construir",[46,47,52],"pre",{"className":48,"code":50,"language":51},[49],"language-text","cada 15 minutos            en cada tick\n┌────────────────────┐     ┌──────────────────────────────────┐\n│ descarga noticias  │ ──► │ ¿hay una publicación dentro de   │\n│ de los próximos    │     │ [-30 min, +30 min] desde ahora?  │\n│ 2 días (CSV, una   │     │   sí → ninguna entrada nueva     │\n│ sola solicitud)    │     │   no → se ejecuta la estrategia  │\n└────────────────────┘     └──────────────────────────────────┘\n","text",[53,54,50],"code",{"__ignoreMap":55},"",[57,58,59,75],"table",{},[60,61,62],"thead",{},[63,64,65,69,72],"tr",{},[66,67,68],"th",{},"Decisión",[66,70,71],{},"Valor predeterminado en el código",[66,73,74],{},"Por qué",[76,77,78,92,108,119,129],"tbody",{},[63,79,80,84,89],{},[81,82,83],"td",{},"Qué divisas",[81,85,86],{},[53,87,88],{},"EUR,USD",[81,90,91],{},"Las dos divisas del par con el que operas. Si lo dejas vacío, entran las nueve principales",[63,93,94,97,102],{},[81,95,96],{},"Qué impacto",[81,98,99],{},[53,100,101],{},"high",[81,103,104,107],{},[53,105,106],{},"high,medium"," para un filtro más prudente",[63,109,110,113,116],{},[81,111,112],{},"Pausa antes",[81,114,115],{},"30 minutos",[81,117,118],{},"Antes del dato los spreads se amplían y la liquidez se reduce",[63,120,121,124,126],{},[81,122,123],{},"Pausa después",[81,125,115],{},[81,127,128],{},"Aquí se concentran la primera reacción y el giro que suele venir después",[63,130,131,134,137],{},[81,132,133],{},"Intervalo de descarga",[81,135,136],{},"15 minutos",[81,138,139],{},"El calendario cambia pocas veces al día y, de todos modos, la API guarda los datos en caché durante 15 minutos",[41,141,143],{"id":142},"paso-1-autoriza-la-dirección-en-metatrader","🔑 Paso 1: autoriza la dirección en MetaTrader",[18,145,146,149,150,153,154,158],{},[53,147,148],{},"WebRequest()",", la función de MQL4 que descarga datos de internet, solo se comunica con las direcciones que hayas aprobado. En el terminal abre ",[31,151,152],{},"Herramientas → Opciones → Asesores Expertos"," (Tools → Options → Expert Advisors), marca ",[155,156,157],"em",{},"Permitir WebRequest para las siguientes URL"," (Allow WebRequest for listed URL) y agrega:",[46,160,163],{"className":161,"code":162,"language":51,"meta":55},[49],"https:\u002F\u002Fshowmytrades.com\n",[53,164,162],{"__ignoreMap":55},[18,166,167,168,171,172,175],{},"Si te saltas este paso, la descarga devuelve ",[53,169,170],{},"-1"," con el error ",[53,173,174],{},"4060",". Cuando eso ocurre, el archivo include deja un aviso en la pestaña Expertos (Experts), así que no te quedarás preguntándote por qué el filtro no dice nada.",[41,177,179],{"id":178},"paso-2-guarda-el-archivo-include","📄 Paso 2: guarda el archivo include",[18,181,182,183,186,187,190,191,194],{},"Guarda el código siguiente como ",[53,184,185],{},"SMT_NewsFilter.mqh"," en la carpeta ",[53,188,189],{},"MQL4\\Include"," de tu terminal; la encuentras en Archivo → Abrir carpeta de datos (File → Open Data Folder). Es el mismo archivo que aparece en la ",[22,192,193],{"href":37},"referencia de la API",", y además compila tal cual en MQL5.",[46,196,200],{"className":197,"code":198,"filename":185,"language":199,"meta":55,"style":55},"language-cpp shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F+------------------------------------------------------------------+\n\u002F\u002F| SMT_NewsFilter.mqh - filtro de noticias para MT4 y MT5           |\n\u002F\u002F| Datos: https:\u002F\u002Fshowmytrades.com\u002Fapi\u002Fpublic\u002Fcalendar\u002Fv1 (gratis)  |\n\u002F\u002F| Docs: https:\u002F\u002Fshowmytrades.com\u002Fdocs\u002Fapi\u002Feconomic-calendar        |\n\u002F\u002F| Configuración: Herramientas > Opciones > Asesores Expertos >     |\n\u002F\u002F|        Permitir WebRequest (Allow WebRequest) para               |\n\u002F\u002F|        https:\u002F\u002Fshowmytrades.com                                  |\n\u002F\u002F+------------------------------------------------------------------+\n#property strict\n\ninput string SMT_Currencies     = \"EUR,USD\"; \u002F\u002F Noticias: divisas (separadas por comas, vacío = todas)\ninput string SMT_Impact         = \"high\";    \u002F\u002F Noticias: impacto (high | high,medium | all)\ninput int    SMT_MinutesBefore  = 30;        \u002F\u002F Noticias: pausa antes de una publicación (minutos)\ninput int    SMT_MinutesAfter   = 30;        \u002F\u002F Noticias: pausa después de una publicación (minutos)\ninput int    SMT_RefreshMinutes = 15;        \u002F\u002F Noticias: intervalo de descarga (minutos, mín. 15)\n\ndatetime smt_eventTime[];\nstring   smt_eventTitle[];\ndatetime smt_nextDownload = 0;\nlong     smt_serverTime   = 0;     \u002F\u002F hora UTC del servidor (segundos Unix) en la última descarga\nuint     smt_syncTick     = 0;     \u002F\u002F GetTickCount() en ese mismo momento\nbool     smt_clockSynced  = false;\n\n\u002F\u002F--- la hora UTC real: el reloj del servidor más los milisegundos transcurridos desde la\n\u002F\u002F--- descarga, contados con GetTickCount(), que no sabe de zonas horarias, horario de\n\u002F\u002F--- verano ni ajustes del reloj del equipo (la resta en uint sobrevive a su desbordamiento).\n\u002F\u002F--- Antes de la primera descarga se usa TimeGMT() como respaldo. Nunca TimeCurrent(): el\n\u002F\u002F--- desfase GMT del bróker es desconocido y salta con el horario de verano.\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--- cuánto se aparta el reloj del bróker de UTC, en segundos (7200 = GMT+2). Útil por sí\n\u002F\u002F--- solo: la mayoría de los EA nunca lo conoce. TimeCurrent() es la hora del último tick,\n\u002F\u002F--- así que léelo con el mercado abierto, no durante el fin de semana.\nint SMT_BrokerGmtOffsetSeconds()\n{\n   return (int)(TimeCurrent() - SMT_Now());\n}\n\n\u002F\u002F--- todo lo que hay después de la n-ésima coma (el título del CSV, que puede contener comas)\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--- descarga los próximos 2 días (la ventana también cubre las últimas 6 horas)\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 reintenta en un minuto\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 la línea 0 es el encabezado\n   {\n      \u002F\u002F última línea \"# server_time=1760702400 server_time_iso=...\": el reloj UTC del servidor\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 segundos Unix, 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 mientras haya una publicación dentro de la ventana de pausa; reason indica cuál\nbool SMT_IsNewsTime(string &reason)\n{\n   reason = \"\";\n   if(MQLInfoInteger(MQL_TESTER)) return false;   \u002F\u002F sin red en el probador de estrategias\n   if(TimeCurrent() >= smt_nextDownload) SMT_Download();\n\n   datetime now = SMT_Now();\n   for(int i = 0; i \u003C ArraySize(smt_eventTime); i++)\n   {\n      if(now >= smt_eventTime[i] - SMT_MinutesBefore * 60 && now \u003C= smt_eventTime[i] + SMT_MinutesAfter * 60)\n      {\n         reason = smt_eventTitle[i];\n         return true;\n      }\n   }\n   return false;\n}\n","cpp",[53,201,202,210,216,222,228,234,240,246,251,257,264,270,276,282,288,294,299,305,311,317,323,329,335,340,346,352,358,364,370,376,382,388,394,400,406,411,417,423,429,435,440,446,451,456,462,468,473,479,485,491,497,503,509,515,521,527,533,539,544,549,555,561,566,572,578,583,589,595,601,607,613,618,624,630,636,642,647,652,658,664,670,675,681,687,693,698,704,710,716,722,728,734,740,746,752,758,764,770,776,782,788,794,800,806,812,817,823,829,835,841,847,852,857,863,869,874,880,886,892,897,903,909,914,920,925,931,937,942,947,953],{"__ignoreMap":55},[203,204,207],"span",{"class":205,"line":206},"line",1,[203,208,209],{},"\u002F\u002F+------------------------------------------------------------------+\n",[203,211,213],{"class":205,"line":212},2,[203,214,215],{},"\u002F\u002F| SMT_NewsFilter.mqh - filtro de noticias para MT4 y MT5           |\n",[203,217,219],{"class":205,"line":218},3,[203,220,221],{},"\u002F\u002F| Datos: https:\u002F\u002Fshowmytrades.com\u002Fapi\u002Fpublic\u002Fcalendar\u002Fv1 (gratis)  |\n",[203,223,225],{"class":205,"line":224},4,[203,226,227],{},"\u002F\u002F| Docs: https:\u002F\u002Fshowmytrades.com\u002Fdocs\u002Fapi\u002Feconomic-calendar        |\n",[203,229,231],{"class":205,"line":230},5,[203,232,233],{},"\u002F\u002F| Configuración: Herramientas > Opciones > Asesores Expertos >     |\n",[203,235,237],{"class":205,"line":236},6,[203,238,239],{},"\u002F\u002F|        Permitir WebRequest (Allow WebRequest) para               |\n",[203,241,243],{"class":205,"line":242},7,[203,244,245],{},"\u002F\u002F|        https:\u002F\u002Fshowmytrades.com                                  |\n",[203,247,249],{"class":205,"line":248},8,[203,250,209],{},[203,252,254],{"class":205,"line":253},9,[203,255,256],{},"#property strict\n",[203,258,260],{"class":205,"line":259},10,[203,261,263],{"emptyLinePlaceholder":262},true,"\n",[203,265,267],{"class":205,"line":266},11,[203,268,269],{},"input string SMT_Currencies     = \"EUR,USD\"; \u002F\u002F Noticias: divisas (separadas por comas, vacío = todas)\n",[203,271,273],{"class":205,"line":272},12,[203,274,275],{},"input string SMT_Impact         = \"high\";    \u002F\u002F Noticias: impacto (high | high,medium | all)\n",[203,277,279],{"class":205,"line":278},13,[203,280,281],{},"input int    SMT_MinutesBefore  = 30;        \u002F\u002F Noticias: pausa antes de una publicación (minutos)\n",[203,283,285],{"class":205,"line":284},14,[203,286,287],{},"input int    SMT_MinutesAfter   = 30;        \u002F\u002F Noticias: pausa después de una publicación (minutos)\n",[203,289,291],{"class":205,"line":290},15,[203,292,293],{},"input int    SMT_RefreshMinutes = 15;        \u002F\u002F Noticias: intervalo de descarga (minutos, mín. 15)\n",[203,295,297],{"class":205,"line":296},16,[203,298,263],{"emptyLinePlaceholder":262},[203,300,302],{"class":205,"line":301},17,[203,303,304],{},"datetime smt_eventTime[];\n",[203,306,308],{"class":205,"line":307},18,[203,309,310],{},"string   smt_eventTitle[];\n",[203,312,314],{"class":205,"line":313},19,[203,315,316],{},"datetime smt_nextDownload = 0;\n",[203,318,320],{"class":205,"line":319},20,[203,321,322],{},"long     smt_serverTime   = 0;     \u002F\u002F hora UTC del servidor (segundos Unix) en la última descarga\n",[203,324,326],{"class":205,"line":325},21,[203,327,328],{},"uint     smt_syncTick     = 0;     \u002F\u002F GetTickCount() en ese mismo momento\n",[203,330,332],{"class":205,"line":331},22,[203,333,334],{},"bool     smt_clockSynced  = false;\n",[203,336,338],{"class":205,"line":337},23,[203,339,263],{"emptyLinePlaceholder":262},[203,341,343],{"class":205,"line":342},24,[203,344,345],{},"\u002F\u002F--- la hora UTC real: el reloj del servidor más los milisegundos transcurridos desde la\n",[203,347,349],{"class":205,"line":348},25,[203,350,351],{},"\u002F\u002F--- descarga, contados con GetTickCount(), que no sabe de zonas horarias, horario de\n",[203,353,355],{"class":205,"line":354},26,[203,356,357],{},"\u002F\u002F--- verano ni ajustes del reloj del equipo (la resta en uint sobrevive a su desbordamiento).\n",[203,359,361],{"class":205,"line":360},27,[203,362,363],{},"\u002F\u002F--- Antes de la primera descarga se usa TimeGMT() como respaldo. Nunca TimeCurrent(): el\n",[203,365,367],{"class":205,"line":366},28,[203,368,369],{},"\u002F\u002F--- desfase GMT del bróker es desconocido y salta con el horario de verano.\n",[203,371,373],{"class":205,"line":372},29,[203,374,375],{},"datetime SMT_Now()\n",[203,377,379],{"class":205,"line":378},30,[203,380,381],{},"{\n",[203,383,385],{"class":205,"line":384},31,[203,386,387],{},"   if(!smt_clockSynced) return TimeGMT();\n",[203,389,391],{"class":205,"line":390},32,[203,392,393],{},"   uint elapsedMs = GetTickCount() - smt_syncTick;\n",[203,395,397],{"class":205,"line":396},33,[203,398,399],{},"   return (datetime)(smt_serverTime + elapsedMs \u002F 1000);\n",[203,401,403],{"class":205,"line":402},34,[203,404,405],{},"}\n",[203,407,409],{"class":205,"line":408},35,[203,410,263],{"emptyLinePlaceholder":262},[203,412,414],{"class":205,"line":413},36,[203,415,416],{},"\u002F\u002F--- cuánto se aparta el reloj del bróker de UTC, en segundos (7200 = GMT+2). Útil por sí\n",[203,418,420],{"class":205,"line":419},37,[203,421,422],{},"\u002F\u002F--- solo: la mayoría de los EA nunca lo conoce. TimeCurrent() es la hora del último tick,\n",[203,424,426],{"class":205,"line":425},38,[203,427,428],{},"\u002F\u002F--- así que léelo con el mercado abierto, no durante el fin de semana.\n",[203,430,432],{"class":205,"line":431},39,[203,433,434],{},"int SMT_BrokerGmtOffsetSeconds()\n",[203,436,438],{"class":205,"line":437},40,[203,439,381],{},[203,441,443],{"class":205,"line":442},41,[203,444,445],{},"   return (int)(TimeCurrent() - SMT_Now());\n",[203,447,449],{"class":205,"line":448},42,[203,450,405],{},[203,452,454],{"class":205,"line":453},43,[203,455,263],{"emptyLinePlaceholder":262},[203,457,459],{"class":205,"line":458},44,[203,460,461],{},"\u002F\u002F--- todo lo que hay después de la n-ésima coma (el título del CSV, que puede contener comas)\n",[203,463,465],{"class":205,"line":464},45,[203,466,467],{},"string SMT_AfterComma(const string line, const int n)\n",[203,469,471],{"class":205,"line":470},46,[203,472,381],{},[203,474,476],{"class":205,"line":475},47,[203,477,478],{},"   int pos = -1;\n",[203,480,482],{"class":205,"line":481},48,[203,483,484],{},"   for(int i = 0; i \u003C n; i++)\n",[203,486,488],{"class":205,"line":487},49,[203,489,490],{},"   {\n",[203,492,494],{"class":205,"line":493},50,[203,495,496],{},"      pos = StringFind(line, \",\", pos + 1);\n",[203,498,500],{"class":205,"line":499},51,[203,501,502],{},"      if(pos \u003C 0) return \"\";\n",[203,504,506],{"class":205,"line":505},52,[203,507,508],{},"   }\n",[203,510,512],{"class":205,"line":511},53,[203,513,514],{},"   string rest = StringSubstr(line, pos + 1);\n",[203,516,518],{"class":205,"line":517},54,[203,519,520],{},"   StringReplace(rest, \"\\\"\\\"\", \"\\\"\");\n",[203,522,524],{"class":205,"line":523},55,[203,525,526],{},"   if(StringLen(rest) >= 2 && StringGetCharacter(rest, 0) == '\"')\n",[203,528,530],{"class":205,"line":529},56,[203,531,532],{},"      rest = StringSubstr(rest, 1, StringLen(rest) - 2);\n",[203,534,536],{"class":205,"line":535},57,[203,537,538],{},"   return rest;\n",[203,540,542],{"class":205,"line":541},58,[203,543,405],{},[203,545,547],{"class":205,"line":546},59,[203,548,263],{"emptyLinePlaceholder":262},[203,550,552],{"class":205,"line":551},60,[203,553,554],{},"\u002F\u002F--- descarga los próximos 2 días (la ventana también cubre las últimas 6 horas)\n",[203,556,558],{"class":205,"line":557},61,[203,559,560],{},"bool SMT_Download()\n",[203,562,564],{"class":205,"line":563},62,[203,565,381],{},[203,567,569],{"class":205,"line":568},63,[203,570,571],{},"   string url = \"https:\u002F\u002Fshowmytrades.com\u002Fapi\u002Fpublic\u002Fcalendar\u002Fv1?format=csv&days=2&impact=\" + SMT_Impact;\n",[203,573,575],{"class":205,"line":574},64,[203,576,577],{},"   if(StringLen(SMT_Currencies) > 0) url += \"&currency=\" + SMT_Currencies;\n",[203,579,581],{"class":205,"line":580},65,[203,582,263],{"emptyLinePlaceholder":262},[203,584,586],{"class":205,"line":585},66,[203,587,588],{},"   char   post[], result[];\n",[203,590,592],{"class":205,"line":591},67,[203,593,594],{},"   string headers;\n",[203,596,598],{"class":205,"line":597},68,[203,599,600],{},"   ResetLastError();\n",[203,602,604],{"class":205,"line":603},69,[203,605,606],{},"   int status = WebRequest(\"GET\", url, \"\", NULL, 10000, post, 0, result, headers);\n",[203,608,610],{"class":205,"line":609},70,[203,611,612],{},"   if(status != 200)\n",[203,614,616],{"class":205,"line":615},71,[203,617,490],{},[203,619,621],{"class":205,"line":620},72,[203,622,623],{},"      Print(\"[SMT] calendar download failed: HTTP \", status, \", error \", GetLastError(),\n",[203,625,627],{"class":205,"line":626},73,[203,628,629],{},"            \". Is https:\u002F\u002Fshowmytrades.com in Tools > Options > Expert Advisors > Allow WebRequest?\");\n",[203,631,633],{"class":205,"line":632},74,[203,634,635],{},"      smt_nextDownload = TimeCurrent() + 60; \u002F\u002F reintenta en un minuto\n",[203,637,639],{"class":205,"line":638},75,[203,640,641],{},"      return false;\n",[203,643,645],{"class":205,"line":644},76,[203,646,508],{},[203,648,650],{"class":205,"line":649},77,[203,651,263],{"emptyLinePlaceholder":262},[203,653,655],{"class":205,"line":654},78,[203,656,657],{},"   string body = CharArrayToString(result, 0, WHOLE_ARRAY, CP_UTF8);\n",[203,659,661],{"class":205,"line":660},79,[203,662,663],{},"   string lines[];\n",[203,665,667],{"class":205,"line":666},80,[203,668,669],{},"   int n = StringSplit(body, '\\n', lines);\n",[203,671,673],{"class":205,"line":672},81,[203,674,263],{"emptyLinePlaceholder":262},[203,676,678],{"class":205,"line":677},82,[203,679,680],{},"   ArrayResize(smt_eventTime, 0);\n",[203,682,684],{"class":205,"line":683},83,[203,685,686],{},"   ArrayResize(smt_eventTitle, 0);\n",[203,688,690],{"class":205,"line":689},84,[203,691,692],{},"   for(int i = 1; i \u003C n; i++) \u002F\u002F la línea 0 es el encabezado\n",[203,694,696],{"class":205,"line":695},85,[203,697,490],{},[203,699,701],{"class":205,"line":700},86,[203,702,703],{},"      \u002F\u002F última línea \"# server_time=1760702400 server_time_iso=...\": el reloj UTC del servidor\n",[203,705,707],{"class":205,"line":706},87,[203,708,709],{},"      if(StringFind(lines[i], \"# server_time=\") == 0)\n",[203,711,713],{"class":205,"line":712},88,[203,714,715],{},"      {\n",[203,717,719],{"class":205,"line":718},89,[203,720,721],{},"         long serverTime = StringToInteger(StringSubstr(lines[i], 14, 10));\n",[203,723,725],{"class":205,"line":724},90,[203,726,727],{},"         if(serverTime > 0)\n",[203,729,731],{"class":205,"line":730},91,[203,732,733],{},"         {\n",[203,735,737],{"class":205,"line":736},92,[203,738,739],{},"            smt_serverTime  = serverTime;\n",[203,741,743],{"class":205,"line":742},93,[203,744,745],{},"            smt_syncTick    = GetTickCount();\n",[203,747,749],{"class":205,"line":748},94,[203,750,751],{},"            smt_clockSynced = true;\n",[203,753,755],{"class":205,"line":754},95,[203,756,757],{},"         }\n",[203,759,761],{"class":205,"line":760},96,[203,762,763],{},"         continue;\n",[203,765,767],{"class":205,"line":766},97,[203,768,769],{},"      }\n",[203,771,773],{"class":205,"line":772},98,[203,774,775],{},"      string f[];\n",[203,777,779],{"class":205,"line":778},99,[203,780,781],{},"      if(StringSplit(lines[i], ',', f) \u003C 8) continue;\n",[203,783,785],{"class":205,"line":784},100,[203,786,787],{},"      int k = ArraySize(smt_eventTime);\n",[203,789,791],{"class":205,"line":790},101,[203,792,793],{},"      ArrayResize(smt_eventTime, k + 1);\n",[203,795,797],{"class":205,"line":796},102,[203,798,799],{},"      ArrayResize(smt_eventTitle, k + 1);\n",[203,801,803],{"class":205,"line":802},103,[203,804,805],{},"      smt_eventTime[k]  = (datetime)StringToInteger(f[0]);      \u002F\u002F segundos Unix, UTC\n",[203,807,809],{"class":205,"line":808},104,[203,810,811],{},"      smt_eventTitle[k] = f[2] + \" \" + f[3] + \": \" + SMT_AfterComma(lines[i], 7);\n",[203,813,815],{"class":205,"line":814},105,[203,816,508],{},[203,818,820],{"class":205,"line":819},106,[203,821,822],{},"   smt_nextDownload = TimeCurrent() + MathMax(SMT_RefreshMinutes, 15) * 60;\n",[203,824,826],{"class":205,"line":825},107,[203,827,828],{},"   Print(\"[SMT] calendar: \", ArraySize(smt_eventTime), \" events loaded. UTC now \",\n",[203,830,832],{"class":205,"line":831},108,[203,833,834],{},"         TimeToString(SMT_Now(), TIME_DATE|TIME_MINUTES), \", broker clock is GMT\",\n",[203,836,838],{"class":205,"line":837},109,[203,839,840],{},"         (SMT_BrokerGmtOffsetSeconds() >= 0 ? \"+\" : \"\"), DoubleToString(SMT_BrokerGmtOffsetSeconds() \u002F 3600.0, 1));\n",[203,842,844],{"class":205,"line":843},110,[203,845,846],{},"   return true;\n",[203,848,850],{"class":205,"line":849},111,[203,851,405],{},[203,853,855],{"class":205,"line":854},112,[203,856,263],{"emptyLinePlaceholder":262},[203,858,860],{"class":205,"line":859},113,[203,861,862],{},"\u002F\u002F--- true mientras haya una publicación dentro de la ventana de pausa; reason indica cuál\n",[203,864,866],{"class":205,"line":865},114,[203,867,868],{},"bool SMT_IsNewsTime(string &reason)\n",[203,870,872],{"class":205,"line":871},115,[203,873,381],{},[203,875,877],{"class":205,"line":876},116,[203,878,879],{},"   reason = \"\";\n",[203,881,883],{"class":205,"line":882},117,[203,884,885],{},"   if(MQLInfoInteger(MQL_TESTER)) return false;   \u002F\u002F sin red en el probador de estrategias\n",[203,887,889],{"class":205,"line":888},118,[203,890,891],{},"   if(TimeCurrent() >= smt_nextDownload) SMT_Download();\n",[203,893,895],{"class":205,"line":894},119,[203,896,263],{"emptyLinePlaceholder":262},[203,898,900],{"class":205,"line":899},120,[203,901,902],{},"   datetime now = SMT_Now();\n",[203,904,906],{"class":205,"line":905},121,[203,907,908],{},"   for(int i = 0; i \u003C ArraySize(smt_eventTime); i++)\n",[203,910,912],{"class":205,"line":911},122,[203,913,490],{},[203,915,917],{"class":205,"line":916},123,[203,918,919],{},"      if(now >= smt_eventTime[i] - SMT_MinutesBefore * 60 && now \u003C= smt_eventTime[i] + SMT_MinutesAfter * 60)\n",[203,921,923],{"class":205,"line":922},124,[203,924,715],{},[203,926,928],{"class":205,"line":927},125,[203,929,930],{},"         reason = smt_eventTitle[i];\n",[203,932,934],{"class":205,"line":933},126,[203,935,936],{},"         return true;\n",[203,938,940],{"class":205,"line":939},127,[203,941,769],{},[203,943,945],{"class":205,"line":944},128,[203,946,508],{},[203,948,950],{"class":205,"line":949},129,[203,951,952],{},"   return false;\n",[203,954,956],{"class":205,"line":955},130,[203,957,405],{},[18,959,960,961],{},"Lo que hace, por orden: construye la solicitud a partir de los parámetros de entrada, descarga el CSV, guarda una marca de tiempo y una etiqueta por evento, y responde a la única pregunta que le importa al EA: ",[155,962,963],{},"¿hay ahora mismo una publicación dentro de la ventana?",[41,965,967],{"id":966},"paso-3-llámala-antes-de-cada-entrada","🔌 Paso 3: llámala antes de cada entrada",[18,969,970],{},"En tu EA, incluye el archivo y pregunta antes de abrir una posición:",[46,972,975],{"className":197,"code":973,"filename":974,"language":199,"meta":55,"style":55},"#include \u003CSMT_NewsFilter.mqh>\n\nvoid OnTick()\n{\n   string news;\n   if(SMT_IsNewsTime(news))\n   {\n      Comment(\"News filter active: \", news);\n      return;                       \u002F\u002F sin entradas nuevas durante la ventana de noticias\n   }\n   Comment(\"\");\n   \u002F\u002F ... tu lógica de entrada ...\n}\n","YourEA.mq4",[53,976,977,982,986,991,995,1000,1005,1009,1014,1019,1023,1028,1033],{"__ignoreMap":55},[203,978,979],{"class":205,"line":206},[203,980,981],{},"#include \u003CSMT_NewsFilter.mqh>\n",[203,983,984],{"class":205,"line":212},[203,985,263],{"emptyLinePlaceholder":262},[203,987,988],{"class":205,"line":218},[203,989,990],{},"void OnTick()\n",[203,992,993],{"class":205,"line":224},[203,994,381],{},[203,996,997],{"class":205,"line":230},[203,998,999],{},"   string news;\n",[203,1001,1002],{"class":205,"line":236},[203,1003,1004],{},"   if(SMT_IsNewsTime(news))\n",[203,1006,1007],{"class":205,"line":242},[203,1008,490],{},[203,1010,1011],{"class":205,"line":248},[203,1012,1013],{},"      Comment(\"News filter active: \", news);\n",[203,1015,1016],{"class":205,"line":253},[203,1017,1018],{},"      return;                       \u002F\u002F sin entradas nuevas durante la ventana de noticias\n",[203,1020,1021],{"class":205,"line":259},[203,1022,508],{},[203,1024,1025],{"class":205,"line":266},[203,1026,1027],{},"   Comment(\"\");\n",[203,1029,1030],{"class":205,"line":272},[203,1031,1032],{},"   \u002F\u002F ... tu lógica de entrada ...\n",[203,1034,1035],{"class":205,"line":278},[203,1036,405],{},[18,1038,1039,1040,1043,1044,1047],{},"Los cinco parámetros de entrada (",[53,1041,1042],{},"SMT_Currencies",", ",[53,1045,1046],{},"SMT_Impact"," y los tres valores en minutos) aparecen en la ventana de parámetros del EA como cualquier otra opción, así que cada gráfico puede tener los suyos.",[18,1049,1050,1051,1054,1055,1058],{},"Vuelve a compilar, coloca el EA en el gráfico y mira la pestaña Expertos: la primera línea debería ser ",[53,1052,1053],{},"[SMT] calendar: N events loaded",". En un día tranquilo ",[53,1056,1057],{},"N"," puede ser cero, y eso es lo correcto, no un error.",[41,1060,1062],{"id":1061},"️-horas-relojes-y-el-probador-de-estrategias","⏱️ Horas, relojes y el probador de estrategias",[18,1064,1065],{},"Hay tres detalles que deciden si el filtro salta en el minuto correcto.",[57,1067,1068,1076],{},[60,1069,1070],{},[63,1071,1072,1074],{},[66,1073],{},[66,1075],{},[76,1077,1078,1099,1116],{},[63,1079,1080,1085],{},[81,1081,1082],{},[31,1083,1084],{},"La API habla en UTC y te dice qué hora es",[81,1086,1087,1090,1091,1094,1095,1098],{},[53,1088,1089],{},"ts"," es tiempo Unix en segundos, en UTC. Cada descarga termina con el reloj del propio servidor (",[53,1092,1093],{},"# server_time=…","), y ",[53,1096,1097],{},"SMT_Now()"," lo mantiene en marcha con el contador de ticks del equipo, que no sabe de zonas horarias ni de horario de verano. Nada depende de la zona horaria del bróker, del horario de verano de ningún país ni de que el VPS tenga bien configurada la zona",[63,1100,1101,1109],{},[81,1102,1103],{},[31,1104,1105,1106],{},"Nunca ",[53,1107,1108],{},"TimeCurrent()",[81,1110,1111,1112,1115],{},"La hora del bróker va desfasada respecto a UTC en una cantidad que el EA no puede conocer y que cambia dos veces al año. ",[53,1113,1114],{},"SMT_BrokerGmtOffsetSeconds()"," te mide ese desfase, algo útil por sí solo; el filtro nunca depende de él",[63,1117,1118,1123],{},[81,1119,1120],{},[31,1121,1122],{},"El probador de estrategias (Strategy Tester) no tiene internet",[81,1124,1125,1126,1128],{},"Ahí ",[53,1127,148],{}," está desactivada, así que en los backtests la función responde «no hay noticias». Para probar un filtro de noticias sobre datos históricos hace falta un archivo local con los eventos pasados, y eso ya es otro proyecto",[41,1130,1132],{"id":1131},"️-cómo-ajustarlo","🎛️ Cómo ajustarlo",[1134,1135,1136,1151,1164,1174],"ul",{},[1137,1138,1139,1142,1143,1146,1147,1150],"li",{},[31,1140,1141],{},"Posiciones abiertas."," El código solo bloquea las entradas ",[155,1144,1145],{},"nuevas",". Cerrar, ajustar los stops o ampliarlos antes de una publicación es una decisión de estrategia; el mismo ",[53,1148,1149],{},"SMT_IsNewsTime()"," te dice cuándo hacerlo.",[1137,1152,1153,1156,1157,1159,1160,1163],{},[31,1154,1155],{},"Solo una divisa del par."," Pon ",[53,1158,1042],{}," en ",[53,1161,1162],{},"USD"," si solo te interesan las noticias del dólar.",[1137,1165,1166,1169,1170,1173],{},[31,1167,1168],{},"También impacto medio."," Con ",[53,1171,1172],{},"SMT_Impact = \"high,medium\""," los eventos se multiplican más o menos por tres. Va bien para los scalpers y suele ser demasiado para los sistemas de swing.",[1137,1175,1176,1179,1180,1183],{},[31,1177,1178],{},"Días festivos."," ",[53,1181,1182],{},"impact=all"," incluye los días festivos de los mercados como eventos de día completo. Casi ningún filtro los quiere, y con el valor predeterminado quedan fuera.",[41,1185,1187],{"id":1186},"cómo-comprobar-los-datos","🔍 Cómo comprobar los datos",[18,1189,1190,1191,1195],{},"El mismo calendario también es una página que puedes consultar: ",[22,1192,1194],{"href":1193},"\u002Ftools\u002Feconomic-calendar","calendario económico",". Cuando el EA indique que se detuvo por «USD high: Nonfarm Payrolls», ahí verás el evento con su previsión y, después de la publicación, el dato publicado (columna «Actual»).",[41,1197,1199],{"id":1198},"preguntas-frecuentes","❓ Preguntas frecuentes",[18,1201,1202,1205,1206,1210],{},[31,1203,1204],{},"¿Hace falta una cuenta de ShowMyTrades?","\nNo. La API del calendario es gratuita y abierta, sin clave. Si quieres la ",[22,1207,1209],{"href":1208},"\u002Fguides\u002Fhow-to-verify-your-account","página pública verificada",", haz seguimiento de tu cuenta en ShowMyTrades, pero el filtro de noticias no depende de ello.",[18,1212,1213,1216],{},[31,1214,1215],{},"¿Cuánto tráfico genera?","\nUna solicitud cada 15 minutos por gráfico, de unos pocos kilobytes cada una. Diez EA en un mismo terminal suman 40 solicitudes por hora. El límite es de 600 por minuto por dirección IP.",[18,1218,1219,1222,1223,1226],{},[31,1220,1221],{},"¿Por qué no leer directamente Forex Factory?","\nSe puede, y muchos EA lo hacen. Su archivo semanal admite dos descargas cada cinco minutos por dirección IP, algo que no aguanta un VPS con muchos terminales, y no trae los valores ",[53,1224,1225],{},"actual",". El endpoint de ShowMyTrades filtra por divisa e impacto en el servidor, devuelve unos pocos kilobytes y está pensado para consultarse a intervalos regulares.",[18,1228,1229,1232],{},[31,1230,1231],{},"El reloj o la zona horaria de mi VPS están mal. ¿El filtro salta igualmente en el minuto correcto?","\nSí. Con cada descarga, el servidor le dice al EA qué hora es en UTC, y el EA mantiene ese reloj en marcha por su cuenta. Que el VPS tenga la zona equivocada o vaya unos minutos desfasado no cambia nada. Ni siquiera el cambio al horario de verano en el VPS afecta: el EA mide el tiempo transcurrido con el contador de ticks, no con el reloj.",[18,1234,1235,1238,1239,1242],{},[31,1236,1237],{},"¿Qué pasa si la descarga falla?","\nEl filtro conserva el último calendario que cargó y vuelve a intentarlo al cabo de un minuto. Si nunca llegó a cargar ninguno (arranque en limpio, sin internet), responde «no hay noticias» y el EA opera. Si no es lo que quieres, comprueba ",[53,1240,1241],{},"ArraySize(smt_eventTime) == 0"," y decide qué hacer.",[18,1244,1245,1248,1249,1253],{},[31,1246,1247],{},"¿El mismo archivo funciona en MT5?","\nSí, sin cambios. MT5 además tiene ",[22,1250,1252],{"href":1251},"\u002Fguides\u002Fnews-filter-mt5-expert-advisor-built-in-calendar-or-api","su propio calendario","; usa el que mejor te venga.",[41,1255,1257],{"id":1256},"artículos-relacionados","🔗 Artículos relacionados",[1134,1259,1260,1266,1271,1278],{},[1137,1261,1262,1265],{},[22,1263,1264],{"href":37},"Referencia de la API del calendario económico",": todos los parámetros, el formato JSON y el WebSocket para cTrader",[1137,1267,1268],{},[22,1269,1270],{"href":1251},"Filtro de noticias en MT5: ¿calendario integrado o API?",[1137,1272,1273,1277],{},[22,1274,1276],{"href":1275},"\u002Fguides\u002Fadd-a-news-filter-to-a-ctrader-cbot","Cómo agregar un filtro de noticias a un cBot de cTrader",": la misma idea donde no hay HTTP disponible",[1137,1279,1280,1284],{},[22,1281,1283],{"href":1282},"\u002Fguides\u002Flive-ea-results-on-your-sales-page","Resultados en real de tu EA en la página de ventas",": cuando el EA opere bien, muéstralo",[1286,1287],"hr",{},[18,1289,1290,1291,1295],{},"El filtro cabe en una página de código y una URL. Si ya ",[22,1292,1294],{"href":1293},"\u002Fsignup","haces seguimiento de tu EA en ShowMyTrades",", las operaciones que evita en torno a las noticias aparecerán como el drawdown que no tuvo.",[1297,1298,1299],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":55,"searchDepth":212,"depth":212,"links":1301},[1302,1303,1304,1305,1306,1307,1308,1309,1310],{"id":43,"depth":212,"text":44},{"id":142,"depth":212,"text":143},{"id":178,"depth":212,"text":179},{"id":966,"depth":212,"text":967},{"id":1061,"depth":212,"text":1062},{"id":1131,"depth":212,"text":1132},{"id":1186,"depth":212,"text":1187},{"id":1198,"depth":212,"text":1199},{"id":1256,"depth":212,"text":1257},"2026-10-17T00:00:00.000Z","MetaTrader 4 no ofrece un calendario económico a los Expert Advisors. Esta guía te enseña a agregarlo en diez minutos: una API de calendario gratuita, un archivo include y una función que llamas antes de cada entrada. Código MQL4 completo, sin clave de API.",false,"md",{"src":1316},"\u002Fimages\u002Fblog\u002Fadd-a-news-filter-to-your-mt4-expert-advisor-hero.svg",{},"\u002Fes\u002Fguides\u002Fadd-a-news-filter-to-your-mt4-expert-advisor",{"title":5,"description":1312},"es\u002F3.guides\u002F41.add-a-news-filter-to-your-mt4-expert-advisor",null,"I6PVbfeVoa5eWWpWFvIFCQSXdanjap4b55S7lZsPM1M",[1324,1329],{"title":1325,"path":1326,"stem":1327,"description":1328,"children":-1},"Cómo mostrar varias cuentas de trading en una sola página","\u002Fes\u002Fguides\u002Fshow-multiple-trading-accounts-on-one-page","es\u002F3.guides\u002F40.show-multiple-trading-accounts-on-one-page","Varias cuentas, varios EA o varios brókeres en una misma página web: una tabla comparativa en vivo con una fila por cuenta, gráficos uno al lado del otro o una sola curva combinada. Con el código.",{"title":1270,"path":1330,"stem":1331,"description":1332,"children":-1},"\u002Fes\u002Fguides\u002Fnews-filter-mt5-expert-advisor-built-in-calendar-or-api","es\u002F3.guides\u002F42.news-filter-mt5-expert-advisor-built-in-calendar-or-api","MetaTrader 5 incluye un calendario económico que los Expert Advisors pueden leer sin descargar nada. Cuándo basta, cuándo no y cómo usar en su lugar una API de calendario gratuita, con código MQL5 para las dos opciones.",[1334,1336,1338,1339,1341],{"path":1335},"\u002Fguides\u002Fadd-a-news-filter-to-your-mt4-expert-advisor",{"path":1337},"\u002Fde\u002Fguides\u002Fadd-a-news-filter-to-your-mt4-expert-advisor",{"path":1318},{"path":1340},"\u002Fja\u002Fguides\u002Fadd-a-news-filter-to-your-mt4-expert-advisor",{"path":1342},"\u002Fzh\u002Fguides\u002Fadd-a-news-filter-to-your-mt4-expert-advisor",1794154056245]