Ver en GitHub

Estrategia Symr de Nueva Barra

La Estrategia Symr de Nueva Barra demuestra cómo detectar el comienzo de nuevas velas en múltiples marcos temporales usando una única suscripción. La estrategia monitorea un marco temporal base y calcula cuándo comienzan intervalos más grandes como 5m, 15m, 30m, 1h, 4h, 1d, 20m y 55m. Cada barra detectada se registra en el log.

Detalles

  • Criterios de entrada: Ninguno. La estrategia no coloca operaciones.
  • Criterios de salida: Ninguno.
  • Largo/Corto: No aplica.
  • Stops: No se utilizan stops.

Parámetros

Nombre Predeterminado Descripción
CandleType TimeSpan.FromMinutes(1).TimeFrame() Marco temporal base para la detección de nuevas barras.

Notas

  • Almacena el último tiempo de apertura para cada período predefinido.
  • Cuando el período base avanza, se evalúan y registran los períodos más grandes si se reinician.
  • Útil como plantilla para el manejo de eventos en múltiples marcos temporales.
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>
/// Strategy that detects new bar openings and trades breakouts.
/// Enters when price breaks the high/low of the previous bar with EMA confirmation.
/// </summary>
public class SymrNewBarStrategy : Strategy
{
	private readonly StrategyParam<int> _emaLength;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevHigh;
	private decimal _prevLow;
	private bool _hasPrev;

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

	public SymrNewBarStrategy()
	{
		_emaLength = Param(nameof(EmaLength), 20)
			.SetGreaterThanZero()
			.SetDisplay("EMA Length", "EMA period for trend filter", "Indicators");

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Type of candles", "General");
	}

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

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevHigh = 0;
		_prevLow = 0;
		_hasPrev = false;
	}

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

		var ema = new ExponentialMovingAverage { Length = EmaLength };

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

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

		var close = candle.ClosePrice;

		if (!_hasPrev)
		{
			_prevHigh = candle.HighPrice;
			_prevLow = candle.LowPrice;
			_hasPrev = true;
			return;
		}

		// Breakout above previous high with EMA confirmation
		if (close > _prevHigh && close > emaVal && Position <= 0)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		// Breakout below previous low with EMA confirmation
		else if (close < _prevLow && close < emaVal && Position >= 0)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}

		_prevHigh = candle.HighPrice;
		_prevLow = candle.LowPrice;
	}
}