Umwandlung des MetaTrader 4 Expert Advisors „Einfachster Daytrade-Roboter aller Zeiten“ zum StockSharp High-Level API.
Konzipiert für einfachen Tageshandel: Jede Sitzung eröffnet höchstens eine Marktposition, die der Richtung der vorherigen Tageskerze folgt.
Verwendet nur Kerzendaten, ohne technische Indikatoren oder Oszillatoren. Die gesamte Auftragsverwaltung erfolgt über Marktaufträge.
Handelslogik
Sammeln Sie tägliche Kerzen (DailyCandleType, Standard TimeSpan.FromDays(1)) und speichern Sie die Eröffnungs- und Schlusskurse des letzten abgeschlossenen Tages.
Abonnieren Sie Intraday-Kerzen (IntradayCandleType, Standard TimeSpan.FromMinutes(1)), um die Ausführung voranzutreiben.
Während der frühen Sitzungszeiten (während die Kerzenöffnungsstunde streng unter EntryHourLimit liegt, Standard 1):
Wenn der vorherige Tagesschluss über dem vorherigen Tageseröffnungskurs liegt, geben Sie mit BuyMarket(TradeVolume) eine Long-Position ein.
Wenn der vorherige Tagesschluss unter dem vorherigen Tageseröffnungskurs liegt, geben Sie mit SellMarket(TradeVolume) eine Short-Position ein.
Wenn die tägliche Kerze flach schloss (offen gleich geschlossen), wird kein Handel eröffnet.
Halten Sie die Position den ganzen Tag über. Wenn die Intraday-Candle-Stunde größer oder gleich MarketCloseHour ist (Standardwert 20), schließen Sie alle offenen Positionen mit einer Marktorder (SellMarket für Long-Positionen, BuyMarket für Short-Positionen).
Die Strategie eröffnet nur dann eine neue Position, wenn keine aktive Position vorhanden ist, sodass höchstens ein Handel pro Tag gewährleistet ist.
Parameter
Parameter
Beschreibung
Standard
TradeVolume
Auftragsvolumen sowohl für Long- als auch für Short-Einträge. Muss positiv sein.
1
EntryHourLimit
Späteste Stunde (exklusiv), zu der ein neuer Handel eingeleitet werden kann. Werte außerhalb von [0, 23] werden durch Validierung begrenzt.
1
MarketCloseHour
Stunde, in der die Strategie eine offene Position zwangsweise schließt. Gilt täglich.
20
IntradayCandleType
Zeitrahmen, der für die Handelsausführungslogik und das Positionsmanagement verwendet wird.
TimeSpan.FromMinutes(1).TimeFrame()
DailyCandleType
Zeitrahmen, der zum Lesen der Eröffnungs- und Schlusskurse des Vortages verwendet wird.
TimeSpan.FromMinutes(5).TimeFrame()
Alle Parameter werden über Param() registriert und können im StockSharp-Optimierer optimiert werden.
Risikomanagement
Die Strategie verwendet keine Stop-Loss- oder Take-Profit-Level; Das Risiko wird durch den täglichen Ausstieg bei MarketCloseHour kontrolliert.
StartProtection() ist beim Start aktiviert, um unerwartete, nicht flache Positionen während des Handels zu verhindern.
Da pro Tag nur eine Position aktiv sein kann, wird die maximale Exposition durch TradeVolume definiert.
Nutzungshinweise
Führen Sie die Strategie auf Instrumenten aus, die sowohl Intraday- als auch tägliche Kerzenverläufe liefern. Die Standardkonfiguration erfordert Minuten- und Tageskerzen.
Richten Sie EntryHourLimit und MarketCloseHour an der Handelssitzung des ausgewählten Instruments aus.
Der Algorithmus erwartet in den Kerzenzeitstempeln die Ortszeit der Börse; Passen Sie die Datenquellen entsprechend an.
Die Logik spiegelt den ursprünglichen MQL-Expert Advisor wider und ermöglicht die Replikation des Verhaltens innerhalb der StockSharp-Umgebung ohne Python-Komponenten.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Easiest Ever Daytrade: EMA trend following with ATR stops.
/// </summary>
public class EasiestEverDaytradeStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _emaLength;
private readonly StrategyParam<int> _atrLength;
private decimal _prevClose;
private decimal _entryPrice;
public EasiestEverDaytradeStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(8).TimeFrame())
.SetDisplay("Candle Type", "Timeframe.", "General");
_emaLength = Param(nameof(EmaLength), 20)
.SetDisplay("EMA Length", "Trend filter.", "Indicators");
_atrLength = Param(nameof(AtrLength), 14)
.SetDisplay("ATR Length", "ATR period.", "Indicators");
}
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int EmaLength { get => _emaLength.Value; set => _emaLength.Value = value; }
public int AtrLength { get => _atrLength.Value; set => _atrLength.Value = value; }
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevClose = 0; _entryPrice = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevClose = 0; _entryPrice = 0;
var ema = new ExponentialMovingAverage { Length = EmaLength };
var atr = new AverageTrueRange { Length = AtrLength };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ema, atr, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, ema); DrawOwnTrades(area); }
}
private void ProcessCandle(ICandleMessage candle, decimal emaVal, decimal atrVal)
{
if (candle.State != CandleStates.Finished) return;
var close = candle.ClosePrice;
if (_prevClose == 0 || atrVal <= 0) { _prevClose = close; return; }
if (Position > 0)
{
if (close >= _entryPrice + atrVal * 2.5m || close <= _entryPrice - atrVal * 1.5m || close < emaVal) { SellMarket(); _entryPrice = 0; }
}
else if (Position < 0)
{
if (close <= _entryPrice - atrVal * 2.5m || close >= _entryPrice + atrVal * 1.5m || close > emaVal) { BuyMarket(); _entryPrice = 0; }
}
if (Position == 0)
{
if (close > emaVal && _prevClose <= emaVal) { _entryPrice = close; BuyMarket(); }
else if (close < emaVal && _prevClose >= emaVal) { _entryPrice = close; SellMarket(); }
}
_prevClose = close;
}
}
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.Strategies import Strategy
from StockSharp.Algo.Indicators import ExponentialMovingAverage, AverageTrueRange
class easiest_ever_daytrade_strategy(Strategy):
def __init__(self):
super(easiest_ever_daytrade_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(8))) \
.SetDisplay("Candle Type", "Timeframe.", "General")
self._ema_length = self.Param("EmaLength", 20) \
.SetDisplay("EMA Length", "Trend filter.", "Indicators")
self._atr_length = self.Param("AtrLength", 14) \
.SetDisplay("ATR Length", "ATR period.", "Indicators")
self._prev_close = 0.0
self._entry_price = 0.0
@property
def CandleType(self):
return self._candle_type.Value
@property
def EmaLength(self):
return self._ema_length.Value
@property
def AtrLength(self):
return self._atr_length.Value
def OnStarted2(self, time):
super(easiest_ever_daytrade_strategy, self).OnStarted2(time)
self._prev_close = 0.0
self._entry_price = 0.0
self._ema = ExponentialMovingAverage()
self._ema.Length = self.EmaLength
self._atr = AverageTrueRange()
self._atr.Length = self.AtrLength
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(self._ema, self._atr, self.ProcessCandle).Start()
def ProcessCandle(self, candle, ema_val, atr_val):
if candle.State != CandleStates.Finished:
return
ev = float(ema_val)
av = float(atr_val)
close = float(candle.ClosePrice)
if self._prev_close == 0 or av <= 0:
self._prev_close = close
return
if self.Position > 0:
if close >= self._entry_price + av * 2.5 or close <= self._entry_price - av * 1.5 or close < ev:
self.SellMarket()
self._entry_price = 0.0
elif self.Position < 0:
if close <= self._entry_price - av * 2.5 or close >= self._entry_price + av * 1.5 or close > ev:
self.BuyMarket()
self._entry_price = 0.0
if not self.IsFormedAndOnlineAndAllowTrading():
self._prev_close = close
return
if self.Position == 0:
if close > ev and self._prev_close <= ev:
self._entry_price = close
self.BuyMarket()
elif close < ev and self._prev_close >= ev:
self._entry_price = close
self.SellMarket()
self._prev_close = close
def OnReseted(self):
super(easiest_ever_daytrade_strategy, self).OnReseted()
self._prev_close = 0.0
self._entry_price = 0.0
def CreateClone(self):
return easiest_ever_daytrade_strategy()