Die Session Breakout-Strategie repliziert den Expertenberater „Session Breakout“ von MetaTrader. Es beobachtet die europäische Morgensitzung
auf und misst seine Preisspanne. Wenn diese Spanne ausreichend eng ist, bereitet sich die Strategie auf den Handel mit Ausbrüchen während des US-Zeitraums vor.
Nachmittagssitzung mit StockSharps High-Level-API. Die Implementierung erzwingt höchstens einen Long- und einen Short-Eintrag pro Tag a
Und fügt jeder Position automatisch Schutzaufträge (Stop-Loss und Take-Profit) hinzu.
Handelslogik
Setzen Sie den Status zu Beginn jedes Handelstages zurück und überspringen Sie Wochenenden. Montags sind optional und werden durch einen Parameter gesteuert.
Verfolgen Sie fertige Kerzen während der europäischen Sitzung (Standard 06:00–12:00 Uhr) und zeichnen Sie das höchste Hoch und das niedrigste Tief auf.
Zu Beginn der US-Sitzung wird der erfasste Bereich als „klein“ klassifiziert, wenn seine Breite kleiner als „SmallSessionThreshol“ ist
dPips`.
Wenn die Spanne klein ist, beobachten Sie die US-Sitzungskerzen (Standard 12:00–16:00) und warten Sie, bis mindestens ein US-Balken geschlossen hat („Eu
RopeSessionStartHour + 5toEuropeSessionStartHour + 10`).
Ein langer Ausbruch wird ausgelöst, wenn die gesamte Kerze über dem europäischen Hoch zuzüglich eines konfigurierbaren Puffers („BreakoutBuffer“) bleibt
Pips`). Für einen kurzen Ausbruch muss die Kerze unter dem europäischen Tief abzüglich des Puffers bleiben.
Nach dem Eingehen einer Position fügt die Strategie Stop-Loss- und Take-Profit-Levels hinzu, die in Pips ausgedrückt werden, und verhindert ein zusätzliches En
versucht den Rest des Tages in die gleiche Richtung.
Parameter
Parameter
Beschreibung
Volume
Das Ordervolumen wird sowohl für Long- als auch für Short-Breakouts verwendet.
EuropeSessionStartHour
Stunde, in der die europäische Reichweitenverfolgung beginnt.
EuropeSessionEndHour
Stunde, in der die europäische Reichweitenverfolgung stoppt.
UsSessionStartHour
Stunde, die den Beginn des US-Sitzungsfensters markiert.
UsSessionEndHour
Stunde, die das Ende des US-Sitzungsfensters markiert.
SmallSessionThresholdPips
Maximale Breite (in Pips), damit der europäische Bereich als Squeeze gilt.
BreakoutBufferPips
Zusätzlicher Puffer oberhalb/unterhalb der Spanne hinzugefügt, bevor Ausbrüche ausgelöst werden.
TradeOnMonday
Ermöglicht den Handel montags. Wochenenden werden immer ausgelassen.
TakeProfitPips
Abstand zwischen Einstiegspreis und Take-Profit-Niveau.
StopLossPips
Abstand zwischen dem Einstiegspreis und dem Stop-Loss-Level.
CandleType
Für alle Berechnungen verwendete Kerzenserie (standardmäßig 15-Minuten-Kerzen).
Notizen
Die Pip-Größe wird vom Instrument PriceStep abgeleitet. Passen Sie die Pip-basierten Parameter an die Vertragsspezifikation an
s des ausgewählten Wertpapiers.
Da Aufträge generiert werden, wenn eine qualifizierte Kerze schließt, erfolgt die Ausführung bei Backtests zum Schlusskurs dieser Kerze. Liv
Die Füllungen können je nach Marktbedingungen variieren.
Pro Tag kann nur ein Long- und ein Short-Trade eröffnet werden. Die Logik spiegelt das ursprüngliche Verhalten des Expert Advisors bei der Verwendung von S wider
tockSharps positionsbasierte Risikomanagement-Helfer.
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>
/// Session breakout strategy that tracks a range during first hours and trades breakouts later.
/// Accumulates high/low during range hours (0-8), then trades breakouts during active hours (8-20).
/// </summary>
public class SessionBreakoutStrategy : Strategy
{
private readonly StrategyParam<int> _rangeStartHour;
private readonly StrategyParam<int> _rangeEndHour;
private readonly StrategyParam<int> _tradeEndHour;
private readonly StrategyParam<DataType> _candleType;
private DateTime _currentDate;
private decimal? _rangeHigh;
private decimal? _rangeLow;
private bool _rangeComplete;
private bool _tradedToday;
public int RangeStartHour { get => _rangeStartHour.Value; set => _rangeStartHour.Value = value; }
public int RangeEndHour { get => _rangeEndHour.Value; set => _rangeEndHour.Value = value; }
public int TradeEndHour { get => _tradeEndHour.Value; set => _tradeEndHour.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public SessionBreakoutStrategy()
{
_rangeStartHour = Param(nameof(RangeStartHour), 0)
.SetDisplay("Range Start", "Hour to start tracking range", "Sessions");
_rangeEndHour = Param(nameof(RangeEndHour), 8)
.SetDisplay("Range End", "Hour to stop tracking range", "Sessions");
_tradeEndHour = Param(nameof(TradeEndHour), 20)
.SetDisplay("Trade End", "Hour to stop trading", "Sessions");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).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();
_currentDate = default;
_rangeHigh = null;
_rangeLow = null;
_rangeComplete = false;
_tradedToday = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_currentDate = default;
_rangeHigh = null;
_rangeLow = null;
_rangeComplete = false;
_tradedToday = false;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
var candleDate = candle.OpenTime.Date;
var hour = candle.OpenTime.Hour;
// Reset on new day
if (candleDate != _currentDate)
{
_currentDate = candleDate;
_rangeHigh = null;
_rangeLow = null;
_rangeComplete = false;
_tradedToday = false;
}
// Build range during accumulation hours
if (hour >= RangeStartHour && hour < RangeEndHour)
{
if (_rangeHigh == null || candle.HighPrice > _rangeHigh)
_rangeHigh = candle.HighPrice;
if (_rangeLow == null || candle.LowPrice < _rangeLow)
_rangeLow = candle.LowPrice;
return;
}
// Mark range as complete
if (!_rangeComplete && hour >= RangeEndHour && _rangeHigh != null && _rangeLow != null)
_rangeComplete = true;
if (!_rangeComplete || _rangeHigh == null || _rangeLow == null)
return;
// Trade during active hours
if (hour >= RangeEndHour && hour < TradeEndHour)
{
// Breakout above range high - buy
if (Position <= 0 && candle.ClosePrice > _rangeHigh.Value && !_tradedToday)
{
if (Position < 0)
BuyMarket();
BuyMarket();
_tradedToday = true;
}
// Breakout below range low - sell
else if (Position >= 0 && candle.ClosePrice < _rangeLow.Value && !_tradedToday)
{
if (Position > 0)
SellMarket();
SellMarket();
_tradedToday = true;
}
}
// Close at end of day
if (hour >= TradeEndHour && Position != 0)
{
if (Position > 0)
SellMarket();
else
BuyMarket();
}
}
}
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.Strategies import Strategy
from datatype_extensions import *
from indicator_extensions import *
class session_breakout_strategy(Strategy):
def __init__(self):
super(session_breakout_strategy, self).__init__()
self._range_start = self.Param("RangeStartHour", 0).SetDisplay("Range Start", "Hour to start tracking range", "Sessions")
self._range_end = self.Param("RangeEndHour", 8).SetDisplay("Range End", "Hour to stop tracking range", "Sessions")
self._trade_end = self.Param("TradeEndHour", 20).SetDisplay("Trade End", "Hour to stop trading", "Sessions")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))).SetDisplay("Candle Type", "Candle timeframe", "General")
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, value): self._candle_type.Value = value
def OnReseted(self):
super(session_breakout_strategy, self).OnReseted()
self._current_date = None
self._range_high = None
self._range_low = None
self._range_complete = False
self._traded_today = False
def OnStarted2(self, time):
super(session_breakout_strategy, self).OnStarted2(time)
self._current_date = None
self._range_high = None
self._range_low = None
self._range_complete = False
self._traded_today = False
sub = self.SubscribeCandles(self.CandleType)
sub.Bind(self.OnProcess).Start()
def OnProcess(self, candle):
if candle.State != CandleStates.Finished:
return
candle_date = candle.OpenTime.Date
hour = candle.OpenTime.Hour
if self._current_date is None or candle_date != self._current_date:
self._current_date = candle_date
self._range_high = None
self._range_low = None
self._range_complete = False
self._traded_today = False
high = float(candle.HighPrice)
low = float(candle.LowPrice)
close = float(candle.ClosePrice)
if hour >= self._range_start.Value and hour < self._range_end.Value:
if self._range_high is None or high > self._range_high:
self._range_high = high
if self._range_low is None or low < self._range_low:
self._range_low = low
return
if not self._range_complete and hour >= self._range_end.Value and self._range_high is not None and self._range_low is not None:
self._range_complete = True
if not self._range_complete or self._range_high is None or self._range_low is None:
return
if hour >= self._range_end.Value and hour < self._trade_end.Value:
if self.Position <= 0 and close > self._range_high and not self._traded_today:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
self._traded_today = True
elif self.Position >= 0 and close < self._range_low and not self._traded_today:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._traded_today = True
if hour >= self._trade_end.Value and self.Position != 0:
if self.Position > 0:
self.SellMarket()
else:
self.BuyMarket()
def CreateClone(self):
return session_breakout_strategy()