Strategie zur Risikokontrolle bei Abschlussaufträgen
Überblick
Die Close Orders Strategy ist ein Risikomanagement-Dienstprogramm, das das Verhalten des ursprünglichen MQL-Expertenberaters CloseOrders.mq4 widerspiegelt. Es überwacht kontinuierlich die schwankenden Gewinne und Verluste offener Positionen und löst entsprechende Aufträge automatisch auf, sobald entweder das Gewinnziel oder die Cut-Loss-Schwelle erreicht ist. Dadurch eignet es sich zum Schutz eines Portfolios oder zur Synchronisierung von Exits über mehrere Strategien hinweg.
Wie es funktioniert
Die Strategie abonniert eine konfigurierbare Kerzenserie (standardmäßig 1 Minute) und wertet den aktuellen schwebenden PnL aus, wenn eine Kerze schließt.
Der variable PnL wird für die aktiven Portfoliopositionen berechnet. Wenn eine magische Zahl angegeben wird, werden nur Positionen einbezogen, deren interner StrategyId mit dem konfigurierten Wert übereinstimmt.
Wenn der variable Gewinn gleich oder größer als der Zielbetrag ist, werden alle passenden Aufträge und Positionen geschlossen.
Wenn der variable Gewinn unter den konfigurierten Cut-Loss (eine negative Zahl) fällt, wird die gleiche Liquidationsroutine ausgelöst, um weitere Verluste zu minimieren.
Aktive Aufträge, die den Magic-Number-Filter erfüllen, werden vor dem Abflachen der Positionen storniert, um sicherzustellen, dass während der Liquidation kein neues Risiko eröffnet wird.
Die Liquidationsroutine läuft weiter, bis alle übereinstimmenden Positionen leer sind, um sicherzustellen, dass Teilbesetzungen ordnungsgemäß gehandhabt werden.
Parameter
Parameter
Beschreibung
Zielgewinngeld
Variabler Gewinn (in Kontowährung), der die Liquidation passender Aufträge auslöst. Muss größer als Null sein.
Verlustgelder reduzieren
Negativer variabler PnL (in Kontowährung), der die Liquidation erzwingt. Ein Wert von 0 deaktiviert den verlustbasierten Exit.
Magische Zahl
Optionaler Strategiebezeichner. Lassen Sie das Feld leer, um alle offenen Positionen zu verwalten. Andernfalls sind nur Positionen betroffen, deren StrategyId dem angegebenen Wert entspricht.
Kerzentyp
Kerzenserien, die dazu dienen, regelmäßige Gewinnüberprüfungen auszulösen. Passen Sie den Zeitrahmen an, wenn eine Überwachung mit höherer Frequenz erforderlich ist.
Hinweise zur Implementierung
Das magische Zahlenkonzept MQL wird den Feldern UserOrderId/StrategyId in StockSharp zugeordnet. Stellen Sie sicher, dass die zu verwaltenden Strategien dieselbe Kennung verwenden.
Zur Einrückung werden Tabulatoren verwendet und die Datei folgt der gemeinsamen Struktur, die für konvertierte Strategien erforderlich ist.
Die Strategie storniert ausstehende Aufträge vor dem Senden von Marktaufträgen, um das Risiko einzudämmen und einen sofortigen Wiedereintritt zu verhindern.
Ein Startschutz kann hinzugefügt werden, wenn die Strategie mit Live-Handelskomponenten kombiniert wird, die im Notfall behandelt werden müssen.
Anwendungstipps
Setzen Sie die Strategie zusammen mit Handelsstrategien ein, die einen benutzerdefinierten StrategyId festlegen, um die Exit-Logik zu zentralisieren.
Passen Sie den Parameter Candle Type an, um Reaktionsfähigkeit und Ressourcennutzung in Einklang zu bringen. Kürzere Zeitrahmen ermöglichen eine schnellere Reaktion auf PnL-Änderungen.
Kombinieren Sie das Dienstprogramm mit Benachrichtigungen, um Benachrichtigungen zu erhalten, wenn eine automatische Liquidation durchgeführt wird.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Close Orders Risk Control strategy: CCI crossover with risk management.
/// Buys when CCI crosses above zero, sells when crosses below zero.
/// </summary>
public class CloseOrdersRiskControlStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _cciPeriod;
private readonly StrategyParam<decimal> _cciLevel;
private readonly StrategyParam<int> _signalCooldownCandles;
private decimal _prevCci;
private int _candlesSinceTrade;
private bool _hasPrev;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int CciPeriod { get => _cciPeriod.Value; set => _cciPeriod.Value = value; }
public decimal CciLevel { get => _cciLevel.Value; set => _cciLevel.Value = value; }
public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }
public CloseOrdersRiskControlStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_cciPeriod = Param(nameof(CciPeriod), 30)
.SetGreaterThanZero()
.SetDisplay("CCI Period", "CCI period", "Indicators");
_cciLevel = Param(nameof(CciLevel), 100m)
.SetDisplay("CCI Level", "CCI threshold for crossover", "Signals");
_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 4)
.SetGreaterThanZero()
.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevCci = 0;
_candlesSinceTrade = SignalCooldownCandles;
_hasPrev = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevCci = 0;
_candlesSinceTrade = SignalCooldownCandles;
_hasPrev = false;
var cci = new CommodityChannelIndex { Length = CciPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(cci, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal cciValue)
{
if (candle.State != CandleStates.Finished) return;
if (_candlesSinceTrade < SignalCooldownCandles)
_candlesSinceTrade++;
if (_hasPrev)
{
if (_prevCci < -CciLevel && cciValue >= -CciLevel && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
{
BuyMarket();
_candlesSinceTrade = 0;
}
else if (_prevCci > CciLevel && cciValue <= CciLevel && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
{
SellMarket();
_candlesSinceTrade = 0;
}
}
_prevCci = cciValue;
_hasPrev = true;
}
}