| 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()