Konvertiert vom MetaTrader 4 Expert Advisor MQL/7637/3_lccfpgubwykd__www_forex-instruments_info.mq4.
Verwendet einen Workflow mit drei Zeitrahmen: Stündliche Kerzen steuern beide MACD-Filter, 15-Minuten-Kerzen liefern Stochastic-Oszillatoren und 1-Minuten-Kerzen bestätigen Preisausbrüche und verwalten Trailing-Exits.
Implementiert eine übergeordnete StockSharp-Strategie mit SubscribeCandles(...).Bind(...) / BindEx(...) ohne manuelle Datenabfrage.
Positionen werden mit Marktaufträgen eröffnet und vollständig innerhalb der Strategie verwaltet (es waren keine externen Test-Änderungen erforderlich).
Indikatoren und Parameter
Name
Typ
Standard
Beschreibung
LongStopLoss
decimal
17
Anfänglicher Stoppabstand für Long-Trades, ausgedrückt in Instrumentenpunkten.
ShortStopLoss
decimal
40
Anfängliche Stoppdistanz für Short-Trades (Punkte).
LongTrailingStop
decimal
88
Nachlaufdistanz für Long-Positionen.
ShortTrailingStop
decimal
76
Nachlaufdistanz für Short-Positionen.
OrderVolume
decimal
0.1
Basishandelsvolumen (Lots), gespiegelt aus der Eingabe MQL.
MacdCandleType
DataType
H1
Zeitrahmen für die bullischen und bärischen MACD-Filter (22/27/9 und 19/77/9).
StochasticCandleType
DataType
M15
Zeitrahmen, der für beide Stochastic-Oszillatoren (5/3/11 und 9/3/19) verwendet wird.
EntryCandleType
DataType
M1
Zeitrahmen, der eine Ausbruchsbestätigung und eine abschließende Logik bereitstellt.
Alle punktbasierten Einstellungen werden durch das Instrument PriceStep in absolute Preise umgewandelt, wodurch der Multiplikator MetaTrader Point originalgetreu reproduziert wird.
Handelsregeln
Langer Eintrag
Die stündliche Hauptlinie MACD(22,27,9) überschreitet ihren vorherigen Wert, bleibt aber unter Null.
M15 Stochastic(%K=5,%D=3,slowing=11) liegt unter 26 und steigt im Vergleich zum vorherigen Wert.
Der aktuelle M1-Schluss durchbricht das vorherige M1-Hoch.
Wenn alle Bedingungen übereinstimmen und keine Position offen ist, kauft die Strategie OrderVolume plus die Menge, die zum Umtausch eines bestehenden Short erforderlich ist.
Kurzer Eintrag
Die stündliche MACD(19,77,9) Hauptlinie fällt unter ihren vorherigen Wert, wobei der vorherige Wert über Null liegt.
M15 Stochastic(%K=9,%D=3,slowing=19) liegt über 70.
Der aktuelle M1-Schlusskurs bricht unter das vorherige M1-Tief.
Ein Short wird mit der gleichen Positions-Flip-Logik wie der ursprüngliche EA eröffnet.
Exit und Trailing
Die anfänglichen Stopps spiegeln die Entfernungen von MQL StopLoss in Punkten wider.
Trailing-Stops werden aktiviert, sobald sich der Preis um mehr als die angegebene Trailing-Distanz zugunsten der Position bewegt, und werden bei jeder beendeten M1-Kerze neu berechnet.
Wenn der Preis das aktive Stop-Level (Anfangs- oder Trailed-Stop-Level) berührt, wird die Position mit einer Marktorder geschlossen.
Implementierungshinweise
Kerzenabonnements werden nach Zeitrahmen aufgeteilt, sodass Indikatoraktualisierungen unabhängig bleiben und genau dem Verhalten von EA in mehreren Zeitrahmen entsprechen.
Die nachgestellten Vergleiche MQL Bid/Ask werden durch die fertigen M1-Kerzenhöchst-/-tiefs angenähert, was die nächstliegende Darstellung innerhalb des kerzenbasierten Hochniveaus API darstellt.
Der Code folgt den Repository-Richtlinien: Tab-Einrückung, Namespace StockSharp.Samples.Strategies, englische Kommentare und Parameterdeklarationen innerhalb des Konstruktors über Param(...).
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>
/// MACD + Stochastic trailing strategy.
/// Enters long when MACD histogram is positive and Stochastic K crosses above D from oversold.
/// Enters short when MACD histogram is negative and Stochastic K crosses below D from overbought.
/// </summary>
public class MacdStochasticTrailingStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private decimal? _prevK;
private decimal? _prevD;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public MacdStochasticTrailingStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevK = null;
_prevD = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevK = null;
_prevD = null;
var macd = new MovingAverageConvergenceDivergenceSignal();
var stoch = new StochasticOscillator();
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(macd, stoch, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue macdValue, IIndicatorValue stochValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!macdValue.IsFinal || !stochValue.IsFinal)
return;
var macdVal = (MovingAverageConvergenceDivergenceSignalValue)macdValue;
var stochVal = (StochasticOscillatorValue)stochValue;
if (macdVal.Macd is not decimal macd || macdVal.Signal is not decimal signal)
return;
if (stochVal.K is not decimal k || stochVal.D is not decimal d)
return;
if (_prevK is not decimal prevK || _prevD is not decimal prevD)
{
_prevK = k;
_prevD = d;
return;
}
var histogram = macd - signal;
var kCrossUp = prevK <= prevD && k > d;
var kCrossDown = prevK >= prevD && k < d;
// Buy: MACD histogram positive + stochastic K crosses above D
if (histogram > 0 && kCrossUp && k < 50 && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// Sell: MACD histogram negative + stochastic K crosses below D
else if (histogram < 0 && kCrossDown && k > 50 && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevK = k;
_prevD = d;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import MovingAverageConvergenceDivergenceSignal, StochasticOscillator
from StockSharp.Algo.Strategies import Strategy
class macd_stochastic_trailing_strategy(Strategy):
"""MACD + Stochastic trailing strategy.
Enters long when MACD histogram positive and Stochastic K crosses above D from oversold.
Enters short when MACD histogram negative and Stochastic K crosses below D from overbought."""
def __init__(self):
super(macd_stochastic_trailing_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_k = None
self._prev_d = None
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
def OnReseted(self):
super(macd_stochastic_trailing_strategy, self).OnReseted()
self._prev_k = None
self._prev_d = None
def OnStarted2(self, time):
super(macd_stochastic_trailing_strategy, self).OnStarted2(time)
self._prev_k = None
self._prev_d = None
macd = MovingAverageConvergenceDivergenceSignal()
stoch = StochasticOscillator()
subscription = self.SubscribeCandles(self.CandleType)
subscription.BindEx(macd, stoch, self._process_candle).Start()
def _process_candle(self, candle, macd_value, stoch_value):
if candle.State != CandleStates.Finished:
return
if not macd_value.IsFinal or not stoch_value.IsFinal:
return
macd_raw = macd_value.Macd if hasattr(macd_value, 'Macd') else None
signal_raw = macd_value.Signal if hasattr(macd_value, 'Signal') else None
if macd_raw is None or signal_raw is None:
return
macd_main = float(macd_raw)
signal_line = float(signal_raw)
k_raw = stoch_value.K if hasattr(stoch_value, 'K') else None
d_raw = stoch_value.D if hasattr(stoch_value, 'D') else None
if k_raw is None or d_raw is None:
return
k = float(k_raw)
d = float(d_raw)
if self._prev_k is None or self._prev_d is None:
self._prev_k = k
self._prev_d = d
return
prev_k = self._prev_k
prev_d = self._prev_d
histogram = macd_main - signal_line
k_cross_up = prev_k <= prev_d and k > d
k_cross_down = prev_k >= prev_d and k < d
# Buy: MACD histogram positive + stochastic K crosses above D from oversold
if histogram > 0 and k_cross_up and k < 50 and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# Sell: MACD histogram negative + stochastic K crosses below D from overbought
elif histogram < 0 and k_cross_down and k > 50 and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_k = k
self._prev_d = d
def CreateClone(self):
return macd_stochastic_trailing_strategy()