Die ExpICustomV1-Strategie ist ein StockSharp-Port des MetaTrader-Experten exp_iCustom_v1. Die Strategie liest Handelssignale von einer konfigurierbaren Indikatorinstanz und reagiert auf Werte ungleich Null in den ausgewählten Puffern. Wenn der Kaufpuffer ungleich Null ist, eröffnet die Strategie eine Long-Position, während der Verkaufspuffer einen Short-Einstieg auslöst. Schützende Stop-Loss-, Take-Profit-, Trailing- und Break-Even-Logik reproduzieren die Geldverwaltungsoptionen des ursprünglichen Experten.
Hinweis: Es wird nur die C#-Implementierung bereitgestellt. Eine Python-Version ist noch nicht verfügbar.
Handelslogik
Abonnieren Sie den durch Kerzentyp angegebenen primären Zeitrahmen und verarbeiten Sie nur geschlossene Kerzen.
Instanziieren Sie den durch Indikatornamen definierten Indikator und wenden Sie die durch Schrägstriche getrennten Indikatorparameter an (unterstützt sowohl Name=Value-Paare als auch geordnete numerische Werte).
Speichern Sie die endgültigen Indikatorausgaben in einem Verlaufspuffer, damit bei späteren Kerzen auf jede Verschiebung zugegriffen werden kann.
Wenn der Kaufpufferwert bei Indicator Shift nicht Null ist, eröffnet/behält die Strategie eine Long-Position. Wenn der Verkaufspuffer ungleich Null ist, eröffnet/behält die Strategie eine Short-Position.
Wenn beide Puffer gleichzeitig Werte ungleich Null zurückgeben, heben sich die Signale gegenseitig auf, um mehrdeutige Einträge zu vermeiden.
Optional kann Close On Reverse die aktuelle Position verlassen, bevor auf das entgegengesetzte Signal reagiert wird.
Die Schlaflogik erzwingt eine Mindestanzahl von Balken zwischen aufeinanderfolgenden Einträgen in derselben Richtung. Der Timer kann abgebrochen werden, wenn das entgegengesetzte Signal ausgelöst wird, wenn Schlafmodus abbrechen aktiviert ist.
Positionen sind durch Stop-Loss, Take-Profit, optionalen Trailing-Stop und Break-Even-Sperre geschützt. Alle Entfernungen werden in Preispunkten angegeben.
Anzeigekonfiguration
Indikatorname – Vollständiger Typname oder kurzer StockSharp-Indikatorname (zum Beispiel SMA, MACD, BollingerBands).
Indikatorparameter – Durch Schrägstriche getrennte Liste, die auf den Indikator angewendet wird. Sowohl Length=14/Width=2 als auch geordnete Werte wie 14/2/0.7 werden unterstützt.
Blöcke überschreiben – Mit bis zu fünf Ersetzungen können Sie Parameterwerte während der Optimierung nach Index anpassen, ähnlich wie bei den Opt_X-Eingaben im ursprünglichen Experten. Indizes sind nullbasiert.
Risiko- und Geldmanagement
Basisvolumen – Betrag, der mit jeder Marktorder gesendet wird.
Stop Loss / Take Profit – Absolute Abstände in Punkten vom Einstiegspreis.
Trailing Stop – Wird nach dem angegebenen Gewinn aktiviert und behält den konfigurierten Abstand zum Extrempreis bei.
Break Even – Verschiebt den Stop nach dem angegebenen Gewinn in Richtung Einstiegspreis und sperrt optional zusätzliche Punkte.
Parameterreferenz
Parameter
Beschreibung
Kerzentyp
Zeitrahmen, der für die Indikator- und Signalauswertung verwendet wird.
Indikatorname
Typname der Indikatorinstanz.
Indikatorparameter
Durch Schrägstriche getrennte Liste der Indikatorparameter.
Puffer kaufen / Puffer verkaufen
Pufferindizes, die die Kauf-/Verkaufsmarkierungen enthalten.
Indikatorverschiebung
Beim Lesen von Indikatorpuffern wird eine historische Verschiebung angewendet.
Blöcke überschreiben
Ersetzen Sie bestimmte Parameterpositionen zur Laufzeit.
Schlafriegel
Mindestbalken zwischen Einträgen in derselben Richtung.
Schlafen abbrechen
Setzen Sie den Sleep-Timer nach einem Gegensignal zurück.
Bei Rückwärtsgang schließen
Bestehende Position schließen, wenn das entgegengesetzte Signal erscheint.
Soft Caps, die die Anzahl gleichzeitiger Positionen begrenzen.
Stop-Loss / Take-Profit
Entfernung in Punkten für Schutzanordnungen.
Trailing Stop-Einstellungen
Parameter, die die Trailing-Stop-Aktivierung und -Distanz steuern.
Break Even-Einstellungen
Parameter, die die Break-Even-Aktivierung und den Sperrabstand steuern.
Grundvolumen
Volumen jedes Markteintritts.
Nutzung
Fügen Sie die Strategie Ihrem Strategiecontainer hinzu und legen Sie Sicherheit und Portfolio fest.
Konfigurieren Sie Indikatorname und Indikatorparameter so, dass sie mit dem benutzerdefinierten Zielindikator übereinstimmen.
Passen Sie die Risikoeinstellungen (Stop, Take, Trailing, Break Even) und das Basisauftragsvolumen an.
Führen Sie die Strategie aus. Es abonniert den gewählten Zeitrahmen, wertet die Indikatorpuffer aus und sendet Marktaufträge, wenn die Bedingungen erfüllt sind.
Einschränkungen
Der Indikator muss als Indikatortyp StockSharp verfügbar sein. Binäre MetaTrader-Indikatoren können nicht direkt geladen werden.
Geldverwaltungsmodi, die von der freien Marge auf Brokerseite abhängen, werden auf ein festes Basisvolumen vereinfacht.
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>
/// ExpICustomV1 - custom indicator signal strategy.
/// Uses fast/slow EMA crossover to generate entry/exit signals.
/// Reverses position on opposite crossover.
/// </summary>
public class ExpICustomV1Strategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFast;
private decimal _prevSlow;
private bool _hasPrev;
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public ExpICustomV1Strategy()
{
_fastPeriod = Param(nameof(FastPeriod), 10)
.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 21)
.SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = 0m;
_prevSlow = 0m;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var fast = new ExponentialMovingAverage { Length = FastPeriod };
var slow = new ExponentialMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fast, slow, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
{
if (candle.State != CandleStates.Finished)
return;
if (!_hasPrev)
{
_prevFast = fast;
_prevSlow = slow;
_hasPrev = true;
return;
}
var bullCross = _prevFast <= _prevSlow && fast > slow;
var bearCross = _prevFast >= _prevSlow && fast < slow;
if (bullCross && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
else if (bearCross && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevFast = fast;
_prevSlow = slow;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class exp_i_custom_v1_strategy(Strategy):
"""Fast/slow EMA crossover strategy. Reverses position on opposite crossover."""
def __init__(self):
super(exp_i_custom_v1_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 10) \
.SetDisplay("Fast EMA", "Fast EMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 21) \
.SetDisplay("Slow EMA", "Slow EMA period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def FastPeriod(self):
return self._fast_period.Value
@property
def SlowPeriod(self):
return self._slow_period.Value
def OnReseted(self):
super(exp_i_custom_v1_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(exp_i_custom_v1_strategy, self).OnStarted2(time)
self._has_prev = False
fast = ExponentialMovingAverage()
fast.Length = self.FastPeriod
slow = ExponentialMovingAverage()
slow.Length = self.SlowPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(fast, slow, self._process_candle).Start()
def _process_candle(self, candle, fast, slow):
if candle.State != CandleStates.Finished:
return
fast_val = float(fast)
slow_val = float(slow)
if not self._has_prev:
self._prev_fast = fast_val
self._prev_slow = slow_val
self._has_prev = True
return
bull_cross = self._prev_fast <= self._prev_slow and fast_val > slow_val
bear_cross = self._prev_fast >= self._prev_slow and fast_val < slow_val
if bull_cross and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif bear_cross and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_fast = fast_val
self._prev_slow = slow_val
def CreateClone(self):
return exp_i_custom_v1_strategy()