Auf GitHub ansehen

Die einfachste Daytrade-Strategie aller Zeiten

Überblick

  • 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

  1. Sammeln Sie tägliche Kerzen (DailyCandleType, Standard TimeSpan.FromDays(1)) und speichern Sie die Eröffnungs- und Schlusskurse des letzten abgeschlossenen Tages.
  2. Abonnieren Sie Intraday-Kerzen (IntradayCandleType, Standard TimeSpan.FromMinutes(1)), um die Ausführung voranzutreiben.
  3. 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.
  4. 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).
  5. 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;
	}
}