//+------------------------------------------------------------------+ //| Cocoa Trading.mq4 | //| Copyright 2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property strict #property version "7.0" #property description "Cocoa Trading Expert Advisor with Telegram integration" #property description "Includes buy/sell limit orders and trading time windows" // Includes #include "My-Functions.mqh" #include #include #include // Global Variables // ================ // Trading Window Parameters int start_hour = 11; // First trading window start hour int start_min = 49; // First trading window start minute int end_hour = 11; // First trading window end hour int end_min = 55; // First trading window end minute int second_start_hour = 18; // Second trading window start hour (18 is best) int second_start_min = 0; // Second trading window start minute int second_end_hour = 22; // Second trading window end hour (22:30 is best) int second_end_min = 30; // Second trading window end minute // Price Boundaries int cocoa_min_price = 8200; // Minimum price level for trading int cocoa_max_price = 11000; // Maximum price level for trading // Trading Control string OK_TO_TRADE = "NG"; // Trading permission flag ("OK" or "NG") string SymbolOrder = "Cocoa_K5"; // Trading symbol // UI Constants const string TP_Value = "TP_Value"; // Take Profit input field name const string SL_Value = "SL_Value"; // Stop Loss input field name // UI Controls CAppDialog OurInterface; // Main dialog window CEdit LotSize, TP, SL; // Input fields CLabel LotLabel, TPLabel, SLLabel; // Labels //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { // Set default trading parameters TradeVolume = 1; // Default lot size sl = 500; // Default stop loss tp = 100; // Default take profit tsl = 0; // Default trailing stop sd = 80; // Default start difference // Initialize Telegram bot bot.Token(InpToken); // Initialize random number generator MathSrand(GetTickCount()); // Set up Telegram update timer EventSetMillisecondTimer(check_telegram_updates); telegram_to_mt4(); // Set up chart interface ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true); // Create main dialog window OurInterface.Create(0, "Cocoa Trading v6.0", 0, 180, 70, 400, 200); // Create and configure lot size label and input LotLabel.Create(0, "LotLabel", 0, 10, 10, 50, 30); OurInterface.Add(LotLabel); LotLabel.Text("Lot Size:"); LotSize.Create(0, LotName, 0, 90, 10, 160, 30); OurInterface.Add(LotSize); LotSize.Text(string(TradeVolume)); // Create and configure take profit label and input TPLabel.Create(0, "TPLabel", 0, 10, 40, 50, 60); OurInterface.Add(TPLabel); TPLabel.Text("TP:"); TP.Create(0, TP_Value, 0, 90, 40, 160, 60); OurInterface.Add(TP); TP.Text(string(tp)); // Create and configure stop loss label and input SLLabel.Create(0, "SLLabel", 0, 10, 70, 50, 90); OurInterface.Add(SLLabel); SLLabel.Text("SL:"); SL.Create(0, SL_Value, 0, 90, 70, 160, 90); OurInterface.Add(SL); SL.Text(string(sl)); // Run the interface OurInterface.Run(); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { // Clean up resources EventKillTimer(); // Stop the timer OurInterface.Destroy(reason); // Destroy the interface } //+------------------------------------------------------------------+ //| Timer function | //+------------------------------------------------------------------+ void OnTimer() { // Check for Telegram updates if (check_telegram_updates >= 2000) { telegram_to_mt4(); } else { Alert("Get Updates Time in Millisecond Should be Greater"); } // Read stored update ID int filehandle = FileOpen("update_id.txt", FILE_READ); int check_used_update_id = (int)(FileReadString(filehandle)); FileClose(filehandle); // Check for new messages if (capture_previous_update_id > check_used_update_id) { Print("New Message Received"); // Update stored update ID int filehandle1 = FileOpen("update_id.txt", FILE_WRITE|FILE_TXT); FileWriteString(filehandle1, IntegerToString(capture_previous_update_id)); FileClose(filehandle1); // Read chat ID int filehandle2 = FileOpen("chat_id.txt", FILE_READ); string check_chat_id = FileReadString(filehandle2); FileClose(filehandle2); // Read message details int filehandle3 = FileOpen("message_details.txt", FILE_READ|FILE_CSV); string check_message_complete = FileReadString(filehandle3); FileClose(filehandle3); // Process message check_message_complete = toUpper(check_message_complete); string check_message = check_message_complete; // Check for shutdown commands int close_ea = StringFind(check_message, "CLOSE"); int stop_ea = StringFind(check_message, "STOP"); int close_cocoa = StringFind(check_message, "COCOA"); int close_china = StringFind(check_message, "CHINA"); // Shutdown if requested if ((close_ea != -1 || stop_ea != -1) && close_cocoa != -1) { Print("EA is shutting down..."); ExpertRemove(); // Terminate the EA } } } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { // Generate magic numbers based on current date int MagicBuy = 100; int MagicSell = 200; int Date = Day(); MagicBuy = MagicBuy + Date; MagicSell = MagicSell + Date; // Calculate trading windows datetime Today = StrToTime(StringConcatenate(Year(), ".", Month(), ".", Day())); datetime start_time = Today + start_hour * 3600 + start_min * 60; datetime end_time = Today + end_hour * 3600 + end_min * 60; datetime second_start_time = Today + second_start_hour * 3600 + second_start_min * 60; datetime second_end_time = Today + second_end_hour * 3600 + second_end_min * 60; // Check if we're in a trading window if ((TimeCurrent() > start_time && TimeCurrent() < end_time)) { // || (TimeCurrent()>second_start_time && TimeCurrent() sd && price < cocoa_max_price) { double buy = price; double slbuy = buy - sl; // buy - previousclose; double tpbuy = buy + tp; // Place buy order int orderbuy = OrderSend(SymbolOrder, OP_BUY, TradeVolume, buy, 0, slbuy, tpbuy, NULL, MagicBuy, 0, clrBlue); Sleep(100000); // Prevent rapid order placement } } // Sell logic if (OK_TO_TRADE == "OK" && CheckSellOpenOrders(MagicSell) == false) { double price = NormalizeDouble(MarketInfo(SymbolOrder, MODE_BID), 4); // Check sell condition if (previousclose - previousopen > sd && price > cocoa_min_price) { double sell = price; double slsell = sell + sl; // sell + previousclose; double tpsell = sell - tp; // Place sell order int ordersell = OrderSend(SymbolOrder, OP_SELL, TradeVolume, sell, 0, slsell, tpsell, NULL, MagicSell, 0, clrBlue); Sleep(100000); // Prevent rapid order placement } } // Update account balance tracking double CurrentAccountBalance = AccountBalance(); if (MaxAccountBalance < AccountBalance()) MaxAccountBalance = AccountBalance(); if (MinAccountBalance > AccountBalance()) MinAccountBalance = AccountBalance(); // Display account information on chart Comment("Initial Account Balance was ", InitialAccountBalance, ", Minimum Balance was ", MinAccountBalance, ", Max Balance was ", MaxAccountBalance, ", Current Balance is ", CurrentAccountBalance, " and Current Equity is ", AccountEquity()); } //+------------------------------------------------------------------+ //| Chart event handler | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { // Forward event to dialog OurInterface.OnEvent(id, lparam, dparam, sparam); // Handle input field changes if (id == CHARTEVENT_OBJECT_ENDEDIT) { // Lot size changed if (sparam == LotName) { string volumeText = ObjectGetString(0, LotName, OBJPROP_TEXT); TradeVolume = StringToDouble(volumeText); ObjectSetString(0, LotName, OBJPROP_TEXT, string(TradeVolume)); return; } // Take profit changed if (sparam == TP_Value) { string volumeText = ObjectGetString(0, TP_Value, OBJPROP_TEXT); tp = StringToDouble(volumeText); ObjectSetString(0, TP_Value, OBJPROP_TEXT, string(tp)); return; } // Stop loss changed if (sparam == SL_Value) { string volumeText = ObjectGetString(0, SL_Value, OBJPROP_TEXT); sl = StringToDouble(volumeText); ObjectSetString(0, SL_Value, OBJPROP_TEXT, string(sl)); return; } } } //+------------------------------------------------------------------+