Täglicher Ausbruch-Strategie
Diese Strategie handelt Ausbrüche vom täglichen Eröffnungskurs. Zu Beginn eines jeden neuen Tages wird der Eröffnungskurs gespeichert. Wenn der Preis sich von diesem Level um eine benutzerdefinierte Anzahl von Punkten entfernt und der vorherige Balken innerhalb eines konfigurierbaren Größenbereichs liegt, tritt die Strategie in die Ausbruchsrichtung ein.
Einstiegslogik
- Wenn der vorherige Balken bullisch ist und der Preis um Break Point Punkte über die Tageseröffnung steigt, wird eine Long-Position eröffnet.
- Wenn der vorherige Balken bärisch ist und der Preis um Break Point Punkte unter die Tageseröffnung fällt, wird eine Short-Position eröffnet.
- Die Größe des vorherigen Balkens muss zwischen Last Bar Min und Last Bar Max Punkten liegen.
- Das Ausbruchsniveau muss innerhalb des Körpers des vorherigen Balkens liegen.
Risikomanagement
- Optionaler Take Profit und Stop Loss werden in Punkten vom Einstiegspreis gemessen.
- Ein Trailing Stop kann mit den Parametern Trailing Start, Trailing Stop und Trailing Step aktiviert werden. Wenn der Preis sich um Trailing Start Punkte zugunsten bewegt, wird der Stop auf Trailing Stop Punkte vom Einstieg gesetzt und folgt dann in Trailing Step-Schritten.
Parameter
| Name |
Beschreibung |
| Candle Type |
Zeitrahmen der verarbeiteten Kerzen. |
| Break Point |
Abstand von der Tageseröffnung zum Auslösen eines Trades (Punkte). |
| Last Bar Min |
Mindestgröße des vorherigen Balkens (Punkte). |
| Last Bar Max |
Maximale Größe des vorherigen Balkens (Punkte). |
| Trailing Start |
Preisbewegung zum Starten des Trailing Stops (Punkte). |
| Trailing Stop |
Anfänglicher Trailing-Abstand (Punkte). |
| Trailing Step |
Schritt zum Bewegen des Trailing Stops (Punkte). |
| Take Profit |
Take-Profit-Abstand (Punkte). |
| Stop Loss |
Stop-Loss-Abstand (Punkte). |
Hinweise
Die Strategie arbeitet nur auf abgeschlossenen Kerzen und verwendet Marktaufträge für Ein- und Ausstiege. Sie speichert interne Variablen für die Daten des vorherigen Balkens und das Trailing-Stop-Level.
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>
/// Daily breakout strategy based on the previous bar size and daily open.
/// </summary>
public class DailyBreakpointStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<decimal> _breakPointPct;
private readonly StrategyParam<decimal> _lastBarMinPct;
private readonly StrategyParam<decimal> _lastBarMaxPct;
private readonly StrategyParam<decimal> _takeProfitPct;
private readonly StrategyParam<decimal> _stopLossPct;
private decimal _prevOpen;
private decimal _prevClose;
private DateTimeOffset _prevTime;
private bool _hasPrev;
private decimal _dayOpen;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public decimal BreakPointPct { get => _breakPointPct.Value; set => _breakPointPct.Value = value; }
public decimal LastBarMinPct { get => _lastBarMinPct.Value; set => _lastBarMinPct.Value = value; }
public decimal LastBarMaxPct { get => _lastBarMaxPct.Value; set => _lastBarMaxPct.Value = value; }
public decimal TakeProfitPct { get => _takeProfitPct.Value; set => _takeProfitPct.Value = value; }
public decimal StopLossPct { get => _stopLossPct.Value; set => _stopLossPct.Value = value; }
public DailyBreakpointStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Candles", "General");
_breakPointPct = Param(nameof(BreakPointPct), 0.3m)
.SetDisplay("Break Point %", "Breakout offset as % of price", "General");
_lastBarMinPct = Param(nameof(LastBarMinPct), 0.05m)
.SetDisplay("Min Bar %", "Minimal bar size as % of price", "Filter");
_lastBarMaxPct = Param(nameof(LastBarMaxPct), 1.0m)
.SetDisplay("Max Bar %", "Maximum bar size as % of price", "Filter");
_takeProfitPct = Param(nameof(TakeProfitPct), 2m)
.SetDisplay("Take Profit %", "Take profit percentage", "Risk");
_stopLossPct = Param(nameof(StopLossPct), 1m)
.SetDisplay("Stop Loss %", "Stop loss percentage", "Risk");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevOpen = default;
_prevClose = default;
_prevTime = default;
_hasPrev = default;
_dayOpen = default;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
StartProtection(
takeProfit: new Unit(TakeProfitPct, UnitTypes.Percent),
stopLoss: new Unit(StopLossPct, UnitTypes.Percent),
isStopTrailing: true,
useMarketOrders: true);
var sub = SubscribeCandles(CandleType);
sub.Bind(Process).Start();
}
private void Process(ICandleMessage c)
{
if (c.State != CandleStates.Finished)
return;
if (!_hasPrev || c.OpenTime.Date != _prevTime.Date)
_dayOpen = c.OpenPrice;
if (Position == 0 && _hasPrev)
{
var price = c.ClosePrice;
var lastSize = Math.Abs(_prevClose - _prevOpen);
var minSize = LastBarMinPct / 100m * price;
var maxSize = LastBarMaxPct / 100m * price;
var offset = BreakPointPct / 100m * price;
var breakBuy = _dayOpen + offset;
var breakSell = _dayOpen - offset;
if (_prevClose > _prevOpen && price - _dayOpen >= offset &&
lastSize >= minSize && lastSize <= maxSize &&
breakBuy >= _prevOpen && breakBuy <= _prevClose)
{
BuyMarket();
}
else if (_prevClose < _prevOpen && _dayOpen - price >= offset &&
lastSize >= minSize && lastSize <= maxSize &&
breakSell <= _prevOpen && breakSell >= _prevClose)
{
SellMarket();
}
}
_prevOpen = c.OpenPrice;
_prevClose = c.ClosePrice;
_prevTime = c.OpenTime;
_hasPrev = true;
}
}
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, Unit, UnitTypes
from StockSharp.Algo.Strategies import Strategy
class daily_breakpoint_strategy(Strategy):
def __init__(self):
super(daily_breakpoint_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Candles", "General")
self._break_point_pct = self.Param("BreakPointPct", 0.3) \
.SetDisplay("Break Point %", "Breakout offset as % of price", "General")
self._last_bar_min_pct = self.Param("LastBarMinPct", 0.05) \
.SetDisplay("Min Bar %", "Minimal bar size as % of price", "Filter")
self._last_bar_max_pct = self.Param("LastBarMaxPct", 1.0) \
.SetDisplay("Max Bar %", "Maximum bar size as % of price", "Filter")
self._take_profit_pct = self.Param("TakeProfitPct", 2.0) \
.SetDisplay("Take Profit %", "Take profit percentage", "Risk")
self._stop_loss_pct = self.Param("StopLossPct", 1.0) \
.SetDisplay("Stop Loss %", "Stop loss percentage", "Risk")
self._prev_open = 0.0
self._prev_close = 0.0
self._prev_time = None
self._has_prev = False
self._day_open = 0.0
@property
def candle_type(self):
return self._candle_type.Value
@property
def break_point_pct(self):
return self._break_point_pct.Value
@property
def last_bar_min_pct(self):
return self._last_bar_min_pct.Value
@property
def last_bar_max_pct(self):
return self._last_bar_max_pct.Value
@property
def take_profit_pct(self):
return self._take_profit_pct.Value
@property
def stop_loss_pct(self):
return self._stop_loss_pct.Value
def OnReseted(self):
super(daily_breakpoint_strategy, self).OnReseted()
self._prev_open = 0.0
self._prev_close = 0.0
self._prev_time = None
self._has_prev = False
self._day_open = 0.0
def OnStarted2(self, time):
super(daily_breakpoint_strategy, self).OnStarted2(time)
self.StartProtection(
takeProfit=Unit(self.take_profit_pct, UnitTypes.Percent),
stopLoss=Unit(self.stop_loss_pct, UnitTypes.Percent),
isStopTrailing=True,
useMarketOrders=True)
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(self.process).Start()
def process(self, candle):
if candle.State != CandleStates.Finished:
return
if not self._has_prev or candle.OpenTime.Date != self._prev_time.Date:
self._day_open = float(candle.OpenPrice)
if self.Position == 0 and self._has_prev:
price = float(candle.ClosePrice)
last_size = abs(self._prev_close - self._prev_open)
min_size = float(self.last_bar_min_pct) / 100.0 * price
max_size = float(self.last_bar_max_pct) / 100.0 * price
offset = float(self.break_point_pct) / 100.0 * price
break_buy = self._day_open + offset
break_sell = self._day_open - offset
if (self._prev_close > self._prev_open and price - self._day_open >= offset and
last_size >= min_size and last_size <= max_size and
break_buy >= self._prev_open and break_buy <= self._prev_close):
self.BuyMarket()
elif (self._prev_close < self._prev_open and self._day_open - price >= offset and
last_size >= min_size and last_size <= max_size and
break_sell <= self._prev_open and break_sell >= self._prev_close):
self.SellMarket()
self._prev_open = float(candle.OpenPrice)
self._prev_close = float(candle.ClosePrice)
self._prev_time = candle.OpenTime
self._has_prev = True
def CreateClone(self):
return daily_breakpoint_strategy()