Die TradePad-Beispielstrategie ist eine Portierung des MetaTrader „TradePad“-Beispiels. Der ursprüngliche Fachberater hat ein Raster erstellt
Schaltflächen, die den kurzfristigen Trend für mehrere Symbole anzeigten, indem sie jede Zelle mit dem aktuellen Stochastic-Oszillator einfärbten
Lesen. Diese StockSharp-Implementierung behält den analytischen Kern der Stichprobe bei und konzentriert sich auf die Überwachung einer Liste von Instrumenten
ohne die Benutzeroberfläche auf dem Diagramm zu replizieren. Die Strategie abonniert Kerzendaten für jedes konfigurierte Symbol und berechnet a
Stochastic-Oszillator und klassifiziert jedes Instrument in die Zustände Aufwärtstrend, Abwärtstrend oder Flat. Jedes Mal, wenn die Klasse wechselt,
Die Strategie schreibt eine Protokollmeldung, die der vom ursprünglichen TradePad durchgeführten Farbänderung ähnelt.
Die Strategie erteilt keine Aufträge. Ziel ist es, diskretionären Händlern dabei zu helfen, den Überblick über mehrere Märkte gleichzeitig und vor Ort zu behalten
Momentumänderungen, die manuelle Maßnahmen erfordern (zum Beispiel das Wechseln von Charts oder das Vorbereiten von Trades).
Wie es funktioniert
Symbolerkennung – der Parameter SymbolList akzeptiert eine durch Kommas getrennte Liste von Tickern. Wenn keine Liste angegeben wird, wird die
Die Strategie greift auf die im Runner zugewiesene Hauptstrategie Security zurück.
Kerzenabonnement – jedes Symbol verwendet denselben Zeitrahmen, der über CandleType konfiguriert wurde.
Indikatorverarbeitung – eine dedizierte StochasticOscillator-Instanz ist an den Kerzenstream gebunden. Wenn die Kerze ist
Wenn der Indikator fertig ist, erzeugt er den %K-Wert, der für die Trendklassifizierung verwendet wird.
Trendklassifizierung – ein Messwert über UpperLevel wird Aufwärtstrend zugeordnet, ein Messwert unter LowerLevel wird Abwärtstrend zugeordnet,
alles dazwischen ist Flach. Der letzte Oszillatorwert wird in LatestKValues gespeichert.
Aktualisierungsintervall – Die Strategie ahmt das Timer-Verhalten des ursprünglichen TradePad nach. Eine Änderung wird höchstens einmal pro Protokoll protokolliert
TimerPeriodSeconds für jedes Symbol, auch wenn innerhalb des Intervalls mehrere Kerzen eintreffen.
Parameter
Parameter
Beschreibung
SymbolList
Durch Kommas getrennte Liste der zu überwachenden Instrumente. Eine leere Zeichenfolge bedeutet „Hauptsicherheit verwenden“.
TimerPeriodSeconds
Mindestanzahl von Sekunden zwischen Statusaktualisierungen pro Symbol. Verhindert Protokoll-Spam, wenn die Kerzen sehr kurz sind.
StochasticLength
Lookback-Zeitraum, der zur Berechnung der Rohzeile %K verwendet wird.
StochasticKPeriod
Auf die Linie %K angewendeter Glättungszeitraum.
StochasticDPeriod
Auf die Zeile %D angewendeter Glättungszeitraum (wird der Vollständigkeit halber beibehalten, obwohl die Strategie nur %K lautet).
UpperLevel
Schwellenwert, oberhalb dessen davon ausgegangen wird, dass sich das Symbol in einem Aufwärtstrend befindet.
LowerLevel
Schwellenwert, unterhalb dessen davon ausgegangen wird, dass sich das Symbol in einem Abwärtstrend befindet.
CandleType
Zeitrahmen der für die Indikatorberechnung verwendeten Kerzen.
Nutzungshinweise
Stellen Sie sicher, dass die angegebenen Ticker im Connector verfügbar sind. Fehlende Symbole werden im Protokoll gemeldet und übersprungen.
Die Eigenschaft TrendStates stellt die neueste Klassifizierung für externe Dashboards oder Designer-Blöcke bereit.
Verwenden Sie die Strategie in Designer oder Runner, um Ihre eigenen visuellen Elemente (Dashboards, Diagramme) anzuhängen, die auf die AddInfoLog reagieren.
Nachrichten oder die öffentlichen Wörterbücher.
Da keine Orders gesendet werden, kann die Strategie sicher auf Live-Datenanbietern ausschließlich zu Überwachungszwecken angewendet werden.
Ursprüngliches MQL-Verhalten im Vergleich zur StockSharp-Version
MQL5 Funktion
StockSharp Implementierung
Grafisches Raster von Schaltflächen
Wird als Protokolleinträge und öffentliche Wörterbücher verfügbar gemacht, damit eine benutzerdefinierte Benutzeroberfläche in Designer erstellt werden kann.
Manuelle KAUF-/VERKAUF-Tasten
Nicht implementiert; Die Strategie bleibt bewusst passiv.
Logik zum Ziehen von Diagrammen
Nicht anwendbar in StockSharp und weggelassen.
Trendfarben-Updates
Ersetzt durch Trendzustandsänderungen, die alle TimerPeriodSeconds pro Symbol ausgelöst werden.
Erweiterung der Strategie
Verbinden Sie das TrendStates-Wörterbuch mit Designer-Widgets, um das farbige Pad mithilfe von XAML-Steuerelementen neu zu erstellen.
Fügen Sie Warnungen oder Benachrichtigungen hinzu, wenn ein Symbol von Flat zu Uptrend oder Downtrend wechselt.
Kombinieren Sie die Klassifizierung mit der Bestelllogik, wenn Sie Eingaben automatisieren möchten, nachdem Sie eine starke Dynamik festgestellt haben.
namespace StockSharp.Samples.Strategies;
using System;
using StockSharp.Algo;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// TradePad Sample strategy.
/// Classifies market state using Stochastic oscillator and trades on state transitions.
/// Buys when stochastic crosses up from oversold, sells when it crosses down from overbought.
/// </summary>
public class TradePadSampleStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _stochasticKPeriod;
private readonly StrategyParam<int> _stochasticDPeriod;
private readonly StrategyParam<decimal> _upperLevel;
private readonly StrategyParam<decimal> _lowerLevel;
private decimal _prevK;
private bool _hasPrev;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int StochasticKPeriod { get => _stochasticKPeriod.Value; set => _stochasticKPeriod.Value = value; }
public int StochasticDPeriod { get => _stochasticDPeriod.Value; set => _stochasticDPeriod.Value = value; }
public decimal UpperLevel { get => _upperLevel.Value; set => _upperLevel.Value = value; }
public decimal LowerLevel { get => _lowerLevel.Value; set => _lowerLevel.Value = value; }
public TradePadSampleStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Timeframe", "General");
_stochasticKPeriod = Param(nameof(StochasticKPeriod), 10)
.SetDisplay("Stochastic %K", "%K period", "Indicators");
_stochasticDPeriod = Param(nameof(StochasticDPeriod), 3)
.SetDisplay("Stochastic %D", "%D period", "Indicators");
_upperLevel = Param(nameof(UpperLevel), 75m)
.SetDisplay("Upper Threshold", "Overbought level", "Signals");
_lowerLevel = Param(nameof(LowerLevel), 25m)
.SetDisplay("Lower Threshold", "Oversold level", "Signals");
}
/// <inheritdoc />
public override System.Collections.Generic.IEnumerable<(StockSharp.BusinessEntities.Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevK = 0;
_hasPrev = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var stochastic = new StochasticOscillator();
stochastic.K.Length = StochasticKPeriod;
stochastic.D.Length = StochasticDPeriod;
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(stochastic, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue stochVal)
{
if (candle.State != CandleStates.Finished)
return;
if (!stochVal.IsFinal || !stochVal.IsFormed)
return;
var stoch = (StochasticOscillatorValue)stochVal;
if (stoch.K is not decimal kValue)
return;
if (!_hasPrev)
{
_prevK = kValue;
_hasPrev = true;
return;
}
// Buy: stochastic crosses up through lower level (leaving oversold)
var crossUp = _prevK <= LowerLevel && kValue > LowerLevel;
// Sell: stochastic crosses down through upper level (leaving overbought)
var crossDown = _prevK >= UpperLevel && kValue < UpperLevel;
if (crossUp && Position <= 0)
{
BuyMarket();
}
else if (crossDown && Position >= 0)
{
SellMarket();
}
_prevK = kValue;
}
}
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 StochasticOscillator
from StockSharp.Algo.Strategies import Strategy
class trade_pad_sample_strategy(Strategy):
"""Stochastic crossover strategy. Buys when %K crosses up from oversold, sells when it crosses down from overbought."""
def __init__(self):
super(trade_pad_sample_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._stochastic_k_period = self.Param("StochasticKPeriod", 10) \
.SetDisplay("Stochastic %K", "%K period", "Indicators")
self._stochastic_d_period = self.Param("StochasticDPeriod", 3) \
.SetDisplay("Stochastic %D", "%D period", "Indicators")
self._upper_level = self.Param("UpperLevel", 75.0) \
.SetDisplay("Upper Threshold", "Overbought level", "Signals")
self._lower_level = self.Param("LowerLevel", 25.0) \
.SetDisplay("Lower Threshold", "Oversold level", "Signals")
self._prev_k = 0.0
self._has_prev = False
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def StochasticKPeriod(self):
return self._stochastic_k_period.Value
@property
def StochasticDPeriod(self):
return self._stochastic_d_period.Value
@property
def UpperLevel(self):
return self._upper_level.Value
@property
def LowerLevel(self):
return self._lower_level.Value
def OnReseted(self):
super(trade_pad_sample_strategy, self).OnReseted()
self._prev_k = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(trade_pad_sample_strategy, self).OnStarted2(time)
self._has_prev = False
stochastic = StochasticOscillator()
stochastic.K.Length = self.StochasticKPeriod
stochastic.D.Length = self.StochasticDPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.BindEx(stochastic, self._process_candle).Start()
def _process_candle(self, candle, stoch_val):
if candle.State != CandleStates.Finished:
return
if not stoch_val.IsFinal or not stoch_val.IsFormed:
return
k_raw = stoch_val.K
if k_raw is None:
return
k_value = float(k_raw)
if not self._has_prev:
self._prev_k = k_value
self._has_prev = True
return
lower = float(self.LowerLevel)
upper = float(self.UpperLevel)
cross_up = self._prev_k <= lower and k_value > lower
cross_down = self._prev_k >= upper and k_value < upper
if cross_up and self.Position <= 0:
self.BuyMarket()
elif cross_down and self.Position >= 0:
self.SellMarket()
self._prev_k = k_value
def CreateClone(self):
return trade_pad_sample_strategy()