I'm trying to make a simple equity screener that keeps stocks that cost < $10 from 5 days ago so I can eventually build more complicated screeners based on history data. When I run the code below over a 10 day backtest, it doesn't finish after 10 minutes, so I stopped it. Any recommendations on quicklly screening the full equity database?
from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Indicators")
AddReference("QuantConnect.Common")
from System import *
from QuantConnect import *
from QuantConnect.Data import *
from QuantConnect.Algorithm import *
from QuantConnect.Indicators import *
from System.Collections.Generic import List
import decimal as d
### <summary>
### In this algorithm we demonstrate how to perform some technical analysis as
### part of your coarse fundamental universe selection
### </summary>
### <meta name="tag" content="using data" />
### <meta name="tag" content="indicators" />
### <meta name="tag" content="universes" />
### <meta name="tag" content="coarse universes" />
class TestAlgorithm(QCAlgorithm):
def Initialize(self):
'''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''
self.SetStartDate(2010,01,01) #Set Start Date
self.SetEndDate(2010,01,10) #Set End Date
self.SetCash(100000) #Set Strategy Cash
self.UniverseSettings.Resolution = Resolution.Daily
self.AddUniverse(self.CoarseSelectionFunction)
def CoarseSelectionFunction(self, coarse):
'''select for all U.S. stocks where share price from 5 days ago was < $10'''
matchingSymbols = []
for cf in coarse:
self.AddSecurity(SecurityType.Equity, cf.Symbol.Value)
hist = self.History(cf.Symbol.Value,5,Resolution.Daily)
if hist['close'][0] <10:
matchingSymbols.append(cf.Symbol)
return matchingSymbols
# this event fires whenever we have changes to our universe
def OnSecuritiesChanged(self, changes):
# liquidate removed securities
for security in changes.RemovedSecurities:
if security.Invested:
self.Liquidate(security.Symbol)
for security in changes.AddedSecurities:
self.SetHoldings(security.Symbol, 0.1)
Jared Broad
You don't need to / can't add the securities like that in coarse selection (no idea what it'll do!). The security price is included in the coarse fundamental object: See Price.
If you want the price from 5 days ago you should cache the days in a rolling window; Alexandre Catarino should be able to help with that =)
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.
Alexandre Catarino
The EmaCrossUniverseSelectionAlgorithm is the best example for universe selection algorithms that rely on one or more indicators. The "trick" is in the definition of the class that will cache the information:
class SymbolData(object): def __init__(self, symbol): self.symbol = symbol self.history = RollingWindow[float](5) self.screen1 = False def update(self, value): self.history.Add(float(value)) if self.history.IsReady: self.screen1 = self.history[4] < 10
Then you need to store the instances of SymbolData object in a dictionay and use it in the universe selector function:
# In Initialize self.averages = { } def CoarseSelectionFunction(self, coarse): '''select for all U.S. stocks where share price from 5 days ago was < $10''' matchingSymbols = [] for cf in coarse: if cf.Symbol not in self.averages: self.averages[cf.Symbol] = SymbolData(cf.Symbol) # Updates the SymbolData object with current EOD price avg = self.averages[cf.Symbol] avg.update(cf.Price) if avg.screen1: matchingSymbols.append(cf.Symbol) return matchingSymbols
In your algorithm, you will need to define another metric to rank and select the securities, since a lot of them are trading below $10.
Morgan Liu
Thanks, Jared and Alexandre.
Morgan Liu
Is there a way to use open, high and low price from previous days? I see it used in some indicators, so I assume that I could learn C# and create a custom indicator if there's not a faster way.
Morgan Liu
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!