bool Stock:: _getIndexRangeByIndex(const KQuery& query, size_t& out_start, size_t& out_end) const { assert(query.queryType() == KQuery::INDEX); out_start = 0; out_end = 0; size_t total = getCount(query.kType()); if (0 == total) { return false; } hku_int64 startix, endix; startix = query.start(); if(startix < 0) { startix += total; if(startix < 0) startix = 0; } endix = query.end(); if(endix < 0) { endix += total; if(endix < 0) endix = 0; } size_t null_size_t = Null<size_t>(); size_t startpos = 0; size_t endpos = null_size_t; try { startpos = boost::numeric_cast<size_t>(startix); } catch(...) { startpos = null_size_t; } try { endpos = boost::numeric_cast<size_t>(endix); } catch (...) { endpos = null_size_t; } if(endpos > total) { endpos = total; } if(startpos >= endpos) { return false; } out_start = startpos; out_end = endpos; return true; }
DatetimeList Stock::getDatetimeList(const KQuery& query) const { DatetimeList result; size_t start = 0, end = 0; if (getIndexRange(query, start, end)) { result = getDatetimeList(start, end, query.kType()); } return result; }
DatetimeList StockManager:: getTradingCalendar(const KQuery& query, const string& market) { Stock stock = getStock("SH000001"); size_t start_ix = 0, end_ix = 0; DatetimeList result; if (stock.getIndexRange(query, start_ix, end_ix)) { result = stock.getDatetimeList(start_ix, end_ix, query.kType()); } return result; }
bool Stock::getIndexRange(const KQuery& query, size_t& out_start, size_t& out_end) const{ out_start = 0; out_end = 0; if (!m_data || !m_kdataDriver) return false; if (KQuery::INDEX == query.queryType()) return _getIndexRangeByIndex(query, out_start, out_end); if ((KQuery::DATE != query.queryType()) || (query.kType() >= KQuery::INVALID_KTYPE) || query.startDatetime() >= query.endDatetime()) return false; if (m_data->pKData[query.kType()]) { return _getIndexRangeByDateFromBuffer(query, out_start, out_end); } if (!m_kdataDriver->getIndexRangeByDate(m_data->m_market, m_data->m_code, query, out_start, out_end)) { out_start = 0; out_end = 0; return false; } return true; }
bool Stock:: _getIndexRangeByDateFromBuffer(const KQuery& query, size_t& out_start, size_t& out_end) const { out_start = 0; out_end = 0; //总数为0,视为失败 size_t total = getCount(query.kType()); if( 0 == total ){ return false; } KRecordList& kdata = *(m_data->pKData[query.kType()]); size_t mid, low = 0, high = total - 1; size_t startpos, endpos; while(low <= high) { if(query.startDatetime() > kdata[high].datetime) { mid = high + 1; break; } if(kdata[low].datetime >= query.startDatetime()) { mid = low; break; } mid = (low + high) / 2; if(query.startDatetime() > kdata[mid].datetime) { low = mid + 1; } else { high = mid - 1; } } if(mid >= total) { return false; } startpos = mid; low = mid; high = total - 1; while(low <= high) { if(query.endDatetime() > kdata[high].datetime) { mid = high + 1; break; } if(kdata[low].datetime >= query.endDatetime()) { mid = low; break; } mid = (low + high) / 2; if(query.endDatetime() > kdata[mid].datetime) { low = mid + 1; } else { high = mid - 1; } } endpos = (mid >= total) ? total : mid; if(startpos >= endpos) { return false; } out_start = startpos; out_end = endpos; return true; }
bool MySQLKDataDriver:: getIndexRangeByDate(const string& market, const string& code, const KQuery& query, size_t& out_start, size_t& out_end) { string func_name(" [MySQLKDataDriver::getIndexRangeByDate]"); out_start = 0; out_end = 0; if (query.queryType() != KQuery::DATE) { HKU_ERROR("queryType must be KQuery::DATE" << func_name); return false; } if(query.startDatetime() >= query.endDatetime() || query.startDatetime() > (Datetime::max)()) { return false; } MYSQL_RES *mysql_result; MYSQL_ROW row; string table(_getTableName(market, code, query.kType())); std::stringstream buf (std::stringstream::out); buf << "select count(1) from " << table << " where date<" << query.startDatetime().number(); if (!_query(buf.str())) { HKU_ERROR("mysql_query error! " << func_name); return false; } mysql_result = mysql_store_result(m_mysql.get()); if (!mysql_result) { HKU_ERROR("mysql_store_result error!" << func_name); return false; } while ((row = mysql_fetch_row(mysql_result))) { try { out_start = boost::lexical_cast<size_t>(row[0]); } catch (...) { HKU_INFO("Error boost::lexical_cast<size_t>" << table << func_name); out_start = 0; mysql_free_result(mysql_result); return false; } } mysql_free_result(mysql_result); buf.str(""); buf << "select count(1) from " << table << " where date<=" << query.endDatetime().number(); if (!_query(buf.str())) { HKU_ERROR("mysql_query error! " << func_name); return false; } mysql_result = mysql_store_result(m_mysql.get()); if (!mysql_result) { HKU_ERROR("mysql_store_result error!" << func_name); return false; } while ((row = mysql_fetch_row(mysql_result))) { try { out_end = boost::lexical_cast<size_t>(row[0]) - 1; } catch (...) { HKU_INFO("Error boost::lexical_cast<size_t>" << table << func_name); out_end = 0; mysql_free_result(mysql_result); return false; } } mysql_free_result(mysql_result); return true; }