Overall Statistics |
Total Trades 48 Average Win 3.82% Average Loss -2.30% Compounding Annual Return 85.107% Drawdown 17.200% Expectancy 0.663 Net Profit 85.016% Sharpe Ratio 2.083 Probabilistic Sharpe Ratio 77.214% Loss Rate 38% Win Rate 62% Profit-Loss Ratio 1.66 Alpha 0.193 Beta 2.028 Annual Standard Deviation 0.286 Annual Variance 0.082 Information Ratio 1.856 Tracking Error 0.214 Treynor Ratio 0.293 Total Fees $292.40 Estimated Strategy Capacity $200000000.00 Lowest Capacity Asset ES XZDYPWUWC7I9 Portfolio Turnover 54.05% |
# 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] if self.HurstExponent() > 0.5 and self.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 self.HurstExponent() < 0.5 and self.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", self.HurstExponent()) 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) hursts = ((np.log(Rn/S)) / np.log(prices)) - 0.5 return hursts[-1][-1] def Entropy(self): base = 2 value,counts = np.unique(self.closingPrices, return_counts=True) return entropy(counts, 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