Start
/
Strategie-Beispiele
Auf GitHub ansehen
Darvas-Boxen-System-Strategie
Überblick
Diese Strategie implementiert einen Ausbruch-Ansatz basierend auf dem klassischen Darvas Boxes -Konzept. Sie überwacht die Preisbewegung innerhalb eines dynamischen Preisbereichs (Box), der mithilfe des Donchian Channels -Indikators berechnet wird. Wenn der Preis oberhalb der oberen Grenze der Box schließt, wird eine Long-Position eröffnet. Wenn der Preis unterhalb der unteren Grenze schließt, wird eine Short-Position eröffnet. Optionale Stop-Loss- und Take-Profit-Niveaus bieten ein grundlegendes Risikomanagement.
Funktionsweise
Für jede Kerze berechnet der Donchian Channels-Indikator die obere und untere Grenze anhand des angegebenen BoxPeriod.
Die Strategie verfolgt die vorherigen oberen und unteren Werte, um Ausbrüche zu erkennen.
Wenn der aktuelle Schlusskurs die vorherige obere Grenze nach oben kreuzt, führt die Strategie folgendes aus:
Schließt jede bestehende Short-Position (sofern erlaubt).
Eröffnet eine neue Long-Position (sofern erlaubt).
Wenn der aktuelle Schlusskurs die vorherige untere Grenze nach unten kreuzt, führt die Strategie folgendes aus:
Schließt jede bestehende Long-Position (sofern erlaubt).
Eröffnet eine neue Short-Position (sofern erlaubt).
Aktive Positionen werden auf Stop-Loss- und Take-Profit-Bedingungen überwacht.
Parameter
BoxPeriod (int): Anzahl der Kerzen zur Berechnung der Preisbox. Standardwert ist 20.
StopLoss (decimal): Abstand vom Einstiegspreis zum Stop-Loss-Niveau. Standardwert ist 1000.
TakeProfit (decimal): Abstand vom Einstiegspreis zum Take-Profit-Niveau. Standardwert ist 2000.
AllowBuyEntry (bool): Ermöglicht das Eröffnen von Long-Positionen. Standardwert ist true.
AllowSellEntry (bool): Ermöglicht das Eröffnen von Short-Positionen. Standardwert ist true.
AllowBuyExit (bool): Ermöglicht das Schließen von Long-Positionen bei umgekehrten Signalen oder Risikoereignissen. Standardwert ist true.
AllowSellExit (bool): Ermöglicht das Schließen von Short-Positionen bei umgekehrten Signalen oder Risikoereignissen. Standardwert ist true.
CandleType (DataType): Kerzentyp für Berechnungen. Standardwert sind 4-Stunden-Kerzen.
Verwendung
Hängen Sie die Strategie an ein Wertpapier an und legen Sie die gewünschten Parameterwerte fest.
Starten Sie die Strategie. Sie abonniert die konfigurierte Kerzenserie und verarbeitet eingehende Daten.
Trades werden mit Marktorders ausgeführt, wenn Ausbruchsbedingungen erfüllt sind.
Optionale Stop-Loss- und Take-Profit-Niveaus verwalten offene Positionen.
Hinweise
Die Strategie verwendet die High-Level-API mit BindEx, um Indikatorwerte und Kerzendaten zu verbinden.
Interne Sammlungen werden vermieden; Indikatorwerte werden über den Binding-Callback abgerufen.
Nur abgeschlossene Kerzen werden verarbeitet, um zuverlässige Signale sicherzustellen.
Kommentare im Code sind auf Englisch, wie erforderlich.
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>
/// Darvas Boxes breakout strategy using Donchian Channels.
/// Opens long position when price breaks above the upper box line.
/// Opens short position when price breaks below the lower box line.
/// </summary>
public class DarvasBoxesSystemStrategy : Strategy
{
private readonly StrategyParam<int> _boxPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevUpper;
private decimal _prevLower;
private decimal _prevClose;
public int BoxPeriod
{
get => _boxPeriod.Value;
set => _boxPeriod.Value = value;
}
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public DarvasBoxesSystemStrategy()
{
_boxPeriod = Param(nameof(BoxPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("Box Period", "Period for box calculation", "Indicators")
.SetOptimize(10, 40, 5);
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevUpper = 0m;
_prevLower = 0m;
_prevClose = 0m;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevUpper = 0m;
_prevLower = 0m;
_prevClose = 0m;
var donchian = new DonchianChannels { Length = BoxPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(donchian, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, donchian);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue value)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (value is not IDonchianChannelsValue box)
return;
if (box.UpperBand is not decimal upper || box.LowerBand is not decimal lower)
return;
if (_prevUpper == 0m)
{
_prevUpper = upper;
_prevLower = lower;
_prevClose = candle.ClosePrice;
return;
}
var isUpBreakout = candle.ClosePrice > _prevUpper && _prevClose <= _prevUpper;
var isDownBreakout = candle.ClosePrice < _prevLower && _prevClose >= _prevLower;
if (isUpBreakout && Position <= 0)
BuyMarket();
else if (isDownBreakout && Position >= 0)
SellMarket();
_prevUpper = upper;
_prevLower = lower;
_prevClose = candle.ClosePrice;
}
}
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 DonchianChannels
from StockSharp.Algo.Strategies import Strategy
class darvas_boxes_system_strategy(Strategy):
def __init__(self):
super(darvas_boxes_system_strategy, self).__init__()
self._box_period = self.Param("BoxPeriod", 20) \
.SetDisplay("Box Period", "Period for box calculation", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
self._prev_upper = 0.0
self._prev_lower = 0.0
self._prev_close = 0.0
@property
def box_period(self):
return self._box_period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(darvas_boxes_system_strategy, self).OnReseted()
self._prev_upper = 0.0
self._prev_lower = 0.0
self._prev_close = 0.0
def OnStarted2(self, time):
super(darvas_boxes_system_strategy, self).OnStarted2(time)
self._prev_upper = 0.0
self._prev_lower = 0.0
self._prev_close = 0.0
donchian = DonchianChannels()
donchian.Length = self.box_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(donchian, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, donchian)
self.DrawOwnTrades(area)
def process_candle(self, candle, value):
if candle.State != CandleStates.Finished:
return
upper = value.UpperBand
lower = value.LowerBand
if upper is None or lower is None:
return
upper = float(upper)
lower = float(lower)
close_price = float(candle.ClosePrice)
if self._prev_upper == 0.0:
self._prev_upper = upper
self._prev_lower = lower
self._prev_close = close_price
return
is_up_breakout = close_price > self._prev_upper and self._prev_close <= self._prev_upper
is_down_breakout = close_price < self._prev_lower and self._prev_close >= self._prev_lower
if is_up_breakout and self.Position <= 0:
self.BuyMarket()
elif is_down_breakout and self.Position >= 0:
self.SellMarket()
self._prev_upper = upper
self._prev_lower = lower
self._prev_close = close_price
def CreateClone(self):
return darvas_boxes_system_strategy()