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 = 276 class DeterminedYellowGreenRabbit(QCAlgorithm): def Initialize(self): # Debug Set # self.SetStartDate(2023,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.equity = self.AddEquity("GLD", Resolution.Minute, extendedMarketHours=False) self.Schedule.On(self.DateRules.EveryDay("GLD"), self.TimeRules.BeforeMarketClose(self.equity.Symbol, 0), self.marketClose) self.gc = self.AddFuture(FUTURES_CONTRACT, dataNormalizationMode = DataNormalizationMode.BackwardsPanamaCanal, dataMappingMode = DataMappingMode.OpenInterest, contractDepthOffset = 0, extendedMarketHours=True) consolidator = TradeBarConsolidator(timedelta(minutes=5)) consolidator.DataConsolidated += self.OnDataConsolidated 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) # Initializaiton Vars self.HE = None def OnData(self, data: Slice): self.futuresPrice = self.gc.Price def OnDataConsolidated(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 HurstExponent(self): #The Hurst Exponent is calculated using the Rescaled Range (R/S) analysis. The formula for the Hurst exponent is: # - The below calculation does not use the rescaled range but provides similar number #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]) # self.Debug(f"{self.Time} Couldn't calculate HE") # 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] def marketClose(self): # Chart if self.HE is not None: self.Plot("Hurst Exponent", "Hurst", self.HE) self.Plot("Hurst Exponent", "Midpoint", 0.50) self.Plot("Price Chart", "Futures Price", self.futuresPrice)