The eInTradePanel strategy automates the workflow of the original MetaTrader trade panel. It allows the same eight order modes (market, stop, limit and stop-limit in both directions) while automatically computing trigger, entry, stop-loss and take-profit distances from the current spread and a volatility-sensitive ATR estimate. Protective orders are simulated through candle monitoring so the strategy can be used with data vendors that do not support attached SL/TP orders.
Highlights
Order modes – choose between Buy, Sell, Buy/Sell Stop, Buy/Sell Limit or Buy/Sell Stop-Limit. Stop-limit orders are armed once price reaches the trigger distance and then submit the limit entry.
Dynamic distances – pending levels, triggers, stops and targets are proportional to the larger of the current spread or an ATR-derived synthetic spread (ATR × AtrFactor). When ATR is not ready, a configurable base tick distance is used.
Volatility adaptation – ATR length follows the original panel (55) so offsets react to regime changes without extra tuning.
Order expiration – optional cancellation window with minimum lifetime enforcement (default 11 minutes) keeps stale pending orders off the book.
Risk management – every open position is watched on each closed candle; if the high/low pierces the computed stop or target the position is closed at market.
Quote awareness – the strategy subscribes to the order book to obtain best bid/ask prices for more accurate offset calculations, falling back to candle closes when depth is unavailable.
Parameters
Name
Description
Volume
Order size used for all entries.
Mode
Entry mode (market, stop, limit or stop-limit).
Candle Type
Aggregation used for ATR and candle-based execution checks.
Base Ticks
Minimum tick distance when ATR data is not available.
Pending Multiplier
Multiplier applied to the base tick distance for pending order offsets.
Trigger Multiplier
Additional multiplier for stop-limit trigger distances.
Stop Multiplier
Multiplier for stop-loss distance (set to 0 to disable).
Take Multiplier
Multiplier for take-profit distance (set to 0 to disable).
Use ATR
Enables ATR-based scaling of all distances.
ATR Factor
Fraction of ATR treated as synthetic spread when scaling.
Expiration
Minutes until pending orders are cancelled (0 keeps them GTC).
Min Expiration
Minimum pending lifetime in minutes, mirroring the panel's guardrail.
Trading Logic
Data preparation – the strategy subscribes to the configured candle type and keeps a 55-period ATR updated. Order book snapshots update the last seen bid/ask.
Distance calculation – every finished candle recomputes base tick distance from ATR and spread, then derives pending, trigger, stop and take-profit prices according to the selected mode.
Order submission –
Market modes execute immediately at the next finished candle while the strategy is flat.
Stop and limit modes place the corresponding pending order and optionally cancel it after the expiration window.
Stop-limit modes wait until the trigger price is printed by the candle high/low, then submit the limit entry.
Position supervision – once a position is open the strategy checks completed candles for stop or target breaches and closes the position at market if either level is violated.
State reset – when the strategy is flat and no order is active it recomputes levels so a new trade can be staged on the next candle.
The approach mirrors the manual panel while remaining compatible with the StockSharp high-level API and asynchronous order flow.
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()