Diese Strategie repliziert den MetaTrader-Expertenberater, der den Übergang zwischen einem schnellen EMA(6) und einem langsamen EMA(12) tauscht. Es abonniert standardmäßig stündliche Kerzen, berechnet beide gleitenden Durchschnitte und wartet auf einen bestätigten Crossover am Ende einer Kerze, bevor es handelt.
Handelslogik
Eintrag:
Ein bullisches Signal erscheint, wenn EMA(6) EMA(12) überschreitet. Die Strategie eröffnet eine Long-Position, wenn keine aktive Position vorhanden ist.
Ein rückläufiges Signal erscheint, wenn EMA(6) unter EMA(12) fällt. Die Strategie eröffnet eine Short-Position, wenn keine aktive Position vorhanden ist.
Ausgang:
Wenn UseCloseSignals aktiviert ist (Standardverhalten), schließt die Strategie die aktuelle Position, sobald ein entgegengesetzter Crossover erkannt wird. Es wartet auf den nächsten Crossover, bevor es einen neuen Trade eröffnet, und spiegelt damit den ursprünglichen Expert Advisor wider.
Optionale Take-Profit- und Trailing-Stop-Schutzmaßnahmen werden über den integrierten StartProtection-Helper von StockSharp verwaltet.
Positionsgröße:
Bestellungen verwenden den Parameter OrderVolume (Standard 1 Los). Vor dem Versenden von Bestellungen werden die Volumina an die Sicherheitseinstellungen angepasst.
Risikomanagement
Trailing Stop: Wandelt die ursprüngliche „Punkte“-Einstellung in Preisschritte um. Wenn der Stop größer als Null ist, bewegt er sich automatisch in die Richtung des Handels, sobald die Position profitabel wird.
Take Profit: Ausgedrückt in Preisschritten. Zum Deaktivieren auf Null setzen.
Bei der Strategie werden niemals Durchschnittswerte nach unten oder Pyramiden gebildet. Es ist nur eine Position pro Symbol zulässig.
Parameter
Parameter
Beschreibung
CandleType
Zeitrahmen, der zum Aufbau von Kerzen und EMAs verwendet wird. Der Standardwert ist 1 Stunde.
OrderVolume
Handelsgröße in Losen.
ShortEmaLength
Zeitraum für das Fasten EMA (Standard 6).
LongEmaLength
Zeitraum für den langsamen EMA (Standard 12).
UseCloseSignals
Schließen Sie die aktuelle Position an einer gegenüberliegenden Kreuzung (Standard: aktiviert).
TrailingStopSteps
Nachlaufdistanz in Preisschritten. Null deaktiviert das Nachziehen.
TakeProfitSteps
Nehmen Sie die Gewinndistanz in Preisschritten. Null deaktiviert es.
Notizen
Signale werden nur bei fertigen Kerzen verarbeitet, um Intrabar-Rauschen zu vermeiden.
Die vorherigen EMA-Werte werden jedes Mal zurückgesetzt, wenn die Position auf Null zurückkehrt, um eine saubere Erkennung für den nächsten Crossover sicherzustellen.
Alle Codekommentare sind auf Englisch verfasst und beim Einrücken werden Tabulatoren gemäß den Projektrichtlinien verwendet.
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>
/// EMA 6/12 crossover strategy.
/// Buys when EMA(6) crosses above EMA(12).
/// Sells when EMA(6) crosses below EMA(12).
/// </summary>
public class Ema612Strategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFast;
private decimal _prevSlow;
private bool _hasPrev;
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public Ema612Strategy()
{
_fastPeriod = Param(nameof(FastPeriod), 6)
.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 12)
.SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
protected override void OnReseted() { base.OnReseted(); _prevFast = 0m; _prevSlow = 0m; _hasPrev = false; }
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var fast = new ExponentialMovingAverage { Length = FastPeriod };
var slow = new ExponentialMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fast, slow, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
{
if (candle.State != CandleStates.Finished)
return;
if (!_hasPrev)
{
_prevFast = fast;
_prevSlow = slow;
_hasPrev = true;
return;
}
if (_prevFast <= _prevSlow && fast > slow && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
else if (_prevFast >= _prevSlow && fast < slow && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevFast = fast;
_prevSlow = slow;
}
}
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
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class ema612_strategy(Strategy):
def __init__(self):
super(ema612_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 6).SetDisplay("Fast EMA", "Fast EMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 12).SetDisplay("Slow EMA", "Slow EMA 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_slow = 0.0
self._has_prev = False
@property
def fast_period(self): return self._fast_period.Value
@property
def slow_period(self): return self._slow_period.Value
@property
def candle_type(self): return self._candle_type.Value
def OnReseted(self):
super(ema612_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(ema612_strategy, self).OnStarted2(time)
self._has_prev = False
fast = ExponentialMovingAverage()
fast.Length = self.fast_period
slow = ExponentialMovingAverage()
slow.Length = self.slow_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(fast, slow, self.process_candle).Start()
def process_candle(self, candle, fast, slow):
if candle.State != CandleStates.Finished: return
f = float(fast); s = float(slow)
if not self._has_prev:
self._prev_fast = f; self._prev_slow = s; self._has_prev = True; return
if self._prev_fast <= self._prev_slow and f > s and self.Position <= 0:
if self.Position < 0: self.BuyMarket()
self.BuyMarket()
elif self._prev_fast >= self._prev_slow and f < s and self.Position >= 0:
if self.Position > 0: self.SellMarket()
self.SellMarket()
self._prev_fast = f; self._prev_slow = s
def CreateClone(self): return ema612_strategy()