Die BollTrade Bollinger-Reversionsstrategie ist eine hochrangige StockSharp-Strategie, die vom klassischen BollTrade MetaTrader-Expertenberater abgeleitet wurde. Es handelt ein einzelnes Instrument mithilfe von Bollinger-Bändern und wartet auf Preisausschläge über die Bänder hinaus sowie einen zusätzlichen Pip-Puffer. Wenn eine Kerze über dem oberen Band schließt, eröffnet die Strategie eine Short-Position, und wenn eine Kerze unter dem unteren Band schließt, eröffnet sie eine Long-Position. Alle Entscheidungen werden anhand fertiger Kerzen getroffen, um eine Reaktion auf unvollständige Daten zu vermeiden.
Handelslogik
Abonnieren Sie den konfigurierten Kerzentyp und berechnen Sie Bollinger Bänder mit der ausgewählten Periode und Abweichung.
Berechnen Sie einen zusätzlichen Preisversatz, ausgedrückt in Pip-Einheiten, um den ursprünglichen Puffer nachzuahmen, der die Geschäfte tiefer in den überkauften/überverkauften Bereich zwang.
Wenn der Schlusskurs einer abgeschlossenen Kerze unter dem unteren Band abzüglich des Offsets liegt, eröffnen Sie eine Long-Position. Wenn es über dem oberen Band plus dem Offset liegt, eröffnen Sie eine Short-Position.
Für jeden eröffneten Trade speichert die Strategie Stop-Loss- und Take-Profit-Level, die in Pip-Einheiten definiert sind. Diese Exits emulieren den ursprünglichen Expertenberater, der Positionen schloss, wenn der schwankende Gewinn oder Verlust vordefinierte Pip-Abstände überschritt.
Positionen werden geschlossen, wenn die Kerzenspanne entweder die Stop-Loss- oder Take-Profit-Schwelle überschreitet. Es wird keine zusätzliche Skalierung oder Pyramidenbildung durchgeführt.
Money-Management
Der Parameter Lots definiert die Basispositionsgröße.
Wenn LotIncrease aktiviert ist, skaliert das Volumen proportional zum aktuellen Portfoliowert im Verhältnis zum zu Beginn der Strategie beobachteten Wert, bis zu einer Sicherheitsobergrenze von 500 Lots. Dies reproduziert die Balance-Linked-Sizing-Logik aus der MetaTrader-Version.
Parameter
Parameter
Beschreibung
Gewinnmitnahme (Pips)
Abstand in Pips, der zur Berechnung des Take-Profit-Levels aus dem Einstiegspreis verwendet wird. Auf Null setzen, um den Take-Profit-Exit zu deaktivieren.
Stop-Loss (Pips)
Abstand in Pips, der zur Berechnung des Stop-Loss-Levels aus dem Einstiegspreis verwendet wird. Auf Null setzen, um den Stop-Loss-Ausstieg zu deaktivieren.
Bandversatz
Zusätzlicher Pip-Abstand, der über das Bollinger-Band hinaus hinzugefügt wird, bevor ein Handel eröffnet wird.
Bollinger Zeitraum
Anzahl der Kerzen, die für den gleitenden Durchschnitt der Bollinger-Bänder verwendet werden.
Bollinger Abweichung
Standardabweichungsmultiplikator für die Bandbreite Bollinger.
Grundvolumen
Basishandelsvolumen in Lots.
Volumen skalieren
Wenn diese Option aktiviert ist, erhöht sich das Auftragsvolumen basierend auf dem Wachstum des Portfoliowerts.
Kerzentyp
Kerzentyp (Zeitrahmen), der zur Signalgenerierung verwendet wird.
Notizen
Die Strategie funktioniert nur mit fertigen Kerzen und benötigt daher historische Daten zum Aufwärmen vor dem Live-Handel.
Stop-Loss- und Take-Profit-Niveaus werden anhand von Kerzenbereichen bewertet, was der ursprünglichen Tick-basierten Logik nahekommt und gleichzeitig mit dem hohen Niveau API kompatibel bleibt.
Schutzfunktionen aus dem StockSharp-Framework (StartProtection) sind aktiviert, um vor versehentlicher Positionsfreilegung zu schützen, wenn die Strategie unerwartet stoppt.
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>
/// Bollinger Bands reversion strategy.
/// Buys when price closes below lower band, sells when above upper band.
/// Uses middle band as exit target.
/// </summary>
public class BollTradeBollingerReversionStrategy : Strategy
{
private readonly StrategyParam<int> _bollingerPeriod;
private readonly StrategyParam<decimal> _bollingerWidth;
private readonly StrategyParam<DataType> _candleType;
public int BollingerPeriod { get => _bollingerPeriod.Value; set => _bollingerPeriod.Value = value; }
public decimal BollingerWidth { get => _bollingerWidth.Value; set => _bollingerWidth.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public BollTradeBollingerReversionStrategy()
{
_bollingerPeriod = Param(nameof(BollingerPeriod), 20)
.SetDisplay("BB Period", "Bollinger Bands period", "Indicators");
_bollingerWidth = Param(nameof(BollingerWidth), 0.5m)
.SetDisplay("BB Width", "Bollinger Bands width", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var bb = new BollingerBands
{
Length = BollingerPeriod,
Width = BollingerWidth
};
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(bb, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue bbValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!bbValue.IsFinal)
return;
var bb = (BollingerBandsValue)bbValue;
var upper = bb.UpBand;
var lower = bb.LowBand;
var middle = bb.MovingAverage;
if (upper == null || lower == null || middle == null)
return;
var close = candle.ClosePrice;
var upperVal = upper.Value;
var lowerVal = lower.Value;
var midVal = middle.Value;
// Buy when close below lower band (oversold)
if (close < lowerVal && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// Sell when close above upper band (overbought)
else if (close > upperVal && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import BollingerBands
from StockSharp.Algo.Strategies import Strategy
class boll_trade_bollinger_reversion_strategy(Strategy):
"""Bollinger Bands reversion strategy.
Buys when price closes below lower band, sells when above upper band."""
def __init__(self):
super(boll_trade_bollinger_reversion_strategy, self).__init__()
self._bollinger_period = self.Param("BollingerPeriod", 20) \
.SetDisplay("BB Period", "Bollinger Bands period", "Indicators")
self._bollinger_width = self.Param("BollingerWidth", 0.5) \
.SetDisplay("BB Width", "Bollinger Bands width", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def BollingerPeriod(self):
return self._bollinger_period.Value
@property
def BollingerWidth(self):
return self._bollinger_width.Value
def OnReseted(self):
super(boll_trade_bollinger_reversion_strategy, self).OnReseted()
def OnStarted2(self, time):
super(boll_trade_bollinger_reversion_strategy, self).OnStarted2(time)
bb = BollingerBands()
bb.Length = self.BollingerPeriod
bb.Width = self.BollingerWidth
subscription = self.SubscribeCandles(self.CandleType)
subscription.BindEx(bb, self._process_candle).Start()
def _process_candle(self, candle, bb_value):
if candle.State != CandleStates.Finished:
return
if not bb_value.IsFinal:
return
up_band = bb_value.UpBand if hasattr(bb_value, 'UpBand') else None
low_band = bb_value.LowBand if hasattr(bb_value, 'LowBand') else None
if up_band is None or low_band is None:
return
upper = float(up_band)
lower = float(low_band)
close = float(candle.ClosePrice)
# Buy when close below lower band (oversold)
if close < lower and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# Sell when close above upper band (overbought)
elif close > upper and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
def CreateClone(self):
return boll_trade_bollinger_reversion_strategy()