// Enumerations enum TradeDirection { BUY, SELL }; enum TradeStatus { NO_TRADE, TRADE_OPENED, TRADE_CLOSED }; enum CloseMethod { CLOSE_CANDLE_ONLY, CLOSE_STOP_LOSS, CLOSE_TAKE_PROFIT, CLOSE_STOP_LOSS_OR_TAKE_PROFIT, CLOSE_STOP_LOSS_OR_CANDLE, CLOSE_TAKE_PROFIT_OR_CANDLE, CLOSE_STOP_LOSS_OR_TAKE_PROFIT_OR_CANDLE }; // User-defined input parameters input ENUM_TIMEFRAMES Timeframe = PERIOD_H1; // Timeframe selection input int FastMAPeriod = 10; // Period for fast moving average input int SlowMAPeriod = 20; // Period for slow moving average input int StopLossPips = 50; // Stop loss in pips input bool CloseOnStopLoss = true; // Close trade only when stop loss is hit input double RiskPercentage = 2.0; // Percentage risk per trade input bool UseFixedLotSize = false; // Use fixed lot size instead of risk percentage input double FixedLotSize = 0.01; // Fixed lot size input bool UseTargetProfit = false; // Use target profit input int TargetProfitPips = 100; // Target profit in pips input CloseMethod CloseMethodOption = CLOSE_CANDLE_ONLY; // Close trade method input bool UseMartingale = false; // Use martingale recovery strategy input double MartingaleRecoveryPercentage = 50.0; // Percentage of loss to recover input int MaxRecoveryTrades = 3; // Maximum number of trades for recovery input int MaxTradeLosses = 5; // Maximum number of consecutive trade losses input ENUM_MA_METHOD MAMethod = MODE_SMA; // Moving average method input double RecoveryLotMultiplier = 2.0; // Lot size multiplier for martingale recovery // Global variables double LotSize; // Calculated lot size int RecoveryTradesCount = 0; // Number of trades for recovery double RecoveryLossPercentage = 0.0; // Current recovery loss percentage int TradeLossesCount = 0; // Number of consecutive trade losses // Moving Average variables int FastMAHandle; int SlowMAHandle; double FastMAValue; double SlowMAValue; // Trade variables TradeDirection tradeDirection = BUY; TradeStatus tradeStatus = NO_TRADE; double entryPrice; double stopLossPrice; double takeProfitPrice; int ticket; double slippage; // Function to calculate lot size based on risk percentage double CalculateLotSize(double riskPercentage) { double accountBalance = AccountBalance(); double accountEquity = AccountEquity(); double stopLossInPoints = StopLossPips * Point; double maximumLots = NormalizeDouble(accountBalance * riskPercentage / 100.0 / stopLossInPoints, 2); double lotSize = NormalizeDouble(accountEquity * riskPercentage / 100.0 / stopLossInPoints, 2); if (lotSize > maximumLots) lotSize = maximumLots; return lotSize; } // Function to open a trade void OpenTrade(TradeDirection direction) { slippage = MarketInfo(Symbol(), MODE_FREEZELEVEL); if (direction == BUY) { entryPrice = Ask; stopLossPrice = entryPrice - StopLossPips * Point; takeProfitPrice = entryPrice + TargetProfitPips * Point; ticket = OrderSend(Symbol(), OP_BUY, LotSize, entryPrice, slippage, stopLossPrice, takeProfitPrice, "Buy order", 0, 0, Green); } else if (direction == SELL) { entryPrice = Bid; stopLossPrice = entryPrice + StopLossPips * Point; takeProfitPrice = entryPrice - TargetProfitPips * Point; ticket = OrderSend(Symbol(), OP_SELL, LotSize, entryPrice, slippage, stopLossPrice, takeProfitPrice, "Sell order", 0, 0, Red); } if (ticket > 0) { tradeStatus = TRADE_OPENED; tradeDirection = direction; Print("Trade opened successfully. Ticket: ", ticket); } else { Print("Error opening trade. Error code: ", GetLastError()); } } // Function to close the trade void CloseTrade() { slippage = MarketInfo(Symbol(), MODE_FREEZELEVEL); if (CloseMethodOption == CLOSE_CANDLE_ONLY) { if (tradeDirection == BUY) { if (CloseOnStopLoss) ticket = OrderClose(ticket, LotSize, Bid, slippage, Violet); else ticket = OrderClose(ticket, LotSize, Bid, slippage, Violet); } else if (tradeDirection == SELL) { if (CloseOnStopLoss) ticket = OrderClose(ticket, LotSize, Ask, slippage, Violet); else ticket = OrderClose(ticket, LotSize, Ask, slippage, Violet); } } else if (CloseMethodOption == CLOSE_STOP_LOSS) { ticket = OrderClose(ticket, LotSize, 0, slippage, Violet); } else if (CloseMethodOption == CLOSE_TAKE_PROFIT) { ticket = OrderClose(ticket, LotSize, takeProfitPrice, slippage, Violet); } else if (CloseMethodOption == CLOSE_STOP_LOSS_OR_TAKE_PROFIT) { if (tradeDirection == BUY) ticket = OrderClose(ticket, LotSize, MathMin(stopLossPrice, takeProfitPrice), slippage, Violet); else if (tradeDirection == SELL) ticket = OrderClose(ticket, LotSize, MathMax(stopLossPrice, takeProfitPrice), slippage, Violet); } else if (CloseMethodOption == CLOSE_STOP_LOSS_OR_CANDLE) { if (tradeDirection == BUY) { if (CloseOnStopLoss) ticket = OrderClose(ticket, LotSize, Bid, slippage, Violet); else ticket = OrderClose(ticket, LotSize, Bid, slippage, Violet); } else if (tradeDirection == SELL) { if (CloseOnStopLoss) ticket = OrderClose(ticket, LotSize, Ask, slippage, Violet); else ticket = OrderClose(ticket, LotSize, Ask, slippage, Violet); } } else if (CloseMethodOption == CLOSE_TAKE_PROFIT_OR_CANDLE) { if (tradeDirection == BUY) { if (UseTargetProfit && Bid >= takeProfitPrice) ticket = OrderClose(ticket, LotSize, takeProfitPrice, slippage, Violet); else ticket = OrderClose(ticket, LotSize, Bid, slippage, Violet); } else if (tradeDirection == SELL) { if (UseTargetProfit && Ask <= takeProfitPrice) ticket = OrderClose(ticket, LotSize, takeProfitPrice, slippage, Violet); else ticket = OrderClose(ticket, LotSize, Ask, slippage, Violet); } } else if (CloseMethodOption == CLOSE_STOP_LOSS_OR_TAKE_PROFIT_OR_CANDLE) { if (tradeDirection == BUY) { if (UseTargetProfit && Bid >= takeProfitPrice) ticket = OrderClose(ticket, LotSize, takeProfitPrice, slippage, Violet); else if (CloseOnStopLoss) ticket = OrderClose(ticket, LotSize, Bid, slippage, Violet); else ticket = OrderClose(ticket, LotSize, Bid, slippage, Violet); } else if (tradeDirection == SELL) { if (UseTargetProfit && Ask <= takeProfitPrice) ticket = OrderClose(ticket, LotSize, takeProfitPrice, slippage, Violet); else if (CloseOnStopLoss) ticket = OrderClose(ticket, LotSize, Ask, slippage, Violet); else ticket = OrderClose(ticket, LotSize, Ask, slippage, Violet); } } if (ticket > 0) { tradeStatus = TRADE_CLOSED; Print("Trade closed successfully. Ticket: ", ticket); } else { Print("Error closing trade. Error code: ", GetLastError()); } } // Initialization function int OnInit() { // Calculate lot size if (UseFixedLotSize) LotSize = FixedLotSize; else LotSize = CalculateLotSize(RiskPercentage); // Initialize Moving Averages FastMAValue = iMA(NULL, Timeframe, FastMAPeriod, 0, MAMethod, PRICE_CLOSE, 0); SlowMAValue = iMA(NULL, Timeframe, SlowMAPeriod, 0, MAMethod, PRICE_CLOSE, 0); return(INIT_SUCCEEDED); } // Deinitialization function void OnDeinit(const int reason) { // Close any open trades before deinitializing if (tradeStatus == TRADE_OPENED) { CloseTrade(); } } // Start function void OnTick() { // Check if recovery trades limit reached if (RecoveryTradesCount >= MaxRecoveryTrades) return; // Check if maximum consecutive trade losses reached if (TradeLossesCount >= MaxTradeLosses) { // Apply martingale recovery strategy if enabled if (UseMartingale) { LotSize *= RecoveryLotMultiplier; RecoveryLossPercentage += MartingaleRecoveryPercentage; RecoveryTradesCount++; TradeLossesCount = 0; } else { Print("Max trade losses reached. No more trades will be opened."); return; } } // Check if trade is already open if (tradeStatus == TRADE_OPENED) { // Check if trade should be closed if (CloseMethodOption != CLOSE_CANDLE_ONLY) { CloseTrade(); return; } // Update trade stop loss if necessary if (tradeDirection == BUY && Low[0] < stopLossPrice) { stopLossPrice = Low[0]; if (!OrderModify(ticket, 0, stopLossPrice, takeProfitPrice, 0, White)) { Print("Error modifying trade. Error code: ", GetLastError()); } Print("Stop loss updated for Buy trade. New price: ", stopLossPrice); } else if (tradeDirection == SELL && High[0] > stopLossPrice) { stopLossPrice = High[0]; if (!OrderModify(ticket, 0, stopLossPrice, takeProfitPrice, 0, White)) { Print("Error modifying trade. Error code: ", GetLastError()); } Print("Stop loss updated for Sell trade. New price: ", stopLossPrice); } // Exit if trade is still valid return; } // Calculate Moving Average values FastMAValue = iMA(NULL, Timeframe, FastMAPeriod, 0, MAMethod, PRICE_CLOSE, 0); SlowMAValue = iMA(NULL, Timeframe, SlowMAPeriod, 0, MAMethod, PRICE_CLOSE, 0); // Check if there is a new crossover if (FastMAValue > SlowMAValue) { // Open a new Buy trade OpenTrade(BUY); TradeLossesCount = 0; } else if (FastMAValue < SlowMAValue) { // Open a new Sell trade OpenTrade(SELL); TradeLossesCount = 0; } else { // No crossover, do nothing } }