Die Triple-SMA-Crossover-Strategie repliziert den ursprünglichen MQL-Expertenberater 3sma.mq4. Das System analysiert drei einfache gleitende Durchschnitte (SMA), die auf der Grundlage des Schlusskurses berechnet werden, und handelt, wenn der kurzfristige Trend mit den mittel- und langfristigen Durchschnittswerten übereinstimmt. Bei der Konvertierung bleiben die ursprünglichen Handelsregeln erhalten, während sie gleichzeitig an die übergeordnete Strategie StockSharp API angepasst werden.
Handelslogik
Berechnen Sie drei SMAs mit konfigurierbaren Zeiträumen.
Verlassen Sie bestehende Long-Positionen, wenn der schnelle SMA unter den mittleren SMA fällt.
Bestehende Short-Positionen verlassen, wenn der schnelle SMA über den mittleren SMA steigt.
Geben Sie eine neue Long-Position ein, wenn:
Schnell SMA liegt mindestens um die konfigurierte Spanne über dem Mittelwert SMA.
Der mittlere SMA liegt mindestens um die konfigurierte Spanne über dem langsamen SMA.
Derzeit ist keine Long-Position offen.
Geben Sie eine neue Short-Position ein, wenn:
Schnell SMA liegt mindestens um die konfigurierte Spanne unter dem Mittelwert SMA.
Der mittlere SMA liegt mindestens um die konfigurierte Spanne unter dem langsamen SMA.
Derzeit ist keine Short-Position offen.
Parameter
Kerzentyp – Primärer Zeitrahmen, der zur Berechnung der gleitenden Durchschnitte verwendet wird.
Schnelle SMA-Länge – Zeitraum für die schnelle SMA (MQL-Eingabe SMA1).
Medium SMA Länge – Zeitraum für das Medium SMA (MQL Eingabe SMA2).
Langsame SMA-Länge – Zeitraum für die langsame SMA (MQL-Eingabe SMA3).
SMA Spread Steps – Zusätzlicher Filter, der erfordert, dass SMAs um eine Reihe von Preisschritten divergieren (MQL Eingabe SMAspread).
Handelsvolumen – Auftragsvolumen, das beim Öffnen von Positionen verwendet wird (MQL Eingabe lots).
Notizen
Die Stop-Loss-Behandlung der Version MQL wird weggelassen, da sie im Quellskript deaktiviert wurde.
Bei allen Ausstiegen handelt es sich um Marktaufträge, die dem unkomplizierten Verhalten des ursprünglichen Experten entsprechen.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Triple SMA crossover strategy.
/// Goes long when fast > medium > slow, short when fast less than medium less than slow.
/// Exits when fast crosses medium in opposite direction.
/// </summary>
public class TripleSmaCrossoverStrategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _mediumPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFast;
private decimal _prevMed;
private bool _hasPrev;
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int MediumPeriod { get => _mediumPeriod.Value; set => _mediumPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public TripleSmaCrossoverStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 5)
.SetDisplay("Fast SMA", "Fast SMA period", "Indicators");
_mediumPeriod = Param(nameof(MediumPeriod), 10)
.SetDisplay("Medium SMA", "Medium SMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 20)
.SetDisplay("Slow SMA", "Slow SMA period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = 0m;
_prevMed = 0m;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var fast = new SimpleMovingAverage { Length = FastPeriod };
var medium = new SimpleMovingAverage { Length = MediumPeriod };
var slow = new SimpleMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fast, medium, slow, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal med, decimal slow)
{
if (candle.State != CandleStates.Finished)
return;
if (!_hasPrev)
{
_prevFast = fast;
_prevMed = med;
_hasPrev = true;
return;
}
// Bullish alignment: fast > medium > slow
if (fast > med && med > slow && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// Bearish alignment: fast < medium < slow
else if (fast < med && med < slow && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
// Exit long when fast crosses below medium
else if (Position > 0 && _prevFast >= _prevMed && fast < med)
{
SellMarket();
}
// Exit short when fast crosses above medium
else if (Position < 0 && _prevFast <= _prevMed && fast > med)
{
BuyMarket();
}
_prevFast = fast;
_prevMed = med;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
class triple_sma_crossover_strategy(Strategy):
"""Triple SMA crossover strategy.
Goes long when fast > medium > slow, short when fast < medium < slow.
Exits when fast crosses medium in opposite direction."""
def __init__(self):
super(triple_sma_crossover_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 5) \
.SetDisplay("Fast SMA", "Fast SMA period", "Indicators")
self._medium_period = self.Param("MediumPeriod", 10) \
.SetDisplay("Medium SMA", "Medium SMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 20) \
.SetDisplay("Slow SMA", "Slow SMA period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_fast = 0.0
self._prev_med = 0.0
self._has_prev = False
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def FastPeriod(self):
return self._fast_period.Value
@property
def MediumPeriod(self):
return self._medium_period.Value
@property
def SlowPeriod(self):
return self._slow_period.Value
def OnReseted(self):
super(triple_sma_crossover_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_med = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(triple_sma_crossover_strategy, self).OnStarted2(time)
self._has_prev = False
fast = SimpleMovingAverage()
fast.Length = self.FastPeriod
medium = SimpleMovingAverage()
medium.Length = self.MediumPeriod
slow = SimpleMovingAverage()
slow.Length = self.SlowPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(fast, medium, slow, self._process_candle).Start()
def _process_candle(self, candle, fast, med, slow):
if candle.State != CandleStates.Finished:
return
fast_val = float(fast)
med_val = float(med)
slow_val = float(slow)
if not self._has_prev:
self._prev_fast = fast_val
self._prev_med = med_val
self._has_prev = True
return
# Bullish alignment: fast > medium > slow
if fast_val > med_val and med_val > slow_val and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# Bearish alignment: fast < medium < slow
elif fast_val < med_val and med_val < slow_val and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
# Exit long when fast crosses below medium
elif self.Position > 0 and self._prev_fast >= self._prev_med and fast_val < med_val:
self.SellMarket()
# Exit short when fast crosses above medium
elif self.Position < 0 and self._prev_fast <= self._prev_med and fast_val > med_val:
self.BuyMarket()
self._prev_fast = fast_val
self._prev_med = med_val
def CreateClone(self):
return triple_sma_crossover_strategy()