Back

Momentum strategy

Hi all, I am new to QuantConnect and I am currently coding up a momentum strategy (Andreas Clenow). 

1) Base screen of the top 500 companies based on trading volume

2) Secondary screen to calculate the screened securities' their regression coefficient multiplied by R squared values. I then store these values in a dictionary for sorting to obtain the top 10 securities with the highest scores 

3) Equal weighting portfolio with monthly rebalancement - Liquidate positions if stock is no longer in the long list. 

Based on all of this, I still am unable to get my backtest to run as I run into the following error

Runtime Error: Value cannot be null.
Parameter name: source

I am not sure where I went wrong so any help is appreciated! Thank you.  

Update Backtest







0

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


import pandas as pd
import numpy as np
from datetime import datetime, timedelta
from QuantConnect.Data.UniverseSelection import *
from scipy.stats import linregress

class SystematicMomentum(QCAlgorithm):

def Initialize(self):
self.num_coarse = 500
self.num_fine = 10
self.SetStartDate(2018, 1, 1) # Set Start Date
self.SetCash(10000) # Set Strategy Cash
# set the flag for rebalance
self.reb = 1
self.AddUniverse(self.CoarseSelectionFunction,self.FineSelectionFunction)
self.spy = self.AddEquity("SPY", Resolution.Daily).Symbol
self.Schedule.On(self.DateRules.MonthStart(self.spy),
self.TimeRules.AfterMarketOpen(self.spy,5), Action(self.rebalance))

def CoarseSelectionFunction(self, coarse):
# if the rebalance flag is not 1, return null list to save time.
if self.reb != 1:
return self.long

# make universe selection once a month
sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True)
filtered = [x.Symbol for x in sortedByDollarVolume if x.HasFundamentalData]

# filtered down to the 500 most liquid stocks
return filtered[:self.num_coarse]

def FineSelectionFunction(self, fine):
# return null list if it's not time to rebalance
if self.reb != 1:
return self.long

# drop counter (will update back to 1 after rebalancement has occurred)
self.reb = 0

# create dictionaries to store the indicator values

stock_filter1 = {}

# sort the fine list by their momentum
for security in fine:

hist = self.History(security.Symbol, timedelta(days=365), Resolution.Daily)
hist["log"] = np.log(hist["close"])
x1 = np.arange(hist["close"].count())
slope, _, rvalue, _, _ = linregress(x1, hist["log"])
coeff = slope*252*(rvalue**2)

# we now have a dictionary storing the values
stock_filter1[security.Symbol] = coeff

# we only want the highest values for the coeff
self.sorted1 = sorted(stock_filter1.items(), key=lambda d:d[1],reverse=True)
sorted1_symbol = [x[0] for x in self.sorted1]


# long the top 10
self.long = sorted1_symbol[:self.num_fine]

def OnData(self, data):
pass

def rebalance(self):
# at the start of rebalancement, if the stock is no longer in the long list, liquidate
long_list = self.long
for i in self.Portfolio.Values:
if (i.Invested) and (i not in long_list):
self.Liquidate(i.Symbol)

# Assign each stock equally. Alternatively you can design your own portfolio construction method
for i in self.long:
self.SetHoldings(i, 0.9/self.num_fine)

self.reb = 1

 

0

I have fixed the above error and managed to get the backtest to run. However, 2 months into the backtest, I ran into an error - Can someone please explain to me the meaning of this error and a way to rectify it. Thank you!

 

Runtime Error: Trying to retrieve an element from a collection using a key that does not exist in that collection throws a KeyError exception. To prevent the exception, ensure that the close key exist in the collection and/or that collection is not empty.
at FineSelectionFunction in main.py:line 56
:: hist["log"] = np.log(hist["close"])
KeyError : 'close'
 
 
0

Hi Ethan,

This usually means that the hist is empty. This likely occurred because there was no data for the given security, and to prevent this from happening, try adding if len(hist) > 0: as a conditional before any calculations.

Furthermore, please try to move all the logic for calculations and buying/selling of securities to the OnSecuritiesChanged method.

Best Regards,
Shile Wen

0

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Update Backtest





0

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Loading...

This discussion is closed