Ver no GitHub

Estratégia do temporizador EA

Esta estratégia é uma porta StockSharp do robô MetaTrader TimerEA. Ele se concentra na abertura e fechamento de negociações em horários programados com ordens pendentes opcionais, proteção de rastreamento e tratamento de ponto de equilíbrio.

Lógica de negociação

  • Programação
    • OpenTime aciona a colocação do pedido assim que a primeira vela concluída atinge o minuto configurado.
    • CloseTime força a liquidação da posição e opcionalmente cancela as ordens pendentes restantes.
  • Modos de pedido
    • Entradas de mercado, stop ou limite podem ser selecionadas. As ordens pendentes são colocadas a uma distância configurável (em etapas de preço) e podem expiram após o número especificado de minutos.
  • Controle de direção
    • Switches separados permitem permitir negociações longas e/ou curtas. Cada lado envia um pedido por corrida.
  • Gerenciamento de Riscos
    • Volume fixo ou dimensionamento baseado em equilíbrio (usando RiskFactor) imita a seleção do lote original.
    • As distâncias de stop-loss e take-profit são expressas em etapas de preço e recriadas após cada entrada.
    • A lógica de trailing stop mantém o stop em um deslocamento constante quando o lucro excede o buffer BreakEvenSteps. A trilha ativa somente quando a parada já estiver além do deslocamento inicial mais o TrailingStep.
  • Proteções
    • O requisito opcional de ponto de equilíbrio evita o rastreamento até que o limite mínimo de lucro seja alcançado.
    • Pedidos pendentes que expiram são cancelados automaticamente.

Parâmetros padrão

  • Modo de pedido: Mercado.
  • Compra/venda aberta: desativado.
  • Take Profit/Stop Loss: 10 passos cada.
  • Trailing stop e ponto de equilíbrio: desativados.
  • Distância pendente: 10 passos com expiração de 60 minutos.
  • Dimensionamento do lote: Volume manual = 1,0 (fator de risco = 1,0 para modo balanceado).
  • Tipo de vela: período de 1 minuto.

Notas

  • A estratégia opera em velas finalizadas e, portanto, reage com até uma barra de latência.
  • StockSharp usa um modelo de posição compensada, portanto, a exposição simultânea longa e curta não é suportada, mesmo que ambas as alternâncias estejam habilitado.
  • As etapas de preço são calculadas com Security.PriceStep. Instrumentos sem etapa configurada tratarão distâncias como preço bruto pontos.
namespace StockSharp.Samples.Strategies;

using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

/// <summary>
/// Timer EA strategy: SMA crossover with time-of-day filter.
/// Trades only during active session hours.
/// </summary>
public class TimerEaStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }

	public TimerEaStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_fastPeriod = Param(nameof(FastPeriod), 10)
			.SetGreaterThanZero()
			.SetDisplay("Fast Period", "Fast SMA period", "Indicators");
		_slowPeriod = Param(nameof(SlowPeriod), 30)
			.SetGreaterThanZero()
			.SetDisplay("Slow Period", "Slow SMA period", "Indicators");
	}

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

		var fast = new SimpleMovingAverage { Length = FastPeriod };
		var slow = new SimpleMovingAverage { Length = SlowPeriod };

		decimal? prevFast = null;
		decimal? prevSlow = null;

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fast, slow, (candle, fastVal, slowVal) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!IsFormedAndOnlineAndAllowTrading())
					return;

				if (prevFast.HasValue && prevSlow.HasValue)
				{
					if (prevFast.Value <= prevSlow.Value && fastVal > slowVal && Position <= 0)
						BuyMarket();
					else if (prevFast.Value >= prevSlow.Value && fastVal < slowVal && Position >= 0)
						SellMarket();
				}

				prevFast = fastVal;
				prevSlow = slowVal;
			})
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, fast);
			DrawIndicator(area, slow);
			DrawOwnTrades(area);
		}
	}
}