//+------------------------------------------------------------------+ //| Pulse_EA_project_MT5.mq5 | //| Copyright 2024, MQL Development | //| https://www.mqldevelopment.com/ | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, MQL Development" #property link "https://www.mqldevelopment.com/" #property version "1.00" #include CTrade trade; #define global "var" #define MaxOrders 10000 struct new_trade_store { int trade_ticket; int trade_type; int trade_magic_no; double trade_open_price; double trade_close_price; datetime trade_open_time; datetime trade_close_time; double trade_sl; double trade_tp; double trade_lot; double trade_profit; new_trade_store() { trade_ticket = -1; trade_type = -1; trade_magic_no = -1; trade_open_price = -1; trade_close_price = -1; trade_open_time = -1; trade_close_time = -1; trade_sl = -1; trade_tp = -1; trade_lot = -1; trade_profit = -1; } }; new_trade_store od[MaxOrders]; struct trade_sync { ulong sim_trade_ticket; ulong live_trade_ticket; trade_sync() { sim_trade_ticket = -1; live_trade_ticket = -1; } }; trade_sync od_sync[MaxOrders]; enum trade_typ { buy, // Buy reverse, // Reverse }; enum EA_TYPE { Tally_Sim, // Tally Sim Tally_Trade, // Tally Trade }; input string gnrlsettings = " ================ General Settings =================== ";//_ input EA_TYPE eaType = Tally_Sim; // EA Option input double tpPips = 20; // Tp Pips input double slPips = 20; // SL Pips input double lot = 0.1; // Lot Size input string gnrlesettings = " ================ Tally Sim Settings =================== ";//_ trade_typ ordTyp = buy; // Order Type (Tally Sim) input int magicNo = 123; // Magic # input string fileName = "TradeDataFile"; // File Name (Tally Sim) input string grlesettings = " ================ Tally Trade Settings =================== ";//_ input trade_typ tradesDirection = buy; // Order Type (Tally Trade) input int magicNo1 = 1; // Copy Trade Magic # input bool CopyTallyTrade = true; // Enable Copy Trade input double glTp = 20; // Copy Take Profit input double glSl = 10; // Copy Stop Loss input bool useMovingAVG = true; // Use moving average filter input string Settings6 = "------------- Display Settings -------------"; //_ input int tradeLineThickness = 2; // Trade Line Thickness input int dollarFontSize = 10; // Dollar Text Font Size input color dollarFontColor = clrAqua; // Dollar Text Font Colour input string horizontalLineName = "close"; // Horizontal Line Name input string Settings5 = "------------- Time Filter Settings -------------"; //_ input bool enableTimeFilter = false; // Enable Time Filter input string startTime = "22:00"; // Start Time input string endTime = "01:00"; // End Time input bool useFridayClose = false; // Use Friday Close input string closeFriday = "23:00"; // Friday Close Time input bool useMondayOpen = false; // Use Monday Open input string mondayOpen = "01:00"; // Monday Open Time input string Settings25 = "------------- Daily Draw Limit Settings -------------"; //_ input bool UseDailyDrawdownLimit = true; // Enable Daily Draw Down input double DailyDrawdownAmount = 2000; // $2000 limit input string DrawdownResetTime = "05:00"; // Enable Trading At input string indSettings = " ================ Indicator Settings =================== ";//_ input color Dot_Color = clrOrangeRed; input double StartingBalance = 10000; input string MagicNumbers = "123"; input int MA_Period = 5; input ENUM_MA_METHOD MA_Method = MODE_SMA; input string fileName1 = "TradeDataFile"; // File Name input int historyTrades = 50; bool tpSlHit = false; static int ticketAssigner = 1; int handler; double bufferData[]; ushort u_sep; // The code of the separator character string sep = ":"; // A separator as a character string result1[]; datetime startTradingTime = 0, endTradingTime = 0, dailyDrawDownTime = 0; datetime mondayTradingStart = 0, fridayTradingClose = 0; datetime eaStartTime; // Store EA start time double g_dailyStartBalance; bool enableTradingDaily = true; int prevOrderCount = 0; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ string filename = fileName + Symbol() + ".csv"; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- if(!GlobalVariableCheck(global)) //for creating { GlobalVariableSet(global,0); // 0 means Free // 1 means busy } if(eaType == Tally_Sim) { FileDelete(filename,FILE_WRITE|FILE_CSV|FILE_COMMON|FILE_END); int filehandle = FileOpen(filename,FILE_WRITE|FILE_CSV|FILE_COMMON|FILE_END,","); if(filehandle != INVALID_HANDLE) { FileClose(filehandle); } } else { // prevOrderCount = orderCount(); } string typ = eaType == 0 ? "Tally Sim" :"Tally Trade"; Comment(" Current Mode: ",typ); tpSlHit = false; ticketAssigner = 1; if(eaType == Tally_Trade) { ArrayInitialize(bufferData,0.0); handler = iCustom(Symbol(),PERIOD_CURRENT,"Pulse Balance Indicator Sim",Dot_Color,StartingBalance,MagicNumbers,MA_Period,MA_Method,fileName1,historyTrades); ArraySetAsSeries(bufferData,true); } trade.SetExpertMagicNumber(magicNo1); trade.SetDeviationInPoints(10); trade.SetTypeFilling(ORDER_FILLING_IOC); trade.LogLevel(LOG_LEVEL_ALL); trade.SetAsyncMode(false); setStart_EndTime_modify(true,startTime,endTime,startTradingTime,endTradingTime); setStart_EndTime(true,startTime,endTime,startTradingTime,endTradingTime); g_dailyStartBalance = AccountInfoDouble(ACCOUNT_BALANCE); enableTradingDaily = true; eaStartTime = TimeCurrent(); // Track EA start time double balance = AccountInfoDouble(ACCOUNT_BALANCE); int magic = 123456; int maPeriod = 50; bool useMA = true; bool ddReached = false; CreateInfoLabels(balance, magic, maPeriod, useMA, ddReached); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- GlobalVariableSet(global,0); if(eaType == Tally_Sim) { deleteObjects(); } ObjectDelete(0,"lbl_drawdown"); ObjectDelete(0,"lbl_use_ma"); ObjectDelete(0,"lbl_ma"); ObjectDelete(0,"lbl_magic"); ObjectDelete(0,"lbl_balance"); Comment(""); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- if(CopyBuffer(handler, 0, 0, 1, bufferData) < 0) { // Print("Error in copying Buffer data ", GetLastError()); } double balance = bufferData[0]; if(CopyBuffer(handler, 1, 0, 1, bufferData) < 0) { // Print("Error in copying Buffer data ", GetLastError()); } double MA = bufferData[0]; if(balance != EMPTY_VALUE) { ObjectSetString(0, "lbl_balance", OBJPROP_TEXT, "Balance = " + DoubleToString(balance, 2)); } else { ObjectSetString(0, "lbl_balance", OBJPROP_TEXT, "Balance = " + DoubleToString(0, 2)); } if(MA != EMPTY_VALUE) { ObjectSetString(0, "lbl_ma", OBJPROP_TEXT, "Moving Average = " + DoubleToString(MA, _Digits)); } else { ObjectSetString(0, "lbl_ma", OBJPROP_TEXT, "Moving Average = " + DoubleToString(0, _Digits)); } timeConversion(); CheckDailyDrawdown(); if(TimeCurrent() >= dailyDrawDownTime && enableTradingDaily == false) { enableTradingDaily = true; g_dailyStartBalance = AccountInfoDouble(ACCOUNT_BALANCE); } if(eaType == Tally_Trade) { markClosedOrder(eaStartTime); checkVirtualTicketClosed(); // check if virtual trade closed so close Active Trade as well } if(eaType == Tally_Sim) { checkTPSLHit(); } newBar(); MqlDateTime dt; TimeToStruct(TimeCurrent(), dt); if(useMondayOpen) { // Print(" Week == ",dt.day_of_week," Start Time = ",mondayTradingStart); if(dt.day_of_week == 1 && TimeCurrent() < mondayTradingStart) // it's Monday { return; } } if(useFridayClose) { // Print(" Week == ",dt.day_of_week," End Time = ",fridayTradingClose); if(dt.day_of_week == 5 && TimeCurrent() >= fridayTradingClose) // it's Friday { closeAllActiveOrders(); closeAllVirtualTrades(); return; } } setStart_EndTime_modify(false,startTime,endTime,startTradingTime,endTradingTime); setStart_EndTime(false,startTime,endTime,startTradingTime,endTradingTime); if(enableTimeFilter && TimeCurrent() >= startTradingTime && TimeCurrent() < endTradingTime) { return; } placeTrade(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool newBar() { static datetime lastbar; datetime curbar = iTime(Symbol(), PERIOD_CURRENT, 0); if(lastbar != curbar) { lastbar = curbar; Print(" ---------------------- New Bar :: ---------------------- ",lastbar); return (true); } else { return (false); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool newDayBar() { static datetime lastbar1; datetime curbar1 = iTime(Symbol(), PERIOD_D1, 0); if(lastbar1 != curbar1) { lastbar1 = curbar1; Print(" ---------------------- New Day Bar :: ---------------------- ",lastbar1); return (true); } else { return (false); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void closeAllActiveOrders() { for(int i=PositionsTotal()-1; i >=0 ; i--) { ulong ticket = PositionGetTicket(i); if(PositionSelectByTicket(ticket)) { if(PositionGetInteger(POSITION_MAGIC) == magicNo && PositionGetString(POSITION_SYMBOL) == Symbol()) { if(trade.PositionClose(ticket)) { Print("Closing All Active Orders"); Print("Position closed ", ticket); } else { Print("Cannot close order: ",GetLastError()); } } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void timeConversion() { MqlDateTime date1, date_1,date_2; TimeToStruct(iTime(Symbol(),PERIOD_CURRENT,0),date1); u_sep=StringGetCharacter(sep,0); StringSplit(mondayOpen,u_sep,result1); date1.hour = (int)StringToInteger(result1[0]); date1.min = (int)StringToInteger(result1[1]); mondayTradingStart = StructToTime(date1); TimeToStruct(iTime(Symbol(),PERIOD_CURRENT,0),date_1); StringSplit(closeFriday,u_sep,result1); date_1.hour = (int)StringToInteger(result1[0]); date_1.min = (int)StringToInteger(result1[1]); fridayTradingClose = StructToTime(date_1); TimeToStruct(iTime(Symbol(),PERIOD_CURRENT,0),date_2); StringSplit(DrawdownResetTime,u_sep,result1); date_2.hour = (int)StringToInteger(result1[0]); date_2.min = (int)StringToInteger(result1[1]); dailyDrawDownTime = StructToTime(date_2); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void placeTrade() { if(tpSlHit == false || eaType == Tally_Trade) { if(ordTyp == buy) { placeBuyTrade(); } if(ordTyp == reverse) { placeSellTrade(); } tpSlHit = true; } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void placeBuyTrade() { double buySl = 0,buyTp=0; double Ask = SymbolInfoDouble(Symbol(),SYMBOL_ASK); if(slPips != 0) { buySl = Ask - (slPips * Point() * 10); } if(tpPips != 0) { buyTp = Ask + (tpPips * Point() * 10); } if(eaType == Tally_Sim) { AddToStructure(ticketAssigner,0,magicNo,Ask,0,TimeCurrent(),0,buySl,buyTp,lot,0); ticketAssigner++; DrawVirtualBuyOpen(Ask); } else { if(GlobalVariableGet(global) == 0) { int count = orderCount(); if(prevOrderCount != count && count != -1) { for(int k = prevOrderCount + 1;k <= count;k++) { if(getTicketByNumber(k,buySl,buyTp) != -1) { if(enableTradingDaily == true) { if(eaType == Tally_Trade && CopyTallyTrade) { if(CopyBuffer(handler, 0, 0, 4, bufferData) < 0) { Print("Error in copying Buffer data ", GetLastError()); } double balance = bufferData[1]; if(CopyBuffer(handler, 1, 0, 4, bufferData) < 0) { Print("Error in copying Buffer data ", GetLastError()); } double MA = bufferData[1]; Print(" Balance = ",balance," MA = ",MA); if(balance != EMPTY_VALUE) { ObjectSetString(0, "lbl_balance", OBJPROP_TEXT, "Balance = " + DoubleToString(balance, 2)); } else { ObjectSetString(0, "lbl_balance", OBJPROP_TEXT, "Balance = " + DoubleToString(0, 2)); } if(MA != EMPTY_VALUE) { ObjectSetString(0, "lbl_ma", OBJPROP_TEXT, "Moving Average = " + DoubleToString(MA, _Digits)); } else { ObjectSetString(0, "lbl_ma", OBJPROP_TEXT, "Moving Average = " + DoubleToString(0, _Digits)); } if(tradesDirection == buy) { if((balance > MA && useMovingAVG) || !(useMovingAVG)) { double buy_Tp = SymbolInfoDouble(Symbol(),SYMBOL_ASK) + glTp * 10 * SymbolInfoDouble(_Symbol, SYMBOL_POINT); double buy_Sl = SymbolInfoDouble(Symbol(),SYMBOL_ASK) - glSl * 10 * SymbolInfoDouble(_Symbol, SYMBOL_POINT); if(!trade.Buy(lot, Symbol(),SymbolInfoDouble(Symbol(),SYMBOL_ASK),buy_Sl,buy_Tp,"Buy Trade")) { Print(" Error in Placing Buy Trade : ",GetLastError()); } else { tradeSyncAddToStruct(k,trade.ResultOrder()); } } else { Print(" Trade is not Placed because Balance is less than MA Value "); } } else { if((balance < MA && useMovingAVG) || !(useMovingAVG)) { double sell_SL = SymbolInfoDouble(Symbol(),SYMBOL_BID) + glSl * 10 * SymbolInfoDouble(_Symbol, SYMBOL_POINT); double Sell_TP = SymbolInfoDouble(Symbol(),SYMBOL_BID) - glTp * 10 * SymbolInfoDouble(_Symbol, SYMBOL_POINT); if(!trade.Sell(lot,Symbol(),SymbolInfoDouble(Symbol(),SYMBOL_BID),sell_SL,Sell_TP,"Sell Trade")) { Print(" Error in Placing Sell Trade : ",GetLastError()); } else { tradeSyncAddToStruct(k,trade.ResultOrder()); } } else { Print(" Trade is not Placed because Balance is less than MA Value "); } } } } prevOrderCount = count; } } } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void placeSellTrade() { double sellSl = 0, sellTp = 0; double Bid = SymbolInfoDouble(Symbol(),SYMBOL_BID); if(slPips != 0) { sellSl = Bid + (slPips * 10 * Point()); } if(tpPips != 0) { sellTp = Bid - (tpPips * 10 * Point()); } if(eaType == Tally_Sim) { AddToStructure(ticketAssigner,1,magicNo,Bid,0,TimeCurrent(),0,sellSl,sellTp,lot,0); ticketAssigner++; } else { int count = orderCount(); if(prevOrderCount != count && count != -1) { for(int k = prevOrderCount + 1;k <= count;k++) { getTicketByNumber(k,sellSl,sellTp); if(getTicketByNumber(k,sellSl,sellTp) != -1) { if(enableTradingDaily == true) { if(eaType == Tally_Trade && CopyTallyTrade) { if(CopyBuffer(handler, 0, 0, 4, bufferData) < 0) { Print("Error in copying Buffer data ", GetLastError()); } double balance = bufferData[1]; if(CopyBuffer(handler, 1, 0, 4, bufferData) < 0) { Print("Error in copying Buffer data ", GetLastError()); } double MA = bufferData[1]; if(balance != EMPTY_VALUE) { ObjectSetString(0, "lbl_balance", OBJPROP_TEXT, "Balance = " + DoubleToString(balance, 2)); } else { ObjectSetString(0, "lbl_balance", OBJPROP_TEXT, "Balance = " + DoubleToString(0, 2)); } if(MA != EMPTY_VALUE) { ObjectSetString(0, "lbl_ma", OBJPROP_TEXT, "Moving Average = " + DoubleToString(MA, _Digits)); } else { ObjectSetString(0, "lbl_ma", OBJPROP_TEXT, "Moving Average = " + DoubleToString(0, _Digits)); } Print(" Balance = ",balance," MA = ",MA); if(tradesDirection == reverse) { if(balance < MA) { if(!trade.Sell(lot,Symbol(),Bid,sellSl,sellTp,"Sell Trade")) { Print(" Error in Placing Sell Trade : ",GetLastError()); } } else { Print(" Trade is not Placed because Balance is less than MA Value "); } } else { if(balance > MA) { if(!trade.Buy(lot,Symbol(),SymbolInfoDouble(Symbol(),SYMBOL_ASK),sellTp,sellSl,"Buy Trade")) { Print(" Error in Placing Buy Trade : ",GetLastError()); } } else { Print(" Trade is not Placed because Balance is less than MA Value "); } } } } prevOrderCount = count; } } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void AddToStructure(int ticket, int type, int magic, double open_price, double close_price, datetime open_time, datetime close_time, double sl, double tp, double lotSize, double profit) { if(GlobalVariableGet(global) == 0) { for(int i = 0; i < MaxOrders; i++) { if(od[i].trade_ticket == -1) { od[i].trade_ticket = ticket; od[i].trade_type = type; od[i].trade_magic_no = magic; od[i].trade_open_price = open_price; od[i].trade_close_price = close_price; od[i].trade_open_time = open_time; od[i].trade_close_time = close_time; od[i].trade_sl = sl; od[i].trade_tp = tp; od[i].trade_lot = lotSize; od[i].trade_profit = profit; Print(" ========== Trade Placed of Ticket ========== ",ticket); Print("[AddToStructure] Added at index: ", i, " | Ticket = ", ticket, " | Type = ", type, " | Magic = ", magic, " | OpenPrice = ", open_price, " | ClosePrice = ", close_price, " | SL = ", sl, " | TP = ", tp, " | Lots = ", lotSize, " | Profit = ", profit); string line = MakeTradeString( od[i].trade_ticket, od[i].trade_type, od[i].trade_magic_no, od[i].trade_open_price, od[i].trade_close_price, od[i].trade_open_time, od[i].trade_close_time, od[i].trade_sl, od[i].trade_tp, od[i].trade_lot, od[i].trade_profit ); writeDatainFile(line); break; } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void writeAllDataToFile() { for(int i = 0; i < MaxOrders; i++) { if(od[i].trade_ticket != -1) { string line = MakeTradeString( od[i].trade_ticket, od[i].trade_type, od[i].trade_magic_no, od[i].trade_open_price, od[i].trade_close_price, od[i].trade_open_time, od[i].trade_close_time, od[i].trade_sl, od[i].trade_tp, od[i].trade_lot, od[i].trade_profit ); if(GlobalVariableGet(global) == 0) { int filehandle = FileOpen(filename,FILE_WRITE|FILE_CSV|FILE_COMMON,","); if(filehandle != INVALID_HANDLE) { GlobalVariableSet(global,1); FileWrite(filehandle,line); Print(line); FileClose(filehandle); GlobalVariableSet(global,0); } } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void tradeSyncAddToStruct(ulong sim_ticket,ulong live_ticket) { for(int i = 0; i < MaxOrders; i++) { if(od_sync[i].sim_trade_ticket == -1) { od_sync[i].sim_trade_ticket = sim_ticket; od_sync[i].live_trade_ticket = live_ticket; Print(" == Sim Ticket = ",sim_ticket," Live Ticket = ",live_ticket," Is Added to Structure === "); break; } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void checkTPSLHit() { if(GlobalVariableGet(global) == 0) { double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); for(int i = 0; i < MaxOrders; i++) { if(od[i].trade_ticket != -1 && od[i].trade_close_price == 0) { int ticket = od[i].trade_ticket; int type = od[i].trade_type; double sl = od[i].trade_sl; double tp = od[i].trade_tp; double closePrice = 0; // ---------------------------------------------- // BUY ORDER CHECK // ---------------------------------------------- if(type == 0) { // TP hit → Bid >= TP if(bid >= tp && tp > 0) { closePrice = bid; Print(" ======== Buy Trade TP Hit ======= ",ticket); } // SL hit → Bid <= SL if(bid <= sl && sl > 0) { closePrice = bid; Print(" ======== Buy Trade SL Hit ======= ",ticket); } } // ---------------------------------------------- // SELL ORDER CHECK // ---------------------------------------------- if(type == 1) { // TP hit → Ask <= TP (price goes DOWN) if(ask <= tp && tp > 0) { closePrice = ask; Print(" ======== Sell Trade TP Hit ======= ",ticket); } // SL hit → Ask >= SL if(ask >= sl && sl > 0) { closePrice = ask; Print(" ======== Sell Trade SL Hit ======= ",ticket); } } // ---------------------------------------------- // IF ANYTHING TRIGGERED → CLOSE TRADE // ---------------------------------------------- if(closePrice > 0) { od[i].trade_close_price = closePrice; od[i].trade_close_time = TimeCurrent(); double tpdifference = type == 1 ? (od[i].trade_open_price - od[i].trade_close_price) / Point() : (od[i].trade_close_price - od[i].trade_open_price) / Point(); od[i].trade_profit += tpinDollar(od[i].trade_lot, tpdifference); Print("======= TRADE CLOSED of ticket =======",ticket); Print("Index: ", i, " | Ticket: ", ticket, " | Type: ", type, " | ClosePrice: ", closePrice, " | Time: ", od[i].trade_close_time, " | Profit: ", od[i].trade_profit); DrawVirtualBuyClose(closePrice); datetime t1 = od[i].trade_open_time; double price1 = od[i].trade_open_price; datetime t2 = od[i].trade_close_time; double price2 = od[i].trade_close_price; // DrawDottedTrendline("Ticket "+string(ticket), t1, price1, t2, price2, clrGreen); tpSlHit = false; // make these zero so new trade place's datetime openTime = od[i].trade_open_time; double openPrice = od[i].trade_open_price; datetime closeTime = od[i].trade_close_time; double closePrice = od[i].trade_close_price; long dealType = od[i].trade_type; string lineName = "TradeLine_" + (string)od[i].trade_ticket; createTrendLine(lineName, openTime, openPrice, closeTime, closePrice, dealType, od[i].trade_profit); PrintFormat("Trend line created for closed trade #%I64u | Profit: %.2f", od[i].trade_ticket, od[i].trade_profit); // string line = MakeTradeString( // od[i].trade_ticket, // od[i].trade_type, // od[i].trade_magic_no, // od[i].trade_open_price, // od[i].trade_close_price, // od[i].trade_open_time, // od[i].trade_close_time, // od[i].trade_sl, // od[i].trade_tp, // od[i].trade_lot, // od[i].trade_profit // ); // // writeDatainFile(line); writeAllDataToFile(); } } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void closeAllVirtualTrades() { if(GlobalVariableGet(global) == 0) { double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); for(int i = 0; i < MaxOrders; i++) { if(od[i].trade_ticket != -1 && od[i].trade_close_price == 0) { int ticket = od[i].trade_ticket; int type = od[i].trade_type; double sl = od[i].trade_sl; double tp = od[i].trade_tp; double closePrice = 0; // ---------------------------------------------- // BUY ORDER CHECK // ---------------------------------------------- if(type == 0) { closePrice = bid; Print(" ======== Buy Trade Closed By close all virtual Trades ======= ",ticket); } // ---------------------------------------------- // SELL ORDER CHECK // ---------------------------------------------- if(type == 1) { closePrice = ask; Print(" ======== Sell Trade Closed By close all virtual Trades ======= ",ticket); } // ---------------------------------------------- // IF ANYTHING TRIGGERED → CLOSE TRADE // ---------------------------------------------- if(closePrice > 0) { od[i].trade_close_price = closePrice; od[i].trade_close_time = TimeCurrent(); double tpdifference = type == 1 ? (od[i].trade_open_price - od[i].trade_close_price) / Point() : (od[i].trade_close_price - od[i].trade_open_price) / Point(); od[i].trade_profit += tpinDollar(od[i].trade_lot, tpdifference); Print("======= TRADE CLOSED of ticket =======",ticket); Print("Index: ", i, " | Ticket: ", ticket, " | Type: ", type, " | ClosePrice: ", closePrice, " | Time: ", od[i].trade_close_time, " | Profit: ", od[i].trade_profit); DrawVirtualBuyClose(closePrice); datetime t1 = od[i].trade_open_time; double price1 = od[i].trade_open_price; datetime t2 = od[i].trade_close_time; double price2 = od[i].trade_close_price; DrawDottedTrendline("Ticket "+string(ticket), t1, price1, t2, price2, clrGreen); tpSlHit = false; // make these zero so new trade place's writeAllDataToFile(); } } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double tpinDollar(double lotSize, double distance) { double pipvalue = NormalizeDouble(((SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE)/(SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_SIZE)/Point()))*10),2); pipvalue = pipvalue / 10; double dollar = lotSize * distance * pipvalue; return NormalizeDouble(dollar,2); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool writeDatainFile(string str) { if(GlobalVariableGet(global) == 0) { int filehandle = FileOpen(filename,FILE_WRITE|FILE_CSV|FILE_COMMON|FILE_END,","); if(filehandle != INVALID_HANDLE) { GlobalVariableSet(global,1); FileSeek(filehandle, 0, SEEK_END); FileWrite(filehandle,str); Print(str); FileClose(filehandle); GlobalVariableSet(global,0); return true; } } return false; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ string MakeTradeString(int ticket, int type, int magic, double open_price, double close_price, datetime open_time, datetime close_time, double sl, double tp, double lotSize, double profit) { string str = StringFormat("%d,%d,%d,%.5f,%.5f,%s,%s,%.5f,%.5f,%.2f,%.2f", ticket, type, magic, open_price, close_price, TimeToString(open_time, TIME_DATE|TIME_SECONDS), TimeToString(close_time, TIME_DATE|TIME_SECONDS), sl, tp, lotSize, profit); return str; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void setStart_EndTime(bool onInit,string start,string end,datetime & sessionStart,datetime & sessionEnd) { int newYorkStartHour = 0, newYorkStartMin = 0, newYorkEndHour = 0, newYorkEndMin = 0; datetime newYorkStartTrading,newYorkEndTrading; string time[]; StringSplit(start,':',time); newYorkStartHour = (int)StringToInteger(time[0]); newYorkStartMin = (int)StringToInteger(time[1]); EventSetMillisecondTimer(500); time[0] = ""; time[1] = ""; StringSplit(end,':',time); newYorkEndHour = (int)StringToInteger(time[0]); newYorkEndMin = (int)StringToInteger(time[1]); // Print(" Start Time Hour: ",newYorkStartHour," Start Time Min: ",newYorkStartMin); // Print(" End Time Hour: ",newYorkEndHour," End Time Min: ",newYorkEndMin); datetime startDateTime; MqlDateTime st; TimeCurrent(st); // get current date st.hour = newYorkStartHour; st.min = newYorkStartMin; st.sec = 0; startDateTime = StructToTime(st); datetime endDateTime; MqlDateTime et; TimeCurrent(et); // get current date et.hour = newYorkEndHour; et.min = newYorkEndMin; et.sec = 0; endDateTime = StructToTime(et); MqlDateTime sdate,edate; datetime start_Time = 0, end_Time = 0; if(startDateTime > endDateTime) { if(onInit) { start_Time = iTime(Symbol(),PERIOD_D1,1); end_Time = iTime(Symbol(),PERIOD_D1,0); } else { start_Time = sessionStart; end_Time = sessionEnd; if(TimeCurrent() >= sessionEnd && sessionEnd != 0) { start_Time = iTime(Symbol(),PERIOD_D1,0); end_Time = start_Time + 86400; } } } else { start_Time = iTime(Symbol(),PERIOD_D1,0); end_Time = iTime(Symbol(),PERIOD_D1,0); } if(TimeToStruct(end_Time,edate)) { edate.hour = newYorkEndHour; edate.min = newYorkEndMin; edate.sec = 0; } else Print("Error in Converting Time: ",GetLastError()); newYorkEndTrading = StructToTime(edate); if(TimeToStruct(start_Time,sdate)) { sdate.hour = newYorkStartHour; sdate.min = newYorkStartMin; sdate.sec = 0; } else Print("Error in Converting Time: ",GetLastError()); newYorkStartTrading = StructToTime(sdate); sessionStart = newYorkStartTrading; sessionEnd = newYorkEndTrading; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void setStart_EndTime_modify(bool onInit,string start,string end,datetime & sessionStart,datetime & sessionEnd) { int newYorkStartHour = 0, newYorkStartMin = 0, newYorkEndHour = 0, newYorkEndMin = 0; datetime newYorkStartTrading,newYorkEndTrading; string time[]; StringSplit(start,':',time); newYorkStartHour = (int)StringToInteger(time[0]); newYorkStartMin = (int)StringToInteger(time[1]); time[0] = ""; time[1] = ""; StringSplit(end,':',time); newYorkEndHour = (int)StringToInteger(time[0]); newYorkEndMin = (int)StringToInteger(time[1]); // Print(" Start Time Hour: ",newYorkStartHour," Start Time Min: ",newYorkStartMin); // Print(" End Time Hour: ",newYorkEndHour," End Time Min: ",newYorkEndMin); datetime startDateTime; MqlDateTime st; TimeCurrent(st); // get current date st.hour = newYorkStartHour; st.min = newYorkStartMin; st.sec = 0; startDateTime = StructToTime(st); datetime endDateTime; MqlDateTime et; TimeCurrent(et); // get current date et.hour = newYorkEndHour; et.min = newYorkEndMin; et.sec = 0; endDateTime = StructToTime(et); MqlDateTime sdate,edate; datetime start_Time = 0, end_Time = 0; if(startDateTime > endDateTime) { start_Time = iTime(Symbol(),PERIOD_D1,1); end_Time = iTime(Symbol(),PERIOD_D1,0); } else { start_Time = iTime(Symbol(),PERIOD_D1,0); end_Time = iTime(Symbol(),PERIOD_D1,0); } if(TimeToStruct(end_Time,edate)) { edate.hour = newYorkEndHour; edate.min = newYorkEndMin; edate.sec = 0; } else Print("Error in Converting Time: ",GetLastError()); newYorkEndTrading = StructToTime(edate); if(TimeToStruct(start_Time,sdate)) { sdate.hour = newYorkStartHour; sdate.min = newYorkStartMin; sdate.sec = 0; } else Print("Error in Converting Time: ",GetLastError()); newYorkStartTrading = StructToTime(sdate); sessionStart = newYorkStartTrading; sessionEnd = newYorkEndTrading; } //+------------------------------------------------------------------+ //| Check Virtual TP/SL for all positions | //+------------------------------------------------------------------+ //void CheckVirtualGlobalTpSl() // { // // double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); // double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); // // for(int i=PositionsTotal()-1; i >=0 ; i--) // { // ulong ticket = PositionGetTicket(i); // if(PositionSelectByTicket(ticket)) // { // if(PositionGetInteger(POSITION_MAGIC) == magicNo && // PositionGetString(POSITION_SYMBOL) == _Symbol) // { // if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) // { // double tp_price = PositionGetDouble(POSITION_PRICE_OPEN) + glTp * 10 * SymbolInfoDouble(_Symbol, SYMBOL_POINT); // double sl_price = PositionGetDouble(POSITION_PRICE_OPEN) - glSl * 10 * SymbolInfoDouble(_Symbol, SYMBOL_POINT); // // if(bid >= tp_price || bid <= sl_price) // { // closeAllActiveOrders(); // return; // } // } // if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) // { // double tp_price = PositionGetDouble(POSITION_PRICE_OPEN) - glTp * 10 * SymbolInfoDouble(_Symbol, SYMBOL_POINT); // double sl_price = PositionGetDouble(POSITION_PRICE_OPEN) + glSl * 10 * SymbolInfoDouble(_Symbol, SYMBOL_POINT); // // if(ask <= tp_price || ask >= sl_price) // { // closeAllActiveOrders(); // return; // } // } // } // } // } // } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CheckDailyDrawdown() { if(!UseDailyDrawdownLimit) return; double equity = AccountInfoDouble(ACCOUNT_EQUITY); double drawdown = g_dailyStartBalance - equity; if(drawdown >= DailyDrawdownAmount) { enableTradingDaily = false; Print("Daily Drawdown Limit Hit: ", drawdown, " >= ", DailyDrawdownAmount); closeAllActiveOrders(); closeAllVirtualTrades(); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void markClosedOrder(datetime eaTime) { HistorySelect(eaTime, TimeCurrent()); for(int i = HistoryDealsTotal() - 1; i >= 0; i--) { ulong dealTicket = HistoryDealGetTicket(i); long dealMagic = HistoryDealGetInteger(dealTicket, DEAL_MAGIC); if(dealMagic != magicNo && dealMagic != 0) continue; if(HistoryDealGetString(dealTicket, DEAL_SYMBOL) == Symbol()) { //Print("Condition 2 ",HistoryDealGetInteger(dealTicket, DEAL_ENTRY)," HistoryDealsTotal(): ",HistoryDealsTotal()); if(HistoryDealGetInteger(dealTicket, DEAL_ENTRY) == DEAL_ENTRY_OUT) { //Print("deal out close: ",dealTicket); long dealType = HistoryDealGetInteger(dealTicket, DEAL_TYPE); if(dealType != DEAL_TYPE_BUY && dealType != DEAL_TYPE_SELL) continue; double profit = HistoryDealGetDouble(dealTicket, DEAL_PROFIT); profit = NormalizeDouble(profit, 2); string lineName = "TradeLine_" + (string)dealTicket; if(ObjectFind(0, lineName) >= 0) continue; ulong entryDeal = findEntryDeal(dealTicket); if(entryDeal == 0) continue; datetime openTime = (datetime)HistoryDealGetInteger(entryDeal, DEAL_TIME); double openPrice = HistoryDealGetDouble(entryDeal, DEAL_PRICE); datetime closeTime = (datetime)HistoryDealGetInteger(dealTicket, DEAL_TIME); double closePrice = HistoryDealGetDouble(dealTicket, DEAL_PRICE); createTrendLine(lineName, openTime, openPrice, closeTime, closePrice, dealType, profit); PrintFormat("Trend line created for closed trade #%I64u | Profit: %.2f", dealTicket, profit); } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void createTrendLine(string name, datetime openTime, double openPrice, datetime closeTime, double closePrice, long dealType, double profit) { if(ObjectFind(0, name) >= 0) return; if(!ObjectCreate(0, name, OBJ_TREND, 0, openTime, openPrice, closeTime, closePrice)) { Print("Error creating trend line: ", GetLastError()); return; } ObjectSetInteger(0, name, OBJPROP_WIDTH, tradeLineThickness); ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_SOLID); ObjectSetInteger(0, name, OBJPROP_RAY, false); color lineColor = (dealType == DEAL_TYPE_BUY) ? clrRed : clrBlue; ObjectSetInteger(0, name, OBJPROP_COLOR, lineColor); createProfitLabel(name + "_label", openTime, openPrice, closeTime, closePrice, dealType, profit); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void createProfitLabel(string name, datetime openTime, double openPrice, datetime closeTime, double closePrice, long dealType, double profit) { if(ObjectFind(0, name) >= 0) return; datetime middleTime = openTime + (closeTime - openTime) / 2; double midPrice = (openPrice + closePrice) / 2; if(!ObjectCreate(0, name, OBJ_TEXT, 0, middleTime, midPrice)) { Print("Error creating profit label: ", GetLastError()); return; } string profitText = "$" + DoubleToString(profit, 2); ObjectSetString(0, name, OBJPROP_TEXT, profitText); ObjectSetInteger(0, name, OBJPROP_FONTSIZE, dollarFontSize); ObjectSetInteger(0, name, OBJPROP_COLOR, dollarFontColor); ObjectSetInteger(0, name, OBJPROP_ANCHOR, ANCHOR_TOP); ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ ulong findEntryDeal(ulong closeDeal) { string symbol = HistoryDealGetString(closeDeal, DEAL_SYMBOL); long positionID = HistoryDealGetInteger(closeDeal, DEAL_POSITION_ID); int dealOutCount = 0; for(int i = HistoryDealsTotal() - 1; i >= 0; i--) { ulong deal = HistoryDealGetTicket(i); if(HistoryDealGetInteger(deal, DEAL_POSITION_ID) == positionID) { if(HistoryDealGetInteger(deal, DEAL_ENTRY) == DEAL_ENTRY_OUT) { dealOutCount++; } } } if(dealOutCount < 2) { for(int i = HistoryDealsTotal() - 1; i >= 0; i--) { ulong deal = HistoryDealGetTicket(i); if(HistoryDealGetInteger(deal, DEAL_POSITION_ID) == positionID && HistoryDealGetInteger(deal, DEAL_ENTRY) == DEAL_ENTRY_IN && HistoryDealGetString(deal, DEAL_SYMBOL) == symbol) return deal; //Print("Deal: ", deal); } } else { for(int i = 0; i < HistoryDealsTotal(); i++) { ulong deal = HistoryDealGetTicket(i); if(HistoryDealGetInteger(deal, DEAL_POSITION_ID) == positionID && HistoryDealGetInteger(deal, DEAL_ENTRY) == DEAL_ENTRY_OUT) { return deal; } //Print("Deal: ", deal); } } return 0; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void DrawArrow(string name, datetime time, double price, color clr, int arrow) { if(ObjectFind(0, name) == -1) { ObjectCreate(0, name, OBJ_ARROW, 0, time, price); ObjectSetInteger(0, name, OBJPROP_COLOR, clr); ObjectSetInteger(0, name, OBJPROP_WIDTH, 1); ObjectSetInteger(0, name, OBJPROP_ARROWCODE, arrow); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void DrawVirtualBuyOpen(double openPrice) { datetime t = TimeCurrent(); string name = "VBUY_OPEN_" + IntegerToString(t); // DrawArrow(name, t, openPrice, clrLime, 233); ObjectCreate(0,name,OBJ_ARROW_BUY,0,TimeCurrent(),openPrice); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void DrawVirtualBuyClose(double closePrice) { datetime t = TimeCurrent(); string name = "VBUY_CLOSE_" + IntegerToString(t); // DrawArrow(name, t, closePrice, clrRed, 234); ObjectCreate(0,name,OBJ_ARROW_SELL,0,TimeCurrent(),closePrice); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void DrawDottedTrendline(string name, datetime time1, double price1, datetime time2, double price2, color clr) { // Delete if already exists if(ObjectFind(0, name) != -1) ObjectDelete(0, name); // Create the trendline if(!ObjectCreate(0, name, OBJ_TREND, 0, time1, price1, time2, price2)) Print("Error creating trendline: ", GetLastError()); // Set properties ObjectSetInteger(0, name, OBJPROP_COLOR, clr); ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_DOT); // Dotted line ObjectSetInteger(0, name, OBJPROP_WIDTH, 1); // Line width } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int orderCount() { int index = 0; if(GlobalVariableGet(global) == 0) { GlobalVariableSet(global,1); int handle = FileOpen(filename, FILE_READ | FILE_COMMON); if(handle == INVALID_HANDLE) { Print("EA=> Handler invalid: orderCount() ", filename," ",GetLastError()," eaType: ",eaType); return -1; } while(!FileIsEnding(handle)) { string line = FileReadString(handle); string parts[]; int count = StringSplit(line, ',', parts); int ticket = (int)StringToInteger(parts[0]); int type = (int)StringToInteger(parts[1]); int magic = (int)StringToInteger(parts[2]); double open_price = StringToDouble(parts[3]); double close_price = StringToDouble(parts[4]); datetime open_time = StringToTime(parts[5]); datetime close_time = StringToTime(parts[6]); double sl = StringToDouble(parts[7]); double tp = StringToDouble(parts[8]); double lotS = StringToDouble(parts[9]); double profit = StringToDouble(parts[10]); index++; } FileClose(handle); GlobalVariableSet(global,0); } return index; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int getTicketByNumber(int id,double & buySl,double & buyTp) { int index = -1; if(GlobalVariableGet(global) == 0) { GlobalVariableSet(global,1); int handle = FileOpen(filename, FILE_READ | FILE_COMMON); if(handle == INVALID_HANDLE) { Print("EA=> Handler invalid: getTicketByNumber() ", filename," error: ",GetLastError()," eaType: ",eaType); return 0; } while(!FileIsEnding(handle)) { string line = FileReadString(handle); // Skip empty line if(StringLen(line) < 2) continue; string parts[]; int count = StringSplit(line, ',', parts); int ticket = (int)StringToInteger(parts[0]); int type = (int)StringToInteger(parts[1]); int magic = (int)StringToInteger(parts[2]); double open_price = StringToDouble(parts[3]); double close_price = StringToDouble(parts[4]); datetime open_time = StringToTime(parts[5]); datetime close_time = StringToTime(parts[6]); double sl = StringToDouble(parts[7]); double tp = StringToDouble(parts[8]); double lotS = StringToDouble(parts[9]); double profit = StringToDouble(parts[10]); if(id == ticket) { buySl = sl; buyTp = tp; index = id; } } FileClose(handle); GlobalVariableSet(global,0); } return index; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void checkVirtualTicketClosed() // check if virtual trade closed so close Active Trade as well { if(GlobalVariableGet(global) == 0) { GlobalVariableSet(global,1); int handle = FileOpen(filename, FILE_READ | FILE_COMMON); if(handle == INVALID_HANDLE) { Print("EA=> Handler invalid: checkVirtualTicketClosed() ", filename," error: ",GetLastError()," eaType: ",eaType); return; } while(!FileIsEnding(handle)) { string line = FileReadString(handle); string parts[]; int count = StringSplit(line, ',', parts); int ticket = (int)StringToInteger(parts[0]); int type = (int)StringToInteger(parts[1]); int magic = (int)StringToInteger(parts[2]); double open_price = StringToDouble(parts[3]); double close_price = StringToDouble(parts[4]); datetime open_time = StringToTime(parts[5]); datetime close_time = StringToTime(parts[6]); double sl = StringToDouble(parts[7]); double tp = StringToDouble(parts[8]); double lotS = StringToDouble(parts[9]); double profit = StringToDouble(parts[10]); for(int i = 0; i < MaxOrders; i++) { if(od_sync[i].sim_trade_ticket != -1) { if(od_sync[i].sim_trade_ticket == ticket && close_time > 0) { if(PositionSelectByTicket(od_sync[i].live_trade_ticket)) { Print(" Virtual Trade is Closed so Remove the Live Trade As well "," Virtual Ticket = ",od_sync[i].sim_trade_ticket," Live Ticket = ",od_sync[i].live_trade_ticket); if(trade.PositionClose(od_sync[i].live_trade_ticket)) { Print("Position closed ", od_sync[i].live_trade_ticket); od_sync[i].sim_trade_ticket = -1; od_sync[i].sim_trade_ticket = -1; } else { Print("Cannot close order: ",GetLastError()); } } } } } } FileClose(handle); GlobalVariableSet(global,0); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void deleteObjects() { int total = ObjectsTotal(0); for(int i = total - 1; i >= 0; i--) { string name = ObjectName(0, i); if(StringFind(name, "VBUY_OPEN_") >= 0 || StringFind(name, "VBUY_CLOSE_") >= 0 || StringFind(name, "Ticket ") >= 0) { ObjectDelete(0, name); } } } //+------------------------------------------------------------------+ //| Create Bottom Right Labels | //+------------------------------------------------------------------+ void CreateInfoLabels(double balance, int magic, int maPeriod, bool useMA, bool drawdownReached) { int corner = CORNER_RIGHT_LOWER; int xOffset = 200; int yStart = 120; // IMPORTANT int yStep = 18; ObjectsDeleteAll(0,-1,-1); if(CopyTallyTrade) { string names[5] = { "lbl_balance", "lbl_magic", "lbl_ma", "lbl_use_ma", "lbl_drawdown" }; string texts[5]; texts[0] = "Balance = " + DoubleToString(balance, 2); texts[1] = "Magic # = " + IntegerToString(magicNo1); texts[2] = "Moving Average = " + IntegerToString(maPeriod); texts[3] = "Use Moving Average = " + (useMovingAVG ? "TRUE" : "FALSE"); texts[4] = "Drawdown Reached = " + (!enableTradingDaily ? "TRUE" : "FALSE"); for(int i = 0; i < 5; i++) { if(ObjectFind(0, names[i]) == -1) { ObjectCreate(0, names[i], OBJ_LABEL, 0, 0, 0); ObjectSetInteger(0, names[i], OBJPROP_CORNER, corner); ObjectSetInteger(0, names[i], OBJPROP_XDISTANCE, xOffset); ObjectSetInteger(0, names[i], OBJPROP_YDISTANCE, yStart - i * yStep); ObjectSetInteger(0, names[i], OBJPROP_FONTSIZE, 9); ObjectSetInteger(0, names[i], OBJPROP_COLOR, clrWhite); ObjectSetString(0, names[i], OBJPROP_FONT, "Arial"); } ObjectSetString(0, names[i], OBJPROP_TEXT, texts[i]); } } else { string names[4] = { "lbl_balance", "lbl_ma", "lbl_use_ma", "lbl_drawdown" }; string texts[4]; texts[0] = "Balance = " + DoubleToString(balance, 2); texts[1] = "Moving Average = " + IntegerToString(maPeriod); texts[2] = "Use Moving Average = " + (useMovingAVG ? "TRUE" : "FALSE"); texts[3] = "Drawdown Reached = " + (!enableTradingDaily ? "TRUE" : "FALSE"); for(int i = 0; i < 4; i++) { if(ObjectFind(0, names[i]) == -1) { ObjectCreate(0, names[i], OBJ_LABEL, 0, 0, 0); ObjectSetInteger(0, names[i], OBJPROP_CORNER, corner); ObjectSetInteger(0, names[i], OBJPROP_XDISTANCE, xOffset); ObjectSetInteger(0, names[i], OBJPROP_YDISTANCE, yStart - i * yStep); ObjectSetInteger(0, names[i], OBJPROP_FONTSIZE, 9); ObjectSetInteger(0, names[i], OBJPROP_COLOR, clrWhite); ObjectSetString(0, names[i], OBJPROP_FONT, "Arial"); } ObjectSetString(0, names[i], OBJPROP_TEXT, texts[i]); } } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+