ExpBuySellSide
This EA trades based on a dual-indicator trend following system combining ATRStops and StepUpDown indicators. It opens buy positions when both indicators signal uptrend and sell positions when both signal downtrend, with optional trailing stop and opposite-signal close functionality. Money management supports both fixed lot sizing and dynamic lot sizing based on risk percentage.
Open the interactive view (equity curve, symbol switch)Key facts
Backtest results (H1, about 1 year)
| Symbol | P&L | Annual | Max DD | Trades | Win rate | Sharpe | Recovery | Losing streak | Per trade | Status |
|---|---|---|---|---|---|---|---|---|---|---|
| EURUSD | +2.94% | +2.55% | 5.69% | 1 | 0.00% | — | — | — | — | Too few trades |
| GBPUSD | -3.89% | -3.39% | 8.34% | 1 | 0.00% | — | — | — | — | Too few trades |
| USDJPY | -2.85% | -2.48% | 7.59% | 1 | 0.00% | — | — | — | — | Too few trades |
| XAUUSD | -91.61% | -87.09% | 94.00% | 2 | 0.00% | -0.45 | -0.97 | 2 | −$4,580.37 | Account stopped out |
Converted from MQL5 to Python and run with the same rules for every EA. Positions use MT5 lot sizes (100,000 units per FX lot, 100 oz per gold lot) with 1:100 leverage, one order at a time, and a stop-out below 10% of the starting balance. Sharpe is computed from the equity curve. Results marked as unreliable are shown for completeness only.
Against the other Trend Following EAs with a reliable result on the same market: XAUUSD: better than 11% of 96
Month by month
| Market | Months with a gain | Best month | Worst month |
|---|---|---|---|
| XAUUSD | 0% | 0.00% 2026-02 | -85.62% 2026-01 |
From the backtest equity curve, sampled about every two days; only reliable results.
Blow-up risk: High
- Hit a stop-out in our backtest (equity below 10%) on XAUUSD
High: stopped out in our backtest, or martingale/grid sizing without a stop loss. Elevated: martingale or grid sizing with a stop loss, or several positions at once without a stop loss. What the label means and what we found →
Strategy analysis
This EA employs a dual-indicator confirmation trend following strategy where entry requires both ATRStops and StepUpDown indicators to signal the same direction simultaneously. The ATRStops indicator calculates a dynamic stop channel based on ATR multiples (Kv=2.5), signaling bullish (+1) when price breaks above the upper channel and bearish (-1) when breaking below the lower channel. The StepUpDown indicator determines trend direction through crossover and divergence between a fast SMA (period 2) and slow SMMA (period 30). Exit conditions include: close on opposite signal (CloseByOppositeSignal), trailing stop (TrailingStop), and profit close when StepUpDown reverses direction. Position sizing supports both fixed lot and dynamic lot modes, with the dynamic mode calculating lots based on account balance, risk percentage, and leverage. Stop loss and take profit are dynamically calculated via the CalculateSLTP function based on money risk and tick value, with TP set as a multiple (TPvsSLRatio) of SL and a minimum SL of 38 pips. A same-hour no-reentry rule prevents overtrading by checking if a position was already closed within the current hour.
Strengths
- Dual-indicator confirmation reduces false signal risk by requiring both ATRStops and StepUpDown to agree before entry
- Dynamic SL calculation based on actual money risk and tick value ensures controllable risk per trade
- Supports both fixed lot and dynamic lot money management modes for flexible trading needs
- Same-hour no-reentry rule effectively prevents overtrading
- ATRStops adaptive channel dynamically adjusts stop distance based on market volatility
Weaknesses
- Critical memory leak: new CTrade/CSymbolInfo/CPositionInfo/CAccountInfo objects created every OnTimer call but never deleted
- ModifySLTP breaks after first modification attempt, only modifying one position per call instead of iterating all
- ClosePosition has misplaced PositionGetTicket call that may match incorrect positions due to stale position info
- CalculateSLTP leveragerisk calculation (leverage/100 rounded) lacks theoretical justification and may produce misleading stop distances
- Redundant iOpen/iHigh/iLow/iClose/iTime function definitions exist but are never called in the code
Possible improvements
- Fix memory leak: either create CTrade etc. objects once in OnInit and reuse, or delete them at the end of each OnTimer call
- Remove break statement in ModifySLTP to allow iterating all positions for modification, and unify OrderSend handling outside conditional blocks
- Fix StepUpDown indicator logic where ups/dns variables are repeatedly overwritten in the loop, making only the last iteration's value effective, which may not match intended behavior
- Add spread filter and maximum position count limit to prevent frequent trading in high-spread environments and overexposure
Risk assessment
Overall risk: Medium
- Memory leak from creating new objects every OnTimer without deletion causes severe performance degradation over long runtimes
- Trailing stop modification breaks after first attempt, potentially leaving some positions without updated stops
- Dynamic lot calculation uses non-intuitive Opentotal logic (minimum 5) that may underestimate risk with high position counts
- Using Sleep(1000) between open and close operations can cause slippage in fast-moving markets
Evaluation scores
Parameters
| Parameter | Default | Description |
|---|---|---|
TimeFrames | PERIOD_H1 | Timeframe for EA operation |
RiskPercentage | 3.0 | Risk percentage for dynamic lot and stop-loss calculation |
TPvsSLRatio | 3.0 | Take-profit to stop-loss multiplier ratio |
MoneyManagementType | DynamicLotSize | Money management: fixed lot or dynamic lot |
TradeLotSize | 0.1 | Manual lot size in fixed lot mode |
CloseByOppositeSignal | Yes | Close position on opposite signal |
UseTrailingStop | No | Enable trailing stop |
Trailing_FixedPipsSL | 10 | Trailing stop value in points |
Magic | 1234 | EA unique identifier ID (max 8 digits) |
Similar Trend Following EAs
Backtests are historical simulations and do not guarantee future results. Not financial advice.