Die Eugene-Strategie portiert den ursprünglichen MetaTrader 4-Expertenberater „Eugene“ auf die StockSharp-Hochebene API. Der Algorithmus überwacht standardmäßig stündliche Kerzen und sucht nach Ausbrüchen von Innenkerzen, die durch ein Retracement auf ein Drittel der vorherigen Kerze bestätigt werden. Sobald ein Ausbruch bestätigt ist, geht die Strategie in die Ausbruchsrichtung über und kann bestehende Positionen umkehren, wenn ein entgegengesetztes Setup auftritt.
Handelslogik
Erkennung innerhalb der Kerze – die vorherige Kerze muss vollständig innerhalb der Reichweite der Kerze davor liegen. Seine Schlussrichtung bestimmt, ob er als schwarzer (bärischer) oder weißer (bullischer) Insider klassifiziert wird.
Vogelfilter – eine innere Kerze, die durch eine andere Kerze derselben Farbe dahinter bestätigt wird, wird als „Vogel“ markiert. Schwarze Vögel blockieren Long-Trades, weiße Vögel blockieren Short-Trades. Dies spiegelt den Schutzfilter der MQL-Version wider.
Zickzack-Bestätigungsniveaus – zwei Bestätigungspreise werden bei einem Drittel des vorherigen Kerzenkörpers oder Dochts berechnet:
Das lange Bestätigungsniveau liegt ein Drittel unter dem vorherigen Schlusskurs (Körper für bullische Kerzen, Docht für bärische Kerzen).
Das Short-Bestätigungsniveau liegt ein Drittel über dem vorherigen Schlusskurs (Körper für bärische Kerzen, Docht für bullische Kerzen).
Sitzungsfilter – wenn die aktuelle Kerze um 08:00 Uhr oder später öffnet, gelten Bestätigungen auch ohne Retracement als erfüllt.
Breakout-Bedingung – ein Kaufsignal erfordert, dass die aktuelle Kerze ein höheres Hoch als die vorherige Kerze erreicht, gleichzeitig aber ein höheres Tief beibehält und sich mit der Spanne der Kerze zwei Balken zurück überschneidet. Ein Verkaufssignal nutzt die symmetrischen Bedingungen mit niedrigeren Tiefs und niedrigeren Hochs.
Positionsmanagement – vor der Eröffnung eines neuen Handels schließt die Strategie alle gegenteiligen Positionen. Pro Kerze kann nur ein Long- und ein Short-Eintrag ausgegeben werden, wodurch die Counter_buy- und Counter_sell-Einschränkungen des ursprünglichen Expert Advisors repliziert werden.
Parameter
Name
Beschreibung
Standard
Trade Volume
Auftragsgröße für Marktaufträge.
0.1
Candle Type
Zeitrahmen der verarbeiteten Kerzenserie.
1 hour
Diagramme
Wenn ein Chartbereich verfügbar ist, zeichnet die Strategie die verarbeiteten Kerzen zusammen mit den ausgeführten Trades auf und hilft so, das Ausbruchsverhalten zu visualisieren.
Notizen
Die StockSharp-Version behält den stündlichen Sitzungsfilter vom MQL-Experten bei. Passen Sie den Kerzentyp an, wenn Sie in anderen Märkten oder Zeitzonen handeln.
Stop-Loss- und Take-Profit-Management sind in der Quelldatei MQL nicht enthalten. Der Port überlässt das Risikomanagement daher der Hosting-Umgebung.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class EugeneStrategy : Strategy
{
private readonly StrategyParam<int> _smaPeriod;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<int> _cooldownCandles;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevClose;
private decimal _prevSma;
private bool _hasPrev;
private int _cooldownRemaining;
public int SmaPeriod { get => _smaPeriod.Value; set => _smaPeriod.Value = value; }
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public int CooldownCandles { get => _cooldownCandles.Value; set => _cooldownCandles.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public EugeneStrategy()
{
_smaPeriod = Param(nameof(SmaPeriod), 50).SetDisplay("SMA Period", "SMA lookback", "Indicators");
_rsiPeriod = Param(nameof(RsiPeriod), 14).SetDisplay("RSI Period", "RSI lookback", "Indicators");
_cooldownCandles = Param(nameof(CooldownCandles), 200).SetDisplay("Cooldown", "Candles between signals", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevClose = default;
_prevSma = default;
_hasPrev = default;
_cooldownRemaining = default;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevClose = 0;
_prevSma = 0;
_hasPrev = false;
_cooldownRemaining = 0;
var sma = new SimpleMovingAverage { Length = SmaPeriod };
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(sma, rsi, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal sma, decimal rsi)
{
if (candle.State != CandleStates.Finished) return;
var close = candle.ClosePrice;
if (!_hasPrev) { _prevClose = close; _prevSma = sma; _hasPrev = true; return; }
if (_cooldownRemaining > 0)
{
_cooldownRemaining--;
_prevClose = close;
_prevSma = sma;
return;
}
if (_prevClose <= _prevSma && close > sma && rsi < 70 && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
_cooldownRemaining = CooldownCandles;
}
else if (_prevClose >= _prevSma && close < sma && rsi > 30 && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
_cooldownRemaining = CooldownCandles;
}
_prevClose = close;
_prevSma = sma;
}
}
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 SimpleMovingAverage, RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class eugene_strategy(Strategy):
def __init__(self):
super(eugene_strategy, self).__init__()
self._sma_period = self.Param("SmaPeriod", 50) \
.SetDisplay("SMA Period", "SMA lookback", "Indicators")
self._rsi_period = self.Param("RsiPeriod", 14) \
.SetDisplay("RSI Period", "RSI lookback", "Indicators")
self._cooldown_candles = self.Param("CooldownCandles", 200) \
.SetDisplay("Cooldown", "Candles between signals", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_close = 0.0
self._prev_sma = 0.0
self._has_prev = False
self._cooldown_remaining = 0
@property
def sma_period(self):
return self._sma_period.Value
@property
def rsi_period(self):
return self._rsi_period.Value
@property
def cooldown_candles(self):
return self._cooldown_candles.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(eugene_strategy, self).OnReseted()
self._prev_close = 0.0
self._prev_sma = 0.0
self._has_prev = False
self._cooldown_remaining = 0
def OnStarted2(self, time):
super(eugene_strategy, self).OnStarted2(time)
self._prev_close = 0.0
self._prev_sma = 0.0
self._has_prev = False
self._cooldown_remaining = 0
sma = SimpleMovingAverage()
sma.Length = self.sma_period
rsi = RelativeStrengthIndex()
rsi.Length = self.rsi_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(sma, rsi, self.process_candle).Start()
def process_candle(self, candle, sma, rsi):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
sma_val = float(sma)
rsi_val = float(rsi)
if not self._has_prev:
self._prev_close = close
self._prev_sma = sma_val
self._has_prev = True
return
if self._cooldown_remaining > 0:
self._cooldown_remaining -= 1
self._prev_close = close
self._prev_sma = sma_val
return
if self._prev_close <= self._prev_sma and close > sma_val and rsi_val < 70 and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
self._cooldown_remaining = self.cooldown_candles
elif self._prev_close >= self._prev_sma and close < sma_val and rsi_val > 30 and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._cooldown_remaining = self.cooldown_candles
self._prev_close = close
self._prev_sma = sma_val
def CreateClone(self):
return eugene_strategy()