Diese Strategie ist ein StockSharp-Port des MetaTrader-Expertenberaters Exp_XPeriodCandleSystem_Tm_Plus. Der ursprüngliche Roboter basiert auf dem benutzerdefinierten Indikator XPeriod Candle System, der Kerzendaten glättet und Balken entsprechend Bollinger-Band-Ausbrüchen einfärbt. Die übersetzte Version reproduziert dieses Verhalten durch Anwendung exponentieller Glättung auf die OHLC-Reihe, Mapping derselben angewandten Preismodi und Steuerung von Trades aus den resultierenden Farbzuständen. Ein zeitbasierter Ausstieg und konfigurierbare Schutzorders ergänzen die Ausbruchslogik.
Handelslogik
Geglättete Kerzen – Exponentielle gleitende Durchschnitte mit konfigurierbarer Länge erstellen synthetische Eröffnungs-, Hoch-, Tief- und Schlusskurswerte, die den Quellindikator annähern.
Angewandter Preis – Der Benutzer kann eine der zwölf Preisformeln (Schluss, Eröffnung, Median, Trendfolge-Variationen, Demark usw.) auswählen, bevor Daten in die Bollinger Bänder gespeist werden.
Bandanalyse – Ein Bollinger-Bänder-Indikator (Länge und Abweichung konfigurierbar) verarbeitet die geglättete Preisreihe. Abgeschlossene Bänder sind erforderlich, bevor Signale ausgewertet werden.
Farbzustände –
Bullischer Balken oberhalb des oberen Bandes → Farbe 0 (Ausbruch nach oben).
Bärischer Balken unterhalb des unteren Bandes → Farbe 4 (Ausbruch nach unten).
Andere bullische Balken → Farbe 1; andere bärische Balken → Farbe 3.
Ein konfigurierbarer Ausbruchs-Offset (bei Möglichkeit in Preiseinheiten unter Verwendung der Tick-Größe des Symbols umgerechnet) vermeidet Fehlauslöser.
Einstiege – Die Strategie betrachtet die durch SignalBar definierte Kerze und ihren Vorgänger:
Long eröffnen, wenn der vorherige Balken ein bullischer Ausbruch (0) war und der Signalbalken es nicht ist.
Short eröffnen, wenn der vorherige Balken ein bärischer Ausbruch (4) war und der Signalbalken es nicht ist.
Ausstiege –
Longs schließen, wenn der Referenzbalken bärisch ist (> 2).
Shorts schließen, wenn der Referenzbalken bullisch ist (< 2).
Ein optionaler Haltetimer (TimeTrade und HoldingMinutes) schließt Positionen nach den angegebenen Minuten.
Risiko – StartProtection setzt optionale absolute Take-Profit- und Stop-Loss-Abstände für jeden Trade ein.
Parameter
Parameter
Beschreibung
Standardwert
OrderVolume
Basisauftragsgröße für Markteinstiege.
0.1
BuyPosOpen / SellPosOpen
Long- oder Short-Einstiege aktivieren/deaktivieren.
true
BuyPosClose / SellPosClose
Long- oder Short-Positionsausstiege erlauben.
true
TimeTrade
Aktiviert den zeitbasierten Ausstiegsfilter.
true
HoldingMinutes
Maximale Haltezeit, bevor der Zeitfilter eine Position schließt.
960
CandleType
Kerzendatentyp (Zeitrahmen), der vom Markt angefordert wird.
4 Stunden
Period
Länge der exponentiellen gleitenden Durchschnitte zur Glättung.
5
BollingerLength
Anzahl geglätteter Balken im Bollinger-Berechnungsfenster.
20
BandsDeviation
Bandbreiten-Multiplikator.
1.001
AppliedPriceMode
Preistransformation vor dem Bollinger-Indikator (Schluss, Eröffnung, Median, Trendfolge, Demark usw.).
Close
SignalBar
Index des Balkens für die Signalauswertung (1 = letzter geschlossener Balken).
1
StopLoss / TakeProfit
Absolute Abstände (in Preiseinheiten) für die Schutz-Engine.
1000 / 2000
Deviation
Zusätzlicher Ausbruchs-Offset, der über/unter die Bollinger Bänder addiert wird.
10
Verwendungshinweise
Der Glättungsschritt verwendet exponentielle gleitende Durchschnitte zur Replikation der proprietären XPeriod-Berechnung. Kleinere Perioden halten die synthetischen Kerzen näher an den Marktpreisen, während größere Perioden die Trendstruktur betonen.
SignalBar muss innerhalb des gespeicherten Verlaufs bleiben (bis zu 14 Positionen nach dem aktuellen Balken). Werte größer als der verfügbare Verlauf überspringen das Trading automatisch.
Der Ausbruchs-Offset wird mit PriceStep multipliziert, wenn das Wertpapier eine Tick-Größe offenlegt. Dies hält das Verhalten ähnlich zur MetaTrader-Version, wo Deviation in Punkten definiert ist.
StopLoss und TakeProfit werden in absoluten Preiseinheiten angegeben. Auf null setzen, um Schutzorders zu deaktivieren, während die Verwaltungsinfrastruktur aktiv bleibt.
Noch keine Python-Übersetzung vorhanden; dieser Ordner enthält nur die C#-Implementierung.
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>
/// XPeriod candle system with Bollinger Bands breakout.
/// Buys on close above upper band with bullish candle, sells on close below lower band with bearish candle.
/// </summary>
public class XPeriodCandleSystemTmPlusStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _bbPeriod;
private readonly StrategyParam<decimal> _bbWidth;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int BbPeriod
{
get => _bbPeriod.Value;
set => _bbPeriod.Value = value;
}
public decimal BbWidth
{
get => _bbWidth.Value;
set => _bbWidth.Value = value;
}
public XPeriodCandleSystemTmPlusStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Timeframe", "General");
_bbPeriod = Param(nameof(BbPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("BB Period", "Bollinger Bands period", "Indicators");
_bbWidth = Param(nameof(BbWidth), 2m)
.SetGreaterThanZero()
.SetDisplay("BB Width", "Bollinger Bands width", "Indicators");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var bb = new BollingerBands { Length = BbPeriod, Width = BbWidth };
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(bb, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, bb);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue value)
{
if (candle.State != CandleStates.Finished)
return;
var bb = (BollingerBandsValue)value;
if (bb.UpBand is not decimal upper ||
bb.LowBand is not decimal lower ||
bb.MovingAverage is not decimal middle)
return;
var close = candle.ClosePrice;
var isBullish = candle.ClosePrice > candle.OpenPrice;
var isBearish = candle.ClosePrice < candle.OpenPrice;
// Buy: close above upper band with bullish candle
if (close > upper && isBullish && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// Sell: close below lower band with bearish candle
else if (close < lower && isBearish && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
// Exit long at middle band
else if (Position > 0 && close < middle)
{
SellMarket();
}
// Exit short at middle band
else if (Position < 0 && close > middle)
{
BuyMarket();
}
}
}
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 BollingerBands
from StockSharp.Algo.Strategies import Strategy
class x_period_candle_system_tm_plus_strategy(Strategy):
def __init__(self):
super(x_period_candle_system_tm_plus_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._bb_period = self.Param("BbPeriod", 20) \
.SetDisplay("BB Period", "Bollinger Bands period", "Indicators")
self._bb_width = self.Param("BbWidth", 2.0) \
.SetDisplay("BB Width", "Bollinger Bands width", "Indicators")
@property
def CandleType(self):
return self._candle_type.Value
@property
def BbPeriod(self):
return self._bb_period.Value
@property
def BbWidth(self):
return self._bb_width.Value
def OnStarted2(self, time):
super(x_period_candle_system_tm_plus_strategy, self).OnStarted2(time)
bb = BollingerBands()
bb.Length = self.BbPeriod
bb.Width = self.BbWidth
subscription = self.SubscribeCandles(self.CandleType)
subscription.BindEx(bb, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, bb)
self.DrawOwnTrades(area)
def _on_process(self, candle, bb_value):
if candle.State != CandleStates.Finished:
return
upper = bb_value.UpBand
lower = bb_value.LowBand
middle = bb_value.MovingAverage
if upper is None or lower is None or middle is None:
return
upper = float(upper)
lower = float(lower)
middle = float(middle)
close = float(candle.ClosePrice)
is_bullish = float(candle.ClosePrice) > float(candle.OpenPrice)
is_bearish = float(candle.ClosePrice) < float(candle.OpenPrice)
# Buy: close above upper band with bullish candle
if close > upper and is_bullish and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# Sell: close below lower band with bearish candle
elif close < lower and is_bearish and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
# Exit long at middle band
elif self.Position > 0 and close < middle:
self.SellMarket()
# Exit short at middle band
elif self.Position < 0 and close > middle:
self.BuyMarket()
def CreateClone(self):
return x_period_candle_system_tm_plus_strategy()