Auf GitHub ansehen

Strategie Three Black Crows

Drei Schwarze Krähen ist das bärische Gegenstück zu Drei Weißen Soldaten und besteht aus drei langen Abwärtskerzen nach einem Aufschwung. Das Muster deutet darauf hin, dass die Verkäufer die Kontrolle übernommen haben, da jeder Schlusskurs nahe dem Sitzungstief liegt.

Tests zeigen eine durchschnittliche jährliche Rendite von etwa 178%. Die Strategie funktioniert am besten am Aktienmarkt.

Diese Strategie eröffnet eine Short-Position, sobald die dritte Krähe erscheint, und erwartet, dass der Schwung weiter nach unten geht. Sie kann auch verwendet werden, um Longs zu schließen, die von anderen Systemen eröffnet wurden, wenn das Muster am Widerstand entsteht.

Das Risiko wird mit einem engen prozentualen Stop oberhalb des Musterhochs gesteuert, und Trades werden beendet, wenn der Preis wieder über dieses Niveau schließt.

Details

  • Einstiegskriterien: Mustererkennung
  • Long/Short: Beide
  • Ausstiegskriterien: Stop-Loss oder entgegengesetztes Signal
  • Stops: Ja, prozentbasiert
  • Standardwerte:
    • CandleType = 15 Minuten
    • StopLossPercent = 2 Die Strategie verkauft nur. Der Stop liegt StopLossPercent über dem höchsten Hoch des Musters, und die Position schließt, wenn eine Kerze darüber schließt.
  • Filter:
    • Kategorie: Muster
    • Richtung: Beide
    • Indikatoren: Candlestick
    • Stops: Ja
    • Komplexität: Mittel
    • Zeitrahmen: Intraday
    • Saisonalität: Nein
    • Neuronale Netze: Nein
    • Divergenz: Nein
    • Risikolevel: Mittel
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>
/// Three Black Crows strategy.
/// While flat it sells after three bearish candles in a row, each closing below the previous close.
/// The stop lies StopLossPercent above the pattern's highest high, and a close beyond it closes the position.
/// </summary>
public class ThreeBlackCrowsStrategy : Strategy
{
	private readonly StrategyParam<decimal> _stopLossPercent;
	private readonly StrategyParam<DataType> _candleType;

	private readonly List<ICandleMessage> _candles = [];
	private decimal _stopPrice;

	/// <summary>
	/// Distance of the stop beyond the pattern, in percent.
	/// </summary>
	public decimal StopLossPercent
	{
		get => _stopLossPercent.Value;
		set => _stopLossPercent.Value = value;
	}

	/// <summary>
	/// Candle type.
	/// </summary>
	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	/// <summary>
	/// Constructor.
	/// </summary>
	public ThreeBlackCrowsStrategy()
	{
		_stopLossPercent = Param(nameof(StopLossPercent), 2m)
			.SetNotNegative()
			.SetDisplay("Stop Loss %", "Distance of the stop beyond the pattern, in percent", "Risk");

		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(15).TimeFrame())
			.SetDisplay("Candle Type", "Type of candles to use", "General");
	}

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

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_candles.Clear();
		_stopPrice = default;
	}

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

		_candles.Clear();
		_stopPrice = default;

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

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

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

		_candles.Add(candle);

		if (_candles.Count > 3)
			_candles.RemoveAt(0);

		if (!IsFormedAndOnlineAndAllowTrading())
			return;

		if (Position < 0)
		{
			if (candle.ClosePrice >= _stopPrice)
				BuyMarket(-Position);

			return;
		}

		if (Position != 0 || _candles.Count < 3)
			return;

		var c0 = _candles[0];
		var c1 = _candles[1];
		var c2 = _candles[2];

		if (!(c0.ClosePrice < c0.OpenPrice && c1.ClosePrice < c1.OpenPrice && c2.ClosePrice < c2.OpenPrice && c1.ClosePrice < c0.ClosePrice && c2.ClosePrice < c1.ClosePrice))
			return;

		SellMarket(Volume);
		_stopPrice = Math.Max(Math.Max(c0.HighPrice, c1.HighPrice), c2.HighPrice) * (1 + StopLossPercent / 100m);
	}
}