Auf GitHub ansehen

Accelerator Trailing TP & SL-Strategie

Übersicht

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;
	}
}