| Overall Statistics |
|
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio -0.585 Tracking Error 0.153 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset Portfolio Turnover 0% |
"""
Algo Overview:
Use the Hurst Exponent to quantify wheteher gold has been trending or mean reverting.
- run over different lengths and timeframes to see how it is changing.
-
How does the change in periods affect HE? Are shorter periods more mean reverting than longer lookback periods akin to SPX?
"""
'''
Explanation: https://blog.quantinsti.com/hurst-exponent/#:~:text=Hurst%20Exponent%20Definition,between%20pairs%20of%20values%20increases
- > 0.5 = trending | < 0.5 = sideways market | = 0.5 = random walk where prediction of futre based on past dat is not possible
Hurst python example: https://www.quantconnect.com/forum/discussion/14875/hurst-exponent-function/p1
accompaning YT video by author: https://www.youtube.com/watch?v=IbfplwDAMik
Steps:
1) create rolling window called self.closingPrices (python list of closing prices in a rolling window)
2)
Hurst Exponent ex: https://www.quantconnect.com/forum/discussion/1695/hurst-exponent-indicator/p
Next Steps:
Build out for other time frames and hurst_periods
test other markets
'''
# region imports
from AlgorithmImports import *
import numpy as np
# endregion
FUTURES_CONTRACT = Futures.Indices.SP500EMini
# FUTURES_CONTRACT = Futures.Metals.MicroGold
HURST_PERIODS = 90
class DeterminedYellowGreenRabbit(QCAlgorithm):
def Initialize(self):
# Debug Set
# self.SetStartDate(2020,1,1)
# self.SetEndDate(2023,7,10)
# Long Set
self.SetStartDate(2015,1,1)
self.SetEndDate(2023,7,10)
# Long Set 2
# self.SetStartDate(2016,1,1)
# self.SetEndDate(2020,1,1)
self.SetCash(50000)
self.gc = self.AddFuture(FUTURES_CONTRACT, dataNormalizationMode = DataNormalizationMode.BackwardsPanamaCanal, dataMappingMode = DataMappingMode.OpenInterest, contractDepthOffset = 0, extendedMarketHours=True)
consolidator = TradeBarConsolidator(self.CustomDaily)
consolidator.DataConsolidated += self.CustomDailyHandler
self.SubscriptionManager.AddConsolidator(self.gc.Symbol, consolidator)
hurst_periods = self.GetParameter("hurst_periods")
self.hurst_periods = HURST_PERIODS if hurst_periods is None else float(hurst_periods)
self.closingPricesRW = RollingWindow[float](self.hurst_periods)
self.closingPrices = []
# Vizualization Vars
HurstChart = Chart("Hurst Exponent")
HurstChart.AddSeries(Series("Hurst", SeriesType.Line, 0))
HurstChart.AddSeries(Series("Midpoint", SeriesType.Line, 0))
self.AddChart(HurstChart)
priceChart = Chart("Price Chart")
priceChart.AddSeries(Series("Futures Price", SeriesType.Line, 0))
self.AddChart(priceChart)
def OnData(self, data: Slice):
self.futuresPrice = self.gc.Price
def CustomDailyHandler(self, sender, bar):
# self.Debug(f"{self.Time} Close Price: {bar.Close}")
self.closingPricesRW.Add(bar.Close)
if self.closingPricesRW.IsReady:
# Convert closingPricesRW into a list
for n in self.closingPricesRW:
self.closingPrices.append(n)
# self.Debug(f"{self.Time} closingPrices List: {self.closingPrices}")
# Calculate Hurst Exponent
self.HE = self.HurstExponent()
# self.Debug(f"{self.Time} Hurst Exponent: {self.HE}")
# Chart
self.Plot("Hurst Exponent", "Hurst", self.HE)
self.Plot("Hurst Exponent", "Midpoint", 0.50)
self.Plot("Price Chart", "Futures Price", bar.Close)
self.closingPrices = []
def CustomDaily(self, dt):
start = (dt if dt.hour > 17 else dt - timedelta(1)).date()
start = datetime.combine(start, datetime.min.time())+timedelta(hours=17)
return CalendarInfo(start, timedelta(1))
def HurstExponent(self):
#The Hurst Exponent is calculated using the Rescaled Range (R/S) analysis. The formula for the Hurst exponent is:
#Hurst Exponent = (log(Rn/S) / log(n)) - 0.5
#where Rn is the range of the cumulative sum of n data points and S is the standard deviation of the n data points
# Generate vector of prices
prices = np.array([self.closingPrices])
# Calculate log returns
Rn = np.cumsum(prices)
S = np.std(prices)
# Calculate Hurst exponent
hurst = (np.log(Rn/S)) / np.log(prices) - 0.5
# self.Debug(f"{self.Time} Hurst Exponent: {hurst}")
return hurst[-1][-1]