Diese Strategie ist eine direkte StockSharp-Konvertierung des „Sensitive" MACD-Experten-Advisors für MetaTrader 5. Sie kombiniert MACD-Crossovers mit konfigurierbaren Risikomanagement-Tools (fester Stop-Loss, Take-Profit und Pip-basierte Trailing-Stops). Der Algorithmus arbeitet ausschließlich auf abgeschlossenen Kerzen und verwendet die High-Level-API, um den gewünschten Zeitrahmen zu abonnieren.
Indikatoren und Daten
MACD (Moving Average Convergence Divergence) – konfiguriert mit unabhängigen Fast-, Slow- und Signal-EMA-Längen.
Kerzen – benutzerwählbarer Zeitrahmen, bereitgestellt über den Parameter CandleType.
Einstiegsbedingungen
Eine neue Kerze muss schließen, um Intrabar-Rauschen zu vermeiden.
MACD-Werte werden aus der Indikatorbindung verarbeitet:
macd repräsentiert die MACD-Hauptlinie.
signal ist die Signallinie (EMA der MACD-Differenz).
Anforderungen für Long-Einstieg:
MACD kreuzt über die Signallinie (macd > signal, während die vorherigen Werte macd < signal erfüllten).
MACD bleibt im negativen Bereich (macd < 0).
Die absolute MACD-Magnitude ist größer als MacdOpenLevel * Point, was eine bedeutungsvolle Verschiebung sicherstellt.
Keine aktive Long-Position (Nettoposition ist kleiner oder gleich null). Bestehende Shorts werden durch Senden der erforderlichen Menge umgekehrt.
Anforderungen für Short-Einstieg spiegeln das Long-Setup wider:
MACD kreuzt unter die Signallinie, bleibt dabei positiv.
Die absolute MACD-Magnitude übersteigt den konfigurierten Schwellenwert.
Keine Short-Position vorhanden (Nettoposition ist größer oder gleich null). Bestehende Longs werden geglättet, bevor der Short eröffnet wird.
Exit-Management
Take-Profit: Sobald der Trade eröffnet ist, speichert die Strategie ein Zielniveau, das durch TakeProfitPips definiert wird. Wenn das Hoch einer Long-Kerze oder das Tief einer Short-Kerze dieses Niveau erreicht, wird die Position zu Marktpreisen geschlossen.
Stop-Loss: Ein Schutz-Stop wird aus StopLossPips berechnet. Bei Longs löst ein Kursrückgang auf das Stop-Niveau einen Marktausstieg aus. Shorts reagieren auf Kursanstiege, die den Stop erreichen.
Trailing-Stop: Wenn TrailingStopPips ungleich null ist, aktiviert der Algorithmus eine Trailing-Logik, nachdem der Kurs mindestens TrailingStopPips + TrailingStepPips Pips vom Einstieg vorgerückt ist. Nachfolgende Bewegungen halten das Stop-Niveau immer in der angegebenen Trailing-Distanz vom letzten Schlusskurs. Der Trailing-Schritt muss positiv sein, wenn der Trailing-Stop aktiviert ist; andernfalls stoppt die Strategie mit einer Fehlermeldung.
Wenn keine Position aktiv ist, werden interne Tracking-Variablen zurückgesetzt, um sich auf den nächsten Trade vorzubereiten.
Positionsgröße
Ordermengen werden durch den eingebauten Volume-Strategieparameter gesteuert (Standard: 0.1). Umkehrungen fügen automatisch den absoluten Wert der aktuellen Position zum gewünschten Volumen hinzu, um die Richtung in einer einzigen Marktorder zu wechseln.
Parameter
Parameter
Beschreibung
Standard
FastLength
Schnelle EMA-Periode, die von der MACD-Hauptlinie verwendet wird.
12
SlowLength
Langsame EMA-Periode, die von der MACD-Hauptlinie verwendet wird.
26
SignalLength
Signal-EMA-Periode für den MACD.
9
MacdOpenLevel
Minimale MACD-Magnitude (in Preispunkten), die zum Auslösen von Trades erforderlich ist.
3
StopLossPips
Abstand des Schutz-Stops in Pips.
35
TakeProfitPips
Take-Profit-Abstand in Pips.
75
TrailingStopPips
Trailing-Stop-Abstand in Pips (0 deaktiviert Trailing).
5
TrailingStepPips
Zusätzliche Distanz, die der Kurs bewegen muss, bevor der Trailing-Stop aktualisiert wird.
5
CandleType
Quell-Kerzentyp (Zeitrahmen).
1-Minuten-Kerzen
Volume
Order-Volumen, ausgedrückt in Lots/Kontrakten je nach Instrument.
0.1
Zusätzliche Hinweise
Pip- und MACD-Punktwerte werden aus dem Preisschritt des Instruments und seiner Dezimalgenauigkeit abgeleitet. Der Code passt sich für 3- und 5-stellige Forex-Symbole an, indem die Pip-Größe entsprechend skaliert wird.
Alle Kommentare im Quellcode sind in Englisch geschrieben, und die Implementierung verwendet nur High-Level-StockSharp-APIs gemäß den Projektrichtlinien.
Die Strategie vermeidet absichtlich die Verwaltung von Teilfüllungen und geht davon aus, dass Marktorders beim Ausführen im Simulator oder Echthandel sofort gefüllt werden. Weitere Sicherheitsvorkehrungen können bei Bedarf hinzugefügt werden.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Sensitive MACD Trailing strategy. Uses EMA crossover (5/15).
/// </summary>
public class SensitiveMacdTrailingStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private decimal? _prevFast;
private decimal? _prevSlow;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public SensitiveMacdTrailingStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame()).SetDisplay("Candle Type", "Timeframe", "General");
_fastPeriod = Param(nameof(FastPeriod), 5).SetGreaterThanZero().SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 15).SetGreaterThanZero().SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = null;
_prevSlow = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevFast = null; _prevSlow = null;
var fast = new ExponentialMovingAverage { Length = FastPeriod };
var slow = new ExponentialMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(fast, slow, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, fast); DrawIndicator(area, slow); DrawOwnTrades(area); }
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
{
if (candle.State != CandleStates.Finished) return;
if (!IsFormedAndOnlineAndAllowTrading()) { _prevFast = fast; _prevSlow = slow; return; }
if (_prevFast == null || _prevSlow == null) { _prevFast = fast; _prevSlow = slow; return; }
var prevAbove = _prevFast.Value > _prevSlow.Value;
var currAbove = fast > slow;
_prevFast = fast; _prevSlow = slow;
if (!prevAbove && currAbove && Position <= 0) { if (Position < 0) BuyMarket(); BuyMarket(); }
else if (prevAbove && !currAbove && Position >= 0) { if (Position > 0) SellMarket(); SellMarket(); }
}
}
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 sensitive_macd_trailing_strategy(Strategy):
def __init__(self):
super(sensitive_macd_trailing_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._fast_period = self.Param("FastPeriod", 5) \
.SetDisplay("Fast EMA", "Fast EMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 15) \
.SetDisplay("Slow EMA", "Slow EMA period", "Indicators")
self._prev_fast = None
self._prev_slow = None
@property
def CandleType(self):
return self._candle_type.Value
@property
def FastPeriod(self):
return self._fast_period.Value
@property
def SlowPeriod(self):
return self._slow_period.Value
def OnReseted(self):
super(sensitive_macd_trailing_strategy, self).OnReseted()
self._prev_fast = None
self._prev_slow = None
def OnStarted2(self, time):
super(sensitive_macd_trailing_strategy, self).OnStarted2(time)
self._prev_fast = None
self._prev_slow = None
fast = ExponentialMovingAverage()
fast.Length = self.FastPeriod
slow = ExponentialMovingAverage()
slow.Length = self.SlowPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(fast, slow, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, fast)
self.DrawIndicator(area, slow)
self.DrawOwnTrades(area)
def _on_process(self, candle, fast_value, slow_value):
if candle.State != CandleStates.Finished:
return
fv = float(fast_value)
sv = float(slow_value)
if self._prev_fast is None or self._prev_slow is None:
self._prev_fast = fv
self._prev_slow = sv
return
prev_above = self._prev_fast > self._prev_slow
curr_above = fv > sv
self._prev_fast = fv
self._prev_slow = sv
if not prev_above and curr_above and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif prev_above and not curr_above and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
def CreateClone(self):
return sensitive_macd_trailing_strategy()