Diese Strategie versucht, Ausbrüche aus kurzfristigen Konsolidierungszonen zu handeln. Sie sucht nach kompakten Preisbereichen im 15-Minuten-Chart und eröffnet Trades, wenn der Preis diese Bereiche um eine bestimmte Distanz verlässt.
Strategielogik
Für jede abgeschlossene 15-Minuten-Kerze werden das höchste Hoch und das niedrigste Tief der letzten 40 Kerzen berechnet.
Wenn der Abstand zwischen diesen Extremen unter dem Parameter Range liegt, wird eine Konsolidierungszone angenommen.
Nach Ablauf der Delay Open-Periode ohne neue Trades löst ein Ausbruch über die obere Grenze plus Distance Punkte eine Long-Position aus, während ein Ausbruch unter die untere Grenze minus Distance Punkte eine Short-Position auslöst.
Ein fester Stop Loss und ein Trailing-Stop von Trail Punkten werden angewandt, sobald eine Position eröffnet wird.
Konsolidierungsgrenzen werden nach Ablauf der Period-Stunden zurückgesetzt.
Parameter
DelayOpen – Stunden Wartezeit vor der Eröffnung eines neuen Trades.
Distance – Ausbruchsdistanz von der Konsolidierungsgrenze in Punkten.
Period – Stunden, nach denen Konsolidierungsniveaus neu berechnet werden.
Range – Maximale Größe der Konsolidierungszone in Punkten.
StopLoss – Anfänglicher Stop-Loss in Punkten.
Trail – Trailing-Stop-Distanz in Punkten.
Hinweise
Die Strategie verwendet ausschließlich die High-Level-API: Kerzen werden über SubscribeCandles empfangen, und Indikatorwerte werden mit Bind gebunden. Orders werden mit den Methoden BuyMarket und SellMarket gesendet. Kommentare im Quellcode sind auf Englisch verfasst.
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Breakout strategy based on consolidation zones.
/// </summary>
public class MaximusVxLiteStrategy : Strategy
{
private readonly StrategyParam<int> _lookback;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevHigh;
private decimal _prevLow;
private bool _hasPrev;
public int Lookback { get => _lookback.Value; set => _lookback.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public MaximusVxLiteStrategy()
{
_lookback = Param(nameof(Lookback), 20)
.SetDisplay("Lookback", "Highest/Lowest lookback period", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Time frame for candles", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevHigh = 0;
_prevLow = 0;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var highest = new Highest { Length = Lookback };
var lowest = new Lowest { Length = Lookback };
SubscribeCandles(CandleType).Bind(highest, lowest, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal highest, decimal lowest)
{
if (candle.State != CandleStates.Finished) return;
if (!_hasPrev)
{
_prevHigh = highest;
_prevLow = lowest;
_hasPrev = true;
return;
}
var close = candle.ClosePrice;
// Breakout above previous highest
if (close > _prevHigh && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
// Breakout below previous lowest
else if (close < _prevLow && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevHigh = highest;
_prevLow = lowest;
}
}
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 Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
class maximus_vx_lite_strategy(Strategy):
def __init__(self):
super(maximus_vx_lite_strategy, self).__init__()
self._lookback = self.Param("Lookback", 20) \
.SetDisplay("Lookback", "Highest/Lowest lookback period", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Time frame for candles", "General")
self._prev_high = 0.0
self._prev_low = 0.0
self._has_prev = False
@property
def lookback(self):
return self._lookback.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(maximus_vx_lite_strategy, self).OnReseted()
self._prev_high = 0.0
self._prev_low = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(maximus_vx_lite_strategy, self).OnStarted2(time)
highest = Highest()
highest.Length = self.lookback
lowest = Lowest()
lowest.Length = self.lookback
self.SubscribeCandles(self.candle_type).Bind(highest, lowest, self.process_candle).Start()
def process_candle(self, candle, highest, lowest):
if candle.State != CandleStates.Finished:
return
hv = float(highest)
lv = float(lowest)
if not self._has_prev:
self._prev_high = hv
self._prev_low = lv
self._has_prev = True
return
close = float(candle.ClosePrice)
if close > self._prev_high and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif close < self._prev_low and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_high = hv
self._prev_low = lv
def CreateClone(self):
return maximus_vx_lite_strategy()