Ver en GitHub

Estrategia LotScalp

Esta estrategia abre una sola operación por día a una hora especificada basándose en la diferencia entre las aperturas de velas pasadas.

Cómo Funciona

  1. Esperar el Momento de Operar: La estrategia monitorea los tiempos de apertura de velas. Una vez que la hora es mayor que TradeTime, el trading se permite en la próxima ocurrencia de esa hora.
  2. Generación de Señales:
    • Cuando la hora actual es igual a TradeTime, la estrategia compara el precio de apertura de hace t1 barras con el precio de apertura de hace t2 barras.
    • Si la diferencia Open[t1] - Open[t2] supera DeltaShort puntos, se abre una posición corta.
    • Si la diferencia Open[t2] - Open[t1] supera DeltaLong puntos, se abre una posición larga.
  3. Gestión de Posiciones:
    • Para posiciones largas, la estrategia sale cuando el precio alcanza TakeProfitLong por encima de la entrada o StopLossLong por debajo.
    • Para posiciones cortas, sale cuando el precio se mueve TakeProfitShort por debajo o StopLossShort por encima de la entrada.
    • Las posiciones también se cierran si permanecen abiertas más de MaxOpenTime horas.

La estrategia opera con un volumen fijo y no entra en nuevas operaciones hasta el día siguiente.

Parámetros

Nombre Descripción
CandleType Fuente de velas para la estrategia.
Volume Volumen de la orden.
TakeProfitLong Toma de ganancias en puntos para operaciones largas.
StopLossLong Stop loss en puntos para operaciones largas.
TakeProfitShort Toma de ganancias en puntos para operaciones cortas.
StopLossShort Stop loss en puntos para operaciones cortas.
TradeTime Hora del día en que se evalúan las señales.
T1 Número de barras hacia atrás para el primer precio de apertura.
T2 Número de barras hacia atrás para el segundo precio de apertura.
DeltaLong Diferencia mínima (en puntos) entre Open[t2] y Open[t1] para abrir una operación larga.
DeltaShort Diferencia mínima (en puntos) entre Open[t1] y Open[t2] para abrir una operación corta.
MaxOpenTime Tiempo máximo de mantenimiento en horas.

Notas

  • Solo se procesan velas completadas.
  • La estrategia usa el paso de precio del instrumento para convertir umbrales basados en puntos en precios absolutos.
  • No se utilizan indicadores adicionales.
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>
/// Scalping strategy comparing past open prices with EMA trend filter.
/// </summary>
public class LotScalpStrategy : Strategy
{
	private readonly StrategyParam<int> _emaPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevOpen;
	private decimal _prevPrevOpen;
	private int _barCount;

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

	public LotScalpStrategy()
	{
		_emaPeriod = Param(nameof(EmaPeriod), 20)
			.SetGreaterThanZero()
			.SetDisplay("EMA Period", "EMA period for trend", "Indicators");
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Candle source", "General");
	}

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

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevOpen = 0;
		_prevPrevOpen = 0;
		_barCount = 0;
	}

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

		var ema = new ExponentialMovingAverage { Length = EmaPeriod };
		SubscribeCandles(CandleType).Bind(ema, ProcessCandle).Start();
	}

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

		_barCount++;
		var close = candle.ClosePrice;
		var open = candle.OpenPrice;

		if (_barCount >= 3)
		{
			var diff = _prevPrevOpen - _prevOpen;

			// Open prices diverging downward + close above EMA => buy
			if (diff > 0 && close > emaValue && Position <= 0)
			{
				if (Position < 0) BuyMarket();
				BuyMarket();
			}
			// Open prices diverging upward + close below EMA => sell
			else if (diff < 0 && close < emaValue && Position >= 0)
			{
				if (Position > 0) SellMarket();
				SellMarket();
			}
		}

		_prevPrevOpen = _prevOpen;
		_prevOpen = open;
	}
}