SUPERMACBOT by The Guardian Forex TV Strategy
Overview
The SUPERMACBOT by The Guardian Forex TV Strategy replicates the concept of the original MetaTrader expert advisor by combining the MACD oscillator with a dual simple moving average trend filter and a trailing average exit filter. The converted StockSharp implementation works on completed candles and sends market orders whenever a bullish or bearish confluence forms. The strategy avoids tick-by-tick trading and follows the high-level API guidelines by relying on candle subscriptions and indicator bindings.
The trading engine evaluates momentum through the MACD histogram and trend alignment between two simple moving averages. A trailing moving average acts both as a trade management reference and a delayed confirmation filter, mirroring the trailing module configured in the MQL expert. The StockSharp version focuses on clarity and portability across instruments and timeframes by exposing every key value as a configurable parameter.
Trading Logic
- Data source – the strategy subscribes to a configurable candle type (timeframe). Each completed candle triggers the decision flow.
- Indicator preparation – MACD (with adjustable fast, slow, and signal periods) and two SMAs are recalculated on every candle. An additional SMA replicates the trailing filter from the MQL expert.
- Entry rules
- Long entry
- MACD histogram crosses above the configurable threshold.
- The fast SMA is above the slow SMA, showing an established bullish trend.
- Close price remains above the trailing SMA to ensure price strength.
- The strategy has no existing long position (only one net position is maintained).
- Short entry
- MACD histogram crosses below the negative threshold.
- The fast SMA is below the slow SMA, signalling a bearish environment.
- Close price stays below the trailing SMA.
- The strategy holds no short exposure.
- Exit rules
- Long positions are closed when any of the following happens: histogram turns negative, the fast SMA dips below the slow SMA, or price closes beneath the trailing SMA.
- Short positions are closed when the histogram turns positive, the fast SMA rises above the slow SMA, or price closes above the trailing SMA.
- Risk handling – the algorithm trades a single net position and never pyramids. Protective stops can be added externally by using StockSharp risk rules if desired.
Parameters
| Name |
Description |
Default |
CandleType |
Candle series processed by the strategy. |
1-minute timeframe |
FastMaPeriod |
Period of the fast simple moving average filter. |
12 |
SlowMaPeriod |
Period of the slow simple moving average filter. |
26 |
MacdFastPeriod |
Fast EMA period for the MACD indicator. |
12 |
MacdSlowPeriod |
Slow EMA period for the MACD indicator. |
24 |
MacdSignalPeriod |
Signal EMA period for the MACD indicator. |
9 |
HistogramThreshold |
Minimum absolute value required from the MACD histogram before opening a position. |
0.0 |
TrailingPeriod |
Period of the trailing simple moving average used for confirmations and exits. |
12 |
All parameters are exposed through StrategyParam<T> and can be optimized inside StockSharp Designer.
Usage Notes
- Attach the strategy to any security and timeframe that suits your testing environment.
- Ensure a sufficient history buffer is available so that all indicators become fully formed before trading begins.
- Because the strategy works with finished candles and net positions, it is safe to run in multi-instrument portfolios without conflicting orders.
- Additional money management (lot sizing, stop losses, partial exits) can be added by composing the strategy with other StockSharp modules.
Differences from the Original Expert
- The StockSharp conversion focuses on candle-close logic rather than the event-driven engine of the MetaTrader Expert Advisor. This keeps the behaviour deterministic across backtests and live trading.
- Lot sizing and trailing stop orders from the original Expert Advisor are replaced with a simplified, position-based exit conditioned by the trailing average.
- Signal thresholds are handled via the MACD histogram threshold parameter, allowing users to mimic the scoring system of the MQL Expert by adjusting the value.
Disclaimer
Trading algorithms involve financial risk. Thoroughly backtest and forward-test the strategy before deploying it with real capital.
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// SUPERMACBOT strategy converted from the MQL expert by The Guardian Forex TV.
/// </summary>
public class SupermacbotByTheGuardianForexTvStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastMaPeriod;
private readonly StrategyParam<int> _slowMaPeriod;
private readonly StrategyParam<int> _macdFastPeriod;
private readonly StrategyParam<int> _macdSlowPeriod;
private readonly StrategyParam<int> _macdSignalPeriod;
private readonly StrategyParam<decimal> _histogramThreshold;
private readonly StrategyParam<int> _trailingPeriod;
/// <summary>
/// Candle type to process.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Fast simple moving average period.
/// </summary>
public int FastMaPeriod
{
get => _fastMaPeriod.Value;
set => _fastMaPeriod.Value = value;
}
/// <summary>
/// Slow simple moving average period.
/// </summary>
public int SlowMaPeriod
{
get => _slowMaPeriod.Value;
set => _slowMaPeriod.Value = value;
}
/// <summary>
/// Fast EMA period for MACD.
/// </summary>
public int MacdFastPeriod
{
get => _macdFastPeriod.Value;
set => _macdFastPeriod.Value = value;
}
/// <summary>
/// Slow EMA period for MACD.
/// </summary>
public int MacdSlowPeriod
{
get => _macdSlowPeriod.Value;
set => _macdSlowPeriod.Value = value;
}
/// <summary>
/// Signal EMA period for MACD.
/// </summary>
public int MacdSignalPeriod
{
get => _macdSignalPeriod.Value;
set => _macdSignalPeriod.Value = value;
}
/// <summary>
/// Minimal absolute histogram value required for new entries.
/// </summary>
public decimal HistogramThreshold
{
get => _histogramThreshold.Value;
set => _histogramThreshold.Value = value;
}
/// <summary>
/// Trailing simple moving average period.
/// </summary>
public int TrailingPeriod
{
get => _trailingPeriod.Value;
set => _trailingPeriod.Value = value;
}
/// <summary>
/// Initializes a new instance of <see cref="SupermacbotByTheGuardianForexTvStrategy"/>.
/// </summary>
public SupermacbotByTheGuardianForexTvStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to process", "General");
_fastMaPeriod = Param(nameof(FastMaPeriod), 12)
.SetGreaterThanZero()
.SetDisplay("Fast SMA", "Fast SMA period", "Indicators")
.SetOptimize(5, 30, 1);
_slowMaPeriod = Param(nameof(SlowMaPeriod), 26)
.SetGreaterThanZero()
.SetDisplay("Slow SMA", "Slow SMA period", "Indicators")
.SetOptimize(10, 60, 1);
_macdFastPeriod = Param(nameof(MacdFastPeriod), 12)
.SetGreaterThanZero()
.SetDisplay("MACD Fast", "MACD fast EMA period", "Indicators")
.SetOptimize(5, 20, 1);
_macdSlowPeriod = Param(nameof(MacdSlowPeriod), 24)
.SetGreaterThanZero()
.SetDisplay("MACD Slow", "MACD slow EMA period", "Indicators")
.SetOptimize(18, 40, 1);
_macdSignalPeriod = Param(nameof(MacdSignalPeriod), 9)
.SetGreaterThanZero()
.SetDisplay("MACD Signal", "MACD signal EMA period", "Indicators")
.SetOptimize(3, 15, 1);
_histogramThreshold = Param(nameof(HistogramThreshold), 0m)
.SetDisplay("Histogram Threshold", "Required MACD histogram magnitude", "Logic");
_trailingPeriod = Param(nameof(TrailingPeriod), 12)
.SetGreaterThanZero()
.SetDisplay("Trailing SMA", "Trailing SMA period", "Logic")
.SetOptimize(6, 30, 1);
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fastMa = new SimpleMovingAverage { Length = FastMaPeriod };
var slowMa = new SimpleMovingAverage { Length = SlowMaPeriod };
var trailingMa = new SimpleMovingAverage { Length = TrailingPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fastMa, slowMa, trailingMa, ProcessCandle)
.Start();
StartProtection(
takeProfit: new Unit(2, UnitTypes.Percent),
stopLoss: new Unit(1, UnitTypes.Percent));
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, fastMa);
DrawIndicator(area, slowMa);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal fastMa, decimal slowMa, decimal trailingMa)
{
if (candle.State != CandleStates.Finished)
return;
if (Position != 0)
return;
var bullishTrend = fastMa > slowMa;
var bearishTrend = fastMa < slowMa;
var price = candle.ClosePrice;
if (bullishTrend && price > trailingMa)
BuyMarket();
else if (bearishTrend && price < trailingMa)
SellMarket();
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates, Unit, UnitTypes
from StockSharp.Algo.Indicators import SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
class supermacbot_by_the_guardian_forex_tv_strategy(Strategy):
def __init__(self):
super(supermacbot_by_the_guardian_forex_tv_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Type of candles to process", "General")
self._fast_ma_period = self.Param("FastMaPeriod", 12) \
.SetGreaterThanZero() \
.SetDisplay("Fast SMA", "Fast SMA period", "Indicators")
self._slow_ma_period = self.Param("SlowMaPeriod", 26) \
.SetGreaterThanZero() \
.SetDisplay("Slow SMA", "Slow SMA period", "Indicators")
self._macd_fast_period = self.Param("MacdFastPeriod", 12) \
.SetGreaterThanZero() \
.SetDisplay("MACD Fast", "MACD fast EMA period", "Indicators")
self._macd_slow_period = self.Param("MacdSlowPeriod", 24) \
.SetGreaterThanZero() \
.SetDisplay("MACD Slow", "MACD slow EMA period", "Indicators")
self._macd_signal_period = self.Param("MacdSignalPeriod", 9) \
.SetGreaterThanZero() \
.SetDisplay("MACD Signal", "MACD signal EMA period", "Indicators")
self._histogram_threshold = self.Param("HistogramThreshold", 0.0) \
.SetDisplay("Histogram Threshold", "Required MACD histogram magnitude", "Logic")
self._trailing_period = self.Param("TrailingPeriod", 12) \
.SetGreaterThanZero() \
.SetDisplay("Trailing SMA", "Trailing SMA period", "Logic")
self._is_histogram_initialized = False
self._prev_histogram = 0.0
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def FastMaPeriod(self):
return self._fast_ma_period.Value
@FastMaPeriod.setter
def FastMaPeriod(self, value):
self._fast_ma_period.Value = value
@property
def SlowMaPeriod(self):
return self._slow_ma_period.Value
@SlowMaPeriod.setter
def SlowMaPeriod(self, value):
self._slow_ma_period.Value = value
@property
def TrailingPeriod(self):
return self._trailing_period.Value
@TrailingPeriod.setter
def TrailingPeriod(self, value):
self._trailing_period.Value = value
def OnReseted(self):
super(supermacbot_by_the_guardian_forex_tv_strategy, self).OnReseted()
self._is_histogram_initialized = False
self._prev_histogram = 0.0
def OnStarted2(self, time):
super(supermacbot_by_the_guardian_forex_tv_strategy, self).OnStarted2(time)
fast_ma = SimpleMovingAverage()
fast_ma.Length = self.FastMaPeriod
slow_ma = SimpleMovingAverage()
slow_ma.Length = self.SlowMaPeriod
trailing_ma = SimpleMovingAverage()
trailing_ma.Length = self.TrailingPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(fast_ma, slow_ma, trailing_ma, self._process_candle).Start()
self.StartProtection(
takeProfit=Unit(2, UnitTypes.Percent),
stopLoss=Unit(1, UnitTypes.Percent))
def _process_candle(self, candle, fast_ma, slow_ma, trailing_ma):
if candle.State != CandleStates.Finished:
return
if self.Position != 0:
return
fma = float(fast_ma)
sma_val = float(slow_ma)
tma = float(trailing_ma)
price = float(candle.ClosePrice)
bullish_trend = fma > sma_val
bearish_trend = fma < sma_val
if bullish_trend and price > tma:
self.BuyMarket()
elif bearish_trend and price < tma:
self.SellMarket()
def CreateClone(self):
return supermacbot_by_the_guardian_forex_tv_strategy()