| 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 Tracking Error 0 Treynor Ratio 0 Total Fees $0.00 |
import random
from datetime import datetime, timedelta
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import statsmodels.formula.api as sm
class OvernightMomo(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2018, 1, 1)
self.SetEndDate(2018, 1, 30)
# cash and buffer
self.Settings.FreePortfolioValuePercentage = 0.1
self.SetCash(20000)
# Reality modelling
self.SetBrokerageModel(BrokerageName.AlphaStreams)
# Universe settings
self.Reso = Resolution.Daily
self.UniverseSettings.Resolution = self.Reso
self.SetUniverseSelection(FineFundamentalUniverseSelectionModel(self.CoarseSelectionFunction, self.FineSelectionFunction, None, None))
self.SetSecurityInitializer(lambda x: x.SetDataNormalizationMode(DataNormalizationMode.TotalReturn))
# check if its a new month (don't need to select by cap more than once a monty)
self.lastMonth = -1
# number of symbols in Fine universe
self.count = 10
# minimum market cap of companies
self.MinCap = 3e9
# array for symbols to trade
self.selected = []
# scheduling for trades
self.AddEquity("SPY", self.Reso)
self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.BeforeMarketClose("SPY", 20), self.HistLookup)
self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen("SPY", -20), self.ClosePositions)
def OnData(self, data):
pass
def OnSecuritiesChanged(self, changes):
# self.Debug("ADDED" + str([security.Symbol.Value for security in changes.AddedSecurities]))
# self.Debug("REMOVED" + str([security.Symbol.Value for security in changes.RemovedSecurities]))
pass
def CoarseSelectionFunction(self, coarse):
if self.Time.month == self.lastMonth:
return Universe.Unchanged
# sort descending by daily dollar volume
self.Log('Refreshing COARSE Universe >> ' + str(self.Time))
sortedByDollarVolume = sorted([x for x in coarse if x.HasFundamentalData and x.Volume > 0 and x.Price > 5],
key=lambda x: x.DollarVolume, reverse=True)[:1000]
# return the symbol objects of the top entries from our sorted collection
return [ x.Symbol for x in sortedByDollarVolume]
# sort the data by MarketCap and take the bottom 'NumberOfSymbolsFine'
def FineSelectionFunction(self, fine):
"""
sortedByMktCap = sorted([x for x in fine if x.MarketCap > self.MinCap],
key=lambda x: x.MarketCap, reverse=False)[:self.count]
count = len(sortedByMktCap)
if count == 0:
return Universe.Unchanged
# update if all checks passed
self.lastMonth = self.Time.month
# this is a list of symbol objects
selected_symbols = [ x.Symbol for x in sortedByMktCap ]
# convert universe to DF (https://www.quantconnect.com/forum/discussion/2644/how-do-i-get-a-percentile-of-dollarvolume-universe/p1)
intercepts = []
for symbol in selected_symbols:
# make history call for past 12 months of daily prices
hist = self.History(symbol, 253, Resolution.Daily)
# need thorough history check is performing regression correctly
# Warning: when performing history requests, the start date will be adjusted if it is before the first known date for the symbol.
# think something to do with this
# Check history returns correct number of datapoints, then do regression
if len(hist) == 253:
self.Log(hist)
# Define overnight returns: r_o = ln(open_t / close_t-1)
hist['r_o'] = pd.Series(np.log(hist['open']/hist['close'].shift(1)))
# Define total returns: r = ln(close / close_t-1)
hist['r_t'] = pd.Series(np.log(hist['close']/hist['open']))
# regression of overnight on total
model = sm.ols(formula = 'r_o~r_t',data = hist).fit()
# append intercept param to intercepts list
intercepts.append(model.params[0])
# Make dataframe
data_df = pd.DataFrame(list(zip(selected_symbols,intercepts)), columns = ['symbol','intercepts'])
self.Log(data_df)
# Get quantiles
lower_percent = data_df.intercepts.quantile(.9)
upper_percent = data_df.intercepts.quantile(1.0)
self.selected = (data_df.
query('(intercepts >= @lower_percent) & (intercepts <= @upper_percent)'))
"""
return self.selected
def HistLookup(self):
for symbol in self.selected:
quantity = self.CalculateOrderQuantity(symbol, 1/len(self.selected))
marketCloseOrderTicket = self.MarketOnCloseOrder(symbol,quantity)
self.Debug(f"{self.Time} {str([symbol.Value for symbol in self.selected])} will be bot and held overnight")
def ClosePositions(self):
self.Liquidate()