Auf GitHub ansehen

CandlesticksBW-Strategie

Diese Strategie repliziert den Bill Williams CandlesticksBW-Ansatz. Jede Kerze wird anhand des Momentums des Awesome Oscillator (AO) und des Accelerator Oscillator (AC) eingefärbt. Die Strategie öffnet oder schließt Positionen basierend auf Übergängen zwischen bullischen und bearischen Farben.

Funktionsweise

  • Berechnet AO als Differenz zwischen 5- und 34-Perioden-SMAs des Medianpreises.
  • Berechnet AC als AO minus 5-Perioden-SMA des AO.
  • Jede Kerze wird in sechs Farben eingeteilt, abhängig vom AO/AC-Wachstum und der Kerzenrichtung.
  • Ein bullisches Setup tritt auf, wenn die vorletzte Kerze bullisch ist (Farbe 0 oder 1). Wenn die Farbe der letzten Kerze über 1 liegt, wird eine Long-Position eröffnet und Short-Positionen werden geschlossen.
  • Ein bearisches Setup tritt auf, wenn die vorletzte Kerze bearisch ist (Farbe 4 oder 5). Wenn die Farbe der letzten Kerze unter 4 liegt, wird eine Short-Position eröffnet und Long-Positionen werden geschlossen.
  • Stops und Ziele werden über StartProtection angewendet.

Parameter

  • CandleType – Kerzen-Zeitrahmen.
  • SignalBar – Versatz-Balken für die Signalauswertung.
  • StopLoss – Stop-Loss-Distanz in Punkten.
  • TakeProfit – Take-Profit-Distanz in Punkten.
  • BuyPosOpen – Long-Positionen öffnen erlauben.
  • SellPosOpen – Short-Positionen öffnen erlauben.
  • BuyPosClose – Long-Positionen schließen erlauben.
  • SellPosClose – Short-Positionen schließen erlauben.

Indikatoren

  • Awesome Oscillator (aus SMAs abgeleitet).
  • Accelerator Oscillator.

Handelsregeln

  • Long-Einstieg: vorletzte Kerzenfarbe <2 und letzte Farbe >1.
  • Short-Einstieg: vorletzte Kerzenfarbe >3 und letzte Farbe <4.
  • Long-Ausstieg: bei Short-Einstiegsbedingung wenn Position >0.
  • Short-Ausstieg: bei Long-Einstiegsbedingung wenn Position <0.
using System;
using System.Collections.Generic;

using Ecng.Common;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// CandlesticksBW strategy based on Bill Williams' color classification of candles.
/// Uses Awesome and Accelerator oscillators to detect momentum shifts.
/// </summary>
public class CandlesticksBwStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;

	private SimpleMovingAverage _aoFast;
	private SimpleMovingAverage _aoSlow;
	private SimpleMovingAverage _acMa;

	private decimal _prevAo;
	private decimal _prevAc;
	private bool _hasPrev;
	private int _prevColor = -1;

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

	public CandlesticksBwStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Time frame for analysis", "General");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		return [(Security, CandleType)];
	}

	protected override void OnReseted()
	{
		base.OnReseted();
		_aoFast = null;
		_aoSlow = null;
		_acMa = null;
		_prevAo = 0;
		_prevAc = 0;
		_hasPrev = false;
		_prevColor = -1;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_prevAo = 0;
		_prevAc = 0;
		_hasPrev = false;
		_prevColor = -1;

		_aoFast = new SimpleMovingAverage { Length = 5 };
		_aoSlow = new SimpleMovingAverage { Length = 34 };
		_acMa = new SimpleMovingAverage { Length = 5 };

		Indicators.Add(_aoFast);
		Indicators.Add(_aoSlow);
		Indicators.Add(_acMa);

		var sma = new SimpleMovingAverage { Length = 1 };

		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(sma, ProcessCandle).Start();

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

	private void ProcessCandle(ICandleMessage candle, decimal _unused)
	{
		if (candle.State != CandleStates.Finished)
			return;

		var hl2 = (candle.HighPrice + candle.LowPrice) / 2m;
		var t = candle.CloseTime;

		var aoFastResult = _aoFast.Process(hl2, t, true);
		var aoSlowResult = _aoSlow.Process(hl2, t, true);

		if (!_aoFast.IsFormed || !_aoSlow.IsFormed)
			return;

		var ao = aoFastResult.GetValue<decimal>() - aoSlowResult.GetValue<decimal>();
		var acMaResult = _acMa.Process(ao, t, true);

		if (!_acMa.IsFormed)
			return;

		var ac = ao - acMaResult.GetValue<decimal>();

		// Bill Williams candle color classification:
		// 0 = green (bullish candle + AO up + AC up)
		// 1 = fade (bearish candle + AO up + AC up)
		// 2 = squat green (bullish, mixed)
		// 3 = squat red (bearish, mixed)
		// 4 = fake (bullish candle + AO down + AC down)
		// 5 = red (bearish candle + AO down + AC down)
		int color;
		if (_hasPrev && ao >= _prevAo && ac >= _prevAc)
			color = candle.OpenPrice <= candle.ClosePrice ? 0 : 1;
		else if (_hasPrev && ao <= _prevAo && ac <= _prevAc)
			color = candle.OpenPrice >= candle.ClosePrice ? 5 : 4;
		else
			color = candle.OpenPrice <= candle.ClosePrice ? 2 : 3;

		_prevAo = ao;
		_prevAc = ac;
		_hasPrev = true;

		if (!IsFormedAndOnline())
		{
			_prevColor = color;
			return;
		}

		if (_prevColor < 0)
		{
			_prevColor = color;
			return;
		}

		// Bullish signal: prev was up momentum (0 or 1), current transitions
		if (_prevColor < 2 && color > 1 && Position <= 0)
			BuyMarket();
		// Bearish signal: prev was down momentum (4 or 5), current transitions
		else if (_prevColor > 3 && color < 4 && Position >= 0)
			SellMarket();

		_prevColor = color;
	}
}