Bollinger Bands Abstand-Strategie
Strategie für den Handel von Bollinger-Bands-Umkehrungen mit einem zusätzlichen Abstandsfilter. Verkauft, wenn der Preis über dem oberen Band plus einem festgelegten Abstand schließt, und kauft, wenn er unter dem unteren Band minus demselben Abstand schließt. Positionen werden durch ein Gewinnziel oder einen Stop-Loss in Preisschritten geschlossen.
Details
- Einstiegskriterien:
- Long: Schluss unterhalb des unteren Bollinger Bands minus Abstand
- Short: Schluss oberhalb des oberen Bollinger Bands plus Abstand
- Long/Short: Beide
- Ausstiegskriterien:
- Gewinnziel erreicht
- Stop-Loss erreicht
- Stops: Absolut in Preisschritten
- Standardwerte:
BollingerPeriod= 4BollingerDeviation= 2mBandDistance= 3mProfitTarget= 3mLossLimit= 20mCandleType= TimeSpan.FromMinutes(5).TimeFrame()
- Filter:
- Kategorie: Umkehr
- Richtung: Beide
- Indikatoren: Bollinger Bands
- Stops: Ja
- Komplexität: Grundlegend
- Zeitrahmen: Kurzfristig
- Saisonalität: Nein
- Neuronale Netze: Nein
- Divergenz: Nein
- Risikolevel: Mittel
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Strategy trading reversals from Bollinger Bands with extra distance.
/// </summary>
public class BollingerBandsDistanceStrategy : Strategy
{
private readonly StrategyParam<int> _bbPeriod;
private readonly StrategyParam<decimal> _bbDeviation;
private readonly StrategyParam<decimal> _bandDistance;
private readonly StrategyParam<DataType> _candleType;
private readonly List<decimal> _closes = new();
public int BollingerPeriod
{
get => _bbPeriod.Value;
set => _bbPeriod.Value = value;
}
public decimal BollingerDeviation
{
get => _bbDeviation.Value;
set => _bbDeviation.Value = value;
}
public decimal BandDistance
{
get => _bandDistance.Value;
set => _bandDistance.Value = value;
}
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public BollingerBandsDistanceStrategy()
{
_bbPeriod = Param(nameof(BollingerPeriod), 20)
.SetDisplay("BB Period", "Bollinger Bands length", "Parameters");
_bbDeviation = Param(nameof(BollingerDeviation), 2m)
.SetDisplay("Deviation", "Bollinger Bands deviation", "Parameters");
_bandDistance = Param(nameof(BandDistance), 1m)
.SetDisplay("Band Distance", "Extra distance from bands in price steps", "Parameters");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_closes.Clear();
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
SubscribeCandles(CandleType)
.Bind(ProcessCandle)
.Start();
StartProtection(
new Unit(2000m, UnitTypes.Absolute),
new Unit(1000m, UnitTypes.Absolute));
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
_closes.Add(candle.ClosePrice);
if (_closes.Count > BollingerPeriod)
_closes.RemoveAt(0);
if (_closes.Count < BollingerPeriod)
return;
var sum = 0m;
foreach (var close in _closes)
sum += close;
var middle = sum / _closes.Count;
var variance = 0m;
foreach (var close in _closes)
{
var delta = close - middle;
variance += delta * delta;
}
var stdDev = (decimal)Math.Sqrt((double)(variance / _closes.Count));
var upper = middle + BollingerDeviation * stdDev;
var lower = middle - BollingerDeviation * stdDev;
var closePrice = candle.ClosePrice;
var distance = BandDistance * (Security?.PriceStep ?? 1m);
if (Position > 0 && closePrice >= middle)
SellMarket();
else if (Position < 0 && closePrice <= middle)
BuyMarket();
if (Position == 0)
{
if (closePrice > upper + distance)
SellMarket();
else if (closePrice < lower - distance)
BuyMarket();
}
}
}
import clr
import math
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, Unit, UnitTypes
from StockSharp.Algo.Strategies import Strategy
class bollinger_bands_distance_strategy(Strategy):
def __init__(self):
super(bollinger_bands_distance_strategy, self).__init__()
self._bb_period = self.Param("BollingerPeriod", 20)
self._bb_deviation = self.Param("BollingerDeviation", 2.0)
self._band_distance = self.Param("BandDistance", 1.0)
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4)))
self._closes = []
@property
def BollingerPeriod(self):
return self._bb_period.Value
@BollingerPeriod.setter
def BollingerPeriod(self, value):
self._bb_period.Value = value
@property
def BollingerDeviation(self):
return self._bb_deviation.Value
@BollingerDeviation.setter
def BollingerDeviation(self, value):
self._bb_deviation.Value = value
@property
def BandDistance(self):
return self._band_distance.Value
@BandDistance.setter
def BandDistance(self, value):
self._band_distance.Value = value
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
def OnStarted2(self, time):
super(bollinger_bands_distance_strategy, self).OnStarted2(time)
self._closes = []
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(self.ProcessCandle).Start()
self.StartProtection(
Unit(2000.0, UnitTypes.Absolute),
Unit(1000.0, UnitTypes.Absolute))
def ProcessCandle(self, candle):
if candle.State != CandleStates.Finished:
return
close_price = float(candle.ClosePrice)
period = int(self.BollingerPeriod)
self._closes.append(close_price)
if len(self._closes) > period:
self._closes.pop(0)
if len(self._closes) < period:
return
total = 0.0
for c in self._closes:
total += c
middle = total / len(self._closes)
variance = 0.0
for c in self._closes:
delta = c - middle
variance += delta * delta
std_dev = math.sqrt(variance / len(self._closes))
dev = float(self.BollingerDeviation)
upper = middle + dev * std_dev
lower = middle - dev * std_dev
step = float(self.Security.PriceStep) if self.Security is not None and self.Security.PriceStep is not None else 1.0
distance = float(self.BandDistance) * step
if self.Position > 0 and close_price >= middle:
self.SellMarket()
elif self.Position < 0 and close_price <= middle:
self.BuyMarket()
if self.Position == 0:
if close_price > upper + distance:
self.SellMarket()
elif close_price < lower - distance:
self.BuyMarket()
def OnReseted(self):
super(bollinger_bands_distance_strategy, self).OnReseted()
self._closes = []
def CreateClone(self):
return bollinger_bands_distance_strategy()