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