Fib Hurst Ruptura
Fib Hurst Ruptura combina niveles de retroceso de Fibonacci del marco temporal diario con un filtro de exponente de Hurst. El cruce del precio por los niveles clave de Fibonacci en la dirección de la tendencia predominante activa las entradas, mientras que un stop del 2% y una relación riesgo-recompensa de 1:2 gestionan el riesgo.
Detalles
- Criterios de entrada:
- Largo: El cierre cruza por encima del nivel 61.8% y Hurst diario > 0.5
- Corto: El cierre cruza por debajo del nivel 38.2% y Hurst diario < 0.5
- Largo/Corto: Ambos
- Criterios de salida: Stop-loss o take-profit
- Stops: Sí
- Valores predeterminados:
CandleType= TimeSpan.FromMinutes(15)HurstPeriod= 50MaxTradesPerDay= 5MaxTotalTrades= 510RiskPercent= 2mRiskReward= 2m
- Filtros:
- Categoría: Ruptura
- Dirección: Ambos
- Indicadores: Hurst, Fibonacci
- Stops: Sí
- Complejidad: Intermedio
- Marco temporal: Intradía
- Estacionalidad: No
- Redes neuronales: No
- Divergencia: No
- Nivel de riesgo: Medio
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>
/// Fibonacci levels with Hurst exponent filter.
/// Uses rolling high/low for Fib levels and Hurst to detect trending.
/// Enters long when price crosses above 61.8% level and Hurst > 0.5.
/// Enters short when price crosses below 38.2% level and Hurst less than 0.5.
/// </summary>
public class FibHurstBreakoutStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _hurstPeriod;
private readonly StrategyParam<int> _lookbackPeriod;
private readonly StrategyParam<int> _cooldownBars;
private readonly List<decimal> _highs = [];
private readonly List<decimal> _lows = [];
private decimal _prevClose;
private int _cooldownRemaining;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int HurstPeriod { get => _hurstPeriod.Value; set => _hurstPeriod.Value = value; }
public int LookbackPeriod { get => _lookbackPeriod.Value; set => _lookbackPeriod.Value = value; }
public int CooldownBars { get => _cooldownBars.Value; set => _cooldownBars.Value = value; }
public FibHurstBreakoutStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Type of candles for strategy", "Parameters");
_hurstPeriod = Param(nameof(HurstPeriod), 50)
.SetGreaterThanZero()
.SetDisplay("Hurst Period", "Period for Hurst exponent", "Parameters");
_lookbackPeriod = Param(nameof(LookbackPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("Lookback Period", "Period for Fib level calculation", "Parameters");
_cooldownBars = Param(nameof(CooldownBars), 10)
.SetDisplay("Cooldown Bars", "Bars between trades", "Risk");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_highs.Clear();
_lows.Clear();
_prevClose = 0;
_cooldownRemaining = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var hurst = new HurstExponent { Length = HurstPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(hurst, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal hurstValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
// Track rolling highs/lows for Fib levels
_highs.Add(candle.HighPrice);
_lows.Add(candle.LowPrice);
if (_highs.Count > LookbackPeriod)
{
_highs.RemoveAt(0);
_lows.RemoveAt(0);
}
if (_highs.Count < LookbackPeriod || _prevClose == 0)
{
_prevClose = candle.ClosePrice;
return;
}
// Calculate Fibonacci levels from recent range
decimal high = decimal.MinValue, low = decimal.MaxValue;
for (var i = 0; i < _highs.Count; i++)
{
if (_highs[i] > high) high = _highs[i];
if (_lows[i] < low) low = _lows[i];
}
var range = high - low;
if (range <= 0)
{
_prevClose = candle.ClosePrice;
return;
}
var fib382 = low + 0.382m * range;
var fib618 = low + 0.618m * range;
if (_cooldownRemaining > 0)
{
_cooldownRemaining--;
_prevClose = candle.ClosePrice;
return;
}
var crossUp = _prevClose <= fib618 && candle.ClosePrice > fib618;
var crossDown = _prevClose >= fib382 && candle.ClosePrice < fib382;
if (hurstValue > 0.5m && crossUp && Position <= 0)
{
if (Position < 0)
BuyMarket(Math.Abs(Position));
BuyMarket(Volume);
_cooldownRemaining = CooldownBars;
}
else if (hurstValue < 0.5m && crossDown && Position >= 0)
{
if (Position > 0)
SellMarket(Math.Abs(Position));
SellMarket(Volume);
_cooldownRemaining = CooldownBars;
}
_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, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import HurstExponent
from StockSharp.Algo.Strategies import Strategy
class fib_hurst_breakout_strategy(Strategy):
def __init__(self):
super(fib_hurst_breakout_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(30))) \
.SetDisplay("Candle Type", "Type of candles for strategy", "Parameters")
self._hurst_period = self.Param("HurstPeriod", 50) \
.SetGreaterThanZero() \
.SetDisplay("Hurst Period", "Period for Hurst exponent", "Parameters")
self._lookback_period = self.Param("LookbackPeriod", 20) \
.SetGreaterThanZero() \
.SetDisplay("Lookback Period", "Period for Fib level calculation", "Parameters")
self._cooldown_bars = self.Param("CooldownBars", 10) \
.SetDisplay("Cooldown Bars", "Bars between trades", "Risk")
self._highs = []
self._lows = []
self._prev_close = 0.0
self._cooldown_remaining = 0
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(fib_hurst_breakout_strategy, self).OnReseted()
self._highs = []
self._lows = []
self._prev_close = 0.0
self._cooldown_remaining = 0
def OnStarted2(self, time):
super(fib_hurst_breakout_strategy, self).OnStarted2(time)
hurst = HurstExponent()
hurst.Length = int(self._hurst_period.Value)
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(hurst, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def _on_process(self, candle, hurst_val):
if candle.State != CandleStates.Finished:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
hurst_v = float(hurst_val)
lookback = int(self._lookback_period.Value)
self._highs.append(float(candle.HighPrice))
self._lows.append(float(candle.LowPrice))
if len(self._highs) > lookback:
self._highs = self._highs[-lookback:]
self._lows = self._lows[-lookback:]
if len(self._highs) < lookback or self._prev_close == 0:
self._prev_close = float(candle.ClosePrice)
return
high = max(self._highs)
low = min(self._lows)
rng = high - low
if rng <= 0:
self._prev_close = float(candle.ClosePrice)
return
fib382 = low + 0.382 * rng
fib618 = low + 0.618 * rng
close = float(candle.ClosePrice)
cooldown = int(self._cooldown_bars.Value)
if self._cooldown_remaining > 0:
self._cooldown_remaining -= 1
self._prev_close = close
return
cross_up = self._prev_close <= fib618 and close > fib618
cross_down = self._prev_close >= fib382 and close < fib382
if hurst_v > 0.5 and cross_up and self.Position <= 0:
if self.Position < 0:
self.BuyMarket(Math.Abs(self.Position))
self.BuyMarket(self.Volume)
self._cooldown_remaining = cooldown
elif hurst_v < 0.5 and cross_down and self.Position >= 0:
if self.Position > 0:
self.SellMarket(Math.Abs(self.Position))
self.SellMarket(self.Volume)
self._cooldown_remaining = cooldown
self._prev_close = close
def CreateClone(self):
return fib_hurst_breakout_strategy()