Strategie: Gewichteter Harrell-Davis-Quantilschätzer mit AbsoluterAbweichung
Die Strategie verwendet einen medianbasierten Quantilschätzer mit Bändern der absoluten Abweichung, um Preisausreißer zu erkennen. Kauft, wenn der Schlusskurs unter das untere Band fällt, und verkauft, wenn er über das obere Band steigt.
Details
- Einstiegskriterien: Schlusskurs unterhalb des unteren Abweichungsbandes oder oberhalb des oberen Bandes
- Long/Short: Beide
- Ausstiegskriterien: Kreuzung des gegenüberliegenden Bandes
- Stops: Nein
- Standardwerte:
Length= 39DeviationMultiplier= 1.213
- Filter:
- Kategorie: Mean Reversion
- Richtung: Beide
- Indikatoren: Median
- Stops: Nein
- Komplexität: Grundlegend
- Zeitrahmen: Intraday
- 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>
/// Quantile estimator strategy with deviation bands.
/// Uses SMA + StdDev as Bollinger-like bands for mean reversion.
/// Buys when price drops below the lower band, sells when above upper band.
/// </summary>
public class WeightedHarrellDavisQuantileEstimatorWithAbsoluteDeviationStrategy : Strategy
{
private readonly StrategyParam<int> _length;
private readonly StrategyParam<decimal> _devMult;
private readonly StrategyParam<DataType> _candleType;
public int Length { get => _length.Value; set => _length.Value = value; }
public decimal DevMult { get => _devMult.Value; set => _devMult.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public WeightedHarrellDavisQuantileEstimatorWithAbsoluteDeviationStrategy()
{
_length = Param(nameof(Length), 39)
.SetGreaterThanZero()
.SetDisplay("Length", "Lookback period", "General");
_devMult = Param(nameof(DevMult), 1.5m)
.SetGreaterThanZero()
.SetDisplay("Deviation Mult", "Band multiplier", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var sma = new SimpleMovingAverage { Length = Length };
var stdDev = new StandardDeviation { Length = Length };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(sma, stdDev, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, sma);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal smaVal, decimal stdVal)
{
if (candle.State != CandleStates.Finished)
return;
if (stdVal <= 0)
return;
var upper = smaVal + DevMult * stdVal;
var lower = smaVal - DevMult * stdVal;
if (candle.ClosePrice > upper && Position >= 0)
SellMarket();
else if (candle.ClosePrice < lower && Position <= 0)
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.Indicators import SimpleMovingAverage, StandardDeviation
from StockSharp.Algo.Strategies import Strategy
class weighted_harrell_davis_quantile_estimator_with_absolute_deviation_strategy(Strategy):
def __init__(self):
super(weighted_harrell_davis_quantile_estimator_with_absolute_deviation_strategy, self).__init__()
self._length = self.Param("Length", 39) \
.SetDisplay("Length", "Lookback period", "General")
self._dev_mult = self.Param("DevMult", 1.5) \
.SetDisplay("Deviation Mult", "Band multiplier", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Type of candles", "General")
@property
def length(self):
return self._length.Value
@property
def dev_mult(self):
return self._dev_mult.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnStarted2(self, time):
super(weighted_harrell_davis_quantile_estimator_with_absolute_deviation_strategy, self).OnStarted2(time)
sma = SimpleMovingAverage()
sma.Length = self.length
std_dev = StandardDeviation()
std_dev.Length = self.length
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(sma, std_dev, self.on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, sma)
self.DrawOwnTrades(area)
def on_process(self, candle, sma_val, std_val):
if candle.State != CandleStates.Finished:
return
if std_val <= 0:
return
upper = sma_val + self.dev_mult * std_val
lower = sma_val - self.dev_mult * std_val
if candle.ClosePrice > upper and self.Position >= 0:
self.SellMarket()
elif candle.ClosePrice < lower and self.Position <= 0:
self.BuyMarket()
def CreateClone(self):
return weighted_harrell_davis_quantile_estimator_with_absolute_deviation_strategy()