Start
/
Strategie-Beispiele
Auf GitHub ansehen
Plan X-Strategie
Überblick
Die Plan X-Strategie ist ein Ausbruchssystem, das vom ursprünglichen MetaTrader 5 Expert Advisor konvertiert wurde. Es wertet den Abschluss jeder abgeschlossenen Kerze gegen eine Referenzkerze aus, die um eine konfigurierbare Anzahl von Bars verschoben ist. Wenn der aktuellste Schlusskurs den Referenzschlusskurs um eine bestimmte Kanalhöhe überschreitet, öffnet die Strategie eine Position in der Ausbruchsrichtung. Optionale Signalumkehrung ermöglicht den Handel von Ausbrüchen in der entgegengesetzten Richtung.
Die Implementierung verwendet die High-Level-API von StockSharp. Sie unterstützt anpassbaren Stop-Loss, Take-Profit, Trailing-Stop-Logik und einen Trading-Session-Filter.
Funktionsweise
Kerzenverarbeitung – die Strategie abonniert den konfigurierten Kerzentyp und verarbeitet nur abgeschlossene Kerzen. Eine kurze Historie von Schlusskursen wird geführt, um den letzten Wert mit einer verschobenen Referenzkerze zu vergleichen.
Ausbruchserkennung – wenn der letzte Schlusskurs die Referenzkerze um mehr als die Kanalhöhe überschreitet, wird ein Long-Signal erzeugt. Wenn er um denselben Betrag darunter liegt, wird ein Short-Signal generiert. Wenn das Umkehrkennzeichen aktiviert ist, werden die Signale umgekehrt.
Orderausführung – die Strategie verwendet Marktorders. Bei der Umkehrung aus einer entgegengesetzten Position schließt das Ordervolumen automatisch den absoluten Wert der aktuellen Position ein, um in einem einzigen Vorgang zu glätten und neu einzusteigen.
Risikomanagement – Stop-Loss- und Take-Profit-Niveaus werden unmittelbar nach dem Einstieg gesetzt. Ein Trailing-Stop kann den ursprünglichen Stop ersetzen, wenn der Preis günstig um mehr als die Trailing-Distanz plus den Trailing-Schritt läuft.
Zeitfilter – der Handel kann auf eine Start- und Endstunde begrenzt werden. Wenn die Startstunde größer als die Endstunde ist, wird das Fenster als Mitternachtsüberquerung behandelt.
Parameter
Parameter
Beschreibung
Stop Loss (pips)
Schutz-Stop-Abstand in Pips, in Preiseinheiten basierend auf dem Instrument-Preisschritt konvertiert.
Take Profit (pips)
Zielabstand in Pips.
Trailing Stop (pips)
Abstand zwischen Preis und Trailing-Stop. Auf null setzen, um Trailing zu deaktivieren.
Trailing Step (pips)
Zusätzlicher Gewinn, der benötigt wird, bevor der Trailing-Stop vorgerückt wird. Muss positiv sein, wenn Trailing aktiviert ist.
Channel Height (pips)
Ausbruchsschwelle in Pips ausgedrückt.
Candle Shift
Anzahl der Bars zwischen dem letzten Schlusskurs und der Referenzkerze.
Use Time Control
Aktiviert oder deaktiviert den Trading-Session-Filter.
Start Hour
Erste Stunde (0–23), wenn Trading erlaubt ist.
End Hour
Letzte Stunde (0–23), wenn Trading erlaubt ist.
Reverse Signals
Kehrt die Ausbruchsrichtung um.
Order Volume
Marktordergröße in Lots/Kontrakten ausgedrückt.
Candle Type
Datenkerztyp für die Analyse.
Signallogik
Long-Einstieg – letzter Schlusskurs ≥ Referenzschlusskurs + Kanalhöhe, Umkehr deaktiviert.
Short-Einstieg – letzter Schlusskurs ≤ Referenzschlusskurs − Kanalhöhe, Umkehr deaktiviert.
Wenn die Umkehr aktiviert ist, tauscht die Logik die Long- und Short-Bedingungen.
Trailing-Stop-Logik
Der Trailing-Stop aktiviert sich, wenn die günstige Bewegung Trailing Stop + Trailing Step in Preistermen überschreitet.
Bei Long-Positionen wird der Stop auf high − Trailing Stop verschoben, wenn der neue Wert höher als der bestehende Stop ist.
Bei Short-Positionen wird der Stop auf low + Trailing Stop verschoben, wenn der neue Wert niedriger als der bestehende Stop ist.
Zusätzliche Hinweise
Die Pip-Größenberechnung emuliert die MQL-Version, indem der Preisschritt für 3- oder 5-dezimale Instrumente mit 10 multipliziert wird.
Der Handel außerhalb der erlaubten Session überspringt neue Einträge, verwaltet aber weiterhin offene Positionen.
Die Strategie ruft StartProtection() einmal beim Start auf, um integrierte Portfolio-Schutzdienste zu aktivieren.
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class PlanXStrategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<int> _stopLossPoints;
private readonly StrategyParam<int> _takeProfitPoints;
private ExponentialMovingAverage _fast;
private ExponentialMovingAverage _slow;
private decimal _prevFast;
private decimal _prevSlow;
private decimal _entryPrice;
private int _cooldown;
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public int StopLossPoints { get => _stopLossPoints.Value; set => _stopLossPoints.Value = value; }
public int TakeProfitPoints { get => _takeProfitPoints.Value; set => _takeProfitPoints.Value = value; }
public PlanXStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 14).SetGreaterThanZero().SetDisplay("Fast Period", "Fast EMA period", "Indicator");
_slowPeriod = Param(nameof(SlowPeriod), 50).SetGreaterThanZero().SetDisplay("Slow Period", "Slow EMA period", "Indicator");
_stopLossPoints = Param(nameof(StopLossPoints), 200).SetNotNegative().SetDisplay("Stop Loss", "Stop-loss in price steps", "Risk");
_takeProfitPoints = Param(nameof(TakeProfitPoints), 400).SetNotNegative().SetDisplay("Take Profit", "Take-profit in price steps", "Risk");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
yield return (Security, TimeSpan.FromMinutes(5).TimeFrame());
}
protected override void OnReseted()
{
base.OnReseted();
_fast = null; _slow = null;
_prevFast = 0; _prevSlow = 0; _entryPrice = 0; _cooldown = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_fast = new ExponentialMovingAverage { Length = FastPeriod };
_slow = new ExponentialMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(TimeSpan.FromMinutes(5).TimeFrame());
subscription.Bind(_fast, _slow, ProcessCandle);
subscription.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fastValue, decimal slowValue)
{
if (candle.State != CandleStates.Finished) return;
if (!_fast.IsFormed || !_slow.IsFormed) { _prevFast = fastValue; _prevSlow = slowValue; return; }
if (_cooldown > 0) { _cooldown--; _prevFast = fastValue; _prevSlow = slowValue; return; }
var close = candle.ClosePrice;
var step = Security?.PriceStep ?? 1m;
if (Position > 0 && _entryPrice > 0)
{
if (StopLossPoints > 0 && close <= _entryPrice - StopLossPoints * step) { SellMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
if (TakeProfitPoints > 0 && close >= _entryPrice + TakeProfitPoints * step) { SellMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
}
else if (Position < 0 && _entryPrice > 0)
{
if (StopLossPoints > 0 && close >= _entryPrice + StopLossPoints * step) { BuyMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
if (TakeProfitPoints > 0 && close <= _entryPrice - TakeProfitPoints * step) { BuyMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
}
if (_prevFast <= _prevSlow && fastValue > slowValue && Position <= 0)
{ if (Position < 0) BuyMarket(); BuyMarket(); _entryPrice = close; _cooldown = 100; }
else if (_prevFast >= _prevSlow && fastValue < slowValue && Position >= 0)
{ if (Position > 0) SellMarket(); SellMarket(); _entryPrice = close; _cooldown = 100; }
_prevFast = fastValue; _prevSlow = slowValue;
}
}
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 plan_x_strategy(Strategy):
def __init__(self):
super(plan_x_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 14) \
.SetDisplay("Fast Period", "Fast MA period", "Indicator")
self._slow_period = self.Param("SlowPeriod", 50) \
.SetDisplay("Slow Period", "Slow MA period", "Indicator")
self._stop_loss_points = self.Param("StopLossPoints", 200) \
.SetDisplay("Stop Loss", "Stop-loss in price steps", "Risk")
self._take_profit_points = self.Param("TakeProfitPoints", 400) \
.SetDisplay("Take Profit", "Take-profit in price steps", "Risk")
self._fast = None
self._slow = None
self._prev_fast = 0.0
self._prev_slow = 0.0
self._entry_price = 0.0
self._cooldown = 0
@property
def fast_period(self):
return self._fast_period.Value
@property
def slow_period(self):
return self._slow_period.Value
@property
def stop_loss_points(self):
return self._stop_loss_points.Value
@property
def take_profit_points(self):
return self._take_profit_points.Value
def OnReseted(self):
super(plan_x_strategy, self).OnReseted()
self._fast = None
self._slow = None
self._prev_fast = 0.0
self._prev_slow = 0.0
self._entry_price = 0.0
self._cooldown = 0
def OnStarted2(self, time):
super(plan_x_strategy, self).OnStarted2(time)
self._fast = ExponentialMovingAverage()
self._fast.Length = self.fast_period
self._slow = ExponentialMovingAverage()
self._slow.Length = self.slow_period
subscription = self.SubscribeCandles(DataType.TimeFrame(TimeSpan.FromMinutes(5)))
subscription.Bind(self._fast, self._slow, self._process_candle)
subscription.Start()
def _process_candle(self, candle, fast_value, slow_value):
if candle.State != CandleStates.Finished:
return
fast_val = float(fast_value)
slow_val = float(slow_value)
if not self._fast.IsFormed or not self._slow.IsFormed:
self._prev_fast = fast_val
self._prev_slow = slow_val
return
if self._cooldown > 0:
self._cooldown -= 1
self._prev_fast = fast_val
self._prev_slow = slow_val
return
close = float(candle.ClosePrice)
step = float(self.Security.PriceStep) if self.Security is not None and self.Security.PriceStep is not None else 1.0
if self.Position > 0 and self._entry_price > 0:
if self.stop_loss_points > 0 and close <= self._entry_price - self.stop_loss_points * step:
self.SellMarket()
self._entry_price = 0.0
self._cooldown = 100
self._prev_fast = fast_val
self._prev_slow = slow_val
return
if self.take_profit_points > 0 and close >= self._entry_price + self.take_profit_points * step:
self.SellMarket()
self._entry_price = 0.0
self._cooldown = 100
self._prev_fast = fast_val
self._prev_slow = slow_val
return
elif self.Position < 0 and self._entry_price > 0:
if self.stop_loss_points > 0 and close >= self._entry_price + self.stop_loss_points * step:
self.BuyMarket()
self._entry_price = 0.0
self._cooldown = 100
self._prev_fast = fast_val
self._prev_slow = slow_val
return
if self.take_profit_points > 0 and close <= self._entry_price - self.take_profit_points * step:
self.BuyMarket()
self._entry_price = 0.0
self._cooldown = 100
self._prev_fast = fast_val
self._prev_slow = slow_val
return
if self._prev_fast <= self._prev_slow and fast_val > slow_val and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
self._entry_price = close
self._cooldown = 100
elif self._prev_fast >= self._prev_slow and fast_val < slow_val and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._entry_price = close
self._cooldown = 100
self._prev_fast = fast_val
self._prev_slow = slow_val
def CreateClone(self):
return plan_x_strategy()