Stock Price Adjustment Algorithm

Adjusted stocks data is invalidated whenever dividends and splits happen. Instead of pulling fully updated data each time, only storing unadjusted data and calculating adjustments on-demand is much easier.

The following is the author’s implementation in rust. Input is stock price data in reverse chronological order.

fn adjust(price_history: &Vec<StockPriceDaily>) -> Vec<StockPriceDaily> {
    let mut dividend_adjustment_rate = 1.0;
    let mut split_rate = 1.0;
    let mut price_history_new = price_history.clone();
    for price in &mut price_history_new {
        price.low = price.low * split_rate * dividend_adjustment_rate;
        price.high = price.high * split_rate * dividend_adjustment_rate;
        price.open = price.open * split_rate * dividend_adjustment_rate;
        price.close = price.close * split_rate * dividend_adjustment_rate;
        price.volume = ((price.volume as f32) * split_rate) as i64;
        if price.split_coefficient != 1.0 {
            split_rate = split_rate / price.split_coefficient;
        }
        if price.dividend_amount != 0.0 {
            // Not sure why the second one works - common sense is first one
            // let single_day_adjusted = close - dividend;
            // let adjustment = single_day_adjusted / close;
            let adjustment = price.close / (price.close + price.dividend_amount);
            dividend_adjustment_rate = dividend_adjustment_rate * adjustment;
        }
    }
    price_history_new
}