Holen Sie sich die trendige Stochastic-Strategie
Die Strategie ist eine StockSharp High-Level-Portierung des MetaTrader 4 Expert Advisors Get trend.mq4. Es wertet das M15-Diagramm aus
Einträge, validiert den breiteren Trend im ersten Halbjahr und stützt sich auf zwei geglättete gleitende Durchschnitte zusammen mit einem Paar stochastischer Werte
Oszillatoren zur Erkennung von Mean-Reversion-Ausbrüchen in der Nähe des längerfristigen Trends. Die Implementierung behält die ursprüngliche Geldverwaltung bei
Regeln, die auf festen Take-Profit-, Stop-Loss- und Trailing-Stop-Abständen basieren, ausgedrückt in Preispunkten.
Handelslogik
- Indikatoren und Daten
- M15-Kerzen speisen einen geglätteten gleitenden Durchschnitt (SMMA, Medianpreis) mit der Periode
M15MaPeriod und zwei stochastischen Oszillatoren.
- H1-Kerzen versorgen einen weiteren SMMA (Medianpreis) mit der Periode
H1MaPeriod.
- Die schnelle Stochastik (
FastStochasticPeriod, 3, 3) liefert die %K-Linie und ihren vorherigen Wert. Die langsame Stochastik (SlowStochasticPeriod, 3, 3) liefert die %D-Signalleitung.
- Lange Einrichtung
- Der aktuelle M15-Schlusskurs liegt unter seinem SMMA und der H1-Schlusskurs liegt unter seinem eigenen SMMA.
- Der Abstand zwischen dem M15 SMMA und dem Schlusskurs liegt innerhalb von
ThresholdPoints Preisschritten.
- Beide stochastischen Linien liegen unter 20. Die schnelle Linie kreuzt während der letzten Kerze die langsame Linie (
fast > slow, während der vorherige schnelle Wert unter slow lag).
- Wenn eine Short-Position besteht, kauft die Strategie zunächst genug Volumen, um diese zu glätten, und eröffnet dann eine neue Long-Position mit
TradeVolume.
- Kurzer Aufbau spiegelt die lange Logik wider:
- Beide Schlusskurse liegen über ihren SMMAs, der Abstand liegt innerhalb von
ThresholdPoints, die stochastischen Werte liegen über 80 und der schnelle
Linie kreuzt unterhalb der langsamen Linie. Die Strategie verkauft und schließt bei Bedarf eine bestehende Long-Position.
- Risikomanagement
- Nach jeder Eingabe werden Schutzaufträge zu
StopLossPoints und TakeProfitPoints (umgerechnet in einen absoluten Preis) platziert
Entfernungen anhand der Preisstufe des Instruments).
- Ein Trailing Stop richtet die Stop-Loss-Order neu aus, sobald der Trade mindestens
TrailingStopPoints Punkte erreicht. Die neue Haltestelle ist
positioniert am aktuellen Schlusskurs minus/plus der Nachlaufdistanz für Longs/Shorts.
- Wenn die Position wieder flach ist, werden alle Schutzaufträge storniert.
Unterschiede zum Original EA
- Der SMMA von MetaTrader verwendet eine Indikatorverschiebung von acht Balken; StockSharp-Indikatoren machen keine direkte Verschiebungseinstellung verfügbar. Der Hafen
wertet stattdessen den aktuellsten Endwert aus. Dadurch wird das Crossover-Timing beibehalten und gleichzeitig zusätzliche benutzerdefinierte Puffer vermieden.
- Der ursprüngliche EA verwendete die Bid/Ask-Kurse von MQL für den Schluss. Der Port verwendet den abgeschlossenen Kerzenschluss, der das Trailing ausgelöst hat
Update, das dem nächsten verfügbaren Analogon im High-Level API entspricht.
- Die Geldverwaltung stützt sich stattdessen auf die Auftragsregistrierungshilfen von StockSharp (
BuyMarket, SellMarket, SellStop usw.).
OrderSend und OrderModify.
Parameter
| Gruppe |
Name |
Beschreibung |
Standard |
| Daten |
M15 Candle Type |
Kerzentyp/Zeitrahmen, der für die Hauptberechnungen verwendet wird. |
Zeitrahmen M15 |
| Daten |
H1 Candle Type |
Kerzentyp/Zeitrahmen, der zur Bestätigung verwendet wird. |
H1-Zeitrahmen |
| Indikatoren |
M15 SMMA Period |
Länge des geglätteten gleitenden Durchschnitts der M15-Serie. |
200 |
| Indikatoren |
H1 SMMA Period |
Länge des geglätteten gleitenden Durchschnitts der H1-Serie. |
200 |
| Indikatoren |
Slow Stochastic Period |
%K-Länge für den langsamen stochastischen Oszillator, der die %D-Linie bereitstellt. |
14 |
| Indikatoren |
Fast Stochastic Period |
%K-Länge für den schnellen stochastischen Oszillator, der die %K-Hauptleitung bereitstellt. |
14 |
| Signale |
Threshold (points) |
Maximaler Abstand zwischen dem M15 SMMA und dem aktuellen Nahbereich, um Eingaben zu ermöglichen. |
50 |
| Risiko |
Take Profit (points) |
Take-Profit-Distanz, ausgedrückt in Preisschritten. |
570 |
| Risiko |
Stop Loss (points) |
Stop-Loss-Distanz ausgedrückt in Preisschritten. |
30 |
| Risiko |
Trailing Stop (points) |
Trailing-Stop-Distanz, ausgedrückt in Preisschritten. |
200 |
| Handel |
Trade Volume |
Mit jeder Marktorder gesendetes Volumen. |
0,1 |
Hinweise zur Nutzung
- Stellen Sie sicher, dass das gehandelte Wertpapier
PriceStep offenlegt; Andernfalls fallen die punktbasierten Abstände auf 1 zurück, was zu großen Entfernungen führen kann
Schutzanordnungen für Instrumente, die in Bruchteilen notiert sind.
- Die Strategie storniert Stop-Orders und erstellt sie neu, sobald ein besseres Trailing-Level erkannt wird. Makler, die häufiges verbieten
Änderungen erfordern möglicherweise eine Drosselung.
- Da der Port nur mit fertigen Kerzen arbeitet, ist das System für Backtests und die Ausführung am Ende des Balkens konzipiert. Läuft weiter
Live-Tick-Daten erfordern den Abgleich der Kerzenaufbaueinstellungen zwischen dem Terminal und StockSharp.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class GetTrendStochasticStrategy : Strategy
{
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<decimal> _oversold;
private readonly StrategyParam<decimal> _overbought;
private readonly StrategyParam<int> _cooldownCandles;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevRsi;
private bool _hasPrev;
private int _cooldownRemaining;
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public decimal Oversold { get => _oversold.Value; set => _oversold.Value = value; }
public decimal Overbought { get => _overbought.Value; set => _overbought.Value = value; }
public int CooldownCandles { get => _cooldownCandles.Value; set => _cooldownCandles.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public GetTrendStochasticStrategy()
{
_rsiPeriod = Param(nameof(RsiPeriod), 14).SetDisplay("RSI Period", "RSI lookback", "Indicators");
_emaPeriod = Param(nameof(EmaPeriod), 20).SetDisplay("EMA Period", "EMA filter", "Indicators");
_oversold = Param(nameof(Oversold), 35m).SetDisplay("Oversold", "RSI oversold level", "Levels");
_overbought = Param(nameof(Overbought), 65m).SetDisplay("Overbought", "RSI overbought level", "Levels");
_cooldownCandles = Param(nameof(CooldownCandles), 30).SetDisplay("Cooldown", "Candles between signals", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevRsi = default;
_hasPrev = default;
_cooldownRemaining = default;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevRsi = 0;
_hasPrev = false;
_cooldownRemaining = 0;
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(rsi, ema, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal rsi, decimal ema)
{
if (candle.State != CandleStates.Finished) return;
var close = candle.ClosePrice;
if (!_hasPrev) { _prevRsi = rsi; _hasPrev = true; return; }
if (_cooldownRemaining > 0)
{
_cooldownRemaining--;
_prevRsi = rsi;
return;
}
if (_prevRsi <= Oversold && rsi > Oversold && close > ema && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
_cooldownRemaining = CooldownCandles;
}
else if (_prevRsi >= Overbought && rsi < Overbought && close < ema && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
_cooldownRemaining = CooldownCandles;
}
_prevRsi = rsi;
}
}
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 RelativeStrengthIndex, ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class get_trend_stochastic_strategy(Strategy):
def __init__(self):
super(get_trend_stochastic_strategy, self).__init__()
self._rsi_period = self.Param("RsiPeriod", 14).SetDisplay("RSI Period", "RSI lookback", "Indicators")
self._ema_period = self.Param("EmaPeriod", 20).SetDisplay("EMA Period", "EMA filter", "Indicators")
self._oversold = self.Param("Oversold", 35.0).SetDisplay("Oversold", "RSI oversold level", "Levels")
self._overbought = self.Param("Overbought", 65.0).SetDisplay("Overbought", "RSI overbought level", "Levels")
self._cooldown_candles = self.Param("CooldownCandles", 30).SetDisplay("Cooldown", "Candles between signals", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_rsi = 0.0
self._has_prev = False
self._cooldown_remaining = 0
@property
def rsi_period(self): return self._rsi_period.Value
@property
def ema_period(self): return self._ema_period.Value
@property
def oversold(self): return self._oversold.Value
@property
def overbought(self): return self._overbought.Value
@property
def cooldown_candles(self): return self._cooldown_candles.Value
@property
def candle_type(self): return self._candle_type.Value
def OnReseted(self):
super(get_trend_stochastic_strategy, self).OnReseted()
self._prev_rsi = 0.0
self._has_prev = False
self._cooldown_remaining = 0
def OnStarted2(self, time):
super(get_trend_stochastic_strategy, self).OnStarted2(time)
self._prev_rsi = 0.0
self._has_prev = False
self._cooldown_remaining = 0
rsi = RelativeStrengthIndex()
rsi.Length = self.rsi_period
ema = ExponentialMovingAverage()
ema.Length = self.ema_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(rsi, ema, self.process_candle).Start()
def process_candle(self, candle, rsi, ema):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
rsi_val = float(rsi)
ema_val = float(ema)
if not self._has_prev:
self._prev_rsi = rsi_val
self._has_prev = True
return
if self._cooldown_remaining > 0:
self._cooldown_remaining -= 1
self._prev_rsi = rsi_val
return
oversold = float(self.oversold)
overbought = float(self.overbought)
if self._prev_rsi <= oversold and rsi_val > oversold and close > ema_val and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
self._cooldown_remaining = self.cooldown_candles
elif self._prev_rsi >= overbought and rsi_val < overbought and close < ema_val and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._cooldown_remaining = self.cooldown_candles
self._prev_rsi = rsi_val
def CreateClone(self):
return get_trend_stochastic_strategy()