Ver en GitHub

Estrategia Three Black Crows

Tres Cuervos Negros es el equivalente bajista de Tres Soldados Blancos, compuesto por tres velas largas bajistas después de un avance. El patrón sugiere que los vendedores han tomado el control, ya que cada cierre cae cerca del mínimo de la sesión.

Las pruebas indican un rendimiento anual promedio de aproximadamente 178%. Funciona mejor en el mercado de acciones.

Esta estrategia inicia una posición corta una vez que aparece el tercer cuervo, esperando que el impulso continúe a la baja. También puede usarse para salir de posiciones largas abiertas por otros sistemas si el patrón se forma en resistencia.

El riesgo se gestiona con un stop porcentual ajustado por encima del máximo del patrón, y las operaciones se cierran si el precio vuelve a cerrar por encima de ese nivel.

Detalles

  • Criterios de entrada: coincidencia de patrón
  • Largo/Corto: Ambos
  • Criterios de salida: stop-loss o señal opuesta
  • Stops: Sí, basado en porcentaje
  • Valores predeterminados:
    • CandleType = 15 minutos
    • StopLossPercent = 2 La estrategia solo vende. El stop se coloca StopLossPercent por encima del máximo más alto del patrón y la posición se cierra cuando una vela cierra por encima.
  • Filtros:
    • Categoría: Patrón
    • Dirección: Ambos
    • Indicadores: Candlestick
    • Stops: Sí
    • Complejidad: Intermedio
    • Marco temporal: Intradía
    • Estacionalidad: No
    • Redes neuronales: No
    • Divergencia: No
    • Nivel de riesgo: Medio
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);
	}
}