#property strict /* v9.0 Started in US with Version 9.0 on May 9, 2025 v9.1 Updated with Chart Open Close Function */ #include "My-Functions5.mqh" CAppDialog OurInterface; CEdit LotSize1,LotSize2,LotSize3,SD1,TP1,SL1,TSL1,SD2,TP2,SL2,TSL2,SD3,TP3,SL3,TSL3; CLabel LotLabel1,LotLabel2,LotLabel3, SDLabel1,TPLabel1,SLLabel1,TSLLabel1, SDLabel2,TPLabel2,SLLabel2,TSLLabel2, SDLabel3,TPLabel3,SLLabel3,TSLLabel3, NewsTime,NewsRemaining; struct NewsAlertData { string timeStr; string currency; string impact; string newsnumber; string event; string difference; string result; }; struct NextNewsData { string timeStr; string impact; string currency; }; double TradeVolume1 =1; double sd1=0; double tp1=500; double sl1=1000; double tsl1=0; double TradeVolume2 =1.2; double sd2=20; double tp2=1000; double sl2=1000; double tsl2=500; double TradeVolume3 =3; double sd3=0; double tp3=0; double sl3=0; double tsl3=0; string trade_status; string content_msg; string content_file; string SymbolOrder ="None"; string ordertype = "None"; bool basecurrency = true; double diffvalue=0; double mindiffvaluefortrade=1; string OK_TO_TRADE="NG"; int thisnewsnumber = 0; int totalnewsnumber = 0; long MagicNewsTime1=1; long MagicNewsTime2=2; long MagicNewsTime3=3; long MagicNewsTime4=4; long MagicNewsTime5=5; long MagicNewsTime6=6; string CurrentTimeOrderExecFirst = "ExecFirst"; string CurrentTimeOrderTakenFirst = "TakenFirst"; string CurrentTimeOrderExecSecond = "ExecSecond"; string CurrentTimeOrderTakenSecond = "TakenSecond"; string CurrentTimeOrderExecThird = "ExecThird"; string CurrentTimeOrderTakenThird = "TakenThird"; int OnInit() { capture_previous_update_id= 0; chat_id = 0; bot.Token(InpToken); // Random Number Generator MathSrand(GetTickCount()); EventSetMillisecondTimer(900); telegram_to_mt4(); // Enable mouse move events ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true); // Register this chart as having an active EA string gvName = "EA_Active_"+IntegerToString(ChartID()); GlobalVariableTemp(gvName); // Will auto-delete on terminal shutdown GlobalVariableSet(gvName, 1); // Create the dialog if(!OurInterface.Create(0, __FILE__, 0, 50, 50, 460, 300)) { Print("Failed to create dialog!"); return INIT_FAILED; } createLabel(LotLabel1, OurInterface,"LotLabel1", "Lot1 :",10,50,10,30); createInputBox(LotSize1, OurInterface,"LotVolume1", string(TradeVolume1),60,130,10,30); createLabel(SDLabel1, OurInterface,"SDLabel1", "SD1:",10,50,40,60); createInputBox(SD1, OurInterface,"SD_Value1", string(sd1),60,130,40,60); createLabel(TPLabel1, OurInterface,"TPLabel1", "TP1:",10,50,70,90); createInputBox(TP1, OurInterface,"TP_Value1", string(tp1),60,130,70,90); createLabel(SLLabel1, OurInterface,"SLLabel1", "SL1:",10,50,100,120); createInputBox(SL1, OurInterface,"SL_Value1", string(sl1),60,130,100,120); createLabel(TSLLabel1, OurInterface,"TSLLabel1", "TSL1:",10,50,130,150); createInputBox(TSL1, OurInterface,"TSL_Value1", string(tsl1),60,130,130,150); createLabel(LotLabel2, OurInterface,"LotLabel2", "Lot2 :",140,180,10,30); createInputBox(LotSize2, OurInterface,"LotVolume2", string(TradeVolume2),190,260,10,30); createLabel(SDLabel2, OurInterface,"SDLabel2", "SD2:",140,180,40,60); createInputBox(SD2, OurInterface,"SD_Value2", string(sd2),190,260,40,60); createLabel(TPLabel2, OurInterface,"TPLabel2", "TP2:",140,180,70,90); createInputBox(TP2, OurInterface,"TP_Value2", string(tp2),190,260,70,90); createLabel(SLLabel2, OurInterface,"SLLabel2", "SL2:",140,180,100,120); createInputBox(SL2, OurInterface,"SL_Value2", string(sl2),190,260,100,120); createLabel(TSLLabel2, OurInterface,"TSLLabel2", "TSL2:",140,180,130,150); createInputBox(TSL2, OurInterface,"TSL_Value2", string(tsl2),190,260,130,150); createLabel(LotLabel3, OurInterface,"LotLabel3", "Lot3 :",270,310,10,30); createInputBox(LotSize3, OurInterface,"LotVolume3", string(TradeVolume3),320,390,10,30); createLabel(SDLabel3, OurInterface,"SDLabel3", "SD3:",270,310,40,60); createInputBox(SD3, OurInterface,"SD_Value3", string(sd3),320,390,40,60); createLabel(TPLabel3, OurInterface,"TPLabel3", "TP3:",270,310,70,90); createInputBox(TP3, OurInterface,"TP_Value3", string(tp3),320,390,70,90); createLabel(SLLabel3, OurInterface,"SLLabel3", "SL3:",270,310,100,120); createInputBox(SL3, OurInterface,"SL_Value3", string(sl3),320,390,100,120); createLabel(TSLLabel3, OurInterface,"TSLLabel3", "TSL3:",270,310,130,150); createInputBox(TSL3, OurInterface,"TSL_Value3", string(tsl3),320,390,130,150); Print("Dialog created: ", OurInterface.IsVisible()); // Should return true if showing // After creation, try forcing redraw ChartRedraw(); OurInterface.Run(); // Bring the dialog to front OurInterface.Show(); return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { // Clean up when EA is removed string gvName = "EA_Active_"+IntegerToString(ChartID()); if(GlobalVariableCheck(gvName)) { GlobalVariableDel(gvName); Print("EA removed - deleted global variable: ", gvName); } EventKillTimer(); // Kill the timer OurInterface.Destroy(reason); } void OnTick() { // Check for pending orders to delete CheckAndDeleteOldPendingOrders(); // Check for news files string filePattern = "News_Alert_*.*"; string foundFile; long handle = FileFindFirst(filePattern, foundFile, 0); if(handle != INVALID_HANDLE) { do { NewsAlertData news = ReadNewsAlert(foundFile); string getnewsnumber[]; StringSplit(news.newsnumber, StringGetCharacter("/", 0), getnewsnumber); int count_getnewsnumber = ArraySize(getnewsnumber); if(count_getnewsnumber > 1) { thisnewsnumber = (int)StringToInteger(getnewsnumber[0]); totalnewsnumber = (int)StringToInteger(getnewsnumber[1]); } string getdifference[]; StringSplit(news.difference, StringGetCharacter("%", 0), getdifference); int count_getdifference = ArraySize(getdifference); if(count_getdifference > 0) { diffvalue = MathAbs(StringToDouble(getdifference[0])); } if(diffvalue > mindiffvaluefortrade) OK_TO_TRADE = "OK"; if(news.currency == "USD") SymbolOrder = "XAUUSD"; if(news.currency == "JPY") SymbolOrder = "USDJPY"; if(news.currency == "CHF") SymbolOrder = "USDCHF"; if(news.currency == "CAD") SymbolOrder = "USDCAD"; if(news.currency == "AUD") SymbolOrder = "AUDUSD"; if(news.currency == "EUR") SymbolOrder = "XAUEUR"; if(news.currency == "GBP") SymbolOrder = "XAUGBP"; if(news.currency == "NZD") SymbolOrder = "NZDUSD"; basecurrency = isbasecurrency(SymbolOrder, news.currency); if((news.result == "Better" && basecurrency == true) || (news.result == "Worse" && basecurrency == false)) ordertype = "Buy"; if((news.result == "Worse" && basecurrency == true) || (news.result == "Better" && basecurrency == false)) ordertype = "Sell"; if(thisnewsnumber == 1) { MagicNewsTime1 = CreateMagicNumber("News", SymbolOrder, ordertype, 1); MagicNewsTime2 = CreateMagicNumber("News", SymbolOrder, ordertype, 2); CurrentTimeOrderExecFirst = news.timeStr + news.currency + DoubleToString(thisnewsnumber); if((CurrentTimeOrderTakenFirst != CurrentTimeOrderExecFirst) && (news.result == "Better" || news.result == "Worse") && IsNewsWithinOneMinute(news.timeStr) <= 60 && IsNewsWithinOneMinute(news.timeStr) > 0) { if(ordertype == "Buy" && OK_TO_TRADE == "OK") { SendBuyOrder(SymbolOrder, TradeVolume1, 0, 0, MagicNewsTime1); SendBuyLimitOrder(SymbolOrder, TradeVolume2, sd2 , 0, 0, MagicNewsTime2); } if(ordertype == "Sell" && OK_TO_TRADE == "OK") { SendSellOrder(SymbolOrder, TradeVolume1, 0, 0, MagicNewsTime1); SendSellLimitOrder(SymbolOrder, TradeVolume2,sd2 , 0, 0, MagicNewsTime2); } CurrentTimeOrderTakenFirst = CurrentTimeOrderExecFirst; } } if(thisnewsnumber == 2) { MagicNewsTime3 = CreateMagicNumber("News", SymbolOrder, ordertype, 3); MagicNewsTime4 = CreateMagicNumber("News", SymbolOrder, ordertype, 4); CurrentTimeOrderExecSecond = news.timeStr + news.currency + DoubleToString(thisnewsnumber); if((CurrentTimeOrderTakenSecond != CurrentTimeOrderExecSecond) && (news.result == "Better" || news.result == "Worse") && IsNewsWithinOneMinute(news.timeStr) <= 60 && IsNewsWithinOneMinute(news.timeStr) > 0) { if(ordertype == "Buy" && OK_TO_TRADE == "OK") { SendBuyOrder(SymbolOrder, TradeVolume1, 0, 0, MagicNewsTime3); SendBuyLimitOrder(SymbolOrder, TradeVolume2,sd2 , 0, 0, MagicNewsTime4); } if(ordertype == "Sell" && OK_TO_TRADE == "OK") { SendSellOrder(SymbolOrder, TradeVolume1, 0, 0, MagicNewsTime3); SendSellLimitOrder(SymbolOrder, TradeVolume2,sd2 , 0, 0, MagicNewsTime4); } CurrentTimeOrderTakenSecond = CurrentTimeOrderExecSecond; } } if(thisnewsnumber == 3) { MagicNewsTime5 = CreateMagicNumber("News", SymbolOrder, ordertype, 5); MagicNewsTime6 = CreateMagicNumber("News", SymbolOrder, ordertype, 6); CurrentTimeOrderExecThird = news.timeStr + news.currency + DoubleToString(thisnewsnumber); if((CurrentTimeOrderTakenThird != CurrentTimeOrderExecThird) && (news.result == "Better" || news.result == "Worse") && IsNewsWithinOneMinute(news.timeStr) <= 60 && IsNewsWithinOneMinute(news.timeStr) > 0) { if(ordertype == "Buy" && OK_TO_TRADE == "OK") { SendBuyOrder(SymbolOrder, TradeVolume1, 0, 0, MagicNewsTime5); SendBuyLimitOrder(SymbolOrder, TradeVolume2,sd2 , 0, 0, MagicNewsTime6); } if(ordertype == "Sell" && OK_TO_TRADE == "OK") { SendSellOrder(SymbolOrder, TradeVolume1, 0, 0, MagicNewsTime5); SendSellLimitOrder(SymbolOrder, TradeVolume2,sd2 , 0, 0, MagicNewsTime6); } CurrentTimeOrderTakenThird = CurrentTimeOrderExecThird; } } OK_TO_TRADE = "NG"; if(IsNewsWithinOneMinute(news.timeStr) > 120) FileDelete(foundFile); } while(FileFindNext(handle, foundFile)); FileFindClose(handle); } // Modify positions with SL/TP for(int i = PositionsTotal()-1; i >= 0; i--) { if(PositionGetTicket(i)) { ulong ticket = PositionGetInteger(POSITION_TICKET); long magic = PositionGetInteger(POSITION_MAGIC); if(GetMagicSource(magic) == "News") { ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); double sl = PositionGetDouble(POSITION_SL); if((type == POSITION_TYPE_BUY) && sl == 0) { double new_sl = PositionGetDouble(POSITION_PRICE_OPEN) - PipsToPrice(sl1, PositionGetString(POSITION_SYMBOL)); double new_tp = PositionGetDouble(POSITION_PRICE_OPEN) + PipsToPrice(tp1, PositionGetString(POSITION_SYMBOL)); MqlTradeRequest request = {}; MqlTradeResult result = {}; request.action = TRADE_ACTION_SLTP; request.position = ticket; request.symbol = PositionGetString(POSITION_SYMBOL); request.sl = new_sl; request.tp = new_tp; if(!OrderSend(request, result)) { Print("OrderSend failed. Error code: ", result.retcode); } else { Print("OrderSend successful. Ticket: ", result.order); } } if((type == POSITION_TYPE_SELL) && sl == 0) { double new_sl = PositionGetDouble(POSITION_PRICE_OPEN) + PipsToPrice(sl1, PositionGetString(POSITION_SYMBOL)); double new_tp = PositionGetDouble(POSITION_PRICE_OPEN) - PipsToPrice(tp1, PositionGetString(POSITION_SYMBOL)); MqlTradeRequest request = {}; MqlTradeResult result = {}; request.action = TRADE_ACTION_SLTP; request.position = ticket; request.symbol = PositionGetString(POSITION_SYMBOL); request.sl = new_sl; request.tp = new_tp; if(!OrderSend(request, result)) { Print("OrderSend failed. Error code: ", result.retcode); } else { Print("OrderSend successful. Ticket: ", result.order); } } } } } // Trailing StopLoss for(int i = PositionsTotal()-1; i >= 0; i--) { if(PositionGetTicket(i)) { ulong ticket = PositionGetInteger(POSITION_TICKET); long magic = PositionGetInteger(POSITION_MAGIC); if(GetMagicSource(magic) == "News") { ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); double sl = PositionGetDouble(POSITION_SL); // Trailing StopLoss for Buy if(type == POSITION_TYPE_BUY) { double ask = SymbolInfoDouble(PositionGetString(POSITION_SYMBOL), SYMBOL_ASK); if(tsl1 != 0 && ask > PositionGetDouble(POSITION_PRICE_OPEN) + tsl1 * _Point) { double new_sl = ask - tsl1 * _Point; new_sl = NormalizeDouble(new_sl, _Digits); if(sl < new_sl && sl != 0) { MqlTradeRequest request = {}; MqlTradeResult result = {}; request.action = TRADE_ACTION_SLTP; request.position = ticket; request.symbol = PositionGetString(POSITION_SYMBOL); request.sl = new_sl; request.tp = PositionGetDouble(POSITION_TP); if(!OrderSend(request, result)) { Print("OrderSend failed. Error code: ", result.retcode); } else { Print("OrderSend successful. Ticket: ", result.order); } } } } // Trailing StopLoss for Sell if(type == POSITION_TYPE_SELL) { double bid = SymbolInfoDouble(PositionGetString(POSITION_SYMBOL), SYMBOL_BID); if(tsl1 != 0 && bid < PositionGetDouble(POSITION_PRICE_OPEN) - tsl1 * _Point) { double new_sl = bid + tsl1 * _Point; new_sl = NormalizeDouble(new_sl, _Digits); if(sl > new_sl && sl != 0) { MqlTradeRequest request = {}; MqlTradeResult result = {}; request.action = TRADE_ACTION_SLTP; request.position = ticket; request.symbol = PositionGetString(POSITION_SYMBOL); request.sl = new_sl; request.tp = PositionGetDouble(POSITION_TP); if(!OrderSend(request, result)) { Print("OrderSend failed. Error code: ", result.retcode); } else { Print("OrderSend successful. Ticket: ", result.order); } } } } } } } } // End of On Tick void OnTimer() { chartopenclose(); showbalance(); if(FileIsExist("Next_News_Alert.txt")) { NextNewsData nextnews = ReadNextNews("Next_News_Alert.txt"); string nextnewstime = nextnews.timeStr; string nextnewscurr = nextnews.currency; datetime myTime = TimeLocal(); // or any datetime value string fullTimeStr = TimeToString(myTime, TIME_SECONDS); // "2025.04.17 14:32:15" string infofirstline = "Next High Imp News at "+nextnewstime+" \n for "+nextnewscurr; string infosecondline = "Calculating......"; int timediff = IsNewsWithinOneMinute(nextnewstime); if(timediff > 0 && timediff <= 60) infosecondline = "News Windows Active......."; if(timediff > 60) { infofirstline = "Wait for the next news tomorrow...."; infosecondline = "No More News today"; } if(timediff < 0) { int remaining = MathAbs(timediff); infosecondline = "Time Remaining "+SecondsToHMS(remaining); } createLabel(NewsTime, OurInterface, "NewsTime", infofirstline, 40, 100, 160, 180); createLabel(NewsRemaining, OurInterface, "NewsRemaing", infosecondline, 100, 150, 190, 200); } } // End On Timer // Start of Event Handling void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { OurInterface.OnEvent(id, lparam, dparam, sparam); if(id == CHARTEVENT_OBJECT_ENDEDIT) { TradeVolume1 = updatetextboxdouble(sparam, "LotVolume1", TradeVolume1); sd1 = updatetextboxdouble(sparam, "SD_Value1", sd1); tp1 = updatetextboxdouble(sparam, "TP_Value1", tp1); sl1 = updatetextboxdouble(sparam, "SL_Value1", sl1); tsl1 = updatetextboxdouble(sparam, "TSL_Value1", tsl1); TradeVolume2 = updatetextboxdouble(sparam, "LotVolume1", TradeVolume2); sd2 = updatetextboxdouble(sparam, "SD_Value2", sd2); tp2 = updatetextboxdouble(sparam, "TP_Value2", tp2); sl2 = updatetextboxdouble(sparam, "SL_Value2", sl2); tsl2 = updatetextboxdouble(sparam, "TSL_Value2", tsl2); TradeVolume3 = updatetextboxdouble(sparam, "LotVolume1", TradeVolume3); sd3 = updatetextboxdouble(sparam, "SD_Value3", sd3); tp3 = updatetextboxdouble(sparam, "TP_Value3", tp3); sl3 = updatetextboxdouble(sparam, "SL_Value3", sl3); tsl3 = updatetextboxdouble(sparam, "TSL_Value3", tsl3); } // End of CHARTEVENT_OBJECT_ENDEDIT } // End of Event Handling NewsAlertData ReadNewsAlert(string filename) { NewsAlertData data; int fileHandle = FileOpen(filename, FILE_READ | FILE_TXT |FILE_ANSI); if(fileHandle == INVALID_HANDLE) { Print("Failed to open file: " + filename); return data; } string line = ""; while(!FileIsEnding(fileHandle)) { line = FileReadString(fileHandle); if(StringFind(line, "Time:") == 0) { string temp = StringSubstr(line, 5); StringTrimLeft(temp); data.timeStr = temp; } else if(StringFind(line, "Currency:") == 0) { string temp = StringSubstr(line, 9); StringTrimLeft(temp); data.currency = temp; } else if(StringFind(line, "Impact:") == 0) { string temp = StringSubstr(line, 7); StringTrimLeft(temp); data.impact = temp; } else if(StringFind(line, "High Impact News Number :") == 0) { string temp = StringSubstr(line, 25); StringTrimLeft(temp); data.newsnumber = temp; } else if(StringFind(line, "Event:") == 0) { string temp = StringSubstr(line, 6); StringTrimLeft(temp); data.event = temp; } else if(StringFind(line, "Difference:") == 0) { string temp = StringSubstr(line, 11); StringTrimLeft(temp); data.difference = temp; } else if(StringFind(line, "Result:") == 0) { string temp = StringSubstr(line, 7); StringTrimLeft(temp); data.result = temp; } } FileClose(fileHandle); return data; } NextNewsData ReadNextNews(string filename) { NextNewsData data; int fileHandle = FileOpen(filename, FILE_READ | FILE_TXT |FILE_ANSI); if(fileHandle == INVALID_HANDLE) { Print("Failed to open file: " + filename); // Fixed error here too return data; } string line; while(!FileIsEnding(fileHandle)) { line = FileReadString(fileHandle); if(StringFind(line, "Time:") == 0) { string temp = StringSubstr(line, 5); StringTrimLeft(temp); data.timeStr = temp; } else if(StringFind(line, "Currency:") == 0) { string temp = StringSubstr(line, 9); StringTrimLeft(temp); data.currency = temp; } } FileClose(fileHandle); return data; } bool MagicNumberUsed(long magic, int N = 10) { // Get the total number of history orders int total = HistoryOrdersTotal(); // Determine the range to check (last N orders) int startIndex = MathMax(0, total - N); datetime startTime = TimeCurrent() - 60 * 60 * 24 * 365; // Start time (1 year ago) datetime endTime = TimeCurrent(); // End time (current time) // Select orders within the time range if (!HistorySelect(startTime, endTime)) { Print("Error selecting history orders: ", GetLastError()); return false; } // Loop through the selected orders for (int i = total - 1; i >= startIndex; i--) { ulong ticket = HistoryOrderGetTicket(i); // Get the ticket for the order if (ticket != 0) { int orderMagic = (int)HistoryOrderGetInteger(ticket, ORDER_MAGIC); // Get magic number of the order if (orderMagic == magic) { return true; // Magic number found } } } return false; // Magic number not found } int IsNewsWithinOneMinute(string timeStr) { // Trim whitespace directly on the variable StringTrimLeft(timeStr); StringTrimRight(timeStr); // Find colon int colonPos = StringFind(timeStr, ":"); if(colonPos < 0) { Print("Invalid time format: no colon found"); return false; } // Extract hour, minute, am/pm string hourStr = StringSubstr(timeStr, 0, colonPos); string minuteStr = StringSubstr(timeStr, colonPos + 1, 2); string ampm = StringSubstr(timeStr, StringLen(timeStr) - 2, 2); int hour = (int)StringToInteger(hourStr); int minute = (int)StringToInteger(minuteStr); // Convert to 24-hour format if(ampm == "pm" && hour < 12) hour += 12; if(ampm == "am" && hour == 12) hour = 0; // Build datetime datetime now = TimeLocal(); datetime todayStart = StringToTime(TimeToString(now, TIME_DATE)); datetime newsTime = todayStart + (hour * 3600) + (minute * 60); int diff = (int)(now - newsTime); return diff; }