Estrategia que coloca órdenes límite de compra en la banda inferior de Bollinger Bands y órdenes límite de venta en la banda superior. Las posiciones se cierran cuando el precio toca la banda media. Las órdenes pendientes se actualizan al inicio de cada vela.
Detalles
Criterios de entrada:
Largo: compra límite en la banda inferior de Bollinger Bands
Corto: venta límite en la banda superior de Bollinger Bands
Largo/Corto: Ambos
Criterios de salida:
Largo: el precio cruza por encima de la banda media de Bollinger Bands
Corto: el precio cruza por debajo de la banda media de Bollinger Bands
Stops: Ninguno
Valores predeterminados:
BbPeriod = 20
BbDeviation = 2m
CandleType = TimeSpan.FromMinutes(15).TimeFrame()
Filtros:
Categoría: Reversión a la media
Dirección: Ambos
Indicadores: Bollinger Bands
Stops: No
Complejidad: Básico
Marco temporal: Corto plazo
Estacionalidad: No
Redes neuronales: No
Divergencia: No
Nivel de riesgo: Medio
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>
/// Bollinger Bands mean reversion strategy.
/// Buys when price touches lower band, sells when price touches upper band.
/// Closes at middle band.
/// </summary>
public class BollingerBandsAutomatedStrategy : Strategy
{
private readonly StrategyParam<int> _bbPeriod;
private readonly StrategyParam<decimal> _bbDeviation;
private readonly StrategyParam<DataType> _candleType;
public int BbPeriod { get => _bbPeriod.Value; set => _bbPeriod.Value = value; }
public decimal BbDeviation { get => _bbDeviation.Value; set => _bbDeviation.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public BollingerBandsAutomatedStrategy()
{
_bbPeriod = Param(nameof(BbPeriod), 20)
.SetDisplay("BB Period", "Bollinger Bands period", "Indicators")
.SetGreaterThanZero();
_bbDeviation = Param(nameof(BbDeviation), 2m)
.SetDisplay("BB Deviation", "Bollinger Bands deviation", "Indicators")
.SetGreaterThanZero();
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var bb = new BollingerBands
{
Length = BbPeriod,
Width = BbDeviation
};
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 bbValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var bb = bbValue as BollingerBandsValue;
if (bb?.UpBand is not decimal upper || bb?.LowBand is not decimal lower)
return;
var middle = (upper + lower) / 2m;
var close = candle.ClosePrice;
// Close long at middle band
if (Position > 0 && close >= middle)
SellMarket();
// Close short at middle band
else if (Position < 0 && close <= middle)
BuyMarket();
// Open new positions at band extremes
if (close <= lower && Position <= 0)
BuyMarket();
else if (close >= upper && Position >= 0)
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
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import BollingerBands
from StockSharp.Algo.Strategies import Strategy
class bollinger_bands_automated_strategy(Strategy):
def __init__(self):
super(bollinger_bands_automated_strategy, self).__init__()
self._bb_period = self.Param("BbPeriod", 20) \
.SetDisplay("BB Period", "Bollinger Bands period", "Indicators")
self._bb_deviation = self.Param("BbDeviation", 2.0) \
.SetDisplay("BB Deviation", "Bollinger Bands deviation", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles", "General")
@property
def bb_period(self):
return self._bb_period.Value
@property
def bb_deviation(self):
return self._bb_deviation.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnStarted2(self, time):
super(bollinger_bands_automated_strategy, self).OnStarted2(time)
bb = BollingerBands()
bb.Length = self.bb_period
bb.Width = self.bb_deviation
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(bb, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, bb)
self.DrawOwnTrades(area)
def process_candle(self, candle, bb_value):
if candle.State != CandleStates.Finished:
return
if not bb_value.IsFormed:
return
upper = bb_value.UpBand
lower = bb_value.LowBand
if upper is None or lower is None:
return
upper = float(upper)
lower = float(lower)
middle = (upper + lower) / 2.0
close = float(candle.ClosePrice)
if self.Position > 0 and close >= middle:
self.SellMarket()
elif self.Position < 0 and close <= middle:
self.BuyMarket()
if close <= lower and self.Position <= 0:
self.BuyMarket()
elif close >= upper and self.Position >= 0:
self.SellMarket()
def CreateClone(self):
return bollinger_bands_automated_strategy()