Auf GitHub ansehen

BBStrategy-Strategie

Überblick

BBStrategy ist ein Bollinger-Band-Breakout-System, das aus dem MetaTrader-Expertenberater „BBStrategy“ abgeleitet wurde. Die Strategie verfolgt zwei Sätze von Bollinger-Bändern mit demselben Zeitraum, aber unterschiedlichen Abweichungsmultiplikatoren. Wenn der Preis das äußere Band durchbricht, aktiviert der Algorithmus einen Handel, ein tatsächlicher Einstieg wird jedoch verschoben, bis der Preis wieder in das innere Band zurückkehrt. Durch dieses Verhalten wird versucht, den Kauf überzogener Ausbrüche oder den Verkauf stark überverkaufter Bedingungen zu vermeiden und gleichzeitig die Fortsetzungsbewegung nach einer Volatilitätsexpansion zu erfassen.

Kernlogik

  1. Abonnieren Sie Kerzen und berechnen Sie zwei Bollinger-Bänder:
    • Äußeres Band verwendet einen konfigurierbaren Abweichungsmultiplikator (Standard 3,0).
    • Inneres Band verwendet eine geringere Abweichung (Standard 2,0).
  2. Erkennen Sie, wann der Schlusskurs außerhalb des äußeren Bandes endet:
    • Über den oberen äußeren Bandarmen befindet sich ein langer Aufbau.
    • Unterhalb der unteren äußeren Bandarme ein kurzer Aufbau.
  3. Steigen Sie nur dann ein, wenn die nächste abgeschlossene Kerze wieder innerhalb des inneren Bandes in Richtung des Ausbruchs schließt. Während der Preis darauf wartet, wieder einzusteigen, bleibt die Strategie im „Wartezustand“ auf die entsprechende Richtung.
  4. Senden Sie eine einzelne Marktorder, wenn die Bedingungen übereinstimmen und keine offenen Positionen oder aktiven Orders vorhanden sind. Bestehende Gegenpositionen werden durch Erhöhung des Volumens der Market Order geschlossen.
  5. Optionale Take-Profit- und Stop-Loss-Distanzen (ausgedrückt in Punkten) werden in absolute Preis-Offsets umgewandelt und über den integrierten Schutzhelfer verwaltet.

Parameter

Name Beschreibung
Bestellvolumen Handelsgröße für jede Position.
Bollinger Zeitraum Anzahl der Kerzen, die für beide Bollinger-Bandberechnungen verwendet werden.
Innere Abweichung Abweichungsmultiplikator für das innere Band, der Pullbacks validiert.
Äußere Abweichung Abweichungsmultiplikator für das äußere Band, das Ausbrüche erkennt.
Stop-Loss-Punkte Abstand des Schutzstopps in Punkten (0 deaktiviert den Stopp).
Take-Profit-Punkte Take-Profit-Distanz in Punkten (0 deaktiviert das Ziel).
Kerzentyp Kerzenzeitrahmen für Berechnungen.

Notizen

  • Die Strategie handelt jeweils nur eine Position und ignoriert neue Signale, solange Aufträge aktiv sind.
  • Für das Risikomanagement wandelt der Helfer MetaTrader „Punkte“ in tatsächliche Preiserhöhungen basierend auf der Tick-Größe des Instruments um.
  • Diagrammzeichnungen umfassen Kerzen, beide Bollinger-Bänder und die eigenen Trades der Strategie, um das visuelle Debuggen zu erleichtern.
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);
		}
	}
}