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
Abonnieren Sie die konfigurierte Kerzenserie und berechnen Sie den Indikator Parabolic SAR mit den bereitgestellten Beschleunigungseinstellungen.
Warten Sie, bis jede Kerze fertig ist, um das ursprüngliche EA-Timing zu emulieren.
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.
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;
}
}
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.Indicators import ExponentialMovingAverage, AverageTrueRange
from StockSharp.Algo.Strategies import Strategy
class parabolic_sar_flip_alert_strategy(Strategy):
def __init__(self):
super(parabolic_sar_flip_alert_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).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")
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, value): self._candle_type.Value = value
def OnReseted(self):
super(parabolic_sar_flip_alert_strategy, self).OnReseted()
self._prev_close = 0
self._entry_price = 0
def OnStarted2(self, time):
super(parabolic_sar_flip_alert_strategy, self).OnStarted2(time)
self._prev_close = 0
self._entry_price = 0
ema = ExponentialMovingAverage()
ema.Length = self._ema_length.Value
atr = AverageTrueRange()
atr.Length = self._atr_length.Value
sub = self.SubscribeCandles(self.CandleType)
sub.Bind(ema, atr, self.OnProcess).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, sub)
self.DrawIndicator(area, ema)
self.DrawOwnTrades(area)
def OnProcess(self, candle, ema_val, atr_val):
if candle.State != CandleStates.Finished:
return
close = candle.ClosePrice
if self._prev_close == 0 or atr_val <= 0:
self._prev_close = close
return
if self.Position > 0:
if close >= self._entry_price + atr_val * 2.5 or close <= self._entry_price - atr_val * 1.5 or close < ema_val:
self.SellMarket()
self._entry_price = 0
elif self.Position < 0:
if close <= self._entry_price - atr_val * 2.5 or close >= self._entry_price + atr_val * 1.5 or close > ema_val:
self.BuyMarket()
self._entry_price = 0
if self.Position == 0:
if close > ema_val and self._prev_close <= ema_val:
self._entry_price = close
self.BuyMarket()
elif close < ema_val and self._prev_close >= ema_val:
self._entry_price = close
self.SellMarket()
self._prev_close = close
def CreateClone(self):
return parabolic_sar_flip_alert_strategy()