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()