Die ROC-Strategie ist ein StockSharp-Port des MetaTrader-Expertenberaters, der in MQL/26938/ROC.mq4 gespeichert ist. Es arbeitet mit einem einzelnen Symbol und bewertet die Preisbewegung mithilfe einer Kette linearer gewichteter gleitender Durchschnitte (LWMA), eines benutzerdefinierten Änderungsratenmodells (ROC), eines höheren Zeitrahmenmomentums und eines monatlichen MACD-Filters. Die ursprünglichen Geldmanagementfunktionen wie Break-Even, Pip-basierte Trailing-Stops, Aktienschutz und auf Geld lautende Gewinnziele bleiben erhalten.
Eingabelogik
Die Strategie abonniert drei Datenströme:
Primäre Handelskerzen, die durch die Eigenschaft CandleType definiert werden.
Ein höherer Zeitrahmen für den 14-Perioden-Momentum-Oszillator (wird automatisch entsprechend dem Handelszeitrahmen ausgewählt).
Monatliche Kerzen für den Bestätigungsfilter MACD.
Bei jeder abgeschlossenen Handelskerze müssen die folgenden Bedingungen erfüllt sein, um eine Position zu eröffnen:
Das benutzerdefinierte ROC-Modell muss einen Aufwärtstrend (Line4 < Line5) für Käufe oder einen Abwärtstrend (Line4 > Line5) für Verkäufe melden.
Der anhand des typischen Preises berechnete schnelle LWMA muss bei Käufen über dem langsamen LWMA und bei Verkäufen darunter liegen.
Jeder der letzten drei Momentum-Messwerte aus dem höheren Zeitrahmen muss den konfigurierten Kauf- oder Verkaufsschwellenwert überschreiten (absolute Abweichung von 100).
Die monatliche MACD-Hauptlinie muss für Käufe über ihrer Signallinie und für Verkäufe darunter bleiben.
Die Positionsgröße respektiert das MaxTrades-Limit und skaliert optional das nächste Handelsvolumen nach aufeinanderfolgenden Verlusten, wenn IncreaseFactor größer als Null ist.
Exit-Logik
Klassische Stop-Loss- und Take-Profit-Orders werden in MetaTrader Punkten projiziert, sobald sich die Positionsgröße ändert.
Der optionale Break-Even-Block verschiebt den Schutzstopp auf den Einstiegspreis zuzüglich des konfigurierten Offsets, sobald die Triggerdistanz in Punkten erreicht ist.
Pip-basierte Trailing-Stops erhöhen den Stop-Wert bei jedem Kerzenschluss.
Money-Management-Prüfungen schließen die Position, wenn ein Währungsziel oder ein Prozentziel erreicht ist, und können schwankende Gewinne verfolgen, indem sie Pullbacks erkennen, die größer als StopLossMoney sind, nachdem der Gewinn TakeProfitMoney übersteigt.
Ein Aktienstopp vergleicht den gleitenden Drawdown mit dem höchsten aufgezeichneten Eigenkapital und liquidiert die Position, wenn der zulässige Prozentsatz überschritten wird.
Wenn Sie ExitStrategy auf true setzen, wird die Notausgangsroutine ausgeführt und die aktuelle Position zum Markt geschlossen.
Parameter
Name
Beschreibung
LotSize
Das bei jedem Signal eröffnete Basishandelsvolumen.
IncreaseFactor
Berechnet das nächste Volumen nach aufeinanderfolgenden Verlustgeschäften neu.
Erzwingt bei Aktivierung eine sofortige flache Position.
Notizen
Der höhere Zeitrahmen für den Momentum-Indikator wird automatisch aus dem Handelszeitrahmen abgeleitet, um mit der ursprünglichen Switch-Anweisung im MetaTrader-Code übereinzustimmen.
Alle Indikatorberechnungen verwenden die hohe Ebene Bind API, daher sind keine manuellen Datenanfragen erforderlich.
Bei der Strategie handelt es sich nur um eine Netting-Strategie: Wenn beim Halten von Short-Positionen ein neues Long-Signal auftritt, wird das Short-Engagement zuerst geschlossen, bevor Long-Positionen eingegangen werden. Dies spiegelt das Verhalten des ursprünglichen EA auf Nicht-Hedging-Konten wider.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Rate of Change strategy: uses ROC indicator with WMA trend filter.
/// Buys when ROC crosses above zero and fast WMA > slow WMA.
/// Sells when ROC crosses below zero and fast WMA less than slow WMA.
/// </summary>
public class RocStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _rocPeriod;
private readonly StrategyParam<int> _fastMaPeriod;
private readonly StrategyParam<int> _slowMaPeriod;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int RocPeriod
{
get => _rocPeriod.Value;
set => _rocPeriod.Value = value;
}
public int FastMaPeriod
{
get => _fastMaPeriod.Value;
set => _fastMaPeriod.Value = value;
}
public int SlowMaPeriod
{
get => _slowMaPeriod.Value;
set => _slowMaPeriod.Value = value;
}
public RocStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_rocPeriod = Param(nameof(RocPeriod), 12)
.SetGreaterThanZero()
.SetDisplay("ROC Period", "Rate of Change period", "Indicators");
_fastMaPeriod = Param(nameof(FastMaPeriod), 5)
.SetGreaterThanZero()
.SetDisplay("Fast WMA", "Fast WMA period", "Indicators");
_slowMaPeriod = Param(nameof(SlowMaPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("Slow WMA", "Slow WMA period", "Indicators");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var roc = new RateOfChange { Length = RocPeriod };
var fastMa = new WeightedMovingAverage { Length = FastMaPeriod };
var slowMa = new WeightedMovingAverage { Length = SlowMaPeriod };
decimal? prevRoc = null;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(roc, fastMa, slowMa, (candle, rocVal, fastMaVal, slowMaVal) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (prevRoc.HasValue)
{
if (prevRoc.Value <= 0 && rocVal > 0 && fastMaVal > slowMaVal && Position <= 0)
BuyMarket();
else if (prevRoc.Value >= 0 && rocVal < 0 && fastMaVal < slowMaVal && Position >= 0)
SellMarket();
}
prevRoc = rocVal;
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, fastMa);
DrawIndicator(area, slowMa);
DrawOwnTrades(area);
}
}
}
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 RateOfChange, WeightedMovingAverage
from StockSharp.Algo.Strategies import Strategy
class roc_strategy(Strategy):
def __init__(self):
super(roc_strategy, self).__init__()
self._roc_period = self.Param("RocPeriod", 12) \
.SetDisplay("ROC Period", "Rate of Change period", "Indicators")
self._fast_ma_period = self.Param("FastMaPeriod", 5) \
.SetDisplay("Fast WMA", "Fast WMA period", "Indicators")
self._slow_ma_period = self.Param("SlowMaPeriod", 20) \
.SetDisplay("Slow WMA", "Slow WMA period", "Indicators")
self._roc = None
self._fast_ma = None
self._slow_ma = None
self._prev_roc = None
@property
def roc_period(self):
return self._roc_period.Value
@property
def fast_ma_period(self):
return self._fast_ma_period.Value
@property
def slow_ma_period(self):
return self._slow_ma_period.Value
def OnReseted(self):
super(roc_strategy, self).OnReseted()
self._roc = None
self._fast_ma = None
self._slow_ma = None
self._prev_roc = None
def OnStarted2(self, time):
super(roc_strategy, self).OnStarted2(time)
self._roc = RateOfChange()
self._roc.Length = self.roc_period
self._fast_ma = WeightedMovingAverage()
self._fast_ma.Length = self.fast_ma_period
self._slow_ma = WeightedMovingAverage()
self._slow_ma.Length = self.slow_ma_period
subscription = self.SubscribeCandles(DataType.TimeFrame(TimeSpan.FromMinutes(30)))
subscription.Bind(self._roc, self._fast_ma, self._slow_ma, self._process_candle)
subscription.Start()
def _process_candle(self, candle, roc_value, fast_ma_value, slow_ma_value):
if candle.State != CandleStates.Finished:
return
if not self._roc.IsFormed or not self._fast_ma.IsFormed or not self._slow_ma.IsFormed:
return
roc_val = float(roc_value)
fast_val = float(fast_ma_value)
slow_val = float(slow_ma_value)
if self._prev_roc is not None:
if self._prev_roc <= 0.0 and roc_val > 0.0 and fast_val > slow_val and self.Position <= 0:
self.BuyMarket()
elif self._prev_roc >= 0.0 and roc_val < 0.0 and fast_val < slow_val and self.Position >= 0:
self.SellMarket()
self._prev_roc = roc_val
def CreateClone(self):
return roc_strategy()