//+------------------------------------------------------------------+ //| localHedgingMasterCopierMt5.mq5 | //| Copyright 2025, MQL Development | //| https://www.mqldevelopment.com/ | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MQL Development" #property link "https://www.mqldevelopment.com/" #property version "1.00" #include CTrade trade; #define orderCount 2000 #define count1 50 #define testCounter 50 #define MaxOrders 20000 #define daysOfTradesToAdd 20 #property description "Control Panels and Dialogs. Demonstration class CLabel" #include #include #include #include #include #include #include //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ struct historyTradesClientSide { ulong ticket; ulong magic; historyTradesClientSide() { ticket = -1; magic = 0; } }; historyTradesClientSide historyTradeStore[MaxOrders]; struct masterOrder { datetime opentime; string symbol; ulong ordertype; double price; double lots; double stoploss; double takeprofit; ulong ticket; ulong magic; double accountBalance; int contractSize; string comment; masterOrder() { ticket=-1; price=-1; symbol=Symbol(); ordertype=-1; lots=0; stoploss=0; takeprofit=0; } }; masterOrder mod1[orderCount]; struct order { ulong ticket; double price; datetime opentime; string symbol; int ordertype; double lots; double stoploss; double takeprofit; double accountBalance; int contractSize; string comments; ulong magicNo; double closedPercentageOfTrade; order() { ticket =-1; closedPercentageOfTrade = 0; } }; struct clientOrder { ulong ticket; double price; datetime opentime; string symbol; int ordertype; double lots; double stoploss; double takeprofit; ulong magic; string comments; double masterLot; clientOrder() { ticket=-1; price=-1; symbol=Symbol(); ordertype=-1; lots=0; masterLot=0; stoploss=0; takeprofit=0; magic=-1; comments=""; } }; clientOrder cod[orderCount]; enum operation_mode { Master, //Master Slave, //Slave }; enum lotcalculator { fix, //Fixed Lot Size rsk, //Risk Percentage }; sinput string string_0 = "<><><><><><> General SETTINGS <><><><><><>"; //__ input int magic_no = 333; // Magic no input string suffix = ""; // Suffix input string prefix = ""; // Prefix input bool useMinimumLot = false; // Use Minimum Lot Threshold input double takeprofitTrade = 10; // Fixed Take Profit in Pips input double stoplossTrade = 10; // Fixed Stop Loss in Pips input double inpPips = 0.2; // Pips To Start Copy input double minimumLot = 0.01; // Minimum Lot input bool useMaximumLot = false; // Use Maximum Lot Threshold input double maximumLot = 0.01; // Maximum Lot input string string_0_3 = "<><><><><><> Lot Management<><><><><><>"; //__ input double lot_size = 0.1; // Lot Size input lotcalculator lot_calculator = fix; // Lot Size Calculator input double risk = 0.1; // Risk in Percentage % // Heart Beat sinput string string_1 = "<><><><><><> HeartBeat Setting <><><><><><>"; //__ input string slaveServer = ""; // Slave Server input string slaveId = ""; // Slave Login ID input string masterServer = ""; // Master Server input string slaveVersion = "4"; // Slave Version input string localApiKey = "U2FsdGVkX18vBY4H1uzQiZwuh8B++8VBtCGJ3yGr2XPII0qCodmfuhjssKu5oug1J4e97bkwPtDQLi4py1OODQ=="; // Local API Key input string localHB_req_link = "http://localhost/api/mlastConnected"; // Request Link For LastConnected input string dashboardSettings = "<><><><><><> Dashboard Settings<><><><><><>"; input int DashHeight = 115; // Enter Height of Dashboard input int DashWidth = 490; // Enter Width of Dashboard input int FontSize = 10; // Text Font Size // Global Variables int filehandle; int gmtDifference = 0; bool doReversal = true; // Reverse Trades bool auth = false; datetime last_check_expiry; ENUM_TIMEFRAMES check_expiry_timeframe = PERIOD_H1; int orderTotal=0; bool fileLastEmpty=false; bool fileHandlerIssue=false; int counter = 0, testCounterVar = 0; int yAxisGlobal = 5; int dashHeight; // Height of Dashboard int dashWidth; // Width of Dashboard long accountNumber = AccountInfoInteger(ACCOUNT_LOGIN); operation_mode mode1=Master; //Working Mode order order_array[]; long lastFileSize=0; datetime lastModified=0; string symbolExclude = ""; // Symbol to Exclude string mappingSymbol = ""; // Mapping Pairs Inp,Out;Inp,Out int OnInit() { //--- trade.SetExpertMagicNumber(magic_no); trade.SetDeviationInPoints(10); trade.SetTypeFilling(ORDER_FILLING_IOC); trade.LogLevel(LOG_LEVEL_ALL); trade.SetAsyncMode(false); if(!ObjectFind(0,"mode") || ObjectGetString(0,"mode",OBJPROP_TEXT,0)!=EnumToString(mode1)+" Account") { ObjectDelete(0,"mode"); ObjectCreate(0,"mode",OBJ_LABEL,0,0,0); ObjectSetInteger(0,"mode",OBJPROP_XDISTANCE,10); ObjectSetInteger(0,"mode",OBJPROP_YDISTANCE,25); ObjectSetInteger(0,"mode",OBJPROP_CORNER,CORNER_RIGHT_UPPER); ObjectSetInteger(0,"mode",OBJPROP_ANCHOR,ANCHOR_RIGHT_UPPER); ObjectSetInteger(0,"mode",OBJPROP_COLOR,clrLightBlue); ObjectSetString(0,"mode",OBJPROP_TEXT,EnumToString(mode1)+" Account"); ObjectSetInteger(0,"mode",OBJPROP_FONTSIZE,14); } dashHeight = DashHeight; dashWidth = DashWidth; double width = double(ChartGetInteger(0,CHART_WIDTH_IN_PIXELS)); double height = double(ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS)); double minHeight = (110/height) * (height); double minWidth = (480.0/width) * (width); Print(" Minimum Required minHeight = ",minHeight," minWidth ",minWidth); if(dashWidth < minWidth) { dashWidth = (int)minWidth; Print(" Dashboard width is updated because user input is less than required width "); } if(dashHeight < minHeight) { dashHeight = (int)minHeight; Print(" Dashboard Height is updated because user input is less than required Height "); } if(!ExtDialog.Create(0,"Local Hedge Master",10,10,40,dashWidth,dashHeight)) // the panel position return(INIT_FAILED); ExtDialog.Run(); gmtDifference = (int)TimeCurrent() - (int)TimeGMT(); Print("GMT Difference(sec): ",gmtDifference); EventSetMillisecondTimer(1000); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- ExtDialog.Destroy(reason); EventKillTimer(); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTimer() { gmtDifference = (int)TimeCurrent() - (int)TimeGMT(); dashboard_data(); remove_old_tickets_from_store(); store_live_and_history_tickets(); writeData(); readDataCofClient(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnTick() { //--- } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //--- ExtDialog.ChartEvent(id,lparam,dparam,sparam); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void readDataCofClient() { int fileHandleClient = 0; fileHandleClient = FileOpen("COF_client.csv", FILE_SHARE_READ|FILE_CSV|FILE_COMMON|FILE_READ|FILE_ANSI|FILE_TXT|FILE_COMMON); if(fileHandleClient != INVALID_HANDLE) { datetime lastFileModified = (datetime)FileGetInteger(fileHandleClient, FILE_MODIFY_DATE); long fileSize = FileGetInteger(fileHandleClient, FILE_SIZE); if(lastModified == lastFileModified && fileSize == lastFileSize) { FileClose(fileHandleClient); } else { clearOrderArray(); while(!FileIsEnding(fileHandleClient)) { string OrderToRead = FileReadString(fileHandleClient); string Order_specs[]; StringSplit(OrderToRead, StringGetCharacter(",", 0), Order_specs); if(ArraySize(Order_specs) == 12 || ArraySize(Order_specs) == 13) { string symbol = getSymbol(Order_specs[1]); int orderType = StringToInteger(Order_specs[2]); ArrayResize(order_array, ArraySize(order_array) + 1); //if(StringFind(symbol, symbolExclude, 0) < 0 && // (((orderType == POSITION_TYPE_BUY || orderType == ORDER_TYPE_BUY_STOP || orderType == ORDER_TYPE_SELL_STOP) && (tradeType == 0 || tradeType == 2)) || // ((orderType == POSITION_TYPE_SELL || orderType == ORDER_TYPE_BUY_LIMIT || orderType == ORDER_TYPE_SELL_LIMIT) && (tradeType == 1 || tradeType == 2)))) { order_array[ArraySize(order_array)-1].symbol = symbol; order_array[ArraySize(order_array)-1].opentime = StringToTime(Order_specs[0]); order_array[ArraySize(order_array)-1].price = StringToDouble(Order_specs[3]); order_array[ArraySize(order_array)-1].ordertype = orderType; order_array[ArraySize(order_array)-1].lots = StringToDouble(Order_specs[4]); order_array[ArraySize(order_array)-1].stoploss = StringToDouble(Order_specs[5]); order_array[ArraySize(order_array)-1].takeprofit = StringToDouble(Order_specs[6]); order_array[ArraySize(order_array)-1].ticket = StringToInteger(Order_specs[7]); order_array[ArraySize(order_array)-1].magicNo = StringToInteger(Order_specs[8]); order_array[ArraySize(order_array)-1].accountBalance=StringToDouble(Order_specs[9]); order_array[ArraySize(order_array)-1].closedPercentageOfTrade = StringToDouble(Order_specs[10]); order_array[ArraySize(order_array)-1].contractSize=StringToInteger(Order_specs[11]); if(ArraySize(Order_specs) == 13) order_array[ArraySize(order_array)-1].comments=Order_specs[12]; else order_array[ArraySize(order_array)-1].comments=""; if(ArraySize(Order_specs) == 13) { StringReplace(Order_specs[12],"from #",""); StringReplace(Order_specs[12]," ",""); Print(" Order_specs[12] ",Order_specs[12], " order_array[ArraySize(order_array)-1].ticket ",order_array[ArraySize(order_array)-1].ticket); //for(int l = 0; l < orderCount; l++) // { // if(cod[l].magic == int(Order_specs[11])) // cod[l].magic = order_array[ArraySize(order_array)-1].ticket; // } } //for(int i = 0 ; i < ArraySize(Order_specs) ; i++) // { // Print("Order_specs[", i, "] = ", Order_specs[i]); // } Print(" Client Magic: ", order_array[ArraySize(order_array)-1].magicNo, " | Client Ticket: ", order_array[ArraySize(order_array)-1].ticket, " | Symbol: ", order_array[ArraySize(order_array)-1].symbol, " | Open Price: ", order_array[ArraySize(order_array)-1].price, " | Lot: ", order_array[ArraySize(order_array)-1].lots, " | Lot Closed %: ", order_array[ArraySize(order_array)-1].closedPercentageOfTrade, " | Open time: ", order_array[ArraySize(order_array)-1].opentime); } } } lastModified = lastFileModified; lastFileSize = fileSize; FileClose(fileHandleClient); } } // Order Operations int arraySize=ArraySize(order_array); if(ArraySize(order_array) == 0) // { //if(PositionsTotal() > 0) // { // for(int i=PositionsTotal()-1; i>=0; i--) // { // ulong ticket = PositionGetTicket(i); // if(PositionSelectByTicket(ticket)) // { // if(history_ticket_present(PositionGetInteger(POSITION_MAGIC))) // if(!trade.PositionClose(ticket)) // { // Print(" Order Close Error on No Master Trade: "+IntegerToString(GetLastError())); // } // else // Print(" ------------- Order Close by empty array ------------------ "); // } // } // } //if(OrdersTotal() > 0) // { // for(int i=OrdersTotal()-1; i>=0; i--) // { // ulong ticket = OrderGetTicket(i); // if(OrderSelect(ticket)) // { // if(history_ticket_present(OrderGetInteger(ORDER_MAGIC))) // if(!trade.OrderDelete(ticket)) // { // Print(" Error in Deleting Pending Order (Empty Array) : "+IntegerToString(GetLastError())); // } // else // Print("Order Close by empty array (Empty Array)"); // } // } // } //deleteAllArray(); } //else { for(int i=0; i 0.0) closedPercentage = NormalizeDouble((sumOfClosed / totalLot) * 100.0, 1); } // Print(" Magic: ", cod[j].magic, " Ticket: ", order_array[i].magicNo, " Array Lot: ", order_array[i].lots, " Client Lot: ", order_array[i].lots); // Print(" Magic: ", cod[j].magic, " Ticket: ", order_array[i].magicNo); if(cod[j].magic == order_array[i].magicNo) { if(closedPercentage < order_array[i].closedPercentageOfTrade) { percentageToClose = MathAbs(order_array[i].closedPercentageOfTrade - closedPercentage); //Print(" Cod Lot Size: ", cod[j].masterLot, " Order Array Lot: ", order_array[i].lots); //Print(" Client Closed % = ", closedPercentage, " Client Ticket Percentage: ", order_array[i].closedPercentageOfTrade); //Print("Order is partial close:",cod[j].ticket, " Percentage To Be Closed: ", percentageToClose); trade_taken=1; partialCloseOrderPosition=j; } } } } if(order_array[i].ticket != -1) { if(trade_taken==1) { //current order need to close partially if(partialCloseOrderPosition!=-1) { bool isOrderClose=false; int roundDigit=0; double step=SymbolInfoDouble(cod[partialCloseOrderPosition].symbol,SYMBOL_VOLUME_STEP); while(step<1) { roundDigit++; step=step*10; } // Print("Round Digits:", roundDigit); double lotClosePer = NormalizeDouble((totalLot * percentageToClose) / 100, roundDigit); if(percentageToClose > 0 && lotClosePer > SymbolInfoDouble(cod[partialCloseOrderPosition].symbol,SYMBOL_VOLUME_MIN)) { if(!trade.PositionClosePartial(cod[partialCloseOrderPosition].magic, lotClosePer)) { // ExpertRemove(); Print("Partial order did not close:",cod[partialCloseOrderPosition].magic, " Lot To Close is: ", lotClosePer); } else { isOrderClose=true; //cod[partialCloseOrderPosition].lots=cod[partialCloseOrderPosition].lots-closeLot; //PositionGetDouble(POSITION_VOLUME); //cod[partialCloseOrderPosition].masterLot = order_array[i].lots; Print("Order Partial Close. currentLot Was =", currentLot, " Percentage to close = ", percentageToClose, " Lot I am Going To close = ", lotClosePer); } } } } else if(trade_taken == 2) { // Live Orders if(PositionSelectByTicket(order_array[i].magicNo)) { int index = findEmptyIndexClientStructure(); cod[index].ticket = order_array[i].ticket; cod[index].price = order_array[i].price; cod[index].symbol = order_array[i].symbol; cod[index].ordertype = order_array[i].ordertype; cod[index].lots = order_array[i].lots; cod[index].stoploss = order_array[i].stoploss; cod[index].takeprofit = order_array[i].takeprofit; cod[index].magic = order_array[i].magicNo; cod[index].masterLot = PositionGetDouble(POSITION_VOLUME); cod[index].comments = order_array[i].comments; Print("========== CLIENT ORDER STORED =========="); int digitss = (int)getDoubleSymbolInfo(PositionGetString(POSITION_SYMBOL), "digits"); Print(" index=", index, " | master_magic=", cod[index].magic, " | client_ticket=", cod[index].ticket, " | symbol=", cod[index].symbol, " | order_type=", cod[index].ordertype, " | open_price=", DoubleToString(cod[index].price, digitss), " | lots=", DoubleToString(cod[index].lots, 2), " | master_lot=", DoubleToString(cod[index].masterLot, 2), " | sl=", DoubleToString(cod[index].stoploss, digitss), " | tp=", DoubleToString(cod[index].takeprofit, digitss), " | comment=", cod[index].comments); Print("========================================"); } // Pending Orders if(OrderSelect(order_array[i].magicNo)) { int index = findEmptyIndexClientStructure(); cod[index].ticket = order_array[i].ticket; cod[index].price = order_array[i].price; cod[index].symbol = order_array[i].symbol; cod[index].ordertype = order_array[i].ordertype; cod[index].lots = order_array[i].lots; cod[index].stoploss = order_array[i].stoploss; cod[index].takeprofit = order_array[i].takeprofit; cod[index].magic = order_array[i].magicNo; cod[index].masterLot = OrderGetDouble(ORDER_VOLUME_CURRENT); cod[index].comments = order_array[i].comments; Print("========== CLIENT PENDING ORDER STORED =========="); int digitss = (int)getDoubleSymbolInfo(cod[index].symbol, "digits"); Print(" index=", index, " | master_magic=", cod[index].magic, " | client_ticket=", cod[index].ticket, " | symbol=", cod[index].symbol, " | order_type=", cod[index].ordertype, " | open_price=", DoubleToString(cod[index].price, digitss), " | lots=", DoubleToString(cod[index].lots, 2), " | master_lot=", DoubleToString(cod[index].masterLot, 2), " | sl=", DoubleToString(cod[index].stoploss, digitss), " | tp=", DoubleToString(cod[index].takeprofit, digitss), " | comment=", cod[index].comments); Print("==============================================="); } } } } for(int i=0; i= 0 ; i--) { ulong ticket = PositionGetTicket(i); if(PositionSelectByTicket(ticket)) { if(((useMinimumLot && (PositionGetDouble(POSITION_VOLUME) > minimumLot))||!useMinimumLot) && ((useMaximumLot && (PositionGetDouble(POSITION_VOLUME) < maximumLot)) || !useMaximumLot)) { string time = TimeToString(PositionGetInteger(POSITION_TIME)-gmtDifference,TIME_DATE|TIME_SECONDS); string symbol = PositionGetString(POSITION_SYMBOL); double digits=getDoubleSymbolInfo(symbol,"digits"); int symbolContractSize=(int)getDoubleSymbolInfo(symbol,"contract"); ulong tempTicket = PositionGetInteger(POSITION_TICKET); if(suffix != "") symbol = StringSubstr(symbol, 0, StringFind(symbol, suffix, 0)); if(prefix != "") StringReplace(symbol, prefix, ""); long orderType = PositionGetInteger(POSITION_TYPE); double takeProfit = PositionGetDouble(POSITION_TP), stopLoss = PositionGetDouble(POSITION_SL); if(doReversal) { if(orderType == POSITION_TYPE_BUY) orderType = POSITION_TYPE_SELL; else if(orderType == POSITION_TYPE_SELL) orderType = POSITION_TYPE_BUY; takeProfit = PositionGetDouble(POSITION_SL); stopLoss = PositionGetDouble(POSITION_TP); } double sumOfClosed = dealOutLotsCheck(0, PositionGetInteger(POSITION_TICKET)); double currentLot = PositionGetDouble(POSITION_VOLUME); double totalLot = sumOfClosed + currentLot; double closedPercentage = 0.0; if(totalLot > 0.0) closedPercentage = (sumOfClosed / totalLot) * 100.0; Print("Closed % = ", closedPercentage); string OrderToWrite = time+","+symbol+","+IntegerToString(orderType)+","+DoubleToString(PositionGetDouble(POSITION_PRICE_OPEN), (int)digits)+","+DoubleToString(PositionGetDouble(POSITION_VOLUME),2)+","+DoubleToString(stopLoss,(int) digits)+","+DoubleToString(takeProfit, (int) digits)+","+IntegerToString(PositionGetInteger(POSITION_TICKET))+","+IntegerToString(PositionGetInteger(POSITION_MAGIC))+","+(string)AccountInfoDouble(ACCOUNT_BALANCE)+","+DoubleToString(closedPercentage, 1)+","+(string)SymbolInfoDouble(PositionGetString(POSITION_SYMBOL),SYMBOL_TRADE_CONTRACT_SIZE)+PositionGetString(POSITION_COMMENT)+"\r\n"; FileWrite(filehandle,OrderToWrite); } } } for(int i = OrdersTotal()-1 ; i >= 0 ; i--) { ulong ticket = OrderGetTicket(i); if(OrderSelect(ticket)) { if(((useMinimumLot && (OrderGetDouble(ORDER_VOLUME_CURRENT) > minimumLot))||!useMinimumLot) && ((useMaximumLot && (OrderGetDouble(ORDER_VOLUME_CURRENT) < maximumLot))||!useMaximumLot)) { string time = TimeToString(OrderGetInteger(ORDER_TIME_SETUP)-gmtDifference,TIME_DATE|TIME_SECONDS); string symbol = OrderGetString(ORDER_SYMBOL); double digits=getDoubleSymbolInfo(symbol,"digits"); int symbolContractSize=(int)getDoubleSymbolInfo(symbol,"contract"); ulong tempTicket = OrderGetInteger(ORDER_TICKET); if(suffix != "") symbol = StringSubstr(symbol, 0, StringFind(symbol, suffix, 0)); if(prefix != "") StringReplace(symbol, prefix, ""); long orderType = OrderGetInteger(ORDER_TYPE); double takeProfit = OrderGetDouble(ORDER_TP), stopLoss = OrderGetDouble(ORDER_SL); if(doReversal) { if(orderType == ORDER_TYPE_BUY_STOP) orderType = ORDER_TYPE_SELL_LIMIT; else if(orderType == ORDER_TYPE_SELL_STOP) orderType = ORDER_TYPE_BUY_LIMIT; else if(orderType == ORDER_TYPE_BUY_LIMIT) orderType = ORDER_TYPE_SELL_STOP; else if(orderType == ORDER_TYPE_SELL_LIMIT) orderType = ORDER_TYPE_BUY_STOP; takeProfit = OrderGetDouble(ORDER_SL); stopLoss = OrderGetDouble(ORDER_TP); } double closedPercentage = 0; string OrderToWrite = time+","+symbol+","+IntegerToString(orderType)+","+DoubleToString(OrderGetDouble(ORDER_PRICE_OPEN), (int)digits)+","+DoubleToString(OrderGetDouble(ORDER_VOLUME_CURRENT),2)+","+DoubleToString(stopLoss,(int) digits)+","+DoubleToString(takeProfit, (int) digits)+","+IntegerToString(OrderGetInteger(ORDER_TICKET))+","+IntegerToString(OrderGetInteger(ORDER_MAGIC))+","+(string)AccountInfoDouble(ACCOUNT_BALANCE)+","+DoubleToString(closedPercentage)+","+(string)SymbolInfoDouble(OrderGetString(ORDER_SYMBOL),SYMBOL_TRADE_CONTRACT_SIZE)+OrderGetString(ORDER_COMMENT)+"\r\n"; Print("Writing Pending Order Block."); FileWrite(filehandle,OrderToWrite); } } } FileClose(filehandle); fileLastEmpty=false; Print("File Updated:",TimeCurrent()); } else { Print("File Handle Issue: ", GetLastError()); } } else { if(counter>=count1 && TerminalInfoInteger(TERMINAL_CONNECTED)) { if(testCounterVar>=testCounter) { testCounterVar=0; } adminHeartBeat(); counter=0; } counter++; testCounterVar++; } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void adminHeartBeat() { string headers = "apikey:"+localApiKey+"\r\naccept: */* \r\nContent-Type: application/json\r\nUser-Agent: MetaTraderApi"; string url =localHB_req_link;// Request_link+(string)accountNumber; bool isPost; int timeout = 100000; string lastConnected=TimeToString(TimeCurrent()); StringReplace(lastConnected,".","-"); StringReplace(lastConnected," ","T"); string gmtTime=TimeToString(TimeGMT()); string jsonData="{\"mLogin\":\""+(string)accountNumber+"\",\"mServer\":\""+masterServer+"\",\"mVersion\":\"5\" ,\"sLogin\":\""+slaveId+"\",\"sServer\":\""+slaveServer+"\",\"sVersion\":\""+slaveVersion+"\" ,\"mLastConnected\":\""+gmtTime+"\"}";//\",\"url\":"+"\""+url+"\""+headers+"}"; uchar data[]; StringToCharArray(jsonData, data, 0, StringLen(jsonData)); // Print("Making the heart beat request to the local host"); POST_function(url,headers,timeout,data,isPost); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool POST_function(string url, string headers, int timeout, uchar &data[], bool &IsPost) { ResetLastError(); // clear previous error static int lastErrorPrinted = 0; uchar result[]; // use uchar for WebRequest result string resultHeaders; int res = WebRequest("POST", url, headers, timeout, data, result, resultHeaders); if(res == 200 || res == 201) { Print("***Request success. HTTP response code POST: ", res); string result_string = CharArrayToString(result); Print("content POST: ", result_string); lastErrorPrinted = 0; // reset remembered error on success IsPost = true; return true; } else { int err = GetLastError(); // read the error once // only print when there's a real error and it's different from last time if(err != 0 && err != lastErrorPrinted) { Print("Get last error: ", err); Print("***Request failed. HTTP response code: ", res); string result_string = CharArrayToString(result); Print("content: ", result_string); lastErrorPrinted = err; // remember this error so we don't spam it } IsPost = false; return false; } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void removeDeleteOrderMaster() { for(int i=0; i=0; j--) { ulong ticket = PositionGetTicket(j); if(PositionSelectByTicket(ticket)) { if(ticket==mod1[i].ticket) { isPresent=true; } } } if(!isPresent) { Print("The order ticket:",mod1[i].ticket," found no more"); //delete from list mod1[i].ticket=-1; } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void clearOrderArray() { //Resize to one ArrayFree(order_array); ArrayResize(order_array,0); //Clear all data //order_array[0].symbol = ""; //order_array[0].opentime = 0; //order_array[0].price = 0; //order_array[0].ordertype = 0; //order_array[0].lots = 0; //order_array[0].stoploss = 0; //order_array[0].takeprofit = 0; //order_array[0].ticket = -1; //order_array[0].magicNo = 0; //order_array[0].accountBalance=0; //order_array[0].contractSize=0; //order_array[0].comments=""; //order_array[0].closedPercentageOfTrade = 0; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void deleteAllArray() { for(int i=0; i points) { return true; } } else { if(openPrice - SymbolInfoDouble(symbol,SYMBOL_BID) > points) { return true; } } return false; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool isOrderThere(ulong ticket,int &index) { for(int i=0; i= 0 ; i--) { ulong ticket = PositionGetTicket(i); if(PositionSelectByTicket(ticket)) { int orderIndex=-1; bool alreadyAdded=isOrderThere(ticket, orderIndex); if(!alreadyAdded) { currCheck=false; currCheck=addOrderMaster(ticket, "Market"); if(!updationRequired) updationRequired=currCheck; } else { if(orderIndex!=-1) { currCheck=false; currCheck=IsOrderChanged(PositionGetInteger(POSITION_TICKET),orderIndex, "Market"); if(!updationRequired) { updationRequired=currCheck; } } } } } for(int i = OrdersTotal()-1 ; i >= 0 ; i--) { ulong ticket = OrderGetTicket(i); if(OrderSelect(ticket)) { if(OrderGetInteger(ORDER_TYPE) != ORDER_TYPE_BUY && OrderGetInteger(ORDER_TYPE) != ORDER_TYPE_SELL && OrderGetInteger(ORDER_TYPE) != ORDER_TYPE_CLOSE_BY) { int orderIndex=-1; bool alreadyAdded=isOrderThere(ticket, orderIndex); if(!alreadyAdded) { Print("Inside pending Adding to master order: ",ticket," type: ",OrderGetInteger(ORDER_TYPE)," ",OrdersTotal()," ",ORDER_TYPE_CLOSE_BY); currCheck=false; currCheck=addOrderMaster(ticket, "Pending"); if(!updationRequired) updationRequired=currCheck; } else { if(orderIndex!=-1) { currCheck=false; currCheck=IsOrderChanged(OrderGetInteger(ORDER_TICKET), orderIndex, "Pending"); if(!updationRequired) { updationRequired=currCheck; } } } } } } for(int i=0; i=0; j--) { ulong ticket = PositionGetTicket(j); if(PositionSelectByTicket(ticket)) { if(ticket==mod1[i].ticket) { isPresent=true; break; } } } // Pending Order for(int j = OrdersTotal()-1; j>=0; j--) { ulong ticket = OrderGetTicket(j); if(OrderSelect(ticket)) { if(ticket==mod1[i].ticket) { isPresent=true; break; } } } if(!isPresent) { Print("Ticket is closed so removed from struct: ",mod1[i].ticket); mod1[i].ticket=-1; mod1[i].price=-1; mod1[i].symbol=""; mod1[i].ordertype=-1; mod1[i].lots=0; mod1[i].stoploss=0; mod1[i].takeprofit=0; currCheck=true; //currCheck=clearStructIndex(mod1[i].ticket); if(!updationRequired) updationRequired=currCheck; } } } return updationRequired; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool clearStructIndex(ulong ticket) { for(int index=0; index SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX)) { lotSize=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX); } else if(lotSize= 0; --j) { ulong deal_ticket = HistoryDealGetTicket(j); if(deal_ticket == 0) continue; // deal execution time long dealTime = (long)HistoryDealGetInteger(deal_ticket, DEAL_TIME); if((datetime)dealTime < cutoff) continue; // older than cutoff, skip // position id related to this deal (the stored "ticket" you track) long position_id = (long)HistoryDealGetInteger(deal_ticket, DEAL_POSITION_ID); if(position_id <= 0) continue; // no position id to store if(HistoryDealGetInteger(deal_ticket, DEAL_ENTRY) != DEAL_ENTRY_IN) continue; ulong ticket = position_id; ulong magic = HistoryDealGetInteger(deal_ticket, DEAL_MAGIC); double dealInLot = HistoryDealGetDouble(deal_ticket, DEAL_VOLUME); double dealOutLot = dealOutLotsCheck(cutoff, position_id); if(dealInLot == dealOutLot) if(!history_ticket_present(ticket)) { Print(" Position Id: ", position_id," Deal In Lot: ", dealInLot, " Deal Out Lot: ", dealOutLot); add_history_ticket(ticket, magic); } } } else { // optional: failed to select history — you may handle/log if needed // Print("HistorySelect failed. LastError=", GetLastError()); } int ordersTotal=HistoryOrdersTotal(); ulong orderTicket=0; for(int j=0; j= cutoff) { ulong magic = HistoryOrderGetInteger(orderTicket, ORDER_MAGIC); if(!history_ticket_present(orderTicket)) { add_history_ticket(orderTicket, magic); } } } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double dealOutLotsCheck(datetime cutOffTimeIs, ulong positionId) { double sumOfLots = 0.0; if(HistorySelect(cutOffTimeIs, LONG_MAX)) { int totalDeals = HistoryDealsTotal(); for(int i = 0; i < totalDeals; i++) { ulong dealTicket = HistoryDealGetTicket(i); ulong dealPositionID = (ulong)HistoryDealGetInteger(dealTicket, DEAL_POSITION_ID); if(HistoryDealGetInteger(dealTicket, DEAL_ENTRY) == DEAL_ENTRY_OUT && dealPositionID == positionId) { sumOfLots += HistoryDealGetDouble(dealTicket, DEAL_VOLUME); } } } return sumOfLots; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool history_ticket_present(ulong ticket) { for(int i = 0 ; i < MaxOrders ; i++) { if(historyTradeStore[i].ticket == ticket) return true; } return false; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void add_history_ticket(ulong ticket, ulong magicIs) { for(int i = 0; i < MaxOrders; i++) { if(historyTradeStore[i].ticket == -1) { historyTradeStore[i].ticket = ticket; historyTradeStore[i].magic = magicIs; Print("Ticket Added to History Structure. Ticket: ", ticket, " Magic: ", magicIs); save_history_store("add_history_ticket()"); return; } } Print("historyTradeStore full, cannot add ticket: ", ticket); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void clear_history_store() { for(int i = 0; i < MaxOrders; i++) { historyTradeStore[i].ticket = -1; historyTradeStore[i].magic = 0; } Print("History store cleaned"); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void save_history_store(string calledBy) { string file_nameIs = "history_trades.csv"; int fileHandle = FileOpen(file_nameIs, FILE_WRITE | FILE_CSV | FILE_COMMON); if(fileHandle != INVALID_HANDLE) { for(int i = 0; i < MaxOrders; i++) { if(historyTradeStore[i].ticket != -1) { string data_to_store = IntegerToString(historyTradeStore[i].ticket) + "," + IntegerToString(historyTradeStore[i].magic) + "\r\n"; FileWriteString(fileHandle, data_to_store); } } //Print("save_history_store() called by: ", calledBy, " Time: ", TimeToString(TimeCurrent(), TIME_DATE | TIME_SECONDS)); FileClose(fileHandle); } else { Print("Error opening file save_history_store(): ", GetLastError()); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void remove_old_tickets_from_store() { datetime cutoff = TimeCurrent() - (datetime)daysOfTradesToAdd * 86400; // Print("remove_old_tickets_from_store: cutoff = ", TimeToString(cutoff, TIME_DATE|TIME_SECONDS)); // Prepare history selection ranges once (for deals we limit by cutoff; for orders we select full history) for(int i = 0; i < MaxOrders; i++) { ulong tk = historyTradeStore[i].ticket; if(tk == -1) // empty slot continue; bool found = false; ulong pos_ticket = (ulong)tk; if(HistorySelect(cutoff, TimeCurrent())) { int deals_count = (int)HistoryDealsTotal(); for(int j = deals_count - 1; j >= 0; --j) { ulong deal_ticket = HistoryDealGetTicket(j); if(deal_ticket == 0) continue; // deal execution time long dealTime = (long)HistoryDealGetInteger(deal_ticket, DEAL_TIME); if((datetime)dealTime < cutoff) continue; // older than cutoff, skip if(HistoryDealGetInteger(deal_ticket, DEAL_ENTRY) != DEAL_ENTRY_IN) continue; // position id related to this deal (the stored "ticket" you track) long position_id = (long)HistoryDealGetInteger(deal_ticket, DEAL_POSITION_ID); if(position_id <= 0) continue; // no position id to store double dealInLot = HistoryDealGetDouble(deal_ticket, DEAL_VOLUME); double dealOutLot = dealOutLotsCheck(cutoff, position_id); if(dealInLot == dealOutLot) if(position_id == pos_ticket) { found = true; break; } } } else { // optional: failed to select history — you may handle/log if needed // Print("HistorySelect failed. LastError=", GetLastError()); } if(!found) { int ordersTotal = HistoryOrdersTotal(); for(int j = 0; j < ordersTotal; j++) { ulong orderTicket = HistoryOrderGetTicket(j); if(orderTicket == 0) continue; long type = HistoryOrderGetInteger(orderTicket, ORDER_TYPE); if(type != ORDER_TYPE_BUY_LIMIT && type != ORDER_TYPE_SELL_LIMIT && type != ORDER_TYPE_BUY_STOP && type != ORDER_TYPE_SELL_STOP) continue; datetime openTime = (datetime)HistoryOrderGetInteger(orderTicket, ORDER_TIME_SETUP); long state=HistoryOrderGetInteger(orderTicket,ORDER_STATE); if(state==ORDER_STATE_CANCELED || state==ORDER_STATE_REJECTED || state==ORDER_STATE_EXPIRED || state==ORDER_STATE_REQUEST_CANCEL) { if(orderTicket == pos_ticket) { if(openTime > cutoff) { found = true; break; } } } } } // 3) Final action: remove if not found if(!found) { Print("Ticket not found, removing from store: ", tk, " index=", i); historyTradeStore[i].ticket = -1; historyTradeStore[i].magic = 0; // (optionally clear other fields if your struct has them) } } // for i } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ //================================================ Dashboard ==================================== //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CControlsDialog : public CAppDialog { public: CLabel m_label0; CButton m_button; CButton m_button1; CControlsDialog(void); ~CControlsDialog(void); //--- create virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2); virtual bool OnEvent(const int id, const long &lparam,const double &dparam, const string &sparam); bool CreateLabel0(void); bool CreateButton(void); bool CreateButton1(void); void OnClickButton(void); void OnClickButton1(void); bool CreatePanel(void); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ EVENT_MAP_BEGIN(CControlsDialog) ON_EVENT(ON_CLICK,m_button,OnClickButton) ON_EVENT(ON_CLICK,m_button1,OnClickButton1) EVENT_MAP_END(CAppDialog) //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CControlsDialog::CControlsDialog(void) { } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CControlsDialog::~CControlsDialog(void) { } //+------------------------------------------------------------------+ //| Create | //+------------------------------------------------------------------+ bool CControlsDialog::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2) { if(!CAppDialog::Create(chart,name,subwin,20,20,dashWidth,dashHeight)) return(false); //--- create dependent controls if(!CreatePanel()) return(false); if(!CreateLabel0()) return(false); if(!CreateButton()) return(false); if(!CreateButton1()) return(false); //--- succeed return(true); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CControlsDialog::CreateLabel0(void) //Trend Info { //--- coordinates int x1 = (dashWidth/2) - 235; int y1 = yAxisGlobal + 15; int x2 = 0; int y2 = 0; //--- create if(!m_label0.Create(m_chart_id,m_name+"Label0",m_subwin,x1,y1,x2,y2)) return(false); if(!m_label0.Text(" Master Trades Lots Calc: 0.00")) return(false); if(!m_label0.Color(clrBlack)) return(false); if(!m_label0.Font("Calibri")) return(false); if(!m_label0.FontSize(FontSize)) return(false); if(!Add(m_label0)) return(false); //--- succeed return(true); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CControlsDialog::CreateButton(void) { //--- coordinates // Buy int x1 = (dashWidth/2) + 14; int y1 = yAxisGlobal + 10; int x2 = x1 + 70; int y2 = y1 + 30; //--- create if(!m_button.Create(m_chart_id,"button",m_subwin,x1,y1,x2,y2)) return(false); if(!m_button.ColorBackground(clrSlateGray)) return(false); if(!m_button.Text("Sell")) return(false); if(!m_button.FontSize(FontSize)) return(false); if(!m_button.ColorBackground(clrRed)) return(false); if(!m_button.Font("Calibri Bold")) return(false); if(!m_button.Color(clrWhiteSmoke)) return(false); if(!m_button.ColorBorder(clrRed)) return(false); if(!Add(m_button)) return(false); m_button.Locking(true); m_button.BringToTop(); //--- succeed return(true); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CControlsDialog::CreateButton1(void) { //--- coordinates // Sell int x1 = (dashWidth/2) + 100; int y1 = yAxisGlobal + 10; int x2 = x1 + 70; int y2 = y1 + 30; //--- create if(!m_button1.Create(m_chart_id,"button1",m_subwin,x1,y1,x2,y2)) return(false); if(!m_button1.ColorBackground(clrBlue)) return(false); if(!m_button1.Text("Buy")) return(false); if(!m_button1.FontSize(FontSize)) return(false); if(!m_button1.Font("Calibri Bold")) return(false); if(!m_button1.Color(clrWhiteSmoke)) return(false); if(!m_button1.ColorBorder(clrBlack)) return(false); if(!Add(m_button1)) return(false); m_button1.Locking(true); m_button1.BringToTop(); //--- succeed return(true); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CControlsDialog::OnClickButton(void) { if(m_button.Pressed()) { Print(" Clicked on Button"); m_button.Pressed(false); placeSellTrade(); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CControlsDialog::OnClickButton1(void) { if(m_button1.Pressed()) { Print(" Clicked on Button 1"); m_button1.Pressed(false); placeBuyTrade(); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CControlsDialog::CreatePanel(void) { //--- coordinates int x1=0; int y1=0; int x2=dashWidth; int y2=dashHeight; //--- create if(!backgroundPanel.Create(0,ExtDialog.Name()+"backPanel",m_subwin,x1,y1,x2,y2)) return(false); if(!backgroundPanel.ColorBackground(clrWhiteSmoke)) return(false); if(!backgroundPanel.ColorBorder(00128)) return(false); if(!ExtDialog.Add(backgroundPanel)) return(false); ExtDialog.Minimized(false); backgroundPanel.Alignment(WND_ALIGN_CLIENT,0,0,0,0); //--- succeed return(true); } CControlsDialog ExtDialog; CPanel backgroundPanel; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+