#include "CandleDataProvider.h" #include "CandleCache.h" CandleDataProvider::CandleDataProvider(std::string const &symbol, bool intraday) : _candleDataNode(CandleDataNode::find(symbol, intraday)), _symbol(symbol) { } void CandleDataProvider::getTimes(GridDataProviderContext *context, int offset, time_t &start, time_t &end) const { context->getPrototype()->getCandleTimer() ->getTimes(context->getCalculationRowPossible(offset), start, end); } SingleCandle CandleDataProvider::getCandle(GridDataProviderContext *context, int offset) const { const int possibleRow = context->getCalculationRowPossible(offset); bool inCache; SingleCandle result; CandleCache::get(this, possibleRow, inCache, result); if (inCache) return result; time_t start; time_t end; context->getPrototype()->getCandleTimer()->getTimes(possibleRow, start, end); return _candleDataNode->threadSafeGet(start, end); } time_t CandleDataProvider::restartAt(EpochCounter::Epoch epoch) const { return _candleDataNode->threadSafeRestartAt(epoch); } bool CandleDataProvider::getValid(GridDataProviderContext *context) const { SingleCandle candle = getCandle(context, 0); return !candle.empty(); } double CandleDataProvider::getValue(std::string const &dataType, GridDataProviderContext *context, int offset, std::string &errorMsg) const { errorMsg.clear(); if (dataType == "possible row") return context->getCalculationRowPossible(offset); else if (dataType == "packed row") return context->getCalculationRowPacked() - offset; else if (dataType == "start") { time_t start; time_t end; getTimes(context, offset, start, end); return start; } else if (dataType == "end") { time_t start; time_t end; getTimes(context, offset, start, end); return end; } else if (dataType == "high") { SingleCandle candle = getCandle(context, offset); if (candle.empty()) return GridInstance::invalid(); else return candle.high; } else if (dataType == "low") { SingleCandle candle = getCandle(context, offset); if (candle.empty()) return GridInstance::invalid(); else return candle.low; } else if (dataType == "open") { SingleCandle candle = getCandle(context, offset); if (candle.empty()) return GridInstance::invalid(); else return candle.open; } else if (dataType == "close") { SingleCandle candle = getCandle(context, offset); if (candle.empty()) return GridInstance::invalid(); else return candle.close; } else if (dataType == "volume") { SingleCandle candle = getCandle(context, offset); if (candle.empty()) return GridInstance::invalid(); else return candle.volume; } else { errorMsg = "Unknown data type \"" + dataType + '"'; return GridInstance::invalid(); } } void CandleDataProvider::preloadToEnd(GridDataProviderContext *context) const { assert(!CandleCache::active()); CandleCache::Requests requests; AllRowTimes allRowTimes; CandleCache::getAllRows(context, requests, allRowTimes); SingleCandle::ByStartTime data; _candleDataNode->threadSafeGet(allRowTimes, data); CandleCache::start(requests, data, this); } void CandleDataProvider::releasePreload() const { assert(CandleCache::active()); CandleCache::release(this); } std::string CandleDataProvider::debugDump() const { return _symbol; } std::string CandleDataProvider::getSymbol() const { return _symbol; } CandleDataProvider::~CandleDataProvider() { _candleDataNode->decrementReferenceCount(); CandleCache::release(this); }