Die eInTradePanel-Strategie automatisiert den Arbeitsablauf des ursprünglichen MetaTrader-Handelspanels. Sie ermöglicht dieselben acht Ordermodi (Markt, Stop, Limit und Stop-Limit in beide Richtungen), während sie Auslöse-, Einstiegs-, Stop-Loss- und Take-Profit-Abstände automatisch aus dem aktuellen Spread und einer volatilitätssensitiven ATR-Schätzung berechnet. Schutzorders werden durch Kerzenüberwachung simuliert, damit die Strategie mit Datenanbietern verwendet werden kann, die keine angehängten SL/TP-Orders unterstützen.
Highlights
Ordermodi – zwischen Buy, Sell, Buy/Sell Stop, Buy/Sell Limit oder Buy/Sell Stop-Limit wählen. Stop-Limit-Orders werden aktiviert, sobald der Preis die Auslösedistanz erreicht, und übermitteln dann den Limit-Einstieg.
Dynamische Abstände – ausstehende Niveaus, Auslöser, Stops und Ziele sind proportional zum Größeren aus aktuellem Spread oder einem ATR-abgeleiteten synthetischen Spread (ATR × AtrFactor). Wenn ATR nicht bereit ist, wird eine konfigurierbare Basis-Tick-Distanz verwendet.
Volatilitätsanpassung – die ATR-Länge folgt dem Originalpanel (55), sodass Offsets auf Regimewechsel reagieren ohne zusätzliche Abstimmung.
Order-Ablauf – optionales Stornierungsfenster mit Mindestlebensdauererzwingung (Standard 11 Minuten) hält veraltete ausstehende Orders aus dem Buch heraus.
Risikomanagement – jede offene Position wird bei jeder geschlossenen Kerze überwacht; wenn das Hoch/Tief den berechneten Stop oder das Ziel durchbricht, wird die Position zum Marktpreis geschlossen.
Kursbewusstsein – die Strategie abonniert das Orderbuch, um beste Geld-/Briefkurse für genauere Offset-Berechnungen zu erhalten, und greift auf Kerzenschlüsse zurück, wenn die Tiefe nicht verfügbar ist.
Parameter
Name
Beschreibung
Volume
Ordergröße für alle Einstiege.
Mode
Einstiegsmodus (Markt, Stop, Limit oder Stop-Limit).
Candle Type
Aggregation für ATR und kerzenbasierte Ausführungsprüfungen.
Base Ticks
Minimale Tick-Distanz wenn ATR-Daten nicht verfügbar sind.
Pending Multiplier
Multiplikator auf die Basis-Tick-Distanz für ausstehende Order-Offsets.
Trigger Multiplier
Zusätzlicher Multiplikator für Stop-Limit-Auslösedistanzen.
Stop Multiplier
Multiplikator für Stop-Loss-Distanz (auf 0 setzen zum Deaktivieren).
Take Multiplier
Multiplikator für Take-Profit-Distanz (auf 0 setzen zum Deaktivieren).
Use ATR
Aktiviert ATR-basierte Skalierung aller Abstände.
ATR Factor
Anteil des ATR, der beim Skalieren als synthetischer Spread behandelt wird.
Expiration
Minuten bis ausstehende Orders storniert werden (0 hält sie GTC).
Min Expiration
Mindestlebensdauer ausstehend in Minuten, spiegelt die Panel-Absicherung wider.
Handelslogik
Datenvorbereitung – die Strategie abonniert den konfigurierten Kerzentyp und hält einen 55-Perioden-ATR aktualisiert. Orderbuch-Snapshots aktualisieren das zuletzt gesehene Geld/Brief.
Abstandsberechnung – jede fertige Kerze berechnet die Basis-Tick-Distanz aus ATR und Spread neu, leitet dann ausstehende, Auslöse-, Stop- und Take-Profit-Preise gemäß dem ausgewählten Modus ab.
Orderübermittlung –
Marktmodi führen sofort auf der nächsten fertigen Kerze aus, während die Strategie flat ist.
Stop- und Limit-Modi platzieren die entsprechende ausstehende Order und stornieren sie optional nach dem Ablaufzeitfenster.
Stop-Limit-Modi warten, bis der Auslösepreis vom Hoch/Tief der Kerze gedruckt wird, dann übermitteln sie den Limit-Einstieg.
Positionsüberwachung – sobald eine Position offen ist, prüft die Strategie abgeschlossene Kerzen auf Stop- oder Zielverletzungen und schließt die Position zum Marktpreis, wenn ein Level verletzt wird.
Zustandsreset – wenn die Strategie flat ist und keine Order aktiv ist, werden Niveaus neu berechnet, damit ein neuer Trade auf der nächsten Kerze vorbereitet werden kann.
Der Ansatz spiegelt das manuelle Panel wider und bleibt dabei kompatibel mit der StockSharp High-Level-API und dem asynchronen Orderfluss.
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()