Auf GitHub ansehen

Parabolic SAR Flip-Alert-Strategie (4164)

Überblick

Diese Strategie reproduziert den MetaTrader-Expertenberater pSAR_alert2 innerhalb des StockSharp-Frameworks. Es überwacht den Indikator Parabolic SAR für das ausgewählte Instrument und den ausgewählten Zeitrahmen. Immer wenn der SAR-Wert von über dem Schlusskurs auf darunter (oder umgekehrt) fällt, generiert die Strategie eine Informationswarnung. Optional kann es Marktaufträge in Richtung des Flips erteilen, um den Alarm in einen automatischen Einstieg umzuwandeln.

Handelslogik

  1. Abonnieren Sie die konfigurierte Kerzenserie und berechnen Sie den Indikator Parabolic SAR mit den bereitgestellten Beschleunigungseinstellungen.
  2. Warten Sie, bis jede Kerze fertig ist, um das ursprüngliche EA-Timing zu emulieren.
  3. Vergleichen Sie den Indikatorwert mit dem Kerzenschluss:
    • Bisher SAR über dem Schlusskurs und aktuell SAR unter dem Schlusskurs → bullischer Flip.
    • Vorheriger SAR unter dem Schlusskurs und aktueller SAR über dem Schlusskurs → bärischer Flip.
  4. Protokollieren Sie für jeden Schlag eine detaillierte Warnung. Wenn der automatische Handel aktiviert ist, glätten Sie jegliches entgegengesetzte Risiko und eröffnen mithilfe von Marktaufträgen eine neue Position in Richtung des Signals.

Parameter

Parameter Beschreibung
Candle Type Zeitrahmen, der zum Erstellen von Kerzen und zum Auswerten des Indikators Parabolic SAR verwendet wird.
SAR Step Anfänglicher Beschleunigungsfaktor, der an Parabolic SAR übergeben wird.
SAR Max Maximaler Beschleunigungsfaktor des Parabolic SAR.
Enable Auto Trading Bei true werden Marktaufträge bei jeder Benachrichtigung gesendet; Bei false werden nur Protokolle generiert.
Trade Volume Die Auftragsgröße wird angewendet, wenn der automatische Handel aktiviert ist.

Konvertierungshinweise

  • Das ursprüngliche MetaTrader-Skript stützte sich auf Sleep, um die Ausführung zu drosseln. StockSharp ist ereignisgesteuert, sodass die Strategie sofort und ohne manuelle Verzögerungen auf neue Kerzen reagiert.
  • Warnungen werden über AddInfoLog erzeugt, wobei das ursprüngliche Verhalten von Popup-Benachrichtigungen beibehalten wird, ohne dass zusätzliche UI-Komponenten erforderlich sind.
  • Um die Alarmlogik in automatisierte Arbeitsabläufe zu integrieren, steht optionaler automatischer Handel zur Verfügung. Deaktivieren Sie den Parameter Enable Auto Trading, um dem genauen Verhalten von MetaTrader zu entsprechen.
  • Auf die Python-Implementierung wird wie gewünscht bewusst verzichtet.
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Parabolic SAR Flip: EMA trend following with ATR stops.
/// </summary>
public class ParabolicSarFlipAlertStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _emaLength;
	private readonly StrategyParam<int> _atrLength;

	private decimal _prevClose;
	private decimal _entryPrice;

	public ParabolicSarFlipAlertStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).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;
	}
}