Back to Community
Stocks missing split adjustment

Hi everyone,

Is there a way to avoid stocks with no split adjustment ?

Regards

Clone Algorithm
0
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 56c74237fe4e420dee74470e
There was a runtime error.
21 responses

Here is another stock.

Clone Algorithm
0
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 56c745078db9080dea197402
There was a runtime error.

Any help would be appreciated. Thanks!

Hi Youness,

While there's no fool-proof way to guard against bad data in your algo, you can implement some sort of guard against drastic jumps such that if the price today is much higher than the price yesterday, you assume that the data is bad and avoid trading the stock. It would look something like this:

hist = history(2, '1d', 'price')  
for stock in data:  
    change_ratio = hist[stock][1] / hist[stock[0]]  
    if change_ratio > 2 or change_ratio < 0.5:  
        # Don't trade this stock  
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.

Normally what you should do is to run an algo in search of such anomalies and correct them. Rather than brushing them under the carpet to trip up the next sucker!

Hi Anthony,

We actually do have an algo to look for these extreme anomalies. The bottleneck is in patching the data. It's not a trivial fix so it can take some time. From your comment, I realized that I forgot to mention here that I had a conversation privately with Youness mentioning that our engineers have been notified of the errors. We are also working on augmenting our communication with our data providers so we can try reduce the frequency at which these errors occur. Rest assured, we aren't just brushing these aside!

Hi Jamie

With your solution, one can prevent trading the name but what to do if the stock is already in the portfolio? The sudden jump in the portfolio value prevents any analysis of the backtest results. Any ideas?

Thanks
Shiv

Hello Jamie,

Regarding your comment, "We actually do have an algo to look for these extreme anomalies" it would be interesting to understand how you are doing the search. As I understand, you have several data sources. One is the historical OHLCV minutely data base, from vendor X (I don't believe you've revealed the source). And then you have the live data feed, from Nanex Nxcore. There is also the Morningstar fundamentals database. So, how are you using these data sources to check for errors and consistency?

One thought is that you would compare historical prices with live ones. As I understand, the live data are derived directly from a real-time stream of trade data. So, for stocks that have not been de-listed, the live OHLCV minute bars should match the historical bars. If there was an error in correcting the historical data, then there would be a mis-match with live data, correct?

See also https://www.quantopian.com/posts/data-sources-backtesting-vs-live-trading. Please respond there, as well, since it is not yet clear under live trading which data source (historical versus Nanex) applies at what time. Since it sounds like splits are sometimes missed in the historical data, then it should be understood how these errors would enter into live trading.

To Anthony's point, if you have a list of securities with suspected problems, shouldn't you make that list available to users? Perhaps you could create a list (e.g. security_lists.data_error)?

Grant

Jamie, I was really referring to my own problems and did not intend to cast stones. I use EOD data from CSI who also sell to Yahoo on US stocks. All to often mistakes creep in and I report them to CSI as I notice them. I just noticed one on a CSU provided bond mutual fund for instance which makes the Markowitz optimisation I am using hiccup, burp and then throw an error. I have taken to chucking such counters out if I can't get them fixed but the real problem is to notice them in the first place.

I keep meaning to run an algo searching daily for likely anamolies in the portfolio before running my daily output. Easily done and then righted but quite a daily hassle.

By the way on another stock I have found such a jump completely messes up an optimiser / Markowitz scheme......perhaps I need to use a different algo

@Jamie - Can you please share the code so that we may utilize it in our algos?

It seems I had a typo in my last response. I was actually referring to an internal script (not an algo) that compares our pricing data (which should also cover corp. actions) to other data sources that are not available in Q.

@Daniel: The code snippet that I posted above is probably your best bet for now.

ugaz has another split (1:25) on Mar14/16 and three of my paper trade algo's I am testing have gone into -XXXX% losses now - I understand it might take time for the prior pricing data to be adjusted in backtests, but why is it not corrected in trade algo's directly? What about algo's in the contest - must effect them also.

This problem is more prevalent that I thought. I pick 20 large stocks ($10b+) and run some simple algo for the last 4 years. 4 out of 20 stocks missed the splits. See below. The concern is that missing split is the norm, not the exception. The other 16 stocks do not seem to have any splits. Plus, these are major stocks, if their splits are missing, how can I trust other less well-known stocks? This is quite concerning....

TimeStamp, Symbol, Price Ratio, Previous, Current
2013-04-22 07:30 my_rebalance:237 ERROR price jump!!! CRM, 4.18553381224, 168.9 , 40.37
2013-06-03 07:30 my_rebalance:237 ERROR price jump!!! NBL, 2.05337895637, 120.02, 58.45
2015-07-20 07:30 my_rebalance:237 ERROR price jump!!! NFLX, 6.35405919088 , 702.06, 110.49
2015-12-14 07:30 my_rebalance:237 ERROR price jump!!! EW, 2.01702766996, 161.1, 79.87

Hi Kevin,

Pricing data on Quantopian is point-in-time split adjusted. In a backtest, that means prices are split adjusted as of the current simulation date. When you ask for a trailing window of pricing data on a particular day, it will be adjusted for all the splits and dividends that were known on that day. Of course, if you hold an equity that undergoes a split or a reverse split, the price of the equity will change, but your position will also change by the appropriate ratio.

I've attached a backtest that demonstrates this behavior. As an example, look at the daily positions and gains between 7/14/2015 and 7/15/2015. The NFLX position jumps 7x while the price drops roughly 7x.

I can't say for sure without seeing the code you used, but it looks like you might be storing the 'current' price of an equity and printing it on consecutive days. Split adjustments are applied to historical windows, so storing pricing data from day to day is strongly discouraged.

Clone Algorithm
4
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 5919b4ba7febf2621bb72c06
There was a runtime error.

Hi Jamie,

That is great. Sorry for the false alarm :)

I do want to do something regarding the price change of a stock, could be as simple as if it does down 10% buys some more. Given the price could have a big drop after the split, what is the recommended way to do that?

Also, what if I just want to plot the price graph? Other sites plot the graph continuously and how can I do the same?

Hi Kevin,

If you want to look at the price change of a stock, you can perform a historical lookback using Pipeline or data.history. Any data you get from one of these calls should be split adjusted, so you should get a continuous price series that you can analyze for a 10% dip.

If you want to plot a price series, you should use Research. You can use get_pricing to get the pricing data of a stock. Any data you get using get_pricing will split adjusted as of the end_date of the data request.

I'd recommend checking out the Introduction to Research lecture to get a better sense of how research works.

Cool, thanks Jamie!

For plotting the price chart, I need to do it in the backtest along with the performance number/time axis, and other attributes like position size, to visually inspect the algo is working as expected.

The reason is I have some trading mechanism reacting to price change. It is not straightforward nor trivial to verify my code is correct. I have pretty extensive logging, but to analyzing the log is not easier either, not to mention the limitation on the logging. The best way is to plot the price, and position size of the stock along the chart to visually spot any irregularity.

Think about when I put this in live trade, I need to plot this on an ongoing basis. I can't use get_pricing in Research.

Instead of plotting the price, could you plot the price difference? That way you could look for (-10%) to identify a trade signal.

I thought about it more. For what I am trying to do, trading based on price fluctuation on the on-going basis(live trading, not just backtesting), I have to build my own split detection, just like in the real life. Of course, it would be nicer if quantopian provide a separate api call for me to subscribe to split notification. Can this be a feature enhancement request?

Jamie, by "price difference", do you mean there is an api for it? Otherwise, for the live trading scenario, I will still run into the splitting issue.
Edit:
I think I can use data.history for calculating the difference. But I am using weekly rebalance, what would be an elegant way to ask "give me the price difference from last week to this week for NFLX"?

Hi Kevin,

Any call to data.history will give you back a continuous price series. The series will be adjusted for all splits known at the given simulation time which is what makes it continuous. The best way to get the price difference from last week to this week for NFLX is like this:

hist = data.history(symbol('NFLX'), 'price', 6, '1d')  
diff = hist[-1] - hist[0]  
pct_diff = (hist[-1] - hist[0]) / hist[0]  

I would strongly recommend going through the Getting Started Tutorial and the Pipeline Tutorial to see how this can be generalized to other symbols and other requests.

Just a heads up. XLF seems to be missing a split adjustment, too.

Clone Algorithm
1
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 59f46c2417c34f428a68bf87
There was a runtime error.