The issue is with the
zscore method. It doesn't like trying to zscore with a population of only a single value. A zscore represents the number of standard deviations a particular value is from the mean of a population of values. That population size needs to be at least two and, realistically, much larger than that. The method doesn't know how to calculate a value when the population size is one and therefore returns nan. It's because the zscore is nan that your algo never trades. The pieces of code below are some of the culprits
STOCK_TO_TEST = symbols('AAPL')
universe = StaticAssets(STOCK_TO_TEST)
bull_scored_messages_10 = SimpleMovingAverage(
bull_over_combined_10 = bull_scored_messages_10 / (bull_scored_messages_10 + bear_scored_messages_10)
factor_10 = bull_over_combined_10.zscore() + bullish_intensity_10.zscore()
The key is to set up a zscore mask which defines what population, or universe, of stocks one wants to rank against. It needs to have at least two stocks and include all the stocks which one wants to calculate a score for. It's algo specific which universe to use but typically the Q500US to rank against big well known stocks or the QTradableStocksUS if one wants to compare to the broader market. By using the
groupby parameter one can also just zscore against other stocks in the same group, typically sector. One can later screen or mask by just the stocks one wants to trade.
It's very important to set a defined universe and mask. Without one, the zscore will score against all stocks in the Quantopian database. This incudes ETFs, leveraged ETFs, ADRs, and some penny stocks. Probably not the population one generally wants to rank against. The filter can either be explicitly set as a zscore mask or implied by the factor.
One other requirement of the
zscore method is no factor values can be infinite (either positive or negative). Infinite values don't play well when calculating means and standard deviations. It's good practice to always include in the mask a
isfinite() filter to prevent this. Nan values are fine (they are ignored) but the
isfinite() filter actually filters those too just for good measure.
I made a few changes to your algo and it places trades.
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 Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian 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.