Diese Strategie erstellt den MetaTrader 5 Expert Advisor "Divergence EA pip sl tp" im StockSharp-Framework neu. Der Algorithmus sucht nach klassischen Abweichungen zwischen der Preisbewegung und dem MACD-Histogramm und validiert das Signal dann mit einem überkauften/überverkauften Stochastic-Oszillatorfilter, bevor er Umkehrgeschäfte eröffnet.
Handelslogik
Abonnieren Sie die durch den Parameter CandleType ausgewählten primären Zeitrahmenkerzen.
Berechnen Sie das MACD-Histogramm (MACD line - Signal line) und die Stochastic %K/%D-Werte für jede fertige Kerze.
Verfolgen Sie die letzten beiden Swing-Hochs und -Tiefs der Preis- und Histogrammwerte.
Bearische Divergenz: Ein neues höheres Preishoch, begleitet von einem niedrigeren MACD-Histogramm-Höhepunkt und Stochastic %K über StochasticUpperLevel, löst eine Short-Position aus oder kehrt eine bestehende Long-Position um.
Bulnische Divergenz: Ein neues niedrigeres Preistief mit einem höheren MACD-Histogrammtief und %K unter StochasticLowerLevel eröffnet oder kehrt sich in eine Long-Position um.
Optionale Schutzmaßnahmen TakeProfitSteps und StopLossSteps werden in StockSharp Schritteinheiten umgewandelt und einmalig aktiviert, wenn die Strategie startet.
Hinweise zur Implementierung
Gebaut mit StockSharp High-Level-API unter Verwendung eines einzelnen Kerzenabonnements, das an die Indikatoren MovingAverageConvergenceDivergenceSignal und StochasticOscillator gebunden ist.
Behält den Divergenzstatus bei, ohne Indikator-GetValue-Helfer aufzurufen, und entspricht den Konvertierungsrichtlinien.
Die Diagrammintegration zeigt Preiskerzen, MACD- und Stochastic-Linien an, wenn ein Diagrammbereich verfügbar ist.
Positionen werden umgekehrt, indem die absolute aktuelle Positionsgröße zur Basis Volume addiert wird, wodurch sofortige Richtungsänderungen nach bestätigten Divergenzen sichergestellt werden.
Parameter
Parameter
Beschreibung
Standard
CandleType
Für Divergenzberechnungen verwendeter Zeitrahmen.
1-Stunden-Kerzen
MacdFastLength, MacdSlowLength, MacdSignalLength
MACD EMA Längen, die die ursprünglichen EA-Eingaben replizieren.
26.12.9
MacdDivergenceThreshold
Minimale Histogrammdifferenz zwischen aufeinanderfolgenden Schwankungen, die zur Bestätigung der Divergenz erforderlich ist.
0,0005
StochasticLength
Schnelle %K-Periode des Stochastic-Oszillators.
50
StochasticSlowK, StochasticSlowD
Zusätzliche %K/%D-Glättungslängen, die die EA-Konfiguration widerspiegeln.
9 / 9
StochasticUpperLevel, StochasticLowerLevel
Überkauft- und Überverkauft-Filter zur Validierung bärischer/bullischer Setups.
80/20
TakeProfitSteps, StopLossSteps
Optionale Schutzabstände, ausgedrückt in Preisschritten (0 deaktiviert die Stufe).
50
Nutzung
Hängen Sie die Strategie an einen StockSharp-Connector mit einem Wertpapier an, das den ausgewählten Zeitrahmen unterstützt.
Konfigurieren Sie die Positionsgröße über die Basiseigenschaft Volume und passen Sie die Indikatoreinstellungen nach Bedarf an.
Starten Sie die Strategie – Aufträge werden automatisch generiert, wenn die Divergenz- und Stochastic-Bedingungen erfüllt sind.
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Simplified from "Divergence MACD Stochastic" MetaTrader expert.
/// Uses MACD histogram divergence (price vs histogram) with RSI confirmation.
/// MACD is computed manually from two EMAs.
/// </summary>
public class DivergenceMacdStochasticStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _macdFast;
private readonly StrategyParam<int> _macdSlow;
private readonly StrategyParam<int> _rsiPeriod;
// Manual EMA for MACD
private decimal _fastEma;
private decimal _slowEma;
private bool _emaInitialized;
private int _barCount;
private decimal _fastMultiplier;
private decimal _slowMultiplier;
private readonly decimal[] _macdWindow = new decimal[DivergenceLookback];
private readonly decimal[] _priceWindow = new decimal[DivergenceLookback];
private int _windowCount;
private int _windowIndex;
private const int DivergenceLookback = 10;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int MacdFast
{
get => _macdFast.Value;
set => _macdFast.Value = value;
}
public int MacdSlow
{
get => _macdSlow.Value;
set => _macdSlow.Value = value;
}
public int RsiPeriod
{
get => _rsiPeriod.Value;
set => _rsiPeriod.Value = value;
}
public DivergenceMacdStochasticStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
.SetDisplay("Candle Type", "Timeframe for divergence detection", "General");
_macdFast = Param(nameof(MacdFast), 20)
.SetGreaterThanZero()
.SetDisplay("MACD Fast", "Fast EMA length", "Indicators");
_macdSlow = Param(nameof(MacdSlow), 50)
.SetGreaterThanZero()
.SetDisplay("MACD Slow", "Slow EMA length", "Indicators");
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "RSI period for confirmation", "Indicators");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_windowCount = 0;
_windowIndex = 0;
_emaInitialized = false;
_barCount = 0;
_fastMultiplier = 2m / (MacdFast + 1);
_slowMultiplier = 2m / (MacdSlow + 1);
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
var close = candle.ClosePrice;
_barCount++;
// Manual EMA computation
if (!_emaInitialized)
{
_fastEma = close;
_slowEma = close;
_emaInitialized = true;
}
else
{
_fastEma = close * _fastMultiplier + _fastEma * (1 - _fastMultiplier);
_slowEma = close * _slowMultiplier + _slowEma * (1 - _slowMultiplier);
}
if (_barCount < MacdSlow)
return;
var macdLine = _fastEma - _slowEma;
_macdWindow[_windowIndex] = macdLine;
_priceWindow[_windowIndex] = close;
_windowIndex = (_windowIndex + 1) % DivergenceLookback;
if (_windowCount < DivergenceLookback)
_windowCount++;
if (_windowCount < DivergenceLookback)
return;
var volume = Volume;
if (volume <= 0)
volume = 1;
var oldestIndex = _windowIndex;
var newestIndex = (_windowIndex + DivergenceLookback - 1) % DivergenceLookback;
var oldMacd = _macdWindow[oldestIndex];
var newMacd = _macdWindow[newestIndex];
var oldPrice = _priceWindow[oldestIndex];
var newPrice = _priceWindow[newestIndex];
var minPriceMove = oldPrice * 0.005m;
// Bullish divergence: price makes lower low but MACD makes higher low.
var bullishDiv = newPrice < oldPrice - minPriceMove && newMacd > oldMacd;
// Bearish divergence: price makes higher high but MACD makes lower high.
var bearishDiv = newPrice > oldPrice + minPriceMove && newMacd < oldMacd;
if (bullishDiv)
{
if (Position <= 0)
BuyMarket(Position < 0 ? Math.Abs(Position) + volume : volume);
}
else if (bearishDiv)
{
if (Position >= 0)
SellMarket(Position > 0 ? Math.Abs(Position) + volume : volume);
}
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_fastEma = 0;
_slowEma = 0;
_emaInitialized = false;
_barCount = 0;
_fastMultiplier = 0;
_slowMultiplier = 0;
Array.Clear(_macdWindow, 0, _macdWindow.Length);
Array.Clear(_priceWindow, 0, _priceWindow.Length);
_windowCount = 0;
_windowIndex = 0;
}
}
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.Strategies import Strategy
class divergence_macd_stochastic_strategy(Strategy):
DIVERGENCE_LOOKBACK = 10
def __init__(self):
super(divergence_macd_stochastic_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(60)))
self._macd_fast = self.Param("MacdFast", 20)
self._macd_slow = self.Param("MacdSlow", 50)
self._fast_ema = 0.0
self._slow_ema = 0.0
self._ema_initialized = False
self._bar_count = 0
self._fast_multiplier = 0.0
self._slow_multiplier = 0.0
self._macd_window = []
self._price_window = []
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def MacdFast(self):
return self._macd_fast.Value
@MacdFast.setter
def MacdFast(self, value):
self._macd_fast.Value = value
@property
def MacdSlow(self):
return self._macd_slow.Value
@MacdSlow.setter
def MacdSlow(self, value):
self._macd_slow.Value = value
def OnReseted(self):
super(divergence_macd_stochastic_strategy, self).OnReseted()
self._fast_ema = 0.0
self._slow_ema = 0.0
self._ema_initialized = False
self._bar_count = 0
self._macd_window = []
self._price_window = []
def OnStarted2(self, time):
super(divergence_macd_stochastic_strategy, self).OnStarted2(time)
self._fast_ema = 0.0
self._slow_ema = 0.0
self._ema_initialized = False
self._bar_count = 0
self._fast_multiplier = 2.0 / (self.MacdFast + 1)
self._slow_multiplier = 2.0 / (self.MacdSlow + 1)
self._macd_window = []
self._price_window = []
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(self._process_candle).Start()
def _process_candle(self, candle):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
self._bar_count += 1
if not self._ema_initialized:
self._fast_ema = close
self._slow_ema = close
self._ema_initialized = True
else:
self._fast_ema = close * self._fast_multiplier + self._fast_ema * (1 - self._fast_multiplier)
self._slow_ema = close * self._slow_multiplier + self._slow_ema * (1 - self._slow_multiplier)
if self._bar_count < self.MacdSlow:
return
macd_line = self._fast_ema - self._slow_ema
self._macd_window.append(macd_line)
self._price_window.append(close)
while len(self._macd_window) > self.DIVERGENCE_LOOKBACK:
self._macd_window.pop(0)
self._price_window.pop(0)
if len(self._macd_window) < self.DIVERGENCE_LOOKBACK:
return
old_macd = self._macd_window[0]
new_macd = self._macd_window[-1]
old_price = self._price_window[0]
new_price = self._price_window[-1]
min_price_move = old_price * 0.005
# Bullish divergence: price makes lower low but MACD makes higher low
bullish_div = new_price < old_price - min_price_move and new_macd > old_macd
# Bearish divergence: price makes higher high but MACD makes lower high
bearish_div = new_price > old_price + min_price_move and new_macd < old_macd
if bullish_div:
if self.Position <= 0:
self.BuyMarket()
elif bearish_div:
if self.Position >= 0:
self.SellMarket()
def CreateClone(self):
return divergence_macd_stochastic_strategy()