Dieses System verwendet den Hurst Exponent, um zu bestimmen, ob der Markt ein Trendverhalten zeigt. Werte über dem Schwellenwert zeigen Persistenz an, während Werte darunter auf Rauschen oder Mean Reversion hindeuten. Ein gleitender Durchschnitt bietet zusätzliche Richtungsbestätigung.
Tests zeigen eine durchschnittliche jährliche Rendite von etwa 40%. Sie funktioniert am besten auf dem Kryptomarkt.
Die Strategie kauft, wenn der Hurst Exponent größer als der Schwellenwert ist und der Preis über dem gleitenden Durchschnitt schließt. Sie verkauft short, wenn der Hurst Exponent hoch ist und der Preis unter dem Durchschnitt schließt. Wenn der Hurst Exponent unter den Schwellenwert fällt, werden bestehende Positionen geschlossen, um den Handel in unruhigen Märkten zu vermeiden.
Dieser Ansatz eignet sich für Trader, die eine objektive Bestätigung dafür wollen, dass ein Trend vorhanden ist, bevor sie einsteigen. Die Kombination aus Trendfilter und Stop-Loss hilft, das Risiko von Fehlsignalen zu managen.
Details
Einstiegskriterien:
Long: Hurst > Schwellenwert && Schluss > MA
Short: Hurst > Schwellenwert && Schluss < MA
Long/Short: Beide Seiten.
Ausstiegskriterien:
Long: Ausstieg, wenn Schluss < MA oder Hurst < Schwellenwert
Short: Ausstieg, wenn Schluss > MA oder Hurst < Schwellenwert
Stops: Ja, prozentualer Stop-Loss.
Standardwerte:
HurstPeriod = 100
MaPeriod = 20
HurstThreshold = 0.55m
CandleType = TimeSpan.FromMinutes(5)
Filter:
Kategorie: Trend
Richtung: Beide
Indikatoren: Hurst Exponent, MA
Stops: Ja
Komplexität: Mittel
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>
/// Hurst Exponent Trend strategy.
/// Uses Hurst exponent to identify trending markets.
/// </summary>
public class HurstExponentTrendStrategy : Strategy
{
private readonly StrategyParam<int> _hurstPeriodParam;
private readonly StrategyParam<int> _maPeriodParam;
private readonly StrategyParam<decimal> _hurstThresholdParam;
private readonly StrategyParam<DataType> _candleTypeParam;
private HurstExponent _hurst;
private SimpleMovingAverage _sma;
/// <summary>
/// Hurst exponent calculation period.
/// </summary>
public int HurstPeriod
{
get => _hurstPeriodParam.Value;
set => _hurstPeriodParam.Value = value;
}
/// <summary>
/// Moving average period.
/// </summary>
public int MaPeriod
{
get => _maPeriodParam.Value;
set => _maPeriodParam.Value = value;
}
/// <summary>
/// Hurst exponent threshold for trend identification.
/// </summary>
public decimal HurstThreshold
{
get => _hurstThresholdParam.Value;
set => _hurstThresholdParam.Value = value;
}
/// <summary>
/// Candle type for strategy.
/// </summary>
public DataType CandleType
{
get => _candleTypeParam.Value;
set => _candleTypeParam.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public HurstExponentTrendStrategy()
{
_hurstPeriodParam = Param(nameof(HurstPeriod), 100)
.SetGreaterThanZero()
.SetDisplay("Hurst Period", "Period for Hurst exponent calculation", "Parameters")
.SetOptimize(50, 150, 25);
_maPeriodParam = Param(nameof(MaPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("MA Period", "Period for Moving Average", "Parameters")
.SetOptimize(10, 50, 10);
_hurstThresholdParam = Param(nameof(HurstThreshold), 0.55m)
.SetRange(0.1m, 0.9m)
.SetDisplay("Hurst Threshold", "Threshold value for trend identification", "Parameters")
.SetOptimize(0.5m, 0.6m, 0.05m);
_candleTypeParam = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candle type for strategy", "Common");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_hurst = null;
_sma = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
// Create indicators
_hurst = new HurstExponent { Length = HurstPeriod };
_sma = new SMA { Length = MaPeriod };
// Create subscription and bind indicators
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(_hurst, _sma, ProcessCandle)
.Start();
// Setup chart visualization if available
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, _sma);
DrawOwnTrades(area);
}
// Enable position protection
StartProtection(
takeProfit: new Unit(0, UnitTypes.Absolute), // No take profit
stopLoss: new Unit(2, UnitTypes.Percent) // 2% stop loss
);
}
private void ProcessCandle(ICandleMessage candle, decimal hurstValue, decimal smaValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
// Check if market is trending (Hurst > 0.5 indicates trending market)
bool isTrending = hurstValue > HurstThreshold;
if (isTrending)
{
// In trending markets, use price relative to MA to determine direction
// Long setup - trending market with price above MA
if (candle.ClosePrice > smaValue && Position <= 0)
{
// Buy signal - trending market with price above MA
BuyMarket(Volume + Math.Abs(Position));
}
// Short setup - trending market with price below MA
else if (candle.ClosePrice < smaValue && Position >= 0)
{
// Sell signal - trending market with price below MA
SellMarket(Volume + Math.Abs(Position));
}
}
else
{
// In non-trending markets, exit positions
if (Position > 0)
{
SellMarket(Position);
}
else if (Position < 0)
{
BuyMarket(Math.Abs(Position));
}
}
}
}
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, Unit, UnitTypes
from StockSharp.Algo.Indicators import HurstExponent, SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
class hurst_exponent_trend_strategy(Strategy):
"""
Hurst Exponent Trend: trades when Hurst > threshold (trending market), exits otherwise.
"""
def __init__(self):
super(hurst_exponent_trend_strategy, self).__init__()
self._hurst_period = self.Param("HurstPeriod", 100).SetDisplay("Hurst Period", "Hurst calculation period", "Indicators")
self._ma_period = self.Param("MaPeriod", 20).SetDisplay("MA Period", "SMA period", "Indicators")
self._threshold = self.Param("HurstThreshold", 0.55).SetDisplay("Threshold", "Hurst threshold", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Timeframe", "General")
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(hurst_exponent_trend_strategy, self).OnReseted()
def OnStarted2(self, time):
super(hurst_exponent_trend_strategy, self).OnStarted2(time)
hurst = HurstExponent()
hurst.Length = self._hurst_period.Value
sma = SimpleMovingAverage()
sma.Length = self._ma_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(hurst, sma, self._process_candle).Start()
self.StartProtection(None, Unit(2, UnitTypes.Percent))
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, sma)
self.DrawOwnTrades(area)
def _process_candle(self, candle, hurst_val, sma_val):
if candle.State != CandleStates.Finished:
return
hurst = float(hurst_val)
sma = float(sma_val)
close = float(candle.ClosePrice)
trending = hurst > self._threshold.Value
if trending:
if close > sma and self.Position <= 0:
self.BuyMarket()
elif close < sma and self.Position >= 0:
self.SellMarket()
else:
if self.Position > 0:
self.SellMarket()
elif self.Position < 0:
self.BuyMarket()
def CreateClone(self):
return hurst_exponent_trend_strategy()