Diese Strategie ist eine StockSharp-Nachbildung des MetaTrader 5-Expert-Advisors XIT_THREE_MA_CROSS.mq5. Sie richtet drei gleitende Durchschnitte aus, prüft die MACD-Momentum-Trennung und dimensioniert Positionen aus ATR-basierten Risikolimiten. Die Methode ist Trendfolge mit Momentum-Bestätigung und zielt auf mittelfristige Swings bei liquiden Währungspaaren oder Indizes.
Überblick
Marktregime: Funktioniert am besten bei Instrumenten, die auf dem ausgewählten Zeitrahmen mehrere Kerzen lang trends.
Indikatoren:
Langsame, mittlere und schnelle gleitende Durchschnitte (Typ vom Benutzer wählbar), auf dem Handelszeitrahmen bewertet.
MACD (EMA-basiert) für Momentum-Richtung und Abstand zwischen MACD- und Signallinie.
Zwei ATR-Berechnungen (gleiche Länge, unabhängige Zeitrahmen), die zur Projektion von Stop-Loss- und Take-Profit-Abständen verwendet werden.
Order-Richtung: Bidirektional. Die Engine kann sowohl Long- als auch Short-Trades öffnen.
Positionierung: Berechnet aus dem konfigurierten Risikoprozentsatz und dem ATR-basierten Stop-Abstand. Wenn die Instrument-Metadaten unvollständig sind, fällt die Strategie auf die Standard-Volume-Eigenschaft zurück.
Handelslogik
Long-Einstieg
Eine Long-Position wird geöffnet, wenn alle nachstehenden Bedingungen auf einer abgeschlossenen Kerze zutreffen:
MACD-Linie steigt im Vergleich zum vorherigen Balken (MACD[t] > MACD[t-1]).
MACD-Signallinie steigt im Vergleich zum vorherigen Balken.
Die MACD-Linie übersteigt die Signallinie um mindestens MacdTriggerPoints * PriceStep.
Mittlerer gleitender Durchschnitt steigt gegenüber dem vorherigen Wert.
Schneller gleitender Durchschnitt steigt gegenüber dem vorherigen Wert.
Mittlerer MA liegt über dem langsamen MA.
Schneller MA liegt über dem mittleren MA.
Beide ATR-Werte sind verfügbar, um Stop- und Zielabstände zu definieren.
Short-Einstieg
Die Short-seitigen Regeln spiegeln das Long-Setup mit invertierten Vergleichen:
MACD-Linie sinkt im Vergleich zum vorherigen Balken.
MACD-Signallinie sinkt im Vergleich zum vorherigen Balken.
Die Signallinie ist um mindestens MacdTriggerPoints * PriceStep größer als die MACD-Linie.
Mittlerer MA fällt im Vergleich zur vorherigen Kerze.
Schneller MA fällt im Vergleich zur vorherigen Kerze.
Mittlerer MA liegt unter dem langsamen MA.
Schneller MA liegt unter dem mittleren MA.
Beide ATR-Serien haben einen fertigen Wert geliefert.
Ausstiegslogik
Long-Positionen schließen, wenn der schnelle MA unter den mittleren MA fällt, oder der Preis die ATR-basierten Stop/Take-Profit-Niveaus erreicht.
Short-Positionen schließen, wenn der schnelle MA über den mittleren MA kreuzt, oder die ATR-Limits berührt werden.
Nach dem Schließen einer Position wartet der Algorithmus auf die nächste Kerze, bevor er neue Einstiege bewertet, was dem ursprünglichen EA-Verhalten entspricht.
Risikomanagement
Stop Loss: Abstand entspricht dem letzten ATR-Wert von AtrStopCandleType. Für Longs ist der Stop-Preis Entry - ATR, für Shorts ist er Entry + ATR.
Take Profit: Abstand entspricht dem ATR-Wert von AtrTakeCandleType. Ziele werden relativ zum Einstiegspreis gespiegelt.
Risikoprozent: Die Strategie schätzt den monetären Verlust pro Einheit aus dem Stop-Abstand. Wenn PriceStep und PriceStepCost bekannt sind, verwendet das Risiko pro Kontrakt die Tick-Bewertung. Andernfalls wird der rohe Preisabstand verwendet. Positionsgröße ist RiskPercent% des aktuellen Portfolio-Werts geteilt durch das Risiko pro Einheit, abgerundet auf das nächste VolumeStep.
Parameter
Name
Beschreibung
Standard
CandleType
Primärer Zeitrahmen für Berechnungen von gleitenden Durchschnitten und MACD.
Mindestabstand zwischen MACD und seiner Signallinie, gemessen in Instrument-Punkten. Konvertiert über PriceStep.
7
AtrLength
Periode für beide ATR-Indikatoren.
14
AtrTakeCandleType / AtrStopCandleType
Zeitrahmen für Take-Profit- und Stop-Loss-ATR-Serien.
4-Stunden-Kerzen
RiskPercent
Prozent des aktuellen Portfolio-Werts, der auf jeden Trade riskiert wird.
10%
Verwendungshinweise
Hängen Sie die Strategie an ein Wertpapier mit genauen PriceStep, PriceStepCost und VolumeStep an, um präzise Positionierung zu erhalten.
Stellen Sie sicher, dass historische Daten für jeden abonnierten Zeitrahmen (CandleType, AtrTakeCandleType, AtrStopCandleType) verfügbar sind. Fehlende ATR-Werte verzögern Einstiege.
Der Algorithmus arbeitet auf vollständig geschlossenen Kerzen und ignoriert intrabar-Schwankungen, was der ursprünglichen MetaTrader-Logik des Abrufens aktueller und vorheriger Indikator-Puffer entspricht.
Ändern Sie die MA-Typen, wenn der Zielmarkt glattere oder schnellere Filter bevorzugt.
Dateien
CS/XitThreeMaCrossStrategy.cs – C#-Implementierung mit High-Level-StockSharp-API, einschließlich ATR-Abonnements und Risiko-Sizing.
README_ru.md – Russische Beschreibung der Strategie.
README_zh.md – Chinesische Übersetzung der Dokumentation.
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 MA alignment strategy.
/// </summary>
public class XitThreeMaCrossStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _midPeriod;
private readonly StrategyParam<int> _slowPeriod;
private decimal? _prevFast;
private decimal? _prevMid;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int FastPeriod
{
get => _fastPeriod.Value;
set => _fastPeriod.Value = value;
}
public int MidPeriod
{
get => _midPeriod.Value;
set => _midPeriod.Value = value;
}
public int SlowPeriod
{
get => _slowPeriod.Value;
set => _slowPeriod.Value = value;
}
public XitThreeMaCrossStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Timeframe", "General");
_fastPeriod = Param(nameof(FastPeriod), 5)
.SetGreaterThanZero()
.SetDisplay("Fast Period", "Fast MA period", "Indicators");
_midPeriod = Param(nameof(MidPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("Mid Period", "Medium MA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 50)
.SetGreaterThanZero()
.SetDisplay("Slow Period", "Slow MA (trend filter)", "Indicators");
Volume = 0.1m;
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = null;
_prevMid = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevFast = null;
_prevMid = null;
var fast = new SimpleMovingAverage { Length = FastPeriod };
var mid = new SimpleMovingAverage { Length = MidPeriod };
var slow = new SimpleMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fast, mid, slow, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, fast);
DrawIndicator(area, mid);
DrawIndicator(area, slow);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal fastVal, decimal midVal, decimal slowVal)
{
if (candle.State != CandleStates.Finished)
return;
if (_prevFast == null || _prevMid == null)
{
_prevFast = fastVal;
_prevMid = midVal;
return;
}
var buySignal = fastVal > midVal && midVal > slowVal;
var sellSignal = fastVal < midVal && midVal < slowVal;
if (buySignal && Position <= 0)
{
if (Position < 0)
BuyMarket(Math.Abs(Position));
BuyMarket(Volume);
}
else if (sellSignal && Position >= 0)
{
if (Position > 0)
SellMarket(Position);
SellMarket(Volume);
}
_prevFast = fastVal;
_prevMid = midVal;
}
}
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 xit_three_ma_cross_strategy(Strategy):
def __init__(self):
super(xit_three_ma_cross_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._fast_period = self.Param("FastPeriod", 5) \
.SetDisplay("Fast Period", "Fast MA period", "Indicators")
self._mid_period = self.Param("MidPeriod", 20) \
.SetDisplay("Mid Period", "Medium MA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 50) \
.SetDisplay("Slow Period", "Slow MA (trend filter)", "Indicators")
self._prev_fast = None
self._prev_mid = None
@property
def CandleType(self):
return self._candle_type.Value
@property
def FastPeriod(self):
return self._fast_period.Value
@property
def MidPeriod(self):
return self._mid_period.Value
@property
def SlowPeriod(self):
return self._slow_period.Value
def OnReseted(self):
super(xit_three_ma_cross_strategy, self).OnReseted()
self._prev_fast = None
self._prev_mid = None
def OnStarted2(self, time):
super(xit_three_ma_cross_strategy, self).OnStarted2(time)
self._prev_fast = None
self._prev_mid = None
fast = SimpleMovingAverage()
fast.Length = self.FastPeriod
mid = SimpleMovingAverage()
mid.Length = self.MidPeriod
slow = SimpleMovingAverage()
slow.Length = self.SlowPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(fast, mid, slow, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, fast)
self.DrawIndicator(area, mid)
self.DrawIndicator(area, slow)
self.DrawOwnTrades(area)
def _on_process(self, candle, fast_value, mid_value, slow_value):
if candle.State != CandleStates.Finished:
return
fv = float(fast_value)
mv = float(mid_value)
sv = float(slow_value)
if self._prev_fast is None or self._prev_mid is None:
self._prev_fast = fv
self._prev_mid = mv
return
buy_signal = fv > mv and mv > sv
sell_signal = fv < mv and mv < sv
if buy_signal and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif sell_signal and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_fast = fv
self._prev_mid = mv
def CreateClone(self):
return xit_three_ma_cross_strategy()