Overall Statistics |
Total Trades 2840 Average Win 0.50% Average Loss -0.49% Compounding Annual Return 5.073% Drawdown 18.700% Expectancy 0.046 Net Profit 32.316% Sharpe Ratio 0.488 Probabilistic Sharpe Ratio 10.517% Loss Rate 48% Win Rate 52% Profit-Loss Ratio 1.02 Alpha 0.069 Beta -0.076 Annual Standard Deviation 0.119 Annual Variance 0.014 Information Ratio -0.346 Tracking Error 0.232 Treynor Ratio -0.77 Total Fees $73567.16 |
from sklearn.linear_model import LinearRegression import numpy as np import pandas as pd class QuantumOptimizedContainmentField(QCAlgorithm): def Initialize(self): self.SetStartDate(2015, 1, 1) self.SetCash(1000000) self.symbol = self.AddEquity("SPY", Resolution.Minute).Symbol lookback = 10*5+1 # 10 weeks of training data self.history = self.History(self.symbol, lookback, Resolution.Daily) # Rollback history timestamp by 1 day to match consolidation timestamps if self.history.shape[0] > 0: self.history = self.history.unstack(level=0) self.history = self.history.set_index(self.history.index.map(lambda x: x - timedelta(days=1))).stack().swaplevel() self.history = self.history.loc[self.symbol] self.history['gap'] = (self.history['open'] - self.history['close'].shift(1)) / self.history['close'].shift(1) self.history['intraday_return'] = (self.history['close'] - self.history['open']) / self.history['close'] self.history = self.history[['intraday_return', 'gap', 'close']].iloc[1:] self.history['weekday'] = self.history.index.map(datetime.weekday) self.consolidator = TradeBarConsolidator(timedelta(days=1)) self.consolidator.DataConsolidated += self.CustomHandler self.SubscriptionManager.AddConsolidator(self.symbol, self.consolidator) self.Schedule.On(self.DateRules.EveryDay(self.symbol), self.TimeRules.AfterMarketOpen(self.symbol, 1), self.Open) self.Schedule.On(self.DateRules.EveryDay(self.symbol), self.TimeRules.BeforeMarketClose(self.symbol, 1), self.Close) def CustomHandler(self, sender, consolidated): intraday_return = (consolidated.Close - consolidated.Open) / consolidated.Open gap = (consolidated.Open - self.history.iloc[-1]['close']) / self.history.iloc[-1]['close'] row = pd.DataFrame({'intraday_return': intraday_return, 'gap': gap, 'close' : consolidated.Close, 'weekday' : consolidated.Time.weekday()}, index=[consolidated.Time]) self.history = self.history.append(row).iloc[1:] def Open(self): weekday = self.Time.weekday() historical_performance = self.history[self.history.weekday == weekday] lm = LinearRegression() model = lm.fit(historical_performance[['intraday_return']], historical_performance.gap) alpha_direction = np.sign(model.coef_) gap_direction = np.sign(self.Securities[self.symbol].Open - self.history.iloc[-1].close) trade_direction = alpha_direction * gap_direction self.SetHoldings(self.symbol, -trade_direction) def Close(self): self.Liquidate()