Diese Strategie repliziert den MetaTrader 5-Expert Exp_XDeMarker_Histogram_Vol_Direct mit der High-Level-API von StockSharp. Sie multipliziert den XDeMarker-Oszillator mit dem gewählten Volumenstrom, glättet sowohl den Oszillator als auch das Volumen mit demselben gleitenden Durchschnitt und vergleicht das Ergebnis mit konfigurierbaren oberen/unteren Niveaus. Handelsentscheidungen werden getroffen, wenn das geglättete Histogramm zwischen aufeinanderfolgenden Bars die Richtung wechselt.
Indikatorlogik
Den klassischen XDeMarker-Oszillator auf dem ausgewählten Zeitrahmen berechnen.
Den Oszillator für jede abgeschlossene Kerze mit Tick-Anzahl oder realem Volumen skalieren.
Sowohl das Histogramm als auch das Volumen mit dem ausgewählten gleitenden Durchschnittstyp glätten.
Das geglättete Volumen mit den konfigurierten Niveau-Multiplikatoren multiplizieren, um vier dynamische Bänder zu erhalten.
Die Histogrammrichtung erkennen (steigend oder fallend). Wenn die Richtung wechselt, eröffnet die Strategie eine neue Position in der entsprechenden Richtung und schließt gleichzeitig jeden entgegengesetzten Trade.
Die Glättungsmethode unterstützt einfache, exponentielle, geglättete (RMA/SMMA) und gewichtete gleitende Durchschnitte. Exotische Filter aus der ursprünglichen Bibliothek (JJMA, JurX, ParMA, T3, VIDYA, AMA) sind in diesem Port nicht verfügbar.
Handelsregeln
Long-Einstieg — aktiviert wenn Allow Long Entry = true. Wenn der vorherige Bar eine "hoch"-Richtung hatte und der letzte Bar zu "runter" wechselte, zielt die Strategie auf eine Long-Position von Volume Lots.
Short-Einstieg — aktiviert wenn Allow Short Entry = true. Ausgelöst wenn der vorherige Bar "runter" war und der neueste Bar auf "hoch" dreht.
Long-Ausstieg — aktiviert wenn Allow Long Exit = true. Wenn die vorherige Bar-Richtung "runter" ist, wird die Position liquidiert, es sei denn, ein neuer Short-Einstieg wird im selben Bar ausgelöst.
Short-Ausstieg — aktiviert wenn Allow Short Exit = true. Aktiviert wenn die vorherige Bar-Richtung "hoch" ist.
Signale werden einmal pro abgeschlossener Kerze ausgewertet. Die StockSharp-Implementierung behält die ursprüngliche Ein-Bar-Verzögerung bei; der Signal Bar-Parameter ist als Referenz vorhanden, aber Werte ungleich 1 werden mit einer Warnung ignoriert.
Parameter
Parameter
Beschreibung
Candle Type
Zeitrahmen für den Aufbau von Kerzen für den Indikator.
DeMarker Period
Rückblickzeitraum für den Basis-XDeMarker-Oszillator.
Volume Source
Auswahl zwischen Tick-Anzahl und realem gehandeltem Volumen.
High Level 2 / High Level 1
Multiplikatoren auf das geglättete Volumen zur Bildung oberer Bänder.
Low Level 1 / Low Level 2
Multiplikatoren für untere Bänder.
Smoothing Method
Gleitender Durchschnittstyp auf Histogramm und Volumen angewendet.
Smoothing Length
Länge des Glättungsfensters.
Smoothing Phase
Kompatibilitäts-Platzhalter (nicht verwendet, aber für Parität beibehalten).
Signal Bar
Historischer Versatz, fest auf 1 wie im Expert.
Allow Long/Short Entry
Öffnung von Positionen in der jeweiligen Richtung aktivieren.
Die Klasse XDeMarkerHistogramVolDirectIndicator reproduziert die MT5-Indikatorpuffer und exponiert das geglättete Histogramm, Bänder und Richtungsflags durch einen komplexen Indikatorwert.
Wenn eine neue Zielexponierung erforderlich ist, sendet die Strategie eine einzelne Marktorder, die die aktuelle Position auf das gewünschte Niveau verschiebt (Volume, -Volume oder flat). Dies ahmt die sequentiellen Schließ-/Öffnungsaufrufe im ursprünglichen MQL5-Code nach, ohne Orders zu duplizieren.
Das Chart-Rendering plottet automatisch die Kerzen, den benutzerdefinierten Indikator und die ausgeführten Trades, wenn ein Chart-Bereich verfügbar ist.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class XDeMarkerHistogramVolDirectStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _period;
private decimal? _prevDm;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int Period { get => _period.Value; set => _period.Value = value; }
public XDeMarkerHistogramVolDirectStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame()).SetDisplay("Candle Type", "Timeframe", "General");
_period = Param(nameof(Period), 14).SetGreaterThanZero().SetDisplay("DeMarker Period", "DeMarker lookback", "Indicators");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevDm = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevDm = null;
var dm = new DeMarker { Length = Period };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(dm, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null) { DrawCandles(area, subscription); DrawOwnTrades(area); }
}
private void ProcessCandle(ICandleMessage candle, decimal dmVal)
{
if (candle.State != CandleStates.Finished) return;
if (!IsFormedAndOnlineAndAllowTrading()) { _prevDm = dmVal; return; }
if (_prevDm == null) { _prevDm = dmVal; return; }
if (_prevDm.Value < 0.45m && dmVal >= 0.55m && Position <= 0) { if (Position < 0) BuyMarket(); BuyMarket(); }
else if (_prevDm.Value > 0.55m && dmVal <= 0.45m && Position >= 0) { if (Position > 0) SellMarket(); SellMarket(); }
_prevDm = dmVal;
}
}
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 DeMarker
from StockSharp.Algo.Strategies import Strategy
class x_de_marker_histogram_vol_direct_strategy(Strategy):
def __init__(self):
super(x_de_marker_histogram_vol_direct_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._period = self.Param("Period", 14) \
.SetDisplay("DeMarker Period", "DeMarker lookback", "Indicators")
self._prev_dm = None
@property
def CandleType(self):
return self._candle_type.Value
@property
def Period(self):
return self._period.Value
def OnReseted(self):
super(x_de_marker_histogram_vol_direct_strategy, self).OnReseted()
self._prev_dm = None
def OnStarted2(self, time):
super(x_de_marker_histogram_vol_direct_strategy, self).OnStarted2(time)
self._prev_dm = None
dm = DeMarker()
dm.Length = self.Period
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(dm, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def _on_process(self, candle, dm_value):
if candle.State != CandleStates.Finished:
return
dv = float(dm_value)
if not self.IsFormedAndOnlineAndAllowTrading():
self._prev_dm = dv
return
if self._prev_dm is None:
self._prev_dm = dv
return
if self._prev_dm < 0.45 and dv >= 0.55 and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif self._prev_dm > 0.55 and dv <= 0.45 and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_dm = dv
def CreateClone(self):
return x_de_marker_histogram_vol_direct_strategy()