Die Accelerator Trailing TP & SL-Strategie portiert den Expertenberater "Accelerator Trailing TP&SL" von MetaTrader in die High-Level-API von StockSharp. Das System kombiniert Bill Williams' Accelerator Oszillator mit Multi-Timeframe-Momentum-Bestätigung und einem monatlichen MACD-Trendfilter. Einstiege werden mit geometrischer Positionsgrößen-Skalierung aufgebaut, während Ausstiege klassische Stop/Ziel-Abstände, adaptives Trailing und Break-Even-Logik kombinieren.
Trading-Logik
Momentum-Filter – ein 14-Perioden-Momentum-Indikator, der auf einem höheren Zeitrahmen berechnet wird, muss auf jedem der letzten drei abgeschlossenen Bars vom neutralen 100er-Niveau um mindestens den konfigurierten Schwellenwert abweichen.
Accelerator Oszillator – Long-Trades erfordern eine positive Accelerator-Ablesung, Short-Trades eine negative Ablesung auf dem Signal-Zeitrahmen.
Gleitende Durchschnitte – ein schneller linear gewichteter gleitender Durchschnitt (LWMA) muss für Longs über dem langsamen LWMA liegen und für Shorts darunter, was den ursprünglichen schnellen/langsamen Trendfilter annähert.
Monatlicher MACD-Trend – standardmäßig beobachtet der Filter monatliche Kerzen. Long-Trades verlangen, dass die MACD-Linie über der Signallinie liegt (auch wenn beide Werte negativ sind), während Short-Trades die umgekehrte Bedingung erfordern.
Gestaffelte Einstiege – die Strategie kann bis zur konfigurierten maximalen Anzahl von Positionen pro Richtung pyramidieren. Jeder zusätzliche Einstieg wird mit dem Lot-Exponenten multipliziert, was die Martingal-artige Größenbestimmung aus dem MQL-Programm recreiert.
Risikomanagement
Statischer Stop-Loss / Take-Profit – Pip-Abstände spiegeln die ursprünglichen Stop-Loss- und Take-Profit-Einstellungen wider.
Trailing Stop – wenn aktiviert, verfolgt die Strategie den günstigsten Preis um die konfigurierte Pip-Anzahl.
Break-Even-Bewegung – nachdem ein Trade die Trigger-Distanz erreicht, wird der Stop um den angegebenen Offset vorgeschoben, um aufgelaufene Gewinne zu schützen.
MACD-Ausstieg – wenn der MACD-Filter gegen die aktive Position umschlägt, kann die Strategie sofort alle Positionen schließen, was dem manuellen Ausstiegshilfer im MQL-Code entspricht.
Parameter
Parameter
Beschreibung
FastMaLength / SlowMaLength
Perioden der schnellen und langsamen LWMAs auf dem Handels-Zeitrahmen.
MomentumThreshold
Minimale absolute Abweichung des Momentums vom neutralen 100er-Wert auf dem höheren Zeitrahmen.
StopLossPips / TakeProfitPips
Schutz-Stop- und Zielabstände in Pips.
TrailingStopPips
Distanz des optionalen Trailing-Stop-Managers.
BreakEvenTriggerPips / BreakEvenOffsetPips
Definiert wann und wie der Stop auf Break-Even verschoben wird.
MaxTrades
Maximale Anzahl gestaffelter Einstiege pro Richtung.
BaseVolume
Volumen der ersten Order in einer Sequenz.
LotExponent
Multiplikator für jeden zusätzlichen gestaffelten Einstieg.
EnableTrailing
Aktiviert oder deaktiviert das Trailing-Stop-Management.
UseBreakEven
Aktiviert oder deaktiviert die Break-Even-Stop-Bewegung.
CloseOnMacdFlip
Schließt alle Trades, wenn der MACD auf dem höheren Zeitrahmen umkehrt.
CandleType
Primäre Kerzenserie für Signale (Standard: 15 Minuten).
MomentumCandleType
Höhere Zeitrahmen-Kerzen für den Momentum-Filter (Standard: 1 Stunde).
MacdCandleType
Kerzenserie für den MACD-Trendfilter (Standard: monatliche Kerzen).
Hinweise
Die Strategie benötigt das Instrument PriceStep, um pip-basierte Risikoeinstellungen in Preisabstände zu konvertieren. Stellen Sie sicher, dass die Wertpapier-Metadaten beim Ausführen der Strategie gefüllt sind.
Da StockSharp Netto-Positionen verwendet, werden zusätzliche gestaffelte Einstiege durch wiederholtes Senden von Market-Orders geöffnet, bis das konfigurierte Maximum erreicht ist. Ausstiege schließen die gesamte Nettoposition und entsprechen den "Alles schließen"-Routinen im ursprünglichen Experten.
Der monatliche MACD-Zeitrahmen kann über den MacdCandleType-Parameter angepasst werden, um verschiedene Instrumente oder Backtests zu unterstützen.
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class AcceleratorTrailingTPSLStrategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<int> _stopLossPoints;
private readonly StrategyParam<int> _takeProfitPoints;
private ExponentialMovingAverage _fast;
private ExponentialMovingAverage _slow;
private decimal _prevFast;
private decimal _prevSlow;
private decimal _entryPrice;
private int _cooldown;
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public int StopLossPoints { get => _stopLossPoints.Value; set => _stopLossPoints.Value = value; }
public int TakeProfitPoints { get => _takeProfitPoints.Value; set => _takeProfitPoints.Value = value; }
public AcceleratorTrailingTPSLStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 14).SetGreaterThanZero().SetDisplay("Fast Period", "Fast EMA period", "Indicator");
_slowPeriod = Param(nameof(SlowPeriod), 50).SetGreaterThanZero().SetDisplay("Slow Period", "Slow EMA period", "Indicator");
_stopLossPoints = Param(nameof(StopLossPoints), 200).SetNotNegative().SetDisplay("Stop Loss", "Stop-loss in price steps", "Risk");
_takeProfitPoints = Param(nameof(TakeProfitPoints), 400).SetNotNegative().SetDisplay("Take Profit", "Take-profit in price steps", "Risk");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
yield return (Security, TimeSpan.FromMinutes(5).TimeFrame());
}
protected override void OnReseted()
{
base.OnReseted();
_fast = null; _slow = null;
_prevFast = 0; _prevSlow = 0; _entryPrice = 0; _cooldown = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_fast = new ExponentialMovingAverage { Length = FastPeriod };
_slow = new ExponentialMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(TimeSpan.FromMinutes(5).TimeFrame());
subscription.Bind(_fast, _slow, ProcessCandle);
subscription.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fastValue, decimal slowValue)
{
if (candle.State != CandleStates.Finished) return;
if (!_fast.IsFormed || !_slow.IsFormed) { _prevFast = fastValue; _prevSlow = slowValue; return; }
if (_cooldown > 0) { _cooldown--; _prevFast = fastValue; _prevSlow = slowValue; return; }
var close = candle.ClosePrice;
var step = Security?.PriceStep ?? 1m;
if (Position > 0 && _entryPrice > 0)
{
if (StopLossPoints > 0 && close <= _entryPrice - StopLossPoints * step) { SellMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
if (TakeProfitPoints > 0 && close >= _entryPrice + TakeProfitPoints * step) { SellMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
}
else if (Position < 0 && _entryPrice > 0)
{
if (StopLossPoints > 0 && close >= _entryPrice + StopLossPoints * step) { BuyMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
if (TakeProfitPoints > 0 && close <= _entryPrice - TakeProfitPoints * step) { BuyMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
}
if (_prevFast <= _prevSlow && fastValue > slowValue && Position <= 0)
{ if (Position < 0) BuyMarket(); BuyMarket(); _entryPrice = close; _cooldown = 100; }
else if (_prevFast >= _prevSlow && fastValue < slowValue && Position >= 0)
{ if (Position > 0) SellMarket(); SellMarket(); _entryPrice = close; _cooldown = 100; }
_prevFast = fastValue; _prevSlow = slowValue;
}
}
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
from StockSharp.Algo.Strategies import Strategy
class accelerator_trailing_tpsl_strategy(Strategy):
def __init__(self):
super(accelerator_trailing_tpsl_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 14) \
.SetDisplay("Fast Period", "Fast MA period", "Indicator")
self._slow_period = self.Param("SlowPeriod", 50) \
.SetDisplay("Slow Period", "Slow MA period", "Indicator")
self._stop_loss_points = self.Param("StopLossPoints", 200) \
.SetDisplay("Stop Loss", "Stop-loss in price steps", "Risk")
self._take_profit_points = self.Param("TakeProfitPoints", 400) \
.SetDisplay("Take Profit", "Take-profit in price steps", "Risk")
self._fast = None
self._slow = None
self._prev_fast = 0.0
self._prev_slow = 0.0
self._entry_price = 0.0
self._cooldown = 0
@property
def fast_period(self):
return self._fast_period.Value
@property
def slow_period(self):
return self._slow_period.Value
@property
def stop_loss_points(self):
return self._stop_loss_points.Value
@property
def take_profit_points(self):
return self._take_profit_points.Value
def OnReseted(self):
super(accelerator_trailing_tpsl_strategy, self).OnReseted()
self._fast = None
self._slow = None
self._prev_fast = 0.0
self._prev_slow = 0.0
self._entry_price = 0.0
self._cooldown = 0
def OnStarted2(self, time):
super(accelerator_trailing_tpsl_strategy, self).OnStarted2(time)
self._fast = ExponentialMovingAverage()
self._fast.Length = self.fast_period
self._slow = ExponentialMovingAverage()
self._slow.Length = self.slow_period
subscription = self.SubscribeCandles(DataType.TimeFrame(TimeSpan.FromMinutes(5)))
subscription.Bind(self._fast, self._slow, self._process_candle)
subscription.Start()
def _process_candle(self, candle, fast_value, slow_value):
if candle.State != CandleStates.Finished:
return
fast_val = float(fast_value)
slow_val = float(slow_value)
if not self._fast.IsFormed or not self._slow.IsFormed:
self._prev_fast = fast_val
self._prev_slow = slow_val
return
if self._cooldown > 0:
self._cooldown -= 1
self._prev_fast = fast_val
self._prev_slow = slow_val
return
close = float(candle.ClosePrice)
step = float(self.Security.PriceStep) if self.Security is not None and self.Security.PriceStep is not None else 1.0
if self.Position > 0 and self._entry_price > 0:
if self.stop_loss_points > 0 and close <= self._entry_price - self.stop_loss_points * step:
self.SellMarket()
self._entry_price = 0.0
self._cooldown = 100
self._prev_fast = fast_val
self._prev_slow = slow_val
return
if self.take_profit_points > 0 and close >= self._entry_price + self.take_profit_points * step:
self.SellMarket()
self._entry_price = 0.0
self._cooldown = 100
self._prev_fast = fast_val
self._prev_slow = slow_val
return
elif self.Position < 0 and self._entry_price > 0:
if self.stop_loss_points > 0 and close >= self._entry_price + self.stop_loss_points * step:
self.BuyMarket()
self._entry_price = 0.0
self._cooldown = 100
self._prev_fast = fast_val
self._prev_slow = slow_val
return
if self.take_profit_points > 0 and close <= self._entry_price - self.take_profit_points * step:
self.BuyMarket()
self._entry_price = 0.0
self._cooldown = 100
self._prev_fast = fast_val
self._prev_slow = slow_val
return
if self._prev_fast <= self._prev_slow and fast_val > slow_val and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
self._entry_price = close
self._cooldown = 100
elif self._prev_fast >= self._prev_slow and fast_val < slow_val and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._entry_price = close
self._cooldown = 100
self._prev_fast = fast_val
self._prev_slow = slow_val
def CreateClone(self):
return accelerator_trailing_tpsl_strategy()