Diese Strategie recreates den originalen MetaTrader "breakdown"-Expertenberater. Sie platziert Stop-Orders rund um den Bereich des Vortages und aktualisiert die Orders kontinuierlich jede Sitzung. Eine Trailing-Stop-Engine repliziert die gestufte Trailing-Logik des Quellskripts und hält die Stops eng, sobald eine Position in die profitable Richtung zu bewegen beginnt.
Funktionsweise
Tägliche Vorbereitung – Wenn eine Tageskerze schließt, speichert die Strategie das Hoch und das Tief. Zu Beginn der folgenden Sitzung werden übrig gebliebene Orders storniert und ein Buy Stop oberhalb des vorherigen Hochs und ein Sell Stop unterhalb des vorherigen Tiefs eingereicht. Der Parameter Min Distance (ticks) versetzt die Orders von den Rohlevels, um Rauschen zu vermeiden.
Order-Aktualisierung – Wann immer ausstehende Orders ausgeführt werden oder ein neuer Tag beginnt, werden die verbleibenden Orders storniert und ein frisches Paar mit denselben Levels des Vortages eingereicht. Das Verhalten spiegelt den MQL-Experten wider, der kontinuierlich Stop-Einstiege auf beiden Marktseiten aufrechterhält.
Risikokontrollen – Ausgeführte Positionen initialisieren Stop-Loss- und Take-Profit-Ziele basierend auf Tick-Distanzen. Eine gestufte Trailing-Regel hebt/senkt den Stop nur, nachdem der Preis mindestens Trailing Stop (ticks) + Trailing Step (ticks) vom Einstieg entfernt ist, genau wie die ursprüngliche Trailing-Stop-Implementierung.
Exits – Positionen schließen sofort, wenn der Preis den aktiven Stop oder das Ziel berührt. Manuelles Trailing schließt Positionen zum Markt, wenn das Trailing-Level verletzt wird, was der MetaTrader-Logik entspricht, die Stops bei jedem Tick modifizierte.
Parameter
Parameter
Beschreibung
Working Candles
Zeitrahmen zur Überwachung der Preisbewegung und Verwaltung von Stops (Standard: 15-Minuten-Kerzen).
Stop Loss (ticks)
Initialer schützender Stop-Abstand, konvertiert in absoluten Preis unter Verwendung der Instrument-Tick-Größe. Auf null setzen zum Deaktivieren.
Take Profit (ticks)
Initialer Take-Profit-Abstand. Auf null setzen zum Deaktivieren.
Trailing Stop (ticks)
Kern-Trailing-Stop-Distanz. Auf null setzen, um Trailing zu deaktivieren.
Trailing Step (ticks)
Zusätzlicher Gewinn erforderlich, bevor der Trailing-Stop bewegt wird.
Min Distance (ticks)
Versatz, der zum Hoch/Tief des Vortages beim Platzieren ausstehender Orders hinzugefügt wird.
Order Volume
Menge, die mit beiden Stop-Orders gesendet wird.
Nutzungshinweise
Die Strategie auf Instrumenten konfigurieren, die Tageskerzen veröffentlichen, damit der vorherige Sitzungsbereich ermittelt werden kann.
Die Logik geht von einer konstanten Tick-Größe aus. Für Instrumente mit variablen Tick-Inkrementen die Standardwerte entsprechend anpassen.
Die Strategie implementiert keine prozentuale Dimensionierung aus dem ursprünglichen MQL-Skript; das Volumen wird explizit durch den Parameter Order Volume definiert.
Für diese Strategie ist noch keine Python-Version verfügbar.
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>
/// Breakout strategy using Highest/Lowest channel.
/// Enters long when price breaks above the channel high, enters short when price breaks below the channel low.
/// </summary>
public class BreakdownPendingStopStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _period;
private decimal? _prevHigh;
private decimal? _prevLow;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int Period
{
get => _period.Value;
set => _period.Value = value;
}
public BreakdownPendingStopStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Timeframe", "General");
_period = Param(nameof(Period), 20)
.SetGreaterThanZero()
.SetDisplay("Period", "Channel lookback period", "Indicators");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevHigh = null;
_prevLow = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevHigh = null;
_prevLow = null;
var highest = new Highest { Length = Period };
var lowest = new Lowest { Length = Period };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(highest, lowest, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, highest);
DrawIndicator(area, lowest);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal high, decimal low)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
{
_prevHigh = high;
_prevLow = low;
return;
}
if (_prevHigh == null || _prevLow == null)
{
_prevHigh = high;
_prevLow = low;
return;
}
var close = candle.ClosePrice;
if (close > _prevHigh.Value && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
else if (close < _prevLow.Value && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevHigh = high;
_prevLow = low;
}
}
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 Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
class breakdown_pending_stop_strategy(Strategy):
def __init__(self):
super(breakdown_pending_stop_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._period = self.Param("Period", 20) \
.SetDisplay("Period", "Channel lookback period", "Indicators")
self._prev_high = None
self._prev_low = None
@property
def CandleType(self):
return self._candle_type.Value
@property
def Period(self):
return self._period.Value
def OnReseted(self):
super(breakdown_pending_stop_strategy, self).OnReseted()
self._prev_high = None
self._prev_low = None
def OnStarted2(self, time):
super(breakdown_pending_stop_strategy, self).OnStarted2(time)
self._prev_high = None
self._prev_low = None
highest = Highest()
highest.Length = self.Period
lowest = Lowest()
lowest.Length = self.Period
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(highest, lowest, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, highest)
self.DrawIndicator(area, lowest)
self.DrawOwnTrades(area)
def _on_process(self, candle, high_value, low_value):
if candle.State != CandleStates.Finished:
return
hv = float(high_value)
lv = float(low_value)
if self._prev_high is None or self._prev_low is None:
self._prev_high = hv
self._prev_low = lv
return
close = float(candle.ClosePrice)
if close > self._prev_high and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif close < self._prev_low and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_high = hv
self._prev_low = lv
def CreateClone(self):
return breakdown_pending_stop_strategy()