Diese Strategie ist eine StockSharp-Portierung des MetaTrader 4 „CrossMA“-Expertenberaters. Es handelt den Schnittpunkt zwischen zwei einfachen gleitenden Durchschnitten und schützt jeden Handel mit einem auf dem Average True Range (ATR) basierenden Stop-Loss. Zusätzlich zur ursprünglichen Logik erfasst die Strategie detaillierte Informationsnachrichten, anstatt E-Mails zu versenden.
Handelslogik
Die Strategie abonniert die konfigurierte Kerzenserie und berechnet einen schnellen und einen langsamen einfachen gleitenden Durchschnitt zusammen mit einem ATR-Indikator.
Wenn der schnelle SMA den langsamen SMA überschreitet, wird jede Short-Position geschlossen und eine Long-Position eröffnet. Der Stop-Loss wird einen ATR unter dem Einstiegspreis platziert.
Wenn der schnelle SMA den langsamen SMA unterschreitet, wird jede Long-Position geschlossen und eine Short-Position eröffnet. Der Stop-Loss wird einen ATR über dem Einstiegspreis platziert.
Bei jeder fertigen Kerze wird der Stop-Preis überprüft. Wenn der Preis das Stop-Level erreicht, wird die Position sofort zum Marktwert geschlossen.
Risikomanagement
Die Positionsgröße wird aus dem Kontokapital und dem Parameter Maximum Risk berechnet. Wenn keine Aktieninformationen verfügbar sind, fällt die Strategie auf den Wert Base Volume zurück.
Nach zwei oder mehr aufeinanderfolgenden Verlustgeschäften wird die Positionsgröße proportional zum Decrease Factor reduziert, wodurch das ursprüngliche MetaTrader-Verhalten reproduziert wird.
Alle Volumina werden auf den Sicherheitsvolumenschritt normalisiert, um gültige Bestellgrößen sicherzustellen.
Benachrichtigungen
Anstatt E-Mails zu versenden, schreibt die Strategie klare Protokollnachrichten, wann immer Aufträge durch Signale oder Stopps geöffnet oder geschlossen werden. Die Protokollierung kann über den Parameter Enable Notifications deaktiviert werden.
Parameter
Kerzentyp – Kerzentyp, der für Indikatorberechnungen verwendet wird.
Fast SMA Period – Periode des schnellen gleitenden Durchschnitts (Standard 4).
Slow SMA Period – Periode des langsamen gleitenden Durchschnitts (Standard 12).
ATR Zeitraum – Anzahl der Kerzen, die von ATR für die Stop-Berechnung verwendet werden (Standard 6).
Basisvolumen – Mindesthandelsvolumen, wenn eine risikobasierte Größenbestimmung nicht verfügbar ist (Standard 0,1).
Maximales Risiko – Anteil des Eigenkapitals, der jedem Trade zugewiesen wird (Standard 0,02).
Verringerungsfaktor – reduziert die Positionsgröße nach verlorenen Trades (Standard 3).
Benachrichtigungen aktivieren – ermöglicht die Protokollierung von Handelsaktionen.
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>
/// CrossMA strategy - fast/slow SMA crossover with ATR volatility filter.
/// Buys when fast SMA crosses above slow SMA.
/// Sells when fast SMA crosses below slow SMA.
/// </summary>
public class CrossMaAtrNotificationStrategy : 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 CrossMaAtrNotificationStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 10)
.SetDisplay("Fast SMA", "Fast SMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 40)
.SetDisplay("Slow SMA", "Slow SMA 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 SimpleMovingAverage { Length = FastPeriod };
var slow = new SimpleMovingAverage { 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 SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
class cross_ma_atr_notification_strategy(Strategy):
def __init__(self):
super(cross_ma_atr_notification_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 10).SetDisplay("Fast SMA", "Fast SMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 40).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_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(cross_ma_atr_notification_strategy, self).OnReseted()
self._prev_fast = 0.0; self._prev_slow = 0.0; self._has_prev = False
def OnStarted2(self, time):
super(cross_ma_atr_notification_strategy, self).OnStarted2(time)
self._has_prev = False
fast = SimpleMovingAverage(); fast.Length = self.fast_period
slow = SimpleMovingAverage(); slow.Length = self.slow_period
sub = self.SubscribeCandles(self.candle_type)
sub.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 cross_ma_atr_notification_strategy()