Auf GitHub ansehen

Intelligente AC-Trader-Strategie

Überblick

Smart AC Trader passt die ursprüngliche „Smart AC Trader“-Idee von MetaTrader an das hohe Niveau von StockSharp an: API. Der MQL-Experte bewertete die relative Stärke der Währungen innerhalb eines Paares und reagierte, wenn die Basiswährung die Notierungswährung übertraf. In StockSharp konzentrieren wir uns auf das gleiche impulsgesteuerte Verhalten, operieren jedoch mit einem einzigen Instrument, mit dem die Strategie verknüpft ist. Die Stärke wird durch eine Kombination aus exponentiellen gleitenden Durchschnitten (EMAs) und dem Indikator für die Änderungsrate (ROC) angenähert:

  • Ein schneller EMA misst die kurzfristige Trendrichtung.
  • Ein langsamer EMA stellt den Haupttrend dar.
  • ROC bestätigt, dass die Preisdynamik mit dem Trend übereinstimmt, bevor Einträge zulässig sind.

Sobald eine Position eröffnet ist, verwaltet die Strategie den Handel aktiv mithilfe von Stop-Loss-, Take-Profit-, Trailing-Stop- und Break-Even-Regeln, die die umfassende Money-Management-Konfiguration des ursprünglichen Experten widerspiegeln.

Handelslogik

  1. Abonnieren Sie den konfigurierten Kerzentyp (Zeitrahmen) und berechnen Sie den schnellen EMA, den langsamen EMA und den ROC beim Kerzenschluss.
  2. Geben Sie eine Long-Position ein, wenn der schnelle EMA über dem langsamen EMA liegt und ROC größer oder gleich dem Kaufmomentum-Schwellenwert ist. Bestehende Short-Positionen werden geschlossen, bevor die neuen Long-Positionen eröffnet werden.
  3. Geben Sie eine Short-Position ein, wenn der schnelle EMA unter dem langsamen EMA liegt und ROC kleiner oder gleich dem negativen Verkaufsmomentum-Schwellenwert ist. Bestehende Long-Positionen werden geschlossen, bevor die neuen Short-Positionen eröffnet werden.
  4. Verwalten Sie eine offene Position für jede fertige Kerze:
    • Schließen Sie den Handel zu den konfigurierten Take-Profit- oder Stop-Loss-Abständen (ausgedrückt in Preisschritten).
    • Aktivieren Sie optional einen Break-Even-Ausstieg, sobald sich der Preis um die Triggerdistanz zu Gunsten des Handels bewegt, und liquidieren Sie ihn, wenn der Preis zum beibehaltenen Offset zurückkehrt.
    • Verfolgen Sie den Stopp optional um den konfigurierten Abstand vom höchsten Höchstwert (lang) oder niedrigsten Tiefstwert (kurz), der nach dem Eintritt beobachtet wird.

Parameter

Parameter Beschreibung
Schneller EMA Länge des schnellen EMA-Trendfilters.
Langsamer EMA Länge des langsamen EMA-Trendfilters.
ROC Zeitraum Lookback-Fenster für den Rate-of-Change-Momentum-Filter.
Momentum kaufen Mindestens positive ROC erforderlich, um Long-Trades zu eröffnen.
Momentum verkaufen Mindestabsolut negativ ROC erforderlich, um Short-Trades zu eröffnen.
Stop-Loss Stop-Loss-Distanz ausgedrückt in Preisschritten.
Gewinn mitnehmen Take-Profit-Distanz, ausgedrückt in Preisschritten.
Trailing verwenden Aktiviert die Trailing-Stop-Verwaltung.
Nachlaufend Trailing-Stop-Distanz in Preisschritten.
Break Even nutzen Aktiviert die Break-Even-Schutzlogik.
Break-Even-Auslöser Profitieren Sie von den Preisschritten, die erforderlich sind, um die Break-Even-Logik zu aktivieren.
Break-Even-Offset Abstand der Preisschritte, der beibehalten wird, nachdem der Break-Even-Trigger erreicht wurde.
Kerzentyp Kerzentyp zur Versorgung der Indikatoren.

Notizen

  • Die Strategie verwendet Strategy.StartProtection() einmal beim Start, um sicherzustellen, dass das integrierte Positionsschutzsystem gemäß den Empfehlungen der Projektrichtlinien aktiv ist.
  • Die Positionsgröße basiert auf der Basiseigenschaft Strategy.Volume. Umkehraufträge berücksichtigen automatisch das aktuelle Risiko, sodass ein entgegengesetztes Signal sowohl die bestehende Position schließt als auch eine neue aufbaut.
  • Alle Risikoparameter werden in Preisschritten ausgedrückt, da der ursprüngliche Fachberater Pip-basierte Abstände verwendete. Stellen Sie sicher, dass für das Gerät ein gültiger PriceStep konfiguriert ist.
namespace StockSharp.Samples.Strategies;

using System;

using Ecng.Common;

using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

/// <summary>
/// Smart AC Trader: EMA trend + ROC momentum filter.
/// Buys when fast EMA above slow EMA and ROC positive.
/// Sells when fast EMA below slow EMA and ROC negative.
/// </summary>
public class SmartAcTraderStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<int> _rocPeriod;

	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 int RocPeriod
	{
		get => _rocPeriod.Value;
		set => _rocPeriod.Value = value;
	}

	public SmartAcTraderStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");

		_fastPeriod = Param(nameof(FastPeriod), 10)
			.SetGreaterThanZero()
			.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 50)
			.SetGreaterThanZero()
			.SetDisplay("Slow EMA", "Slow EMA period", "Indicators");

		_rocPeriod = Param(nameof(RocPeriod), 13)
			.SetGreaterThanZero()
			.SetDisplay("ROC Period", "Rate of Change period", "Indicators");
	}

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

		var fast = new ExponentialMovingAverage { Length = FastPeriod };
		var slow = new ExponentialMovingAverage { Length = SlowPeriod };
		var roc = new RateOfChange { Length = RocPeriod };

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

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

				if (!IsFormedAndOnlineAndAllowTrading())
					return;

				if (prevFast.HasValue && prevSlow.HasValue)
				{
					var crossUp = prevFast.Value <= prevSlow.Value && fastVal > slowVal;
					var crossDown = prevFast.Value >= prevSlow.Value && fastVal < slowVal;

					if (crossUp && rocVal > 0 && Position <= 0)
						BuyMarket();
					else if (crossDown && rocVal < 0 && 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);
		}
	}
}