La Estrategia de reversión Bollinger de BollTrade es una estrategia StockSharp de alto nivel convertida del clásico asesor experto de BollTrade MetaTrader. Opera con un único instrumento utilizando Bollinger bandas y espera las excursiones de precios más allá de las bandas más un buffer de pips adicional. Cuando una vela cierra por encima de la banda superior, la estrategia abre una posición corta, y cuando una vela cierra por debajo de la banda inferior, abre una posición larga. Todas las decisiones se toman sobre velas terminadas para evitar reaccionar ante datos incompletos.
Lógica de trading
Suscríbase al tipo de vela configurado y calcule Bollinger Bandas con el período y la desviación seleccionados.
Calcule una compensación de precio adicional expresada en unidades de pips para imitar el colchón original que obligó a las operaciones a entrar más profundamente en territorio de sobrecompra/sobreventa.
Cuando el precio de cierre de una vela completa esté por debajo de la banda inferior menos el desplazamiento, abra una posición larga. Cuando esté por encima de la banda superior más el desplazamiento, abra una posición corta.
Para cada operación abierta, la estrategia almacena niveles de stop-loss y take-profit definidos en unidades de pips. Estas salidas emulan al asesor experto original que cerraba posiciones cuando las ganancias o pérdidas flotantes cruzaban distancias de pips predefinidas.
Las posiciones se cierran cuando el rango de velas cruza el umbral de stop-loss o take-profit. No se realiza ningún escalado ni piramidal adicional.
Gestión monetaria
El parámetro Lots define el tamaño de la posición base.
Cuando LotIncrease está habilitado, el volumen aumenta proporcionalmente con el valor actual de la cartera en relación con el valor observado al inicio de la estrategia, hasta un límite de seguridad de 500 lotes. Esto reproduce la lógica de tallas vinculada al equilibrio de la versión MetaTrader.
Parámetros
Parámetro
Descripción
Obtener ganancias (pips)
Distancia en pips utilizada para calcular el nivel de obtención de beneficios a partir del precio de entrada. Establezca en cero para desactivar la salida de obtención de beneficios.
Detener pérdidas (pips)
Distancia en pips utilizada para calcular el nivel de stop-loss a partir del precio de entrada. Establezca en cero para desactivar la salida de stop-loss.
Compensación de banda
Distancia de pips adicional agregada más allá de la banda Bollinger antes de abrir una operación.
Bollinger Período
Número de velas utilizadas para la media móvil de Bollinger Bandas.
Bollinger Desviación
Multiplicador de desviación estándar para el ancho de bandas Bollinger.
Volumen base
Volumen de comercio base en lotes.
Volumen de escala
Cuando está habilitado, aumenta el volumen de pedidos en función del crecimiento del valor de la cartera.
Tipo de vela
Tipo de vela (período de tiempo) utilizado para la generación de señales.
Notas
La estrategia funciona únicamente con velas terminadas y, por lo tanto, necesita datos históricos para prepararse antes de operar en vivo.
Los niveles de stop-loss y take-profit se evalúan en rangos de velas, lo que se aproxima a la lógica original basada en ticks sin dejar de ser compatible con el nivel alto API.
Las funciones de protección del marco StockSharp (StartProtection) están habilitadas para proteger contra la exposición accidental de la posición cuando la estrategia se detiene inesperadamente.
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()