Ver no GitHub

Estratégia eInTradePanel

A estratégia eInTradePanel automatiza o fluxo de trabalho do painel de negociação original do MetaTrader. Ela permite os mesmos oito modos de ordem (mercado, stop, limite e stop-limite em ambas as direções) enquanto calcula automaticamente distâncias de disparo, entrada, stop-loss e take-profit a partir do spread atual e uma estimativa de ATR sensível à volatilidade. Ordens de proteção são simuladas através do monitoramento de velas para que a estratégia possa ser usada com provedores de dados que não suportam ordens SL/TP anexadas.

Destaques

  • Modos de ordem – escolher entre Buy, Sell, Buy/Sell Stop, Buy/Sell Limit ou Buy/Sell Stop-Limit. Ordens stop-limite são armadas assim que o preço alcança a distância de disparo e então submetem a entrada limite.
  • Distâncias dinâmicas – níveis pendentes, disparadores, stops e alvos são proporcionais ao maior entre o spread atual ou um spread sintético derivado do ATR (ATR × AtrFactor). Quando o ATR não está pronto, uma distância de tick base configurável é usada.
  • Adaptação à volatilidade – o comprimento do ATR segue o painel original (55) para que os offsets reajam a mudanças de regime sem ajuste extra.
  • Expiração de ordens – janela de cancelamento opcional com imposição de tempo mínimo de vida (padrão 11 minutos) mantém ordens pendentes obsoletas fora do livro.
  • Gestão de risco – cada posição aberta é monitorada em cada vela fechada; se o máximo/mínimo perfura o stop ou alvo calculado, a posição é fechada a mercado.
  • Consciência de cotação – a estratégia se inscreve no livro de ordens para obter os melhores preços de oferta/demanda para cálculos de offset mais precisos, recorrendo a fechamentos de velas quando a profundidade não está disponível.

Parâmetros

Nome Descrição
Volume Tamanho de ordem usado para todas as entradas.
Mode Modo de entrada (mercado, stop, limite ou stop-limite).
Candle Type Agregação usada para ATR e verificações de execução baseadas em velas.
Base Ticks Distância mínima de tick quando os dados de ATR não estão disponíveis.
Pending Multiplier Multiplicador aplicado à distância de tick base para offsets de ordens pendentes.
Trigger Multiplier Multiplicador adicional para distâncias de disparo stop-limite.
Stop Multiplier Multiplicador para distância de stop-loss (definir como 0 para desabilitar).
Take Multiplier Multiplicador para distância de take-profit (definir como 0 para desabilitar).
Use ATR Habilita o escalonamento baseado em ATR de todas as distâncias.
ATR Factor Fração do ATR tratada como spread sintético ao escalonar.
Expiration Minutos até que as ordens pendentes sejam canceladas (0 as mantém GTC).
Min Expiration Tempo de vida mínimo pendente em minutos, replicando a proteção do painel.

Lógica de negociação

  1. Preparação de dados – a estratégia se inscreve no tipo de vela configurado e mantém um ATR de 55 períodos atualizado. Instantâneos do livro de ordens atualizam o último preço de oferta/demanda visto.
  2. Cálculo de distâncias – cada vela finalizada recalcula a distância de tick base a partir do ATR e spread, então deriva preços pendentes, de disparo, stop e take-profit de acordo com o modo selecionado.
  3. Submissão de ordens
    • Os modos de mercado executam imediatamente na próxima vela finalizada enquanto a estratégia está plana.
    • Os modos stop e limite colocam a ordem pendente correspondente e opcionalmente a cancelam após a janela de expiração.
    • Os modos stop-limite aguardam até que o preço de disparo seja impresso pelo máximo/mínimo da vela, então submetem a entrada limite.
  4. Supervisão de posição – uma vez que uma posição está aberta, a estratégia verifica as velas completadas para violações de stop ou alvo e fecha a posição a mercado se qualquer nível for violado.
  5. Reinicialização de estado – quando a estratégia está plana e nenhuma ordem está ativa, os níveis são recalculados para que uma nova operação possa ser preparada na próxima vela.

A abordagem reflete o painel manual enquanto permanece compatível com a API de alto nível do StockSharp e o fluxo de ordens assíncrono.

using System;
using System.Collections.Generic;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// EInTradePanel strategy. Uses ATR breakout for entries.
/// </summary>
public class EInTradePanelStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _atrPeriod;
	private readonly StrategyParam<decimal> _multiplier;
	private decimal? _prevClose;
	private decimal? _prevAtr;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int AtrPeriod { get => _atrPeriod.Value; set => _atrPeriod.Value = value; }
	public decimal Multiplier { get => _multiplier.Value; set => _multiplier.Value = value; }

	public EInTradePanelStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame()).SetDisplay("Candle Type", "Timeframe", "General");
		_atrPeriod = Param(nameof(AtrPeriod), 14).SetGreaterThanZero().SetDisplay("ATR Period", "ATR lookback", "Indicators");
		_multiplier = Param(nameof(Multiplier), 1.5m).SetDisplay("Multiplier", "ATR multiplier for breakout", "Indicators");
	}

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

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevClose = null;
		_prevAtr = null;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevClose = null; _prevAtr = null;
		var atr = new AverageTrueRange { Length = AtrPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(atr, ProcessCandle).Start();
		var area = CreateChartArea();
		if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, atr); DrawOwnTrades(area); }
	}

	private void ProcessCandle(ICandleMessage candle, decimal atrVal)
	{
		if (candle.State != CandleStates.Finished) return;
		if (!IsFormedAndOnlineAndAllowTrading()) { _prevClose = candle.ClosePrice; _prevAtr = atrVal; return; }
		if (_prevClose == null || _prevAtr == null) { _prevClose = candle.ClosePrice; _prevAtr = atrVal; return; }
		var threshold = _prevAtr.Value * Multiplier;
		var diff = candle.ClosePrice - _prevClose.Value;
		if (diff > threshold && Position <= 0) { if (Position < 0) BuyMarket(); BuyMarket(); }
		else if (diff < -threshold && Position >= 0) { if (Position > 0) SellMarket(); SellMarket(); }
		_prevClose = candle.ClosePrice; _prevAtr = atrVal;
	}
}