Die Williams Percent Directional Index Strategy erstellt den MetaTrader 5-Experten „Mt5 Williams % Directional Index EA“ unter Verwendung des High-Level-API von StockSharp nach. Es kombiniert den Williams %R-Oszillator mit dem Average Directional Index (ADX), um Momentum-Wende zu identifizieren, und verlässt sich dann auf den Money Flow Index (MFI) und den Stochastic-Oszillator, um Trades zu beenden. Die Implementierung verarbeitet nur fertige Kerzen und verwendet Indikatorbindungen, sodass jede Entscheidung auf dem zuletzt abgeschlossenen Balken basiert.
Handelslogik
Trendausrichtung
Williams %R muss bei Long-Trades steigen oder bei Short-Trades fallen. Die Strategie vergleicht die Werte der beiden zuvor fertiggestellten Balken, um die Impulssteigung zu ermitteln.
Die Richtungsbewegungskomponente des ADX (+DI - -DI) muss auf dem letzten geschlossenen Balken die Nulllinie überschritten haben: Ein negativer zu positiver Übergang bestätigt ein bullisches Momentum, während ein positiver zu negativer Übergang ein bärisches Momentum bestätigt.
Eintrittsregeln
Wenn beide bullischen Bedingungen erfüllt sind und die aktuelle Position flach oder short ist, eröffnet die Strategie eine Marktkauforder.
Wenn beide rückläufigen Bedingungen erfüllt sind und die aktuelle Position flach oder lang ist, eröffnet die Strategie einen Marktverkaufsauftrag.
Wenn sowohl Long- als auch Short-Signale gleichzeitig auftreten (selten, aber bei identischen Werten möglich), wird der Handel übersprungen, um widersprüchliche Anweisungen zu vermeiden.
Ausgangsregeln
Long-Positionen schließen, wenn entweder der MFI-Wert von vor zwei Balken das überkaufte Niveau überschreitet oder die Stochastic-Hauptlinie ein lokales Tiefpunktmuster (K[−2] > K[−1] < K[0]) bildet.
Short-Positionen werden geschlossen, wenn entweder der MFI-Wert von vor zwei Balken unter das gespiegelte überverkaufte Niveau (100 - level) fällt oder die Stochastic-Hauptlinie ein lokales Spitzenmuster bildet (K[−2] < K[−1] > K[0]).
Risikohandhabung
Bei der Konvertierung bleiben die Ein- und Ausstiegsmechanismen des ursprünglichen Expert Advisors erhalten. Stop-Loss- und Trailing-Funktionen aus der Quelle MQL werden nicht reproduziert; Die Risikokontrolle sollte extern verwaltet oder bei Bedarf über StockSharp-Schutzmaßnahmen hinzugefügt werden.
Parameter
Name
Beschreibung
Standard
Candle Type
Zeitrahmen für alle Indikatorberechnungen.
15-minütiger Zeitrahmen
Williams %R Period
Rückblickzeitraum, der im Williams %R-Oszillator verwendet wird.
42
Directional Period
Zeitraum für ADX-Berechnungen (beeinflusst +DI/−DI).
20
MFI Period
Länge des Geldflussindex.
19
MFI Level
Überkaufter Schwellenwert, der zum Auslösen von Ausstiegen verwendet wird. Der überverkaufte Wert wird als 100 - value berechnet.
79
Stochastic %K
%K Periode des stochastischen Oszillators.
22
Stochastic %D
%D Periode des stochastischen Oszillators.
16
Stochastic Smoothing
Zusätzliche Glättung („Verlangsamung“) des stochastischen Oszillators.
21
Alle Parameter werden als StrategyParam-Werte angezeigt, sodass sie über die StockSharp-GUI optimiert oder angepasst werden können.
Nutzungshinweise
Binden Sie die Strategie an ein beliebiges Instrument und stellen Sie vor dem Start eine entsprechende Lautstärke ein.
Die Strategie verarbeitet nur abgeschlossene Kerzen (CandleStates.Finished) und garantiert so, dass die Indikatorwerte endgültig sind.
Die Diagrammdarstellung ist aktiviert: Williams %R, ADX, MFI, Stochastic und ausgeführte Trades werden dargestellt, wenn ein Diagrammbereich verfügbar ist.
Um das ursprüngliche MT5-Verhalten hinsichtlich der Stoppverwaltung wiederherzustellen, sollten Sie bei Bedarf das Hinzufügen von StartProtection oder einer benutzerdefinierten Risikologik in Betracht ziehen.
Unterschiede zur MQL-Version
Die StockSharp-Konvertierung verwendet Indikatorbindungen anstelle des manuellen Pufferkopierens, aber die logischen Prüfungen, einschließlich Nulldurchgangsvalidierung und Multi-Bar-Muster, folgen dem MT5-Expertenberater.
Sitzungsfilter, Wiederholungslogik und Trailing-Stop-Verwaltung aus dem MQL-Code werden absichtlich weggelassen, um sich auf die für diese Konvertierung erforderliche Kernsignal-Engine zu konzentrieren.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Williams %R Directional Index strategy: Williams %R crossover.
/// Buys when Williams %R crosses above -80, sells when crosses below -20.
/// </summary>
public class WilliamsPercentDirectionalIndexStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _period;
private readonly StrategyParam<int> _signalCooldownCandles;
private decimal _prevWr;
private int _candlesSinceTrade;
private bool _hasPrev;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int Period { get => _period.Value; set => _period.Value = value; }
public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }
public WilliamsPercentDirectionalIndexStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_period = Param(nameof(Period), 14)
.SetGreaterThanZero()
.SetDisplay("Period", "Williams %R period", "Indicators");
_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 4)
.SetGreaterThanZero()
.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevWr = 0;
_candlesSinceTrade = SignalCooldownCandles;
_hasPrev = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevWr = 0;
_candlesSinceTrade = SignalCooldownCandles;
_hasPrev = false;
var wr = new RelativeStrengthIndex { Length = Period };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(wr, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal wrValue)
{
if (candle.State != CandleStates.Finished) return;
if (_candlesSinceTrade < SignalCooldownCandles)
_candlesSinceTrade++;
if (_hasPrev)
{
if (_prevWr < 35 && wrValue >= 35 && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
{
BuyMarket();
_candlesSinceTrade = 0;
}
else if (_prevWr > 65 && wrValue <= 65 && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
{
SellMarket();
_candlesSinceTrade = 0;
}
}
_prevWr = wrValue;
_hasPrev = true;
}
}