Ver no GitHub

Estratégia LotScalp

Esta estratégia abre uma única operação por dia em uma hora especificada com base na diferença entre as aberturas de velas passadas.

Como Funciona

  1. Aguardar o Horário de Negociação: A estratégia monitora os horários de abertura das velas. Uma vez que a hora seja maior que TradeTime, a negociação é permitida na próxima ocorrência dessa hora.
  2. Geração de Sinais:
    • Quando a hora atual é igual a TradeTime, a estratégia compara o preço de abertura de t1 barras atrás com o preço de abertura de t2 barras atrás.
    • Se a diferença Open[t1] - Open[t2] exceder DeltaShort pontos, uma posição vendida é aberta.
    • Se a diferença Open[t2] - Open[t1] exceder DeltaLong pontos, uma posição comprada é aberta.
  3. Gestão de Posições:
    • Para posições compradas, a estratégia sai quando o preço alcança TakeProfitLong acima da entrada ou StopLossLong abaixo dela.
    • Para posições vendidas, sai quando o preço se move TakeProfitShort abaixo ou StopLossShort acima da entrada.
    • As posições também são fechadas se permanecerem abertas por mais de MaxOpenTime horas.

A estratégia opera com volume fixo e não entra em novas operações até o dia seguinte.

Parâmetros

Nome Descrição
CandleType Fonte de velas para a estratégia.
Volume Volume da ordem.
TakeProfitLong Take profit em pontos para operações compradas.
StopLossLong Stop loss em pontos para operações compradas.
TakeProfitShort Take profit em pontos para operações vendidas.
StopLossShort Stop loss em pontos para operações vendidas.
TradeTime Hora do dia em que os sinais são avaliados.
T1 Número de barras atrás para o primeiro preço de abertura.
T2 Número de barras atrás para o segundo preço de abertura.
DeltaLong Diferença mínima (em pontos) entre Open[t2] e Open[t1] para abrir uma operação comprada.
DeltaShort Diferença mínima (em pontos) entre Open[t1] e Open[t2] para abrir uma operação vendida.
MaxOpenTime Tempo máximo de manutenção em horas.

Notas

  • Apenas velas concluídas são processadas.
  • A estratégia usa o passo de preço do instrumento para converter limites baseados em pontos em preços absolutos.
  • Nenhum indicador adicional é utilizado.
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;
	}
}