//+------------------------------------------------------------------+
//|                                             COFIA_MT5_Bridge.mq5 |
//|                        COFIATRADING · Yacht C01 Sovereign Bridge |
//|                                         https://cofiatrading.com |
//+------------------------------------------------------------------+
// INSTALLATION EN 30 SECONDES SUR TON MT5 (Xlence, IronFX, FXcess, Libertex) :
// 1. Dans MetaTrader 5 : Outils -> Options -> Expert Advisors
//    Coche "Autoriser le trading algorithmique" et "Autoriser WebRequest pour les URL listées"
//    Ajoute : https://cofiatrading.com
// 2. Copie ce fichier dans Fichier -> Ouvrir le dossier des données -> MQL5 -> Experts
// 3. Glisse COFIA_MT5_Bridge sur n'importe quel graphique (ex: XAUUSD M15).
//+------------------------------------------------------------------+
#property copyright "COFIATRADING C01"
#property link      "https://cofiatrading.com"
#property version   "3.00"

#include <Trade\Trade.mqh>
CTrade g_trade;

input string InpBridgeUrl     = "https://cofiatrading.com/api/world/mt4-bridge"; // URL Pont Souverain C01
input int    InpPollSeconds   = 2;                                               // Fréquence de lecture (secondes)
input ulong  InpMagicNumber   = 20261018;                                        // Magic Number COFIA C01

datetime g_lastHeartbeat = 0;

int OnInit()
{
   g_trade.SetExpertMagicNumber(InpMagicNumber);
   EventSetTimer(MathMax(1, InpPollSeconds));
   SendHeartbeat();
   Print("[COFIA MT5 Bridge] Pont C01 initialisé sur ", AccountInfoString(ACCOUNT_SERVER), " · Compte #", AccountInfoInteger(ACCOUNT_LOGIN));
   return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
   EventKillTimer();
}

void OnTimer()
{
   PollPendingOrders();
   if(TimeCurrent() - g_lastHeartbeat >= 15)
   {
      SendHeartbeat();
      g_lastHeartbeat = TimeCurrent();
   }
}

void SendHeartbeat()
{
   string headers = "Content-Type: application/json\r\n";
   string payload = StringFormat(
      "{\"action\":\"EA_HEARTBEAT\",\"account_login\":\"%I64d\",\"broker_server\":\"%s\",\"balance\":%.2f,\"equity\":%.2f,\"open_positions\":%d}",
      AccountInfoInteger(ACCOUNT_LOGIN),
      AccountInfoString(ACCOUNT_SERVER),
      AccountInfoDouble(ACCOUNT_BALANCE),
      AccountInfoDouble(ACCOUNT_EQUITY),
      PositionsTotal()
   );
   char post[], result[];
   string resHeaders;
   StringToCharArray(payload, post, 0, StringLen(payload));
   WebRequest("POST", InpBridgeUrl, headers, 3000, post, result, resHeaders);
}

void PollPendingOrders()
{
   char post[], result[];
   string resHeaders;
   string url = InpBridgeUrl + "?format=ea";
   int res = WebRequest("GET", url, "", 3000, post, result, resHeaders);
   if(res != 200) return;

   string line = CharArrayToString(result);
   if(StringFind(line, "ORDER|") != 0) return;

   string parts[];
   int n = StringSplit(line, '|', parts);
   if(n < 7) return;

   string cofiaTicket = parts[1];
   string sym         = parts[2];
   string side        = parts[3];
   double lots        = StringToDouble(parts[4]);
   double sl          = StringToDouble(parts[5]);
   double tp          = StringToDouble(parts[6]);

   bool ok = false;
   double price = (side == "SELL") ? SymbolInfoDouble(sym, SYMBOL_BID) : SymbolInfoDouble(sym, SYMBOL_ASK);
   if(side == "SELL")
      ok = g_trade.Sell(lots, sym, price, sl, tp, "COFIA " + cofiaTicket);
   else
      ok = g_trade.Buy(lots, sym, price, sl, tp, "COFIA " + cofiaTicket);

   ulong dealTicket = g_trade.ResultDeal();
   string mt5TicketStr = ok ? IntegerToString(dealTicket) : ("REJECTED_" + IntegerToString(g_trade.ResultRetcode()));
   SendAck(cofiaTicket, mt5TicketStr, sym, side, lots, price);
}

void SendAck(string cofiaTicket, string mt5Ticket, string sym, string side, double lots, double fillPrice)
{
   string headers = "Content-Type: application/json\r\n";
   string payload = StringFormat(
      "{\"action\":\"EA_ACK\",\"ticket_id\":\"%s\",\"mt4_ticket\":\"%s\",\"symbol\":\"%s\",\"side\":\"%s\",\"lots\":%.2f,\"fill_price\":%.2f,\"account_login\":\"%I64d\",\"broker_server\":\"%s\",\"balance\":%.2f,\"equity\":%.2f,\"open_positions\":%d}",
      cofiaTicket, mt5Ticket, sym, side, lots, fillPrice,
      AccountInfoInteger(ACCOUNT_LOGIN),
      AccountInfoString(ACCOUNT_SERVER),
      AccountInfoDouble(ACCOUNT_BALANCE),
      AccountInfoDouble(ACCOUNT_EQUITY),
      PositionsTotal()
   );
   char post[], result[];
   string resHeaders;
   StringToCharArray(payload, post, 0, StringLen(payload));
   WebRequest("POST", InpBridgeUrl, headers, 3000, post, result, resHeaders);
}
//+------------------------------------------------------------------+
