Diese Strategie ist ein StockSharp-Port des MetaTrader-Expert-Advisors "PSAR Trader EA". Sie beobachtet, wie der Preis mit dem Parabolic-SAR-Indikator interagiert, und reagiert nur, wenn das Punktfeld von einer Seite des Kerzenkörpers auf die andere wechselt. Die Konvertierung bewahrt die ursprüngliche Geldmanagement-Logik: Die Strategie kann entweder mit fester Lotgröße handeln oder das Ordervolumen dynamisch anhand des Kontostands anpassen, feste Stop-Loss- und Take-Profit-Niveaus anwenden und einen Trailing Stop aktivieren, sobald ein Trade ausreichend Gewinn aufgebaut hat.
Strategielogik
Einen Parabolic-SAR-Indikator mit benutzerdefinierter Beschleunigung und Maximalwerten auf der gewählten Kerzenserie aufbauen (standardmäßig 30-Minuten-Kerzen).
Einen bullischen Flip erkennen, wenn der SAR-Punkt von oberhalb des Kerzenkörpers nach darunter wechselt. Ist keine Position offen, eine Markt-Kauforder senden. Besteht eine Short-Position, diese zuerst schließen und auf das nächste Signal für den Long-Wiedereinstieg warten.
Einen bärischen Flip erkennen, wenn der SAR-Punkt von unterhalb des Kerzenkörpers nach darüber wechselt. Wenn flach, eine Short-Position eröffnen. Ist eine Long-Position aktiv, diese schließen und den Einstieg bis zum folgenden Signal aufschieben.
Offene Trades auf jeder abgeschlossenen Kerze überwachen und Ausstiege ausführen, wenn ein Schutzniveau (Stop-Loss, Take-Profit oder Trailing Stop) vom Hoch/Tief der aktuellen Kerze erreicht wird.
Risikomanagement
Stop loss: in Punkten (Preisschritten) angegeben. Bei Long-Trades liegt der Stop unter dem Einstiegspreis, bei Shorts darüber.
Take profit: ebenfalls in Punkten. Das Ziel spiegelt den Stop in Gegenrichtung und schließt die gesamte Position bei Erreichen.
Trailing stop: startet, nachdem der Preis sich um eine konfigurierbare Anzahl Punkte zugunsten des Trades bewegt. Der Trailing Stop zieht nur in Gewinnrichtung enger und repliziert das "tighten stops only"-Verhalten des ursprünglichen EA.
Volumenverwaltung
Festes Lot: Wenn Auto-Lot deaktiviert ist, sendet die Strategie Orders mit der konfigurierten festen Lotgröße.
Kontostandsbasiertes Lot: Wenn Auto-Lot aktiviert ist, wird das Volumen als (Account Balance / 1000) * LotsPerThousand berechnet und an Volumenschritt und Mindestvolumen der Security angepasst.
Parameter und Standards
SarStep: Beschleunigungsfaktor des Parabolic SAR. Standard: 0.02.
SarMaximum: Maximale Beschleunigung des Parabolic SAR. Standard: 0.2.
CandleType: Zeitrahmen für die Analyse. Standard: 30-Minuten-Kerzen.
FixedLot: Volumen bei deaktiviertem Auto-Lot-Sizing. Standard: 0.1.
LotsPerThousand: Multiplikator für Auto-Lot-Berechnungen. Standard: 0.05.
StopLossPoints: Distanz zum Stop in Punkten. Standard: 500.
TakeProfitPoints: Distanz zum Take Profit in Punkten. Standard: 1000.
TrailingStartPoints: Gewinnschwelle zur Aktivierung des Trailings. Standard: 500.
TrailingDistancePoints: Trailing-Offset nach Aktivierung. Standard: 100.
Hinweise
Die Strategie handelt Long- und Short-Richtungen, hält aber höchstens eine Position gleichzeitig offen.
Schutzorders werden auf Kerzendaten simuliert; Intracandle-Spitzen, die kleiner als der gewählte Zeitrahmen sind, können im Live-Handel die Ausführungsqualität beeinflussen.
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Parabolic SAR Cross strategy: PSAR crossover.
/// Buys when close crosses above PSAR. Sells when close crosses below PSAR.
/// </summary>
public class ParabolicSarCrossStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public ParabolicSarCrossStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(15).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var sar = new ParabolicSar { Acceleration = 0.02m, AccelerationStep = 0.02m, AccelerationMax = 0.2m };
decimal? prevSar = null;
decimal? prevClose = null;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(sar, (candle, sarVal) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var close = candle.ClosePrice;
if (prevSar.HasValue && prevClose.HasValue)
{
var crossUp = prevClose.Value <= prevSar.Value && close > sarVal;
var crossDown = prevClose.Value >= prevSar.Value && close < sarVal;
if (crossUp && Position <= 0)
BuyMarket();
else if (crossDown && Position >= 0)
SellMarket();
}
prevSar = sarVal;
prevClose = close;
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, sar);
DrawOwnTrades(area);
}
}
}
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 ParabolicSar
from StockSharp.Algo.Strategies import Strategy
from datatype_extensions import *
from indicator_extensions import *
class parabolic_sar_cross_strategy(Strategy):
def __init__(self):
super(parabolic_sar_cross_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(15))).SetDisplay("Candle Type", "Candle timeframe", "General")
@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_cross_strategy, self).OnReseted()
self._prev_sar = None
self._prev_close = None
def OnStarted2(self, time):
super(parabolic_sar_cross_strategy, self).OnStarted2(time)
self._prev_sar = None
self._prev_close = None
sar = ParabolicSar()
sar.Acceleration = 0.02
sar.AccelerationStep = 0.02
sar.AccelerationMax = 0.2
sub = self.SubscribeCandles(self.CandleType)
sub.Bind(sar, self.OnProcess).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, sub)
self.DrawIndicator(area, sar)
self.DrawOwnTrades(area)
def OnProcess(self, candle, sar_val):
if candle.State != CandleStates.Finished:
return
close = candle.ClosePrice
if self._prev_sar is not None and self._prev_close is not None:
cross_up = self._prev_close <= self._prev_sar and close > sar_val
cross_down = self._prev_close >= self._prev_sar and close < sar_val
if cross_up and self.Position <= 0:
self.BuyMarket()
elif cross_down and self.Position >= 0:
self.SellMarket()
self._prev_sar = sar_val
self._prev_close = close
def CreateClone(self):
return parabolic_sar_cross_strategy()