Volumen-Ausbruch
Die Volumen-Ausbruch-Strategie beobachtet das Volumen auf schnelle Expansionen. Wenn die Werte über ihren durchschnittlichen Bereich hinausspringen, beginnt der Preis oft eine neue Bewegung.
Tests zeigen eine durchschnittliche jährliche Rendite von etwa 103%. Die Strategie funktioniert am besten am Aktienmarkt.
Eine Position wird eröffnet, sobald der Indikator ein Band durchbricht, das aus aktuellen Daten und einem Abweichungsmultiplikator abgeleitet wird. Long- und Short-Trades sind mit einem Stop möglich.
Dieses System eignet sich für Momentum-Trader, die frühe Ausbrüche suchen. Trades schließen, wenn das Volumen zur Mitte zurückkehrt. Standardwerte beginnen mit AvgPeriod = 20.
Details
- Einstiegskriterien: Indikator überschreitet den Durchschnitt um den Abweichungsmultiplikator.
- Long/Short: Beide Richtungen.
- Ausstiegskriterien: Indikator kehrt zum Durchschnitt zurück.
- Stops: Ja.
- Standardwerte:
AvgPeriod= 20Multiplier= 2.0mCandleType= TimeSpan.FromMinutes(5)StopLoss= 2.0m
- Filter:
- Kategorie: Ausbruch
- Richtung: Beide
- Indikatoren: Volume
- Stops: Ja
- Komplexität: Mittel
- Zeitrahmen: Kurzfristig
- Saisonalität: Nein
- Neuronale Netze: Nein
- Divergenz: Nein
- Risikolevel: Mittel
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Strategy that trades on volume breakouts.
/// When volume rises significantly above its average, it enters position in the direction determined by price.
/// </summary>
public class VolumeBreakoutStrategy : Strategy
{
private readonly StrategyParam<int> _avgPeriod;
private readonly StrategyParam<decimal> _multiplier;
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<decimal> _stopLoss;
private SimpleMovingAverage _volumeAverage;
private SimpleMovingAverage _volumeStdDev;
private decimal _lastAvgVolume;
private decimal _lastStdDev;
/// <summary>
/// Period for volume average calculation.
/// </summary>
public int AvgPeriod
{
get => _avgPeriod.Value;
set => _avgPeriod.Value = value;
}
/// <summary>
/// Standard deviation multiplier for breakout detection.
/// </summary>
public decimal Multiplier
{
get => _multiplier.Value;
set => _multiplier.Value = value;
}
/// <summary>
/// Candle type for strategy.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Stop-loss percentage.
/// </summary>
public decimal StopLoss
{
get => _stopLoss.Value;
set => _stopLoss.Value = value;
}
/// <summary>
/// Initialize <see cref="VolumeBreakoutStrategy"/>.
/// </summary>
public VolumeBreakoutStrategy()
{
_avgPeriod = Param(nameof(AvgPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("Average Period", "Period for volume average calculation", "Indicators")
.SetOptimize(10, 50, 5);
_multiplier = Param(nameof(Multiplier), 2.0m)
.SetGreaterThanZero()
.SetDisplay("Multiplier", "Standard deviation multiplier for breakout detection", "Indicators")
.SetOptimize(1.0m, 3.0m, 0.5m);
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
_stopLoss = Param(nameof(StopLoss), 2.0m)
.SetGreaterThanZero()
.SetDisplay("Stop Loss %", "Stop Loss percentage", "Risk Management")
.SetOptimize(1.0m, 5.0m, 0.5m);
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_lastAvgVolume = 0;
_lastStdDev = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
// Create indicators for volume analysis
_volumeAverage = new SMA { Length = AvgPeriod };
_volumeStdDev = new SMA { Length = AvgPeriod };
// Create subscription
var subscription = SubscribeCandles(CandleType);
// Bind candles to processing method
subscription
.Bind(ProcessCandle)
.Start();
// Enable stop loss protection
StartProtection(
takeProfit: new Unit(3, UnitTypes.Percent),
stopLoss: new Unit(StopLoss, UnitTypes.Percent));
// Create chart area for visualization
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
// Calculate volume indicators
var volume = candle.TotalVolume;
// Calculate volume average
var avgValue = _volumeAverage.Process(new DecimalIndicatorValue(_volumeAverage, volume, candle.ServerTime) { IsFinal = true });
var avgVolume = avgValue.ToDecimal();
// Calculate standard deviation approximation
var deviation = Math.Abs(volume - avgVolume);
var stdDevValue = _volumeStdDev.Process(new DecimalIndicatorValue(_volumeStdDev, deviation, candle.ServerTime) { IsFinal = true });
var stdDev = stdDevValue.ToDecimal();
// Skip the first N candles until we have enough data
if (!_volumeAverage.IsFormed || !_volumeStdDev.IsFormed)
{
_lastAvgVolume = avgVolume;
_lastStdDev = stdDev;
return;
}
// Volume breakout detection (volume increases significantly above its average)
if (volume > avgVolume + Multiplier * stdDev && Position == 0)
{
// Determine direction based on price movement
var bullish = candle.ClosePrice > candle.OpenPrice;
// Trade in the direction of price movement
if (bullish)
{
BuyMarket();
}
else
{
SellMarket();
}
}
// Update last values
_lastAvgVolume = avgVolume;
_lastStdDev = stdDev;
}
}
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, UnitTypes, Unit, CandleStates
from StockSharp.Algo.Indicators import SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
from datatype_extensions import *
from indicator_extensions import *
class volume_breakout_strategy(Strategy):
"""
Strategy that trades on volume breakouts.
When volume rises significantly above its average, it enters position in the direction determined by price.
"""
def __init__(self):
super(volume_breakout_strategy, self).__init__()
# Initialize VolumeBreakoutStrategy.
self._avg_period = self.Param("AvgPeriod", 20) \
.SetGreaterThanZero() \
.SetDisplay("Average Period", "Period for volume average calculation", "Indicators") \
.SetCanOptimize(True) \
.SetOptimize(10, 50, 5)
self._multiplier = self.Param("Multiplier", 2.0) \
.SetGreaterThanZero() \
.SetDisplay("Multiplier", "Standard deviation multiplier for breakout detection", "Indicators") \
.SetCanOptimize(True) \
.SetOptimize(1.0, 3.0, 0.5)
self._candle_type = self.Param("CandleType", tf(5)) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
self._stop_loss = self.Param("StopLoss", 2.0) \
.SetGreaterThanZero() \
.SetDisplay("Stop Loss %", "Stop Loss percentage", "Risk Management") \
.SetCanOptimize(True) \
.SetOptimize(1.0, 5.0, 0.5)
self._volume_average = None
self._volume_std_dev = None
self._last_avg_volume = 0
self._last_std_dev = 0
@property
def avg_period(self):
"""Period for volume average calculation."""
return self._avg_period.Value
@avg_period.setter
def avg_period(self, value):
self._avg_period.Value = value
@property
def multiplier(self):
"""Standard deviation multiplier for breakout detection."""
return self._multiplier.Value
@multiplier.setter
def multiplier(self, value):
self._multiplier.Value = value
@property
def candle_type(self):
"""Candle type for strategy."""
return self._candle_type.Value
@candle_type.setter
def candle_type(self, value):
self._candle_type.Value = value
@property
def stop_loss(self):
"""Stop-loss percentage."""
return self._stop_loss.Value
@stop_loss.setter
def stop_loss(self, value):
self._stop_loss.Value = value
def GetWorkingSecurities(self):
return [(self.Security, self.candle_type)]
def OnReseted(self):
"""
Resets internal state when strategy is reset.
"""
super(volume_breakout_strategy, self).OnReseted()
self._last_avg_volume = 0
self._last_std_dev = 0
def OnStarted2(self, time):
super(volume_breakout_strategy, self).OnStarted2(time)
# Create indicators for volume analysis
self._volume_average = SimpleMovingAverage()
self._volume_average.Length = self.avg_period
self._volume_std_dev = SimpleMovingAverage()
self._volume_std_dev.Length = self.avg_period
# Create subscription
subscription = self.SubscribeCandles(self.candle_type)
# Bind candles to processing method
subscription.Bind(self.ProcessCandle).Start()
# Enable stop loss protection
self.StartProtection(
takeProfit=Unit(3, UnitTypes.Percent),
stopLoss=Unit(self.stop_loss, UnitTypes.Percent)
)
# Create chart area for visualization
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def ProcessCandle(self, candle):
if candle.State != CandleStates.Finished:
return
# Calculate volume indicators
volume = float(candle.TotalVolume)
# Calculate volume average
avg_value = process_float(self._volume_average, volume, candle.ServerTime, candle.State == CandleStates.Finished)
avg_volume = float(avg_value)
# Calculate standard deviation approximation
deviation = Math.Abs(volume - avg_volume)
std_dev_value = process_float(self._volume_std_dev, deviation, candle.ServerTime, candle.State == CandleStates.Finished)
std_dev = float(std_dev_value)
# Skip the first N candles until we have enough data
if not self._volume_average.IsFormed or not self._volume_std_dev.IsFormed:
self._last_avg_volume = avg_volume
self._last_std_dev = std_dev
return
# Volume breakout detection (volume increases significantly above its average)
if volume > avg_volume + float(self.multiplier) * std_dev and self.Position == 0:
# Determine direction based on price movement
bullish = candle.ClosePrice > candle.OpenPrice
# Trade in the direction of price movement
if bullish:
self.BuyMarket()
else:
self.SellMarket()
# Update last values
self._last_avg_volume = avg_volume
self._last_std_dev = std_dev
def CreateClone(self):
"""!! REQUIRED!! Creates a new instance of the strategy."""
return volume_breakout_strategy()