Die Strategie zur Absicherung beliebiger Positionen ist eine direkte Konvertierung des ursprünglichen Hedge any positions (barabashkakvn's edition) MQL5-Experts. Die StockSharp-Version hält die Kernidee intakt: Sie überwacht jedes offene Leg, das von der Strategie erstellt wurde, und öffnet sobald ein Leg eine definierte Anzahl von Pips verliert, sofort eine entgegengesetzte Position mit einer verstärkten Losgröße. Die Implementierung basiert auf der High-Level-StockSharp-API, sodass Hedge-Orders über Market-Orders platziert werden und das Positions-Tracking intern ohne benutzerdefinierten Orderrouting-Code behandelt wird.
Die Strategie kann optional einen ersten Trade platzieren, wenn sie startet. Danach reagiert sie einfach auf ungünstige Preisbewegungen und baut eine Treppe von Hedging-Trades auf, wobei jedes Leg als abgesichert markiert wird, damit dieselbe Position nicht mehrere entgegengesetzte Einstiege auslösen kann.
Hedging-Workflow
Kerzenfeed – ein konfigurierbarer CandleType treibt die Strategie. Es werden nur abgeschlossene Kerzen verarbeitet.
Verlustberechnung – bei jedem Kerzenschluss prüft die Strategie, ob sich der Schlusskurs gegen ein offenes Leg um mindestens LosingPips multipliziert mit der berechneten Pip-Größe bewegt hat.
Hedge-Ausführung – wenn ein verlierendes Leg gefunden wird, wird eine Market-Order in der entgegengesetzten Richtung gesendet. Das Ordervolumen entspricht dem ursprünglichen Leg-Volumen multipliziert mit LotCoefficient, gerundet auf den Instrument-Volumenschritt und auf das erlaubte Mindest-/Maximalvolumen beschränkt.
Zustandsaktualisierung – sobald eine entgegengesetzte Order versendet wird, wird das ursprüngliche Leg als abgesichert markiert und der neu eröffnete Trade als frisches Leg gespeichert, das selbst später abgesichert werden kann, wenn sich der Preis erneut umkehrt.
Parameter
Parameter
Beschreibung
Standard
CandleType
Zeitrahmen für die Bewertung von Preisbewegungen und Auslösung von Hedges.
1-Minuten-Kerzen
LosingPips
Anzahl der Pips, um die sich der Preis gegen ein Leg bewegen muss, bevor ein Hedge eröffnet wird.
5
LotCoefficient
Multiplikator, der beim Absenden der Hedge-Order auf das ursprüngliche Volumen angewendet wird.
2.0
AutoPlaceInitialTrade
Wenn aktiviert, sendet die Strategie beim Start automatisch den ersten Trade.
Deaktiviert
InitialVolume
Ordergröße für den optionalen ersten Trade. Gerundet auf den Instrument-Volumenschritt.
0.10
InitialDirection
Seite (Kauf oder Verkauf) für den optionalen ersten Trade.
Kauf
Hinweis: Die Strategy.Volume-Eigenschaft auf die Basisordergröße setzen, die die Strategie verwenden soll. Die obigen Parameter steuern nur Hedging-spezifisches Verhalten.
Verwendungsrichtlinien
Vor dem Starten der Strategie Security, Portfolio und das gewünschte Basis-Volume zuweisen.
LosingPips und LotCoefficient an die Volatilität und Risikotoleranz des ausgewählten Instruments anpassen.
AutoPlaceInitialTrade aktivieren, wenn die StockSharp-Version die allererste Position automatisch erstellen soll; andernfalls manuell ein erstes Leg öffnen oder eine andere Komponente verwenden.
Da die High-Level-StockSharp-API mit Nettopositionen arbeitet, wird die interne Leg-Liste verwendet, um die Hedging-Struktur zu emulieren. Kontoexposure überwachen, wenn auf Netting-Konten läuft.
Ausführungsberichte überprüfen: Jeder Hedge wird mit einer Market-Order platziert (BuyMarket oder SellMarket).
Unterschiede zum Original Expert
Margensvalidierung, Slippage-Prüfungen und ausführliche Ergebnisprotokollierung wurden entfernt; StockSharp meldet Ausführungsprobleme bereits über Strategie-Events.
Die Konvertierung verwendet abgeschlossene Kerzen statt Tick-für-Tick-Daten. Einen ausreichend kleinen Zeitrahmen wählen, wenn schnellere Reaktionszeiten benötigt werden.
Lot-Rundung basiert jetzt auf Security.VolumeStep, Security.MinVolume und Security.MaxVolume, um die Handelsregeln des Instruments einzuhalten.
Alerts, Benachrichtigungen und der nur-Tester-Zufalls-Anfangstrade aus der MQL-Version wurden absichtlich weggelassen. Der optionale automatische Einstiegsparameter ersetzt dieses Verhalten.
Empfohlene Erweiterungen
Das Hedging-Modul mit einer separaten Einstiegsstrategie kombinieren, die definiert, wann die erste Position erstellt werden soll.
Eigenkapitalbasierte Abschalteregeln oder maximale Tiefen-Limits hinzufügen, um unbegrenzte Hedging-Ketten zu verhindern.
Portfolio-Level-Monitoring integrieren, um sicherzustellen, dass Margeanforderungen innerhalb akzeptabler Grenzen bleiben.
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Hedge Any Positions strategy using ATR-based mean reversion.
/// Enters long when price drops below EMA by ATR threshold, enters short on rally above.
/// Uses stop-loss and take-profit for risk management.
/// </summary>
public class HedgeAnyPositionsStrategy : Strategy
{
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<int> _atrPeriod;
private readonly StrategyParam<decimal> _atrMultiplier;
private readonly StrategyParam<int> _stopLossPoints;
private readonly StrategyParam<int> _takeProfitPoints;
private ExponentialMovingAverage _ema;
private AverageTrueRange _atr;
private decimal _entryPrice;
private int _cooldown;
/// <summary>
/// EMA period.
/// </summary>
public int EmaPeriod
{
get => _emaPeriod.Value;
set => _emaPeriod.Value = value;
}
/// <summary>
/// ATR period.
/// </summary>
public int AtrPeriod
{
get => _atrPeriod.Value;
set => _atrPeriod.Value = value;
}
/// <summary>
/// Multiplier applied to ATR for entry threshold.
/// </summary>
public decimal AtrMultiplier
{
get => _atrMultiplier.Value;
set => _atrMultiplier.Value = value;
}
/// <summary>
/// Stop-loss distance in price steps.
/// </summary>
public int StopLossPoints
{
get => _stopLossPoints.Value;
set => _stopLossPoints.Value = value;
}
/// <summary>
/// Take-profit distance in price steps.
/// </summary>
public int TakeProfitPoints
{
get => _takeProfitPoints.Value;
set => _takeProfitPoints.Value = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="HedgeAnyPositionsStrategy"/> class.
/// </summary>
public HedgeAnyPositionsStrategy()
{
_emaPeriod = Param(nameof(EmaPeriod), 100)
.SetGreaterThanZero()
.SetDisplay("EMA Period", "EMA period for mean price", "Indicator");
_atrPeriod = Param(nameof(AtrPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("ATR Period", "ATR calculation period", "Indicator");
_atrMultiplier = Param(nameof(AtrMultiplier), 2m)
.SetGreaterThanZero()
.SetDisplay("ATR Multiplier", "Multiplier for entry distance", "Indicator");
_stopLossPoints = Param(nameof(StopLossPoints), 200)
.SetNotNegative()
.SetDisplay("Stop Loss", "Stop-loss distance in price steps", "Risk");
_takeProfitPoints = Param(nameof(TakeProfitPoints), 300)
.SetNotNegative()
.SetDisplay("Take Profit", "Take-profit distance in price steps", "Risk");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
yield return (Security, TimeSpan.FromMinutes(5).TimeFrame());
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_ema = null;
_atr = null;
_entryPrice = 0;
_cooldown = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_ema = new ExponentialMovingAverage { Length = EmaPeriod };
_atr = new AverageTrueRange { Length = AtrPeriod };
var subscription = SubscribeCandles(TimeSpan.FromMinutes(5).TimeFrame());
subscription.Bind(_ema, _atr, ProcessCandle);
subscription.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal emaValue, decimal atrValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!_ema.IsFormed || !_atr.IsFormed)
return;
if (_cooldown > 0)
{
_cooldown--;
return;
}
var close = candle.ClosePrice;
var step = Security?.PriceStep ?? 1m;
var threshold = atrValue * AtrMultiplier;
// Check SL/TP
if (Position > 0 && _entryPrice > 0)
{
if (StopLossPoints > 0 && close <= _entryPrice - StopLossPoints * step)
{
SellMarket();
_entryPrice = 0;
_cooldown = 80;
return;
}
if (TakeProfitPoints > 0 && close >= _entryPrice + TakeProfitPoints * step)
{
SellMarket();
_entryPrice = 0;
_cooldown = 80;
return;
}
}
else if (Position < 0 && _entryPrice > 0)
{
if (StopLossPoints > 0 && close >= _entryPrice + StopLossPoints * step)
{
BuyMarket();
_entryPrice = 0;
_cooldown = 80;
return;
}
if (TakeProfitPoints > 0 && close <= _entryPrice - TakeProfitPoints * step)
{
BuyMarket();
_entryPrice = 0;
_cooldown = 80;
return;
}
}
// Mean reversion: buy when price drops below EMA by threshold
if (close < emaValue - threshold && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
_entryPrice = close;
_cooldown = 80;
}
// Mean reversion: sell when price rallies above EMA by threshold
else if (close > emaValue + threshold && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
_entryPrice = close;
_cooldown = 80;
}
}
}
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 ExponentialMovingAverage, AverageTrueRange
from StockSharp.Algo.Strategies import Strategy
class hedge_any_positions_strategy(Strategy):
"""
Hedge Any Positions: ATR-based mean reversion.
Enters long when price drops below EMA by ATR*multiplier.
Enters short when price rallies above EMA by ATR*multiplier.
Uses SL/TP for risk management with cooldown.
"""
def __init__(self):
super(hedge_any_positions_strategy, self).__init__()
self._ema_period = self.Param("EmaPeriod", 100) \
.SetDisplay("EMA Period", "EMA period for mean price", "Indicator")
self._atr_period = self.Param("AtrPeriod", 14) \
.SetDisplay("ATR Period", "ATR calculation period", "Indicator")
self._atr_multiplier = self.Param("AtrMultiplier", 2.0) \
.SetDisplay("ATR Multiplier", "Multiplier for entry distance", "Indicator")
self._stop_loss_points = self.Param("StopLossPoints", 200) \
.SetDisplay("Stop Loss", "Stop-loss distance in price steps", "Risk")
self._take_profit_points = self.Param("TakeProfitPoints", 300) \
.SetDisplay("Take Profit", "Take-profit distance in price steps", "Risk")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._entry_price = 0.0
self._cooldown = 0
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(hedge_any_positions_strategy, self).OnReseted()
self._entry_price = 0.0
self._cooldown = 0
def OnStarted2(self, time):
super(hedge_any_positions_strategy, self).OnStarted2(time)
ema = ExponentialMovingAverage()
ema.Length = self._ema_period.Value
atr = AverageTrueRange()
atr.Length = self._atr_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(ema, atr, self._process_candle).Start()
def _process_candle(self, candle, ema_val, atr_val):
if candle.State != CandleStates.Finished:
return
if self._cooldown > 0:
self._cooldown -= 1
return
close = float(candle.ClosePrice)
ema = float(ema_val)
atr = float(atr_val)
step = 1.0
if self.Security is not None and self.Security.PriceStep is not None:
step = float(self.Security.PriceStep)
if step <= 0:
step = 1.0
threshold = atr * self._atr_multiplier.Value
if self.Position > 0 and self._entry_price > 0:
sl_pts = self._stop_loss_points.Value
tp_pts = self._take_profit_points.Value
if sl_pts > 0 and close <= self._entry_price - sl_pts * step:
self.SellMarket()
self._entry_price = 0.0
self._cooldown = 80
return
if tp_pts > 0 and close >= self._entry_price + tp_pts * step:
self.SellMarket()
self._entry_price = 0.0
self._cooldown = 80
return
elif self.Position < 0 and self._entry_price > 0:
sl_pts = self._stop_loss_points.Value
tp_pts = self._take_profit_points.Value
if sl_pts > 0 and close >= self._entry_price + sl_pts * step:
self.BuyMarket()
self._entry_price = 0.0
self._cooldown = 80
return
if tp_pts > 0 and close <= self._entry_price - tp_pts * step:
self.BuyMarket()
self._entry_price = 0.0
self._cooldown = 80
return
if close < ema - threshold and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
self._entry_price = close
self._cooldown = 80
elif close > ema + threshold and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._entry_price = close
self._cooldown = 80
def CreateClone(self):
return hedge_any_positions_strategy()