|
|
@@ -0,0 +1,379 @@
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+//| blTelegramToMT4.mq4 |
|
|
|
+//| Copyright 2025, MQL Development |
|
|
|
+//| https://www.mqldevelopment.com/ |
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+#property copyright "Copyright 2025, MQL Development"
|
|
|
+#property link "https://www.mqldevelopment.com/"
|
|
|
+#property version "1.00"
|
|
|
+#property strict
|
|
|
+
|
|
|
+#define buy "buy"
|
|
|
+#define sell "sell"
|
|
|
+#define MaxOrders 10000
|
|
|
+
|
|
|
+struct msgDetails
|
|
|
+ {
|
|
|
+ int msgid;
|
|
|
+ msgDetails()
|
|
|
+ {
|
|
|
+ msgid = -1;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+msgDetails od[MaxOrders];
|
|
|
+
|
|
|
+struct new_trade_store
|
|
|
+ {
|
|
|
+ ulong ticket; // Ticket
|
|
|
+ int order_type; // OrderType
|
|
|
+ double lot; // Lot
|
|
|
+ double stop_loss; // StopLoss
|
|
|
+ double take_profit; // TakeProfit
|
|
|
+ double price; // Price
|
|
|
+ string symbol; // Symbol
|
|
|
+ int chatId; // ChatId
|
|
|
+ string trade_type; // Trade Type (Trade Type: Tp1, Tp2, Tp3.... Tpn)
|
|
|
+
|
|
|
+ new_trade_store()
|
|
|
+ {
|
|
|
+ ticket = -1;
|
|
|
+ chatId=-1;
|
|
|
+ trade_type = "";
|
|
|
+ }
|
|
|
+
|
|
|
+ };
|
|
|
+new_trade_store newTradeStore[MaxOrders];
|
|
|
+
|
|
|
+input string Settings = " ------------- General Settings ------------- "; //_
|
|
|
+input int magic_no = 333; // Magic no
|
|
|
+input string symbolMatch = "GOLD:XAUUSD,BitCoin:BTCUSD"; // Symbol Mapping (Telegram:MT5)
|
|
|
+input string suffix = ""; // Account Suffix
|
|
|
+input string prefix = ""; // Account Prefix
|
|
|
+input double lotSize = 0.1; // Lot Size
|
|
|
+
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+//| Expert initialization function |
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+// Global Variables
|
|
|
+string url1 = "http://127.0.0.1";
|
|
|
+string header = "Content-Type: application/json\r\nAccept: application/json\r\n";
|
|
|
+
|
|
|
+int getme_result;
|
|
|
+
|
|
|
+string symbolChart[];
|
|
|
+string symbolSnd[];
|
|
|
+string symbolsListUserInput[];
|
|
|
+uchar sym1[];
|
|
|
+uchar sym2[];
|
|
|
+datetime ea_start_time = 0;
|
|
|
+int OnInit()
|
|
|
+ {
|
|
|
+//--- create timer
|
|
|
+ ea_start_time = TimeCurrent();
|
|
|
+
|
|
|
+ ushort u_sep = StringGetCharacter(",",0);
|
|
|
+ StringSplit(symbolMatch,u_sep,symbolsListUserInput);
|
|
|
+ ArrayResize(symbolChart,0);
|
|
|
+ ArrayResize(symbolSnd,0);
|
|
|
+
|
|
|
+ for(int i = 0; i < ArraySize(symbolsListUserInput); i++)
|
|
|
+ {
|
|
|
+
|
|
|
+ string str = symbolsListUserInput[i];
|
|
|
+
|
|
|
+ int index = StringFind(str,":");
|
|
|
+ int index2 = StringLen(str);
|
|
|
+
|
|
|
+ ArrayResize(sym1,0);
|
|
|
+ ArrayResize(sym2,0);
|
|
|
+
|
|
|
+ for(int j = 0; j < index; j++)
|
|
|
+ {
|
|
|
+ ArrayResize(sym1,ArraySize(sym1)+1);
|
|
|
+ sym1[j] = uchar(str[j]);
|
|
|
+ }
|
|
|
+
|
|
|
+ int k = 0;
|
|
|
+
|
|
|
+ for(int j = index + 1 ; j < index2; j++)
|
|
|
+ {
|
|
|
+ ArrayResize(sym2,ArraySize(sym2)+1);
|
|
|
+ sym2[k] = uchar(str[j]);
|
|
|
+ k++;
|
|
|
+ }
|
|
|
+
|
|
|
+ ArrayResize(symbolChart,ArraySize(symbolChart)+1);
|
|
|
+ ArrayResize(symbolSnd,ArraySize(symbolSnd)+1);
|
|
|
+
|
|
|
+ symbolChart[i] = CharArrayToString(sym1);
|
|
|
+ symbolSnd[i] = CharArrayToString(sym2);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ string SplitArray[];
|
|
|
+
|
|
|
+ string jsonString = GET_function(url1+"/get-all-messages",header);
|
|
|
+ StringReplace(jsonString,"},", "*");
|
|
|
+ StringSplit(jsonString,'*',SplitArray);
|
|
|
+
|
|
|
+ for(int i = 0; i < ArraySize(SplitArray); i++)
|
|
|
+ {
|
|
|
+ seperatingDataOnint(i,SplitArray[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ EventSetTimer(1);
|
|
|
+
|
|
|
+//---
|
|
|
+ return(INIT_SUCCEEDED);
|
|
|
+ }
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+//| Expert deinitialization function |
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+void OnDeinit(const int reason)
|
|
|
+ {
|
|
|
+//--- destroy timer
|
|
|
+ EventKillTimer();
|
|
|
+
|
|
|
+ }
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+//| Expert tick function |
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+void OnTick()
|
|
|
+ {
|
|
|
+//---
|
|
|
+
|
|
|
+ }
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+//| Timer function |
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+void OnTimer()
|
|
|
+ {
|
|
|
+//---
|
|
|
+ string SplitArray[];
|
|
|
+
|
|
|
+ string jsonString = GET_function(url1+"/get-all-messages",header);
|
|
|
+ StringReplace(jsonString,"},", "*");
|
|
|
+ StringSplit(jsonString,'*',SplitArray);
|
|
|
+
|
|
|
+ for(int i = 0; i < ArraySize(SplitArray); i++)
|
|
|
+ {
|
|
|
+ seperatingData(i,SplitArray[i]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+//| |
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+string GET_function(string url,string headers)
|
|
|
+ {
|
|
|
+
|
|
|
+ string result_string = NULL;
|
|
|
+ int timeout = 10; // Set the timeout value in seconds
|
|
|
+
|
|
|
+ char result[],data[];
|
|
|
+ string resultHeaders;
|
|
|
+ int res = WebRequest("GET",url,headers,timeout,data,result,resultHeaders);
|
|
|
+
|
|
|
+ if(res == 200)
|
|
|
+ {
|
|
|
+ result_string = CharArrayToString(result);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Print("content GETT: ", result_string," Error: ",GetLastError(), " res: ",res);
|
|
|
+ }
|
|
|
+
|
|
|
+ return result_string;
|
|
|
+ }
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+//| |
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+void seperatingDataOnint(int index, string data)
|
|
|
+ {
|
|
|
+
|
|
|
+ string message = getJsonStringValue(data,"message",4,"\"");
|
|
|
+ int message_id = (int)getJsonStringValue(data,"message_id",4,"\"");
|
|
|
+
|
|
|
+ if(checkExistingTrade(message_id) == false)
|
|
|
+ {
|
|
|
+ Print(" ================ OnInit New Trade Message Found ================");
|
|
|
+ StringReplace(message,"~","#");
|
|
|
+ StringToLower(message);
|
|
|
+ Print("Message is ", message);
|
|
|
+ for(int i=0; i < MaxOrders; i++)
|
|
|
+ {
|
|
|
+ if(od[i].msgid == -1)
|
|
|
+ {
|
|
|
+ od[i].msgid = message_id;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+//| |
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+bool checkExistingTrade(int message_id)
|
|
|
+ {
|
|
|
+ for(int i=0; i < MaxOrders; i++)
|
|
|
+ {
|
|
|
+ if(od[i].msgid == message_id)
|
|
|
+ {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+//| |
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+string getJsonStringValue(string json,string key,int addUp,string endSign)
|
|
|
+ {
|
|
|
+ int indexStart = StringFind(json,key)+StringLen(key)+addUp;
|
|
|
+ int indexEnd = StringFind(json,endSign,indexStart);
|
|
|
+ return StringSubstr(json,indexStart,indexEnd-indexStart);
|
|
|
+ }
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+//| |
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+void seperatingData(int index, string data)
|
|
|
+ {
|
|
|
+// Print(" Data: ", data);
|
|
|
+ string message = getJsonStringValue(data,"message",4,"\"");
|
|
|
+ int message_id = (int)getJsonStringValue(data,"message_id",4,"\"");
|
|
|
+
|
|
|
+ string isReplyValue = getJsonStringValue(data,"is_reply",4,"\"");
|
|
|
+ int reply_to_msg_id = (int)getJsonStringValue(data,"reply_to_msg_id",4,"\"");
|
|
|
+
|
|
|
+ if(isReplyValue == "False")
|
|
|
+ {
|
|
|
+ if(checkExistingTrade(message_id) == false)
|
|
|
+ {
|
|
|
+ Print(" --------------- New Trade Message Found ----------------- ", " Message Id: ", message_id);
|
|
|
+ StringReplace(message,"~","#");
|
|
|
+ StringReplace(message,"##", "#");
|
|
|
+ StringToLower(message);
|
|
|
+ message = removeExtraSpaces(message);
|
|
|
+ Print("Message is ",message);
|
|
|
+ addtoMessageStructure(message_id,message);
|
|
|
+
|
|
|
+ string result[];
|
|
|
+ string tempResult[];
|
|
|
+ int indexTemp = 0;
|
|
|
+
|
|
|
+ StringSplit(message,'#',tempResult);
|
|
|
+
|
|
|
+ for(int i=0; i<ArraySize(tempResult); i++)
|
|
|
+ {
|
|
|
+ //result[i] = StringTrimLeft(result[i]);
|
|
|
+ //result[i] = StringTrimRight(result[i]);
|
|
|
+ //Print("Temp Result : ", tempResult[i], " index is: ", i);
|
|
|
+ if(HasAlphanumeric(tempResult[i]))
|
|
|
+ {
|
|
|
+ //Print(" contains alphanumeric characters.");
|
|
|
+ ArrayResize(result,ArraySize(result)+1);
|
|
|
+ result[indexTemp] = tempResult[i];
|
|
|
+ indexTemp++;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //Print(" does not contain alphanumeric characters.");
|
|
|
+ //ArrayResize(indexToDelete,ArraySize(indexToDelete)+1);
|
|
|
+ //indexToDelete[indexTemp] = i;
|
|
|
+ //indexTemp++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(isReplyValue == "True")
|
|
|
+ {
|
|
|
+ if(checkExistingTrade(message_id) == false)
|
|
|
+ {
|
|
|
+ Print(" --------------- New Replied Message Found ----------------- ", " Message Id: ", message_id, " Reply Message Id: ", reply_to_msg_id);
|
|
|
+ StringToLower(message);
|
|
|
+ Print("Message is ",message);
|
|
|
+ addtoMessageStructure(message_id,message);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+//| |
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+void addtoMessageStructure(int message_id,string message)
|
|
|
+ {
|
|
|
+ for(int i=0; i < MaxOrders; i++)
|
|
|
+ {
|
|
|
+ if(od[i].msgid == -1)
|
|
|
+ {
|
|
|
+ od[i].msgid = message_id;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+//| |
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+string removeExtraSpaces(string str)
|
|
|
+ {
|
|
|
+ string result = "";
|
|
|
+ int len = StringLen(str);
|
|
|
+ bool lastWasSpace = false;
|
|
|
+
|
|
|
+ for(int i = 0; i < len; i++)
|
|
|
+ {
|
|
|
+ string currentChar = StringSubstr(str, i, 1);
|
|
|
+
|
|
|
+ if(currentChar == " ")
|
|
|
+ {
|
|
|
+ // Skip adding this space if the last character was also a space
|
|
|
+ if(lastWasSpace)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ lastWasSpace = true;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ lastWasSpace = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ result += currentChar;
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+//| |
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+bool HasAlphanumeric(string str)
|
|
|
+ {
|
|
|
+//Print("String Length: ", StringLen(str));
|
|
|
+ for(int i = 0; i <= StringLen(str); i++)
|
|
|
+ {
|
|
|
+ //Print("Here ", StringLen(str));
|
|
|
+ if(IsAlphanumeric((char)str[i]))
|
|
|
+ {
|
|
|
+ return true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+//| |
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+bool IsAlphanumeric(char c)
|
|
|
+ {
|
|
|
+ if((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
|
|
|
+ return true;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+//| |
|
|
|
+//+------------------------------------------------------------------+
|
|
|
+//+------------------------------------------------------------------+
|