129 lines
4.8 KiB
MQL5
129 lines
4.8 KiB
MQL5
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| OvercomingAccessibilityIV.mq5 |
|
||
|
|
//| Copyright 2026, Clemence Benjamin |
|
||
|
|
//| http://www.mql5.com |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
|
||
|
|
#include <OvercomingAccessibilityIV/JAson.mqh>
|
||
|
|
#include <Trade/Trade.mqh>
|
||
|
|
|
||
|
|
#define SERVER_URL "http://127.0.0.1:8082"
|
||
|
|
#define POLL_INTERVAL 2
|
||
|
|
|
||
|
|
CTrade trade;
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Expert Advisor initialization |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
int OnInit()
|
||
|
|
{
|
||
|
|
trade.SetExpertMagicNumber(202504);
|
||
|
|
trade.SetDeviationInPoints(10);
|
||
|
|
Print("Voice EA started");
|
||
|
|
return(INIT_SUCCEEDED);
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Fetch command from server via HTTP GET |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
string GetCommand()
|
||
|
|
{
|
||
|
|
string url = SERVER_URL + "/get_command";
|
||
|
|
uchar resultData[];
|
||
|
|
string resultHeaders;
|
||
|
|
uchar postData[];
|
||
|
|
int timeout = 2000;
|
||
|
|
int res = WebRequest("GET", url, NULL, timeout, postData, resultData, resultHeaders);
|
||
|
|
if(res != 200)
|
||
|
|
return("");
|
||
|
|
return(CharArrayToString(resultData));
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Post execution result back to server |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
bool PostResult(string json_result)
|
||
|
|
{
|
||
|
|
string url = SERVER_URL + "/post_response";
|
||
|
|
uchar postData[];
|
||
|
|
StringToCharArray(json_result, postData);
|
||
|
|
//--- remove the null terminator
|
||
|
|
int size = ArraySize(postData);
|
||
|
|
if(size > 0 && postData[size-1] == 0)
|
||
|
|
ArrayResize(postData, size-1);
|
||
|
|
uchar resultData[];
|
||
|
|
string resultHeaders;
|
||
|
|
string headers = "Content-Type: application/json\r\n";
|
||
|
|
int timeout = 2000;
|
||
|
|
int res = WebRequest("POST", url, headers, timeout, postData, resultData, resultHeaders);
|
||
|
|
if(res == 200)
|
||
|
|
Print("Result sent: ", json_result);
|
||
|
|
else
|
||
|
|
Print("POST error: ", res);
|
||
|
|
return(res == 200);
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Execute parsed command (BUY/SELL/CLOSE_ALL/BALANCE) |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
string ExecuteCommand(CJAVal &cmd)
|
||
|
|
{
|
||
|
|
string action = cmd["action"].ToStr();
|
||
|
|
if(action == "BUY" || action == "SELL")
|
||
|
|
{
|
||
|
|
string symbol = cmd["symbol"].ToStr();
|
||
|
|
double volume = cmd["volume"].ToDbl();
|
||
|
|
if(SymbolInfoInteger(symbol, SYMBOL_SELECT) == 0)
|
||
|
|
SymbolSelect(symbol, true);
|
||
|
|
double price = (action == "BUY") ? SymbolInfoDouble(symbol, SYMBOL_ASK)
|
||
|
|
: SymbolInfoDouble(symbol, SYMBOL_BID);
|
||
|
|
ulong ticket = (action == "BUY") ? trade.Buy(volume, symbol, price, 0, 0, "Telegram")
|
||
|
|
: trade.Sell(volume, symbol, price, 0, 0, "Telegram");
|
||
|
|
if(ticket)
|
||
|
|
return(StringFormat("{\"status\":\"success\",\"ticket\":%d,\"price\":%.5f}", ticket, price));
|
||
|
|
else
|
||
|
|
return(StringFormat("{\"status\":\"error\",\"message\":\"Trade failed, error %d\"}", GetLastError()));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
if(action == "CLOSE_ALL")
|
||
|
|
{
|
||
|
|
int closed = 0;
|
||
|
|
for(int i=PositionsTotal()-1; i>=0; i--)
|
||
|
|
if(PositionGetTicket(i) && PositionSelectByTicket(PositionGetTicket(i)))
|
||
|
|
if(trade.PositionClose(PositionGetTicket(i)))
|
||
|
|
closed++;
|
||
|
|
return(StringFormat("{\"status\":\"success\",\"message\":\"Closed %d positions\"}", closed));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
if(action == "BALANCE")
|
||
|
|
{
|
||
|
|
double bal = AccountInfoDouble(ACCOUNT_BALANCE);
|
||
|
|
double eq = AccountInfoDouble(ACCOUNT_EQUITY);
|
||
|
|
return(StringFormat("{\"status\":\"success\",\"balance\":%.2f,\"equity\":%.2f}", bal, eq));
|
||
|
|
}
|
||
|
|
return("{\"status\":\"error\",\"message\":\"Unknown action\"}");
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Periodic command poll and execution |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void OnTick()
|
||
|
|
{
|
||
|
|
static datetime lastPoll = 0;
|
||
|
|
if(TimeCurrent() - lastPoll < POLL_INTERVAL)
|
||
|
|
return;
|
||
|
|
lastPoll = TimeCurrent();
|
||
|
|
string json_str = GetCommand();
|
||
|
|
if(json_str == "")
|
||
|
|
return;
|
||
|
|
CJAVal json;
|
||
|
|
if(!json.Deserialize(json_str))
|
||
|
|
return;
|
||
|
|
string action = json["action"].ToStr();
|
||
|
|
if(action == "" || action == "None")
|
||
|
|
return;
|
||
|
|
Print("Command: ", json_str);
|
||
|
|
string result = ExecuteCommand(json);
|
||
|
|
PostResult(result);
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|