Ver en GitHub

Estrategia N Candles

La estrategia N Candles replica el asesor experto MQL que entra en una operación cuando un número configurable de velas consecutivas comparten la misma dirección. Una vez que las N velas completadas más recientes son todas alcistas, la estrategia envía una orden de compra de mercado. Cuando todas son bajistas, envía una orden de venta de mercado. No se incluye lógica de salida; la posición debe gestionarse externamente o mediante estrategias adicionales.

Descripción general

  • Régimen de mercado: Funciona mejor en mercados que exhiben ráfagas cortas de momentum.
  • Instrumentos: Cualquier instrumento que soporte trading continuo (FX, futuros, cripto).
  • Marcos temporales: Configurables; por defecto velas de 1 hora.
  • Tipos de órdenes: Órdenes de mercado sin stops protectores ni objetivos.

Cómo funciona

  1. En cada vela completada la estrategia evalúa las últimas N velas.
  2. Si cada vela en esa ventana es alcista, emite una orden de compra de mercado con el volumen configurado.
  3. Si cada vela es bajista, emite una orden de venta de mercado.
  4. Las velas doji (apertura igual al cierre) reinician el conteo y suprimen el trading hasta que se forme una nueva racha.
  5. La estrategia no gestiona posiciones abiertas; las señales repetidas añaden a la dirección existente en cuentas de compensación neta.

Parámetros

  • Consecutive Candles: Número de velas idénticas requeridas antes de colocar una orden.
  • Volume: Tamaño de la orden de mercado enviada en cada señal.
  • Candle Type: Serie de velas usada para la detección de racha (marco temporal o tipo de vela personalizado).

Notas de uso

  • Dado que la estrategia carece de stops o salidas, combínela con gestión manual, estrategias protectoras o controles de riesgo de cartera.
  • En mercados muy volátiles considere reducir el recuento de velas o el marco temporal para capturar rachas más rápidas.
  • Rachas consecutivas excesivas pueden acumular posiciones grandes; monitoree el apalancamiento y los límites de cuenta.
using System;
using System.Linq;
using System.Collections.Generic;

using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Trades in the direction of consecutive candles of the same color.
/// </summary>
public class NCandlesStrategy : Strategy
{
	private readonly StrategyParam<int> _consecutiveCandles;
	private readonly StrategyParam<DataType> _candleType;

	private int _currentDirection;
	private int _streakLength;

	/// <summary>
	/// Number of identical candles that must appear in a row to trigger an order.
	/// </summary>
	public int ConsecutiveCandles
	{
		get => _consecutiveCandles.Value;
		set => _consecutiveCandles.Value = value;
	}


	/// <summary>
	/// The type of candles used for analysis.
	/// </summary>
	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	/// <summary>
	/// Initializes a new instance of the strategy.
	/// </summary>
	public NCandlesStrategy()
	{
		_consecutiveCandles = Param(nameof(ConsecutiveCandles), 4)
			.SetGreaterThanZero()
			.SetDisplay("Consecutive Candles", "Number of identical candles required", "General")
			
			.SetOptimize(2, 6, 1);


		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
			.SetDisplay("Candle Type", "Candles to analyze", "General");
	}

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

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();

		_currentDirection = 0;
		_streakLength = 0;
	}

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

		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;

		var direction = 0;

		if (candle.ClosePrice > candle.OpenPrice)
		{
			direction = 1;
		}
		else if (candle.ClosePrice < candle.OpenPrice)
		{
			direction = -1;
		}
		else
		{
			// Doji candle breaks the streak just like in the original expert.
			_currentDirection = 0;
			_streakLength = 0;
			return;
		}

		if (direction == _currentDirection)
		{
			_streakLength = Math.Min(_streakLength + 1, ConsecutiveCandles);
		}
		else
		{
			_currentDirection = direction;
			_streakLength = 1;
		}

		if (_streakLength < ConsecutiveCandles)
			return;

		if (direction > 0 && Position <= 0)
		{
			BuyMarket();
		}
		else if (direction < 0 && Position >= 0)
		{
			SellMarket();
		}
	}
}