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
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.
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.
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.
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.
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;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import AverageTrueRange
from StockSharp.Algo.Strategies import Strategy
class e_in_trade_panel_strategy(Strategy):
def __init__(self):
super(e_in_trade_panel_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._atr_period = self.Param("AtrPeriod", 14) \
.SetDisplay("ATR Period", "ATR lookback", "Indicators")
self._multiplier = self.Param("Multiplier", 1.5) \
.SetDisplay("Multiplier", "ATR multiplier for breakout", "Indicators")
self._prev_close = None
self._prev_atr = None
@property
def CandleType(self):
return self._candle_type.Value
@property
def AtrPeriod(self):
return self._atr_period.Value
@property
def Multiplier(self):
return self._multiplier.Value
def OnReseted(self):
super(e_in_trade_panel_strategy, self).OnReseted()
self._prev_close = None
self._prev_atr = None
def OnStarted2(self, time):
super(e_in_trade_panel_strategy, self).OnStarted2(time)
self._prev_close = None
self._prev_atr = None
atr = AverageTrueRange()
atr.Length = self.AtrPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(atr, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, atr)
self.DrawOwnTrades(area)
def _on_process(self, candle, atr_value):
if candle.State != CandleStates.Finished:
return
av = float(atr_value)
close = float(candle.ClosePrice)
if self._prev_close is None or self._prev_atr is None:
self._prev_close = close
self._prev_atr = av
return
threshold = self._prev_atr * float(self.Multiplier)
diff = close - self._prev_close
if diff > threshold and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif diff < -threshold and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_close = close
self._prev_atr = av
def CreateClone(self):
return e_in_trade_panel_strategy()