Die Tokyo Session Strategy repliziert die Logik des MetaTrader-Expertenberaters TokyoSessionEA_v2.8 in StockSharp. Die
Die Strategie ist für den Intraday-Breakout- oder Mean-Reversion-Handel rund um die asiatische (Tokio) Sitzung konzipiert. Es fängt ein
Referenzkerze zu einer konfigurierbaren Stunde, baut aus dieser Kerze einen Preiskanal auf und bewertet Ausbruch oder Erholung
Bedingungen zu einer anderen Zielstunde. Abhängig vom gewählten Signalmodus kann die Strategie entweder gegensätzlich handeln
Level-Ausbruch (Fade-Bewegungen, die über den Referenzbereich hinausgehen) oder entlang der Ausbruchsrichtung.
Der StockSharp-Port konzentriert sich auf die Verwendung von API auf hoher Ebene. Alle Signalberechnungen werden innerhalb des Kerzenabonnements durchgeführt
Handler, Stopps werden über StartProtection verwaltet und jede Aktion wird über LogInfo protokolliert, um das Verhalten beizubehalten
transparent bei Backtests und Live-Handel.
Handelslogik
Referenzkerze – um TimeSetLevels (Brokerstunde) zeichnet die Strategie den Höchst-, Tief- und Schlusskurs der Kerze auf. Diese
Werte definieren den Sitzungskanal und setzen die internen Validierungsflags zurück.
Kanalvalidierung – jede fertige Kerze zwischen der Referenzstunde und der Eintrittsstunde kann die ungültig machen
anstehendes Signal je nach Konfiguration:
CheckAllBars: Wenn aktiviert, muss der Schlusskurs zwischen dem erfassten Hoch und Tief liegen.
ReCheckPrices: Bei TimeRecheckPrices wird der Schlusskurs der Kerze mit dem laufenden Durchschnitt verglichen, um die Dynamik zu bestätigen.
Einstiegsbewertung – Wenn die Kerze vor TimeCheckLevels schließt, vergleicht die Strategie ihren Schlusskurs
mit den Kanalgrenzen. Liegt der Schluss innerhalb des konfigurierten Distanzbereichs, wird die entsprechende Position geöffnet.
Exits – Positionen können durch drei Mechanismen geschlossen werden:
CloseInSignal schließt einen Handel, sobald der Preis innerhalb des Kanals zurückkehrt (die Logik spiegelt die ursprüngliche EA wider).
CloseOrdersOnTime flacht bei TimeCloseOrders ab, um zu vermeiden, dass das Risiko in der nächsten Sitzung bestehen bleibt.
Schutzstopps, Trailing Stops und Break-Even-Handhabung werden an das StockSharp-Schutzsubsystem delegiert.
Parameter
Allgemein
Parameter
Beschreibung
CandleType
Für die Analyse verwendete Kerzenserie (standardmäßig H1).
BrokerOffset
Differenz zwischen Brokerzeit und GMT in Stunden.
Signale
Parameter
Beschreibung
TypeOfSignals
ContraryTrend repliziert das Verblassen des Ausbruchs; AccordingTrend folgt der Ausbruchsrichtung.
TimeSetLevels
Stunde (0–23), in der die Referenzkerze erfasst wird.
TimeCheckLevels
Stunde, in der die Ausbruchsbedingungen bewertet werden.
TimeRecheckPrices
Zusätzliche Momentum-Check-Stunde.
MinDistanceOfLevel
Mindestabstand (in Pips) zwischen dem Schlusskurs und dem Kanal, bevor ein Handel zugelassen wird.
MaxDistanceOfLevel
Maximaler Abstand (in Pips) vom Level. Null deaktiviert das Limit.
ReCheckPrices
Aktiviert/deaktiviert den zusätzlichen Impulsfilter.
CheckAllBars
Erfordert, dass alle Zwischenschlüsse innerhalb des Kanals bleiben.
Risikomanagement
Parameter
Beschreibung
CloseInSignal
Verlassen Sie den Kurs, sobald der Preis wieder die Kanalgrenze überschreitet.
CloseOrdersOnTime
Reduzieren Sie die Positionen nach TimeCloseOrders.
TimeCloseOrders
Stunde, die vom zeitbasierten Exit verwendet wird.
UseTakeProfit, TakeProfit
Aktivieren und konfigurieren Sie einen festen Take-Profit (Pips).
UseStopLoss, StopLoss
Aktivieren und konfigurieren Sie einen schützenden Stop-Loss (Pips).
UseTrailingStop, TrailingStop, TrailingStep
Aktivieren Sie die Trailing-Stop-Verwaltung (Pips) von StockSharp.
UseBreakEven, BreakEven, BreakEvenAfter
Bewegen Sie den Stop-Loss auf die Gewinnschwelle, sobald der Gewinn die Auslösedistanz erreicht.
Handel
Parameter
Beschreibung
Volume
Grundauftragsvolumen. Bei Richtungsumkehr wird automatisch die Gegenposition geschlossen.
MaxOrders
Maximal zulässige Anzahl von Volume Blöcken in eine Richtung. Auf 0 setzen, um keine Begrenzung zu erhalten.
Arbeitsablauf
Setzen Sie die Strategie auf einem Instrument mit einem gültigen Preisschritt (Security.PriceStep) ein.
Wählen Sie den gewünschten Zeitrahmen aus und konfigurieren Sie die Stundenversätze des Brokers, um den Tagesplan an die Börse anzupassen.
Passen Sie die Distanz- und Validierungsfilter an, um sie an das Verhalten des ursprünglichen EA anzupassen oder um sie an verschiedene Märkte anzupassen.
Risikoparameter konfigurieren. Der StockSharp-Port verwaltet Stopps und Trailing-Logik nativ über StartProtection.
Starten Sie die Strategie. Protokollierungsnachrichten melden die erfassten Level, eröffneten Trades und Ausstiegsentscheidungen.
Unterschiede zur MetaTrader-Version
Gleitkommaeinträge basierend auf UseFloatingPoint und PipsFloatingPoint werden nicht implementiert, da StockSharp
führt Marktaufträge zum Zeitpunkt der Signalgenerierung aus.
Spread- und Slippage-Filter werden weggelassen, da High-Level-Candle-Abonnements keine Bid/Ask-Daten auf Tick-Ebene liefern.
Die automatische Geldverwaltung (AutoLotSize, RiskFactor, Rückgewinnungslose, voreingestellte Symbolumschaltung) wird durch die ersetzt
einfachere Parameter Volume und MaxOrders. Die Positionsgröße sollte direkt in den Strategieeinstellungen angepasst werden.
Ton- und Druckbenachrichtigungen werden durch LogInfo Nachrichten ersetzt.
Alle anderen Signalbedingungen, Validierungs-Gates und zeitbasierten Exits spiegeln das Verhalten des ursprünglichen EA wider.
Notizen
Die Standardkonfiguration ist auf den vom ursprünglichen Fachberater empfohlenen H1-Zeitrahmen abgestimmt. Andere Zeitrahmen
kann verwendet werden, aber die stundenbasierte Logik geht davon aus, dass die Kerzendauer eine Stunde gleichmäßig aufteilt.
Stellen Sie sicher, dass der Datenfeed kontinuierlich Kerzen für den ausgewählten Zeitraum liefert. Fehlende Kerzen können die ungültig machen
Durchschnitts- und Kanalprüfungen.
Da die Strategie Positionen durch das Senden von Marktaufträgen schließt, benötigen Broker Limitaufträge oder einen Mindestbestand
Die Zeiten können zusätzliche Anpassungen erfordern.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Tokyo Session strategy: breakout from session range.
/// Tracks high/low during first hours, then buys breakout above high, sells below low.
/// </summary>
public class TokyoSessionStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _atrPeriod;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int AtrPeriod
{
get => _atrPeriod.Value;
set => _atrPeriod.Value = value;
}
public TokyoSessionStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_atrPeriod = Param(nameof(AtrPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("ATR Period", "ATR period for volatility filter", "Indicators");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var atr = new AverageTrueRange { Length = AtrPeriod };
var sessionHigh = decimal.MinValue;
var sessionLow = decimal.MaxValue;
var candleCount = 0;
var rangeSet = false;
decimal? prevClose = null;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(atr, (candle, atrVal) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
candleCount++;
// Build range from first 4 candles (2 hours of 30min candles)
if (candleCount <= 4)
{
if (candle.HighPrice > sessionHigh)
sessionHigh = candle.HighPrice;
if (candle.LowPrice < sessionLow)
sessionLow = candle.LowPrice;
if (candleCount == 4)
rangeSet = true;
prevClose = candle.ClosePrice;
return;
}
if (!rangeSet)
{
prevClose = candle.ClosePrice;
return;
}
// Reset range every 48 candles (24 hours of 30min candles)
if (candleCount % 48 == 0)
{
sessionHigh = candle.HighPrice;
sessionLow = candle.LowPrice;
rangeSet = false;
candleCount = 0;
prevClose = candle.ClosePrice;
return;
}
var close = candle.ClosePrice;
if (prevClose.HasValue)
{
var crossAboveHigh = prevClose.Value <= sessionHigh && close > sessionHigh;
var crossBelowLow = prevClose.Value >= sessionLow && close < sessionLow;
if (crossAboveHigh && Position <= 0)
BuyMarket();
else if (crossBelowLow && Position >= 0)
SellMarket();
}
prevClose = close;
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
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 AverageTrueRange
from StockSharp.Algo.Strategies import Strategy
class tokyo_session_strategy(Strategy):
def __init__(self):
super(tokyo_session_strategy, self).__init__()
self._atr_period = self.Param("AtrPeriod", 14) \
.SetDisplay("ATR Period", "ATR period for volatility filter", "Indicators")
self._atr = None
self._session_high = None
self._session_low = None
self._candle_count = 0
self._range_set = False
self._prev_close = None
@property
def atr_period(self):
return self._atr_period.Value
def OnReseted(self):
super(tokyo_session_strategy, self).OnReseted()
self._atr = None
self._session_high = None
self._session_low = None
self._candle_count = 0
self._range_set = False
self._prev_close = None
def OnStarted2(self, time):
super(tokyo_session_strategy, self).OnStarted2(time)
self._atr = AverageTrueRange()
self._atr.Length = self.atr_period
self._session_high = -999999999.0
self._session_low = 999999999.0
self._candle_count = 0
self._range_set = False
subscription = self.SubscribeCandles(DataType.TimeFrame(TimeSpan.FromMinutes(30)))
subscription.Bind(self._atr, self._process_candle)
subscription.Start()
def _process_candle(self, candle, atr_value):
if candle.State != CandleStates.Finished:
return
if not self._atr.IsFormed:
return
self._candle_count += 1
high = float(candle.HighPrice)
low = float(candle.LowPrice)
close = float(candle.ClosePrice)
if self._candle_count <= 4:
if high > self._session_high:
self._session_high = high
if low < self._session_low:
self._session_low = low
if self._candle_count == 4:
self._range_set = True
self._prev_close = close
return
if not self._range_set:
self._prev_close = close
return
if self._candle_count % 48 == 0:
self._session_high = high
self._session_low = low
self._range_set = False
self._candle_count = 0
self._prev_close = close
return
if self._prev_close is not None:
cross_above = self._prev_close <= self._session_high and close > self._session_high
cross_below = self._prev_close >= self._session_low and close < self._session_low
if cross_above and self.Position <= 0:
self.BuyMarket()
elif cross_below and self.Position >= 0:
self.SellMarket()
self._prev_close = close
def CreateClone(self):
return tokyo_session_strategy()