Overall Statistics |
Total Trades 5 Average Win 30.29% Average Loss 0% Compounding Annual Return 92.786% Drawdown 15.800% Expectancy 0 Net Profit 92.685% Sharpe Ratio 2.441 Probabilistic Sharpe Ratio 85.622% Loss Rate 0% Win Rate 100% Profit-Loss Ratio 0 Alpha 0.191 Beta 2.206 Annual Standard Deviation 0.257 Annual Variance 0.066 Information Ratio 2.659 Tracking Error 0.161 Treynor Ratio 0.284 Total Fees $10.75 Estimated Strategy Capacity $580000.00 Lowest Capacity Asset ES XUERCWA6EWAP Portfolio Turnover 3.33% |
# region imports from AlgorithmImports import * from scipy.stats import entropy import numpy as np # endregion class SquareMagentaHamster(QCAlgorithm): def Initialize(self): self.SetStartDate(2021, 1, 1) # Set Start Date self.SetEndDate(2022, 1, 1) self.SetCash(100000) # Set Strategy Cash self.ShortcontractSymbol = None self.LongcontractSymbol = None self.future = self.AddFuture(Futures.Indices.SP500EMini, Resolution.Hour, extendedMarketHours= True) self.future.SetFilter(timedelta(0), timedelta(182)) self.symbol = self.future.Symbol self.lookback = 30 self.priceWindow = RollingWindow[QuoteBar](self.lookback) def OnData(self, data: Slice): if not(data.ContainsKey(self.symbol) and data[self.symbol] is not None): return self.priceWindow.Add(data[self.symbol]) if not self.priceWindow.IsReady: return self.closingPrices = [bar.Close for bar in self.priceWindow] hurst_exponent = self.HurstExponent() entropy = self.Entropy() self.Log(str(hurst_exponent[0])) self.Log(str(hurst_exponent)) if hurst_exponent[0] > 0.5 and entropy > 2.6: if self.Portfolio.Invested: if self.ShortcontractSymbol != None: self.Log("covered short for long EMA") self.BuyFuture(data) elif self.LongcontractSymbol != None: return else: self.BuyFuture(data) self.Log("Bought future") elif hurst_exponent[0] < 0.5 and entropy < 2.6: if self.Portfolio.Invested: if self.LongcontractSymbol != None: self.Log("sold long for short EMA") self.ShortFuture(data) elif self.ShortcontractSymbol != None: return else: self.ShortFuture(data) self.Log("Short future") self.Plot("Hurst", "Value", hurst_exponent[0]) #self.Plot("Entropy", "value", self.Entropy()) #self.Log(self.Entropy()) def HurstExponent(self): #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 prices = np.array([self.closingPrices]) Rn = np.cumsum(prices) S = np.std(prices) n = len(prices) epsilon = 1e-10 # small constant hursts = ((np.log(Rn/(S + epsilon))) / (np.log(n + epsilon))) - 0.5 return hursts def Entropy(self): base = 2 value,counts = np.unique(self.closingPrices, return_counts=True) probs = counts / np.sum(counts) return entropy(probs, base=base) def ShortFuture(self, data: Slice): for chain in data.FutureChains: # Get contracts expiring no earlier than in 90 days contracts = list(filter(lambda x: x.Expiry > self.Time + timedelta(90), chain.Value)) # if there is any contract, trade the front contract if len(contracts) == 0: continue self.ShortcontractSymbol = sorted(contracts, key = lambda x: x.Expiry, reverse=True)[0] #self.ShortcontractSymbol = front self.SetHoldings(self.ShortcontractSymbol.Symbol, -0.20, True) return def BuyFuture(self, data: Slice): for chain in data.FutureChains: # Get contracts expiring no earlier than in 90 days contracts = list(filter(lambda x: x.Expiry > self.Time + timedelta(90), chain.Value)) # if there is any contract, trade the front contract if len(contracts) == 0: continue self.LongcontractSymbol = sorted(contracts, key = lambda x: x.Expiry, reverse=True)[0] #self.LongcontractSymbol = front self.SetHoldings(self.LongcontractSymbol.Symbol, 0.20, True) return