How to Normalize Historical Data for Splits, Dividends, Etc.

December 6, 2006 · Filed Under Stock Market 

Note: Please read the disclaimer. The author is not providing professional investing advice or recommendations.

If you’re using historical data to perform backtesting of trading algorithms it is important that your data be transformed from actual to effective historical prices. Otherwise your algorithm may, for example, interpret a 2:1 stock split as a 50% overnight drop.

Luckily if you’re using Yahoo! Finance as your source for historical data they provide an easy way to account for such issues. Yahoo has a short write-up about this, though in my opinion it falls a bit short. Therefore I’ll provide an example here.

The process of normalizing the data is simply to take the ratio between the stock’s “Adj. Close” to “Close” and apply it to all prices – that is the raw High, Low, Open, and Close.

For example, consider the following output from Yahoo’s historical database:

Table 1
Prices
DateOpenHighLowCloseVolumeAdj
Close*
4-Dec-0630.4031.1230.2430.841,455,90030.84
1-Dec-0630.3630.9430.0030.361,503,70030.36
1-Dec-063:2 Stock Split
30-Nov-0645.5145.5644.9645.471,155,80030.31
29-Nov-0645.7046.5445.6146.511,381,60031.01
29-Nov-06$0.09 Dividend
28-Nov-0646.5046.5145.5445.603,001,50030.31

If for each entry of each row (besides volume) we multiply by the ratio of that row’s Adjusted Close to Close, we get the effective historical prices:

Table 2
Prices
DateOpenHighLowCloseVolumeAdj
Close*
4-Dec-0630.4031.1230.2430.841,455,90030.84
1-Dec-0630.3630.9430.0030.361,503,70030.36
30-Nov-0630.3430.3729.9730.311,155,80030.31
29-Nov-0630.4731.0330.4131.011,381,60031.01
28-Nov-0630.9130.9230.2730.313,001,50030.31

For example, we compute the effective Open of the 30-Nov-06 row by multiplying the original value, 45.51, by 30.31 / 45.47 resulting in 30.34.


Comments

8 Responses to “How to Normalize Historical Data for Splits, Dividends, Etc.”

  1. Ran on April 15th, 2009 8:16 am

    Hello,

    I wonder why you don’t adjust the volume as well.
    Looking at your example, on the 28-Nov-2006 volume was 3 Million share, at a share price that ranged 45.5 to 46.5 this means that ~137M$ were traded on this stock that given day.

    After the adjusting you loose this data, it seems like only 90 M$ were traded that day.

    Where am I wrong about this?
    Or should volume be adjusted as well ???

  2. Lumilog on April 15th, 2009 6:28 pm

    You are absolutely correct – never thought about that b/c so far I’ve never used volume in any of my trading simulations.

    I’ll update the script first chance I get and thanks much for pointing this out.

    - Lumi

  3. Missing_Link on July 4th, 2009 11:38 am

    With respect to Monthly and Weekly historicals, I am running into the issue of how to normalize them. Depending on the type of split and whether the open was higher or lower than the close (1:2 vs. 2:1, for example), if you simply adjust for the ratio of the Adjusted Close to the Close, the weekly/monthly high or low might not actually be the real high or low. I was trying to do this with AIG monthly/weekly data for my self-build stock app and discovered that the simple method applied to daily data didn’t work.

    Would it be, in your opinion, simpler to to simply adjust the daily data and as my app runs through the values to calculate the indicators/averages to aggregate the volumes and record monthly/weekly open/high/low/close from the adjusted daily data rather than coming up with some sort of scheme to adjust the data from Yahoo?

    Linkster

  4. Lumilog on July 9th, 2009 4:20 pm

    Hi Linkster,

    I think I see what you’re talking about. Yes it sounds like it would be best to make the adjustments first on your own using the daily data and then computing your own monthly / weekly highs and lows from that.

    One other thing – as pointed out by Ran in the other comment above – my script adjusts prices only, not volume. I don’t use volume but if you do you might want some additional split logic to adjust it as well.

    - lumi

  5. How to Download Historical Stock Data into Matlab( from: luminouslogic ) on July 23rd, 2009 1:49 am

    [...] doubles. Voila – you’re ready to develop your first simulation! Don’t forget to use the relationship between Adjusted Close and Close to first normalize your data – otherwise 2:1 splits could be [...]

  6. How to Import Stock Statistics into Matlab?luminouslogic? | WhooL ! on July 23rd, 2009 5:50 pm

    [...] posts have dealt with how to download historical stock prices into Matlab and how to adjust for splits and dividends so that you can try your luck optimizing neural networks and other homebrewed trading algorithms [...]

  7. Joe on November 24th, 2009 9:50 am

    Hi there,

    I have used your formula to normalise the data from yahoo for JPM and have used Excel to do this.

    However when I compare my JPM chart to the yahoo interactive chart, I find some discrepancies. For example, on 8/10/1998, my chart shows a low of $16.533, whereas on the yahoo interactive chart JPM does not even close below $25 in 1998.

    Do you know why this is?
    Thanks

  8. Lumilog on December 6th, 2009 1:11 pm

    Hi Joe,

    First off, I think one potential discrepancy is that the Yahoo Finance chart only adjusts for splits, whereas when you use “adjusted close” you’re normalizing for both splits and dividends.

    That being said, I have a Matlab script to do this automatically (click here to get it) and I don’t get values close to $16.533 either way.

    The raw Yahoo historical data (un-normalized) shows a range for the day of $67.75 to $69.31. The Yahoo Finance chart for that day shows $45.667. This is because they’re adjusting the average daily price of about $68.50 by 2/3 for the split that happened on June 12, 2000.

    When I run the Matlab script I get a high and low of $31.93 and $31.21 respectively, which is including the effects of splits and dividends since 8/10/98. Your number seems to be half that – so it’s almost like the normalization is happening twice in your code.

    - Lumi

Leave a Reply