Ver en GitHub

Estrategia BBStrategy

Descripción general

BBStrategy es un Bollinger sistema de ruptura de bandas convertido del MetaTrader asesor experto "BBStrategy". La estrategia rastrea dos conjuntos de Bollinger bandas con el mismo período pero diferentes multiplicadores de desviación. Cuando el precio atraviesa la banda exterior, el algoritmo arma una operación, pero la entrada real se pospone hasta que el precio regresa a la banda interior. Este comportamiento intenta evitar comprar rupturas demasiado extendidas o vender condiciones de sobreventa profunda y, al mismo tiempo, capturar el movimiento de continuación después de una expansión de la volatilidad.

Lógica principal

  1. Suscríbete a velas y calcula dos Bollinger Bandas:
    • Banda exterior utiliza un multiplicador de desviación configurable (predeterminado 3.0).
    • La banda interior utiliza una desviación más baja (predeterminada 2.0).
  2. Detectar cuando el precio de cierre termina fuera de la banda exterior:
    • Por encima de la banda exterior superior hay una configuración larga.
    • Debajo de los brazos de la banda exterior inferior hay una configuración corta.
  3. Ingrese solo si la siguiente vela completa se cierra nuevamente dentro de la banda interna en la dirección de la ruptura. Mientras el precio espera volver a entrar, la estrategia permanece en estado de "espera" en la dirección correspondiente.
  4. Envíe una orden de mercado único cuando las condiciones se alineen y no haya posiciones abiertas ni órdenes activas. Las posiciones opuestas existentes se cierran aumentando el volumen de la orden de mercado.
  5. Las distancias opcionales de toma de ganancias y límite de pérdidas (expresadas en puntos) se convierten en compensaciones de precios absolutos y se administran a través del asistente de protección incorporado.

Parámetros

Nombre Descripción
Volumen de pedido Tamaño de la operación para cada posición.
Bollinger Período Número de velas utilizadas para ambos cálculos de banda Bollinger.
Desviación interna Multiplicador de desviación para la banda interior que valida los retrocesos.
Desviación exterior Multiplicador de desviación para la banda exterior que detecta rupturas.
Puntos de limitación de pérdidas Distancia de parada de protección en puntos (0 desactiva la parada).
Puntos de obtención de beneficios Distancia de toma de ganancias en puntos (0 desactiva el objetivo).
Tipo de vela Plazo de vela para los cálculos.

Notas

  • La estrategia negocia una sola posición a la vez e ignora las nuevas señales mientras las órdenes están activas.
  • Para la gestión de riesgos, el asistente convierte MetaTrader "puntos" en incrementos de precio reales según el tamaño del tick del instrumento.
  • Los dibujos del gráfico incluyen velas, tanto Bollinger bandas como las operaciones propias de la estrategia para facilitar la depuración visual.
using System;

using Ecng.Common;

using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Bollinger Bands breakout strategy.
/// When price breaks above outer band, waits for re-entry into inner band then goes long.
/// When price breaks below outer band, waits for re-entry into inner band then goes short.
/// </summary>
public class BBStrategy : Strategy
{
	private readonly StrategyParam<int> _bollingerPeriod;
	private readonly StrategyParam<decimal> _innerDeviation;
	private readonly StrategyParam<decimal> _outerDeviation;
	private readonly StrategyParam<DataType> _candleType;

	public int BollingerPeriod
	{
		get => _bollingerPeriod.Value;
		set => _bollingerPeriod.Value = value;
	}

	public decimal InnerDeviation
	{
		get => _innerDeviation.Value;
		set => _innerDeviation.Value = value;
	}

	public decimal OuterDeviation
	{
		get => _outerDeviation.Value;
		set => _outerDeviation.Value = value;
	}

	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	public BBStrategy()
	{
		_bollingerPeriod = Param(nameof(BollingerPeriod), 20)
			.SetDisplay("BB Period", "Bollinger Bands period", "Indicators");

		_innerDeviation = Param(nameof(InnerDeviation), 2m)
			.SetDisplay("Inner Dev", "Inner band deviations", "Indicators");

		_outerDeviation = Param(nameof(OuterDeviation), 3m)
			.SetDisplay("Outer Dev", "Outer band deviations", "Indicators");

		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Candle series", "General");
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var innerBand = new BollingerBands
		{
			Length = BollingerPeriod,
			Width = InnerDeviation
		};

		var outerBand = new BollingerBands
		{
			Length = BollingerPeriod,
			Width = OuterDeviation
		};

		var waitDirection = 0;

		var subscription = SubscribeCandles(CandleType);
		subscription
			.BindEx(innerBand, outerBand, (candle, innerVal, outerVal) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!innerBand.IsFormed || !outerBand.IsFormed)
					return;

				if (innerVal.IsEmpty || outerVal.IsEmpty)
					return;

				var innerBb = innerVal as IBollingerBandsValue;
				var outerBb = outerVal as IBollingerBandsValue;

				if (innerBb == null || outerBb == null)
					return;

				var innerUpper = innerBb.UpBand ?? 0;
				var innerLower = innerBb.LowBand ?? 0;
				var outerUpper = outerBb.UpBand ?? 0;
				var outerLower = outerBb.LowBand ?? 0;

				if (innerUpper == 0 || innerLower == 0 || outerUpper == 0 || outerLower == 0)
					return;

				if (!IsFormedAndOnlineAndAllowTrading())
					return;

				var price = candle.ClosePrice;
				var signal = 0;

				// Detect outer band breakout
				if (price > outerUpper)
					waitDirection = 1;
				else if (price < outerLower)
					waitDirection = -1;

				// Check re-entry into inner band
				if (waitDirection > 0 && price < innerUpper && price > innerLower)
				{
					signal = 1;
					waitDirection = 0;
				}
				else if (waitDirection < 0 && price > innerLower && price < innerUpper)
				{
					signal = -1;
					waitDirection = 0;
				}

				if (signal == 1 && Position <= 0)
					BuyMarket();
				else if (signal == -1 && Position >= 0)
					SellMarket();
			})
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, innerBand);
			DrawIndicator(area, outerBand);
			DrawOwnTrades(area);
		}
	}
}