#ifndef __SplitList_h_ #define __SplitList_h_ #include #include "../shared/MiscSupport.h" #include "../shared/DatabaseForThread.h" #include "../shared/MiscSQL.h" #include "SingleCandle.h" class SplitList : NoCopy, NoAssign { private: std::map< time_t, double > _splits; public: SplitList(std::string const &symbol) { const std::string sql = "SELECT date, old_shares, new_shares FROM splits WHERE symbol=\"" + mysqlEscapeString(symbol) + "\" ORDER BY date"; for (MysqlResultRef result = DatabaseForThread(DatabaseWithRetry::CANDLES) ->tryQueryUntilSuccess(sql, "SplitList"); result->rowIsValid(); result->nextRow()) { const time_t date = mysqlToTimeT(result->getStringField("date")); const double ratio = result->getDoubleField("old_shares", 0.0) / result->getDoubleField("new_shares", 0.0); _splits[date] = ratio; } double ratioSoFar = 1.0; for (auto it = _splits.rbegin(); it != _splits.rend(); it++) { double &ratio = it->second; ratio *= ratioSoFar; ratioSoFar = ratio; } } // Multiply the open, high, low, and close that you read from the database // by this ratio to get the current values. Divide the volume from the // database by this ratio to get the current values. double getRatio(time_t time) const { const auto it = _splits.upper_bound(time); if (it == _splits.end()) return 1.0; else return it->second; } void fixCandle(time_t time, SingleCandle &candle) const { const double ratio = getRatio(time); candle.open *= ratio; candle.high *= ratio; candle.low *= ratio; candle.close *= ratio; candle.volume = (int64_t)round(candle.volume / ratio); } }; #endif