Die ADX MACD Deev-Strategie ist ein StockSharp-Port des MetaTrader-Expertenberaters mit demselben Namen. Sie kombiniert das Trendstärkesignal des Average Directional Index (ADX) mit der Momentum-Bestätigung des Moving Average Convergence Divergence (MACD). Die Strategie handelt nur, wenn beide Indikatoren in der Marktrichtung übereinstimmen, und kann Gewinne optional durch Trailing Stops und partielle Positionsausstiege sichern.
Funktionsweise
Indikatorvorbereitung
ADX wird mit einer konfigurierbaren Mittelungsperiode berechnet. Die Strategie verfolgt die neuesten ADX-Werte und erfordert, dass sie sich konsistent in eine Richtung bewegen, bevor ein Trade erlaubt wird.
MACD verwendet konfigurierbare schnelle, langsame und Signal-EMAs. Das Histogramm und die Signallinie müssen gemeinsam ein anhaltendes Wachstum für Longs oder einen anhaltenden Rückgang für Shorts zeigen.
Einstiegslogik
Long-Einstiege: ausgelöst, wenn das MACD-Histogramm den MACD Minimum (pips)-Schwellenwert überschreitet, sowohl MACD-Histogramm als auch Signallinie für die gewählte Anzahl von Bars zunehmen und ADX über der erforderlichen Stärke bleibt und ebenfalls steigt.
Short-Einstiege: ausgelöst, wenn das MACD-Histogramm unter dem negativen Schwellenwert liegt, sowohl MACD-Histogramm als auch Signallinie über das gewählte Intervall sinken und ADX über dem Minimum bleibt, während es abnimmt.
Es kann jeweils nur eine Position offen sein.
Risikomanagement
Anfängliche Stop-Loss- und Take-Profit-Niveaus werden in Preiseinheiten platziert, die aus dem Instrument PriceStep und den gewählten Pip-Distanzen abgeleitet werden.
Ein Trailing Stop kann profitable Positionen verfolgen, sobald der Preis um Trailing Stop + Trailing Step Pips vorgerückt ist.
Wenn Take Half Profit aktiviert ist, schließt die Strategie die Hälfte der aktuellen Position auf dem Take-Profit-Niveau und lässt den Rest mit dem Trailing Stop laufen.
Parameter
Gruppe
Name
Beschreibung
Trading
Order Volume
Volumen jeder neuen Market-Order.
Risiko
Stop Loss (pips)
Anfänglicher Stop-Loss-Abstand vom Einstieg.
Risiko
Take Profit (pips)
Anfänglicher Take-Profit-Abstand vom Einstieg.
Risiko
Trailing Stop (pips)
Trailing-Stop-Distanz. Auf null setzen, um Trailing zu deaktivieren.
Risiko
Trailing Step (pips)
Zusätzliche Preisbewegung, bevor der Trailing Stop sich wieder bewegt.
Risiko
Take Half Profit
Aktiviert den Teilausstieg, wenn das Take-Profit-Niveau erreicht ist.
Indikatoren
ADX Period
ADX-Mittelungsperiode.
Indikatoren
ADX Bars Interval
Anzahl der jüngsten ADX-Bars, die in eine Richtung tendieren müssen.
Indikatoren
ADX Minimum
Minimaler ADX-Wert, der für Einstiege erforderlich ist.
Indikatoren
MACD Fast EMA
Schnelle EMA-Länge für MACD.
Indikatoren
MACD Slow EMA
Langsame EMA-Länge für MACD.
Indikatoren
MACD Signal EMA
Signal-EMA-Länge für MACD.
Indikatoren
MACD Bars Interval
Anzahl der MACD-Bars, die in dieselbe Richtung ausgerichtet sein müssen.
Indikatoren
MACD Minimum (pips)
Minimale MACD-Magnitude in Pips konvertiert.
Allgemein
Candle Type
Kerzentyp oder Zeitrahmen für Berechnungen.
Verwendungshinweise
Die Strategie benötigt Instrumente mit einem gültigen PriceStep. Wenn PriceStep null ist, fallen die pip-basierten Schwellenwerte auf rohe MACD-Werte zurück.
Die Volumenrundung für Teilausstiege folgt dem VolumeStep des Instruments.
Trailing-Stop-Anpassungen werden nur auf geschlossenen Kerzen bewertet.
Die Strategie verwendet High-Level-API-Bindungen (SubscribeCandles().BindEx(...)) und basiert nicht auf manuellem Indikatorwert-Polling.
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 AdxMacdDeevStrategy : 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 AdxMacdDeevStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 12).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 CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
from datatype_extensions import *
class adx_macd_deev_strategy(Strategy):
"""
ADX MACD Deev: dual EMA crossover with stop-loss/take-profit in price steps.
"""
def __init__(self):
super(adx_macd_deev_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 12) \
.SetGreaterThanZero() \
.SetDisplay("Fast Period", "Fast EMA period", "Indicator")
self._slow_period = self.Param("SlowPeriod", 50) \
.SetGreaterThanZero() \
.SetDisplay("Slow Period", "Slow EMA 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._prev_fast = 0.0
self._prev_slow = 0.0
self._entry_price = 0.0
self._cooldown = 0
@property
def FastPeriod(self):
return self._fast_period.Value
@FastPeriod.setter
def FastPeriod(self, value):
self._fast_period.Value = value
@property
def SlowPeriod(self):
return self._slow_period.Value
@SlowPeriod.setter
def SlowPeriod(self, value):
self._slow_period.Value = value
@property
def StopLossPoints(self):
return self._stop_loss_points.Value
@StopLossPoints.setter
def StopLossPoints(self, value):
self._stop_loss_points.Value = value
@property
def TakeProfitPoints(self):
return self._take_profit_points.Value
@TakeProfitPoints.setter
def TakeProfitPoints(self, value):
self._take_profit_points.Value = value
def OnReseted(self):
super(adx_macd_deev_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_slow = 0.0
self._entry_price = 0.0
self._cooldown = 0
def OnStarted2(self, time):
super(adx_macd_deev_strategy, self).OnStarted2(time)
fast = ExponentialMovingAverage()
fast.Length = self.FastPeriod
slow = ExponentialMovingAverage()
slow.Length = self.SlowPeriod
subscription = self.SubscribeCandles(tf(5))
subscription.Bind(fast, slow, self.ProcessCandle).Start()
def ProcessCandle(self, candle, fast_value, slow_value):
if candle.State != CandleStates.Finished:
return
if self._cooldown > 0:
self._cooldown -= 1
self._prev_fast = fast_value
self._prev_slow = slow_value
return
close = float(candle.ClosePrice)
step = 1.0
if self.Position > 0 and self._entry_price > 0:
if self.StopLossPoints > 0 and close <= self._entry_price - self.StopLossPoints * step:
self.SellMarket()
self._entry_price = 0.0
self._cooldown = 100
self._prev_fast = fast_value
self._prev_slow = slow_value
return
if self.TakeProfitPoints > 0 and close >= self._entry_price + self.TakeProfitPoints * step:
self.SellMarket()
self._entry_price = 0.0
self._cooldown = 100
self._prev_fast = fast_value
self._prev_slow = slow_value
return
elif self.Position < 0 and self._entry_price > 0:
if self.StopLossPoints > 0 and close >= self._entry_price + self.StopLossPoints * step:
self.BuyMarket()
self._entry_price = 0.0
self._cooldown = 100
self._prev_fast = fast_value
self._prev_slow = slow_value
return
if self.TakeProfitPoints > 0 and close <= self._entry_price - self.TakeProfitPoints * step:
self.BuyMarket()
self._entry_price = 0.0
self._cooldown = 100
self._prev_fast = fast_value
self._prev_slow = slow_value
return
if self._prev_fast <= self._prev_slow and fast_value > slow_value 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_value < slow_value and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._entry_price = close
self._cooldown = 100
self._prev_fast = fast_value
self._prev_slow = slow_value
def CreateClone(self):
"""!! REQUIRED!! Creates a new instance of the strategy."""
return adx_macd_deev_strategy()