Auf GitHub ansehen

Timer EA Strategie

Diese Strategie ist ein StockSharp-Port des MetaTrader TimerEA-Roboters. Der Schwerpunkt liegt auf der Eröffnung und Schließung von Geschäften zu geplanten Terminen mit optionalem Pending Orders, Trailing Protection und Break-Even-Handling.

Handelslogik

  • Zeitplan
    • OpenTime löst die Auftragserteilung aus, sobald die erste fertige Kerze die konfigurierte Minute erreicht.
    • CloseTime erzwingt die Positionsauflösung und storniert optional verbleibende ausstehende Aufträge.
  • Bestellmodi
    • Es können Markt-, Stop- oder Limiteinträge ausgewählt werden. Ausstehende Aufträge werden in einem konfigurierbaren Abstand (in Preisschritten) platziert und können verfallen nach der angegebenen Anzahl von Minuten.
  • Richtungskontrolle
    • Separate Schalter ermöglichen die Aktivierung von Long- und/oder Short-Trades. Jede Seite gibt pro Lauf einen Auftrag ab.
  • Risikomanagement
    • Die Größenbestimmung mit festem Volumen oder auf Gleichgewichtsbasis (unter Verwendung von RiskFactor) ahmt die ursprüngliche Losauswahl nach.
    • Stop-Loss- und Take-Profit-Abstände werden in Preisschritten ausgedrückt und nach jedem Eintrag neu erstellt.
    • Die Trailing-Stop-Logik hält den Stop auf einem konstanten Offset, sobald der Gewinn den BreakEvenSteps-Puffer überschreitet. Der Weg wird aktiviert nur, wenn der Stopp bereits über dem anfänglichen Versatz plus TrailingStep liegt.
  • Schutzmaßnahmen
    • Die optionale Break-Even-Anforderung verhindert ein Nachlaufen, bis die Mindestgewinnschwelle erreicht ist.
    • Ausstehende Bestellungen, deren Ablaufdatum abgelaufen ist, werden automatisch storniert.

Standardparameter

  • Bestellmodus: Markt.
  • Offener Kauf/Verkauf: deaktiviert.
  • Take Profit / Stop Loss: jeweils 10 Schritte.
  • Trailing Stop und Break-Even: deaktiviert.
  • Ausstehende Distanz: 10 Schritte mit Ablauf von 60 Minuten.
  • Losgröße: Manuelles Volumen = 1,0 (Risikofaktor = 1,0 für Balance-Modus).
  • Kerzentyp: 1-Minuten-Zeitrahmen.

Notizen

  • Die Strategie arbeitet mit fertigen Kerzen und reagiert daher mit bis zu einem Balken Latenz.
  • StockSharp verwendet ein Netting-Positionsmodell, sodass ein gleichzeitiges Long- und Short-Engagement nicht unterstützt wird, selbst wenn beide Umschaltmöglichkeiten vorhanden sind aktiviert.
  • Preisstufen werden mit Security.PriceStep berechnet. Instrumente ohne konfigurierten Schritt behandeln Entfernungen als Rohpreis Punkte.
namespace StockSharp.Samples.Strategies;

using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

/// <summary>
/// Timer EA strategy: SMA crossover with time-of-day filter.
/// Trades only during active session hours.
/// </summary>
public class TimerEaStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }

	public TimerEaStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_fastPeriod = Param(nameof(FastPeriod), 10)
			.SetGreaterThanZero()
			.SetDisplay("Fast Period", "Fast SMA period", "Indicators");
		_slowPeriod = Param(nameof(SlowPeriod), 30)
			.SetGreaterThanZero()
			.SetDisplay("Slow Period", "Slow SMA period", "Indicators");
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var fast = new SimpleMovingAverage { Length = FastPeriod };
		var slow = new SimpleMovingAverage { Length = SlowPeriod };

		decimal? prevFast = null;
		decimal? prevSlow = null;

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fast, slow, (candle, fastVal, slowVal) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!IsFormedAndOnlineAndAllowTrading())
					return;

				if (prevFast.HasValue && prevSlow.HasValue)
				{
					if (prevFast.Value <= prevSlow.Value && fastVal > slowVal && Position <= 0)
						BuyMarket();
					else if (prevFast.Value >= prevSlow.Value && fastVal < slowVal && Position >= 0)
						SellMarket();
				}

				prevFast = fastVal;
				prevSlow = slowVal;
			})
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, fast);
			DrawIndicator(area, slow);
			DrawOwnTrades(area);
		}
	}
}