#property strict #property version "2.10" #include CTrade Trade; //================ INPUT PARAMETERS ==================// input int MagicNumber = 456789; input double Risk_Per_Trade = 1.0; input int SR_Lookback_Bars = 50; input int SR_Buffer_Points = 30; input ENUM_TIMEFRAMES Trend_Timeframe = PERIOD_H1; input int Fast_EMA = 50; input int Slow_EMA = 200; input int Initial_SL_Points = 150; input int BreakEven_Points = 120; input double Min_Profit_Lock_Percent = 2.0; input int Trailing_Step_Points = 40; input int Max_Open_Trades = 1; //================ GLOBAL ==================// ulong EA_PositionTicket = 0; //================ LOT SIZE ==================// double GetLotSize(int sl_points) { double riskMoney = AccountInfoDouble(ACCOUNT_BALANCE) * Risk_Per_Trade / 100.0; double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE); double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE); double lot = riskMoney / ((sl_points * _Point / tickSize) * tickValue); return NormalizeDouble(lot, 2); } //================ TREND FILTER ==================// bool GetTrend(bool &uptrend, bool &downtrend) { int fastHandle = iMA(_Symbol, Trend_Timeframe, Fast_EMA, 0, MODE_EMA, PRICE_CLOSE); int slowHandle = iMA(_Symbol, Trend_Timeframe, Slow_EMA, 0, MODE_EMA, PRICE_CLOSE); if(fastHandle == INVALID_HANDLE || slowHandle == INVALID_HANDLE) return false; double fastBuf[1], slowBuf[1]; if(CopyBuffer(fastHandle, 0, 0, 1, fastBuf) <= 0) return false; if(CopyBuffer(slowHandle, 0, 0, 1, slowBuf) <= 0) return false; uptrend = fastBuf[0] > slowBuf[0]; downtrend = fastBuf[0] < slowBuf[0]; IndicatorRelease(fastHandle); IndicatorRelease(slowHandle); return true; } //================ SUPPORT & RESISTANCE ==================// double GetSupport() { double s = iLow(_Symbol, PERIOD_H1, 1); for(int i=2;i<=SR_Lookback_Bars;i++) s = MathMin(s, iLow(_Symbol, PERIOD_H1, i)); return s; } double GetResistance() { double r = iHigh(_Symbol, PERIOD_H1, 1); for(int i=2;i<=SR_Lookback_Bars;i++) r = MathMax(r, iHigh(_Symbol, PERIOD_H1, i)); return r; } //================ TRADE MANAGEMENT ==================// void ManageTrade() { if(!PositionSelect(_Symbol)) return; double entry = PositionGetDouble(POSITION_PRICE_OPEN); double sl = PositionGetDouble(POSITION_SL); double price = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) ? SymbolInfoDouble(_Symbol, SYMBOL_BID) : SymbolInfoDouble(_Symbol, SYMBOL_ASK); double profit = PositionGetDouble(POSITION_PROFIT); long type = PositionGetInteger(POSITION_TYPE); // Break-even if(type == POSITION_TYPE_BUY && price - entry >= BreakEven_Points * _Point && sl < entry) Trade.PositionModify(_Symbol, entry, 0); if(type == POSITION_TYPE_SELL && entry - price >= BreakEven_Points * _Point && sl > entry) Trade.PositionModify(_Symbol, entry, 0); // Profit lock & trailing double minProfit = AccountInfoDouble(ACCOUNT_BALANCE) * Min_Profit_Lock_Percent / 100.0; if(profit >= minProfit) { double newSL; if(type == POSITION_TYPE_BUY) { newSL = price - Trailing_Step_Points * _Point; if(newSL > sl) Trade.PositionModify(_Symbol, newSL, 0); } else { newSL = price + Trailing_Step_Points * _Point; if(newSL < sl) Trade.PositionModify(_Symbol, newSL, 0); } } } //================ MAIN ==================// void OnTick() { ManageTrade(); if(PositionsTotal() >= Max_Open_Trades) return; bool uptrend=false, downtrend=false; if(!GetTrend(uptrend, downtrend)) return; double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double support = GetSupport(); double resistance = GetResistance(); double lot = GetLotSize(Initial_SL_Points); Trade.SetExpertMagicNumber(MagicNumber); // BUY if(uptrend && MathAbs(bid - support) <= SR_Buffer_Points * _Point) { double sl = bid - Initial_SL_Points * _Point; Trade.Buy(lot, _Symbol, ask, sl, 0); } // SELL if(downtrend && MathAbs(ask - resistance) <= SR_Buffer_Points * _Point) { double sl = ask + Initial_SL_Points * _Point; Trade.Sell(lot, _Symbol, bid, sl, 0); } }