Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
data[context.security].stddev(30)

So whenever I try to compute the above value, the first instance always seems to be of type "NoneType". Therefore, any algorithm I write that tries to use this value, but doesn't explicitly check whether or not the above results in "NoneType", will end in:

TypeError: unsupported operand type(s) for -: 'float' and 'NoneType'

Why is it that "data[context.security].stddev(30)" has this behavior? This happens, by the way, regardless of the input (here it is 30).

4 responses

Mathematically, there is no standard deviation when there is only one data point. When you run it on one data point, you get nothing. It's outlined in the help, but we didn't give a great way to work around it.

You found one solution, which is to simply test for it and discard it.

The other thing you could do is use history() in a 30-day window. history() will pre-load the previous 30 days, no matter when the test itself starts. You can use a pandas function to compute the standard dev on the resulting 30-day dataframe. That means you'll never have a problem where you only have one data point in your calculation.

Disclaimer

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.

Thanks Dan! I didn't realize that you had to call the history() function to pre-load the previous 30-days worth of data. I assumed that we were working with all available data for a particular stock all the time, and that the dates on the backtest just determined the day on which handle_data starts.

In some of the early work developing the backtester, I don't think we appreciated how helpful and important it is to pre-load data. We started with a mindset of "start the algorithm, let it warm up, then use it." Customer feedback taught us we were better off instead with "pre-load the data, start the algorithm, use it." The simple transforms (older feature) don't support pre-loading data, but history() does. Over time we'll replace everything with pre-loaded versions.

The good news is that by the time we built live trading, we were in front of the problem. When you run a live trading algorithm, it pre-warms itself so that it hits the first trading day fully loaded.

For instance - if you deploy a live algorithm today (4-Feb-14) and it includes a mavg(30) in it, we actually warm up the algo with data from December and January so when it starts today, the window is fully loaded.

So, the problem that Jonathan noted at the beginning of this thread happens in backtesting but not live trading. It's just unnecessarily confusing in the current form, and we'll fix that in the long run.