//+------------------------------------------------------------------+ //| 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 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]; 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 =================== ";//_ input trade_typ ordTyp = buy; // Order Type (Tally Sim) input int magicNo = 123; // Magic # (Tally Sim) input string fileName = "TradeDataFile.csv"; // File Name (Tally Sim) input string grlesettings = " ================ Tally Trade Settings =================== ";//_ input trade_typ tradesDirection = buy; // Order Type (Tally Trade) input int magicNo1 = 1234; // Magic # (Tally Trade) input bool CopyTallyTrade = true; // Enable Copy Trade 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.csv"; // File Name bool tpSlHit = false; int ticketAssigner = 1; int handler; double bufferData[]; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- 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); ArraySetAsSeries(bufferData,true); } trade.SetExpertMagicNumber(magicNo1); trade.SetDeviationInPoints(10); trade.SetTypeFilling(ORDER_FILLING_IOC); trade.LogLevel(LOG_LEVEL_ALL); trade.SetAsyncMode(false); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- placeTrade(); checkTPSLHit(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void placeTrade() { if(tpSlHit == false) { 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); } AddToStructure(ticketAssigner,0,magicNo,Ask,0,TimeCurrent(),0,buySl,buyTp,lot,0); ticketAssigner++; 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(tradesDirection == buy) { if(balance > MA) { if(!trade.Buy(lot, Symbol(),SymbolInfoDouble(Symbol(),SYMBOL_ASK),buySl,buyTp,"Buy Trade")) { Print(" Error in Placing Buy Trade : ",GetLastError()); } } else { Print(" Trade is not Placed because Balance is less than MA Value "); } } else { if(balance > MA) { if(!trade.Sell(lot,Symbol(),SymbolInfoDouble(Symbol(),SYMBOL_BID),buyTp,buySl,"Sell Trade")) { Print(" Error in Placing Sell Trade : ",GetLastError()); } } else { Print(" Trade is not Placed because Balance is less than MA Value "); } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ 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()); } AddToStructure(ticketAssigner,1,magicNo,Bid,0,TimeCurrent(),0,sellSl,sellTp,lot,0); ticketAssigner++; 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(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 "); } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ 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) { 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); break; } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void checkTPSLHit() { 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); tpSlHit = false; // make these zero so new trade place's 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); } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ 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); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void writeDatainFile(string str) { int filehandle = FileOpen(fileName,FILE_WRITE|FILE_CSV|FILE_COMMON|FILE_END,","); if(filehandle != INVALID_HANDLE) { FileSeek(filehandle, 0, SEEK_END); FileWrite(filehandle,str); Print(str); FileClose(filehandle); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ 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; } //+------------------------------------------------------------------+