# https://quantpedia.com/Screener/Details/162
from QuantConnect.Data.UniverseSelection import *
import math
import numpy as np
import pandas as pd
import scipy as sp
from datetime import timedelta
class MomentumInSmallPortfolio(QCAlgorithm):
def Initialize(self):
self.Log("Initialize - Begin")
self.SetStartDate(2008, 1, 1)
self.SetEndDate(2019, 5, 24)
self.SetCash(1000000)
self.UniverseSettings.Resolution = Resolution.Daily
self.AddUniverse(self.CoarseSelectionFunction, self.FineSelectionFunction)
self.AddEquity("SPY", Resolution.Daily)
self.Schedule.On(self.DateRules.MonthStart("SPY"), self.TimeRules.AfterMarketOpen("SPY"), self.rebalance)
# Count the number of months that have passed since the algorithm starts
self.months = -1
self.yearly_rebalance = True
self.long = None
self.short = None
self.Log("Initialize - End")
def CoarseSelectionFunction(self, coarse):
if self.yearly_rebalance:
# drop stocks which have no fundamental data or have low price
self.filtered_coarse = [x.Symbol for x in coarse if (x.HasFundamentalData)]
return self.filtered_coarse
else:
return []
def FineSelectionFunction(self, fine):
if self.yearly_rebalance:
# Calculate the yearly return and market cap
for i in fine:
i.MarketCap = float(i.EarningReports.BasicAverageShares.ThreeMonths * (i.EarningReports.BasicEPS.TwelveMonths*i.ValuationRatios.PERatio))
top_market_cap = sorted(fine, key = lambda x:x.MarketCap, reverse=True)[:int(len(fine)*0.75)]
has_return = []
for i in top_market_cap:
history = self.History([i.Symbol], timedelta(days=365), Resolution.Daily)
if not history.empty:
close = history.loc[str(i.Symbol)]['close']
i.returns = (close[0]-close[-1])/close[-1]
has_return.append(i)
sorted_by_return = sorted(has_return, key = lambda x: x.returns)
self.long = [i.Symbol for i in sorted_by_return[-10:]]
self.short = [i.Symbol for i in sorted_by_return[:10]]
return self.long+self.short
else:
return []
def rebalance(self):
# yearly rebalance
self.months += 1
if self.months%12 == 0:
self.yearly_rebalance = True
def OnData(self, data):
if not self.yearly_rebalance: return
if self.long and self.short:
stocks_invested = [x.Key for x in self.Portfolio if x.Value.Invested]
# liquidate stocks not in the trading list
for i in stocks_invested:
if i not in self.long+self.short:
self.Liquidate(i)
for i in self.short:
self.SetHoldings(i, -0.5/len(self.short))
for i in self.long:
self.SetHoldings(i, 0.5/len(self.long))
self.long = None
self.short = None
self.yearly_rebalance = False
I'm trying to clone this code from Tutorial and Back Test; didn't seem to even start. I put 2 Logs in the Initialize and none of them are executed. Is it because some of the libraries are black listed?
https://www.quantconnect.com/tutorials/strategy-library/momentum-effect-in-stocks-in-small-portfolios
Julian Lim
This code actually works but the problem is very processing intensive and might be running out of memory and such. Take 75% fo universe of the stocks that has fundalmental then build the history of 365 days.
Link Liang
Hi Julian,
The purpose of our tutorial is to show how to implement a certain strategy. For this specific one, you are 100% correct that this algorithm requests a lot of data and would run very slowly. However, you might find some useful aspects in there for your own algorithm. For example, coarse-fine universe selection, scheduled event, usage of fundamental data, request historical data. Hope you feel more familiar with our APIs after working with this tutorial.
Julian Lim
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.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!