Diese Strategie repliziert den Expert Advisor "MA Cross" aus MetaTrader 5 (Datei MA Cross.mq5) innerhalb des StockSharp-Frameworks. Das System beobachtet zwei konfigurierbare gleitende Durchschnitte und gibt Marktorders aus, wenn der schnelle Durchschnitt den langsamen kreuzt. Die Implementierung behält das ursprüngliche Maß an Flexibilität bei, indem sie die Methode des gleitenden Durchschnitts, den angewandten Preis und den Indikator-Shift für beide Kurven zugänglich macht.
Strategielogik
Abonnieren eines einzelnen Kerzenstroms, der durch den Parameter CandleType definiert wird.
Berechnung des schnellen und langsamen gleitenden Durchschnitts auf jeder abgeschlossenen Kerze. Jeder gleitende Durchschnitt kann eine von vier Methoden verwenden (einfach, exponentiell, geglättet oder linear gewichtet) und liest einen der MetaTrader-Stil angewandten Preise (Schlusskurs, Eröffnung, Hoch, Tief, Median, typisch oder gewichtet).
Speicherung der jüngsten Indikatorwerte unter Berücksichtigung des konfigurierten Shifts, sodass Kreuzungstests auf Werten früherer Bars durchgeführt werden können, wenn erforderlich.
Erkennung eines bullischen Kreuzungspunkts, wenn sich der schnelle Durchschnitt von unter den geshifteten langsamen Durchschnitt nach oben bewegt. Erkennung eines bearischen Kreuzungspunkts beim umgekehrten Bewegung.
Ausgabe von Marktorders nur nachdem beide Indikatoren vollständig gebildet sind und die Strategie online ist. Long-Signale schließen eine bestehende Short-Position und öffnen eine Long-Position von OrderVolume. Short-Signale schließen jede bestehende Long-Position und öffnen eine Short-Position derselben Größe.
Die Strategie arbeitet ausschließlich mit abgeschlossenen Kerzen und inspiziert niemals unfertige Daten. Die Schutzlogik wird durch StartProtection() aktiviert, um sicherzustellen, dass StockSharp die offene Position auf abnormale Bedingungen überwacht.
Parameter
Name
Standard
Beschreibung
FastPeriod
3
Periode des schnellen gleitenden Durchschnitts.
SlowPeriod
13
Periode des langsamen gleitenden Durchschnitts.
FastMethod
Simple
Gleitender Durchschnitt-Methode für die schnelle Linie (einfach, exponentiell, geglättet oder linear gewichtet).
SlowMethod
LinearWeighted
Methode des gleitenden Durchschnitts für die langsame Linie.
FastPriceType
Close
Angewandter Preis für die schnelle Linie (Schluss, Eröffnung, Hoch, Tief, Median, typisch, gewichtet).
SlowPriceType
Median
Angewandter Preis für die langsame Linie.
FastShift
0
Anzahl abgeschlossener Bars zum Verschieben des schnellen Durchschnitts nach links.
SlowShift
0
Anzahl abgeschlossener Bars zum Verschieben des langsamen Durchschnitts nach links.
OrderVolume
1
Volumen für jede Marktorder.
CandleType
1-Minuten-Zeitrahmen
Von der Strategie verarbeitete Kerzendatenserie.
Alle Parameter können innerhalb von StockSharp optimiert werden, da der Konstruktor sie mit StrategyParam-Helfern registriert.
Handelsregeln
Long-Einstieg: Ausgelöst, wenn der schnelle Durchschnitt den langsamen Durchschnitt gemäß den shift-bereinigten Werten von unten nach oben kreuzt. Wenn die Strategie bereits short ist, sendet sie eine einzelne Kauf-Marktorder, die die Short-Exposition schließt und eine neue Long-Position eröffnet. Wenn keine Position vorhanden ist, kauft sie genau OrderVolume.
Short-Einstieg: Ausgelöst, wenn der schnelle Durchschnitt den langsamen von oben kreuzt. Bestehende Long-Exposition wird über eine einzelne Verkaufs-Marktorder umgekehrt; andernfalls eröffnet die Strategie einen neuen Short-Trade mit OrderVolume.
Kein zusätzliches Skalieren: Einmal positioniert werden gleichgerichtete Signale ignoriert, bis die entgegengesetzte Kreuzung erfolgt.
Ausführungsstil: Orders werden mit BuyMarket oder SellMarket gesendet. Die Strategie konfiguriert keine Stop-Loss- oder Take-Profit-Niveaus; Risikomanagement kann bei Bedarf durch andere StockSharp-Module ergänzt werden.
Konvertierungshinweise
Die Indikatorerstellung spiegelt die MetaTrader iMA-Aufrufe wider. Die benutzerdefinierte MovingAverageMethods-Enumeration ordnet MODE_SMA, MODE_EMA, MODE_SMMA und MODE_LWMA den StockSharp-Klassen SimpleMovingAverage, ExponentialMovingAverage, SmoothedMovingAverage und WeightedMovingAverage zu.
Die Behandlung des angewandten Preises reproduziert die MetaTrader ENUM_APPLIED_PRICE-Optionen, indem Median-, typische und gewichtete Preise direkt aus den Kerzendaten berechnet werden.
Die Shift-Parameter verwenden die ursprüngliche Logik wieder: Die Strategie puffert Indikatorwerte und ruft die Einstiegs- und Ausstiegsvergleiche aus früheren Bars ab, wenn FastShift oder SlowShift positiv sind.
Die Positionsverwaltungslogik entspricht dem ursprünglichen Ansatz, bei dem entgegengesetzte Signale zuerst die bestehende Position schließen und dann eine Position in die neue Richtung auf derselben Bar eröffnen.
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>
/// Moving average crossover strategy converted from MetaTrader 5 script.
/// Implements dual SMA crossover signals.
/// </summary>
public class MaCrossStrategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFast;
private decimal _prevSlow;
private bool _hasPrevValues;
/// <summary>
/// Fast moving average period.
/// </summary>
public int FastPeriod
{
get => _fastPeriod.Value;
set => _fastPeriod.Value = value;
}
/// <summary>
/// Slow moving average period.
/// </summary>
public int SlowPeriod
{
get => _slowPeriod.Value;
set => _slowPeriod.Value = value;
}
/// <summary>
/// Candle type used for calculations.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Initializes strategy parameters.
/// </summary>
public MaCrossStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 5)
.SetGreaterThanZero()
.SetDisplay("Fast Period", "Period for the fast moving average", "Moving Averages")
.SetOptimize(2, 20, 1);
_slowPeriod = Param(nameof(SlowPeriod), 21)
.SetGreaterThanZero()
.SetDisplay("Slow Period", "Period for the slow moving average", "Moving Averages")
.SetOptimize(5, 60, 1);
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(15).TimeFrame())
.SetDisplay("Candle Type", "Type of candles for calculations", "Data");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = 0m;
_prevSlow = 0m;
_hasPrevValues = false;
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrevValues = false;
var fastEma = new ExponentialMovingAverage { Length = FastPeriod };
var slowEma = new ExponentialMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fastEma, slowEma, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, fastEma);
DrawIndicator(area, slowEma);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (_hasPrevValues)
{
var crossUp = _prevFast <= _prevSlow && fast > slow;
var crossDown = _prevFast >= _prevSlow && fast < slow;
if (crossUp && Position <= 0)
{
BuyMarket(Volume + Math.Abs(Position));
}
else if (crossDown && Position >= 0)
{
SellMarket(Volume + Math.Abs(Position));
}
}
_prevFast = fast;
_prevSlow = slow;
_hasPrevValues = true;
}
}
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 ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class ma_cross_strategy(Strategy):
def __init__(self):
super(ma_cross_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 5)
self._slow_period = self.Param("SlowPeriod", 21)
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(15)))
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev_values = False
@property
def FastPeriod(self):
return self._fast_period.Value
@FastPeriod.setter
def FastPeriod(self, value):
self._fast_period.Value = value
@property
def SlowPeriod(self):
return self._slow_period.Value
@SlowPeriod.setter
def SlowPeriod(self, value):
self._slow_period.Value = value
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
def OnStarted2(self, time):
super(ma_cross_strategy, self).OnStarted2(time)
self._has_prev_values = False
self._prev_fast = 0.0
self._prev_slow = 0.0
fast_ema = ExponentialMovingAverage()
fast_ema.Length = self.FastPeriod
slow_ema = ExponentialMovingAverage()
slow_ema.Length = self.SlowPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(fast_ema, slow_ema, self.ProcessCandle).Start()
def ProcessCandle(self, candle, fast_val, slow_val):
if candle.State != CandleStates.Finished:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
fast = float(fast_val)
slow = float(slow_val)
if self._has_prev_values:
cross_up = self._prev_fast <= self._prev_slow and fast > slow
cross_down = self._prev_fast >= self._prev_slow and fast < slow
if cross_up and self.Position <= 0:
self.BuyMarket()
elif cross_down and self.Position >= 0:
self.SellMarket()
self._prev_fast = fast
self._prev_slow = slow
self._has_prev_values = True
def OnReseted(self):
super(ma_cross_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev_values = False
def CreateClone(self):
return ma_cross_strategy()