Datetime Datetime::preMonth() const { Datetime result; if (*this == Null<Datetime>()) return result; try { int m = month(); result = (m == 1) ? Datetime(year()-1, 12, 1) : Datetime(year(), m-1, 1); } catch(...) { result = Datetime::min(); } return result; }
Datetime Datetime::preQuarter() const { Datetime result; if (*this == Null<Datetime>()) return result; try { int m = startOfQuarter().month(); result = (m == 1) ? Datetime(year()-1, 10, 1) : Datetime(year(), m-3, 1); } catch(...) { result = Datetime::min(); } return result; }
Datetime Datetime::preHalfyear() const { Datetime result; if (*this == Null<Datetime>()) return result; try { int m = startOfHalfyear().month(); result = (m <= 6) ? Datetime(year()-1, 7, 1) : Datetime(year(), 1, 1); } catch(...) { result = Datetime::min(); } return result; }
Stock StockManager::addTempCsvStock( const string& code, const string& day_filename, const string& min_filename, price_t tick, price_t tickValue, int precision, size_t minTradeNumber, size_t maxTradeNumber) { string new_code(code); boost::to_upper(new_code); Stock result("TMP", new_code, day_filename, STOCKTYPE_TMP, true, Datetime(199901010000), Null<Datetime>(), tick, tickValue, precision, minTradeNumber, maxTradeNumber); KDataTempCsvDriver *p = new KDataTempCsvDriver(day_filename, min_filename); result.setKDataDriver(KDataDriverPtr(p)); result.loadKDataToBuffer(KQuery::DAY); result.loadKDataToBuffer(KQuery::MIN); if (!addStock(result)){ //加入失败,返回Null<Stock> return Null<Stock>(); } return result; }
KRecord Stock:: getKRecordByDate(const Datetime& datetime, KQuery::KType ktype) const { size_t startix = 0, endix = 0; KQuery query = KQueryByDate(datetime, Datetime(datetime.number() + 1), ktype); if (getIndexRange(query, startix, endix)) { return getKRecord(startix, ktype); } return Null<KRecord>(); }
Datetime Datetime::endOfQuarter() const { Datetime result; if (*this == Null<Datetime>()) return result; int m = month(); int y = year(); if (m <= 3) { result = Datetime(y, 3, 31); } else if (m <= 6) { result = Datetime(y, 6, 30); } else if (m <= 9) { result = Datetime(y, 9, 30); } else if (m <= 12) { result = Datetime(y, 12, 31); } return result; }
Datetime Datetime::startOfQuarter() const { Datetime result; if (*this == Null<Datetime>()) return result; int m = month(); int y = year(); if (m <= 3) { result = Datetime(y, 1, 1); } else if (m <= 6) { result = Datetime(y, 4, 1); } else if (m <= 9) { result = Datetime(y, 7, 1); } else if (m <= 12) { result = Datetime(y, 10, 1); } return result; }
Datetime Datetime::endOfDay() const { Datetime result; if (*this == Null<Datetime>()) { return result; } result = date() != bd::date(bd::max_date_time) ? Datetime(year(), month(), day(), 23, 59, 59) : Datetime::max(); return result; }
Datetime Datetime::preWeek() const { Datetime result; if (*this == Null<Datetime>()) return result; try { result = Datetime(date() - bd::date_duration(7)).startOfWeek(); } catch(...) { result = Datetime::min(); } return result; }
KRecord MySQLKDataDriver:: getKRecord(const string& market, const string& code, size_t pos, KQuery::KType kType) { string func_name(" [MySQLKDataDriver::getKRecord]"); KRecord result; if (!m_mysql) { HKU_ERROR("Null m_mysql!" << func_name); return result; } /*if (kType >= KQuery::INVALID_KTYPE ) { HKU_WARN("ktype(" << kType << ") is invalid" << func_name); return result; }*/ MYSQL_RES *mysql_result; MYSQL_ROW row; string table(_getTableName(market, code, kType)); std::stringstream buf (std::stringstream::out); buf << "select date, open, high, low, close, amount, count from " << table << " order by date limit " << pos << ", 1"; if (!_query(buf.str())) { HKU_ERROR("mysql_query error! " << func_name); return result; } mysql_result = mysql_store_result(m_mysql.get()); if (!mysql_result) { HKU_ERROR("mysql_store_result error!" << func_name); return result; } while ((row = mysql_fetch_row(mysql_result))) { try { hku_uint64 d = boost::lexical_cast<hku_uint64>(row[0]); result.datetime = Datetime(d); result.openPrice = boost::lexical_cast<price_t>(row[1]); result.highPrice = boost::lexical_cast<price_t>(row[2]); result.lowPrice = boost::lexical_cast<price_t>(row[3]); result.closePrice = boost::lexical_cast<price_t>(row[4]); result.transAmount = boost::lexical_cast<price_t>(row[5]); result.transCount = boost::lexical_cast<price_t>(row[6]); } catch (...) { HKU_INFO("Error get record " << pos << " " << table << func_name); result = Null<KRecord>(); } } mysql_free_result(mysql_result); return result; }
Datetime Datetime::preYear() const { Datetime result; if (*this == Null<Datetime>()) return result; try { result = Datetime(year()-1, 1, 1); } catch(...) { result = Datetime::min(); } return result; }
Datetime getDatetime(const MYSQL_BIND& bind) { if (isNull(bind)) throw NullValue(); switch (bind.buffer_type) { case MYSQL_TYPE_DATE: case MYSQL_TYPE_TIME: case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_TIMESTAMP: { MYSQL_TIME* ts = static_cast<MYSQL_TIME*>(bind.buffer); return Datetime(ts->year, ts->month, ts->day, ts->hour, ts->minute, ts->second); } default: log_error("type-error in getDatetime, type=" << bind.buffer_type); throw TypeError("type-error in getDatetime"); } }
Datetime Datetime::today() { Datetime x = Datetime::now(); return Datetime(x.year(), x.month(), x.day()); }
string c_time() { return Datetime().strftime("%H:%M:%S"); }
string c_logdate() { return Datetime().strftime("%a, %d %b %Y %H:%M:%S %z"); }
void getString(const MYSQL_BIND& bind, std::string& ret) { if (isNull(bind)) throw NullValue(); switch (bind.buffer_type) { case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: ret.assign(static_cast<const char*>(bind.buffer), *bind.length); break; case MYSQL_TYPE_DATE: { MYSQL_TIME* ts = static_cast<MYSQL_TIME*>(bind.buffer); ret.assign(Date(ts->year, ts->month, ts->day).getIso()); break; } case MYSQL_TYPE_TIME: { MYSQL_TIME* ts = static_cast<MYSQL_TIME*>(bind.buffer); ret.assign(Time(ts->hour, ts->minute, ts->second).getIso()); break; } case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_TIMESTAMP: { MYSQL_TIME* ts = static_cast<MYSQL_TIME*>(bind.buffer); ret.assign(Datetime(ts->year, ts->month, ts->day, ts->hour, ts->minute, ts->second, ts->second_part).getIso()); break; } default: { std::ostringstream s; switch (bind.buffer_type) { case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONG: if (bind.is_unsigned) s << getInteger<unsigned int>(bind); else s << getInteger<int>(bind); break; case MYSQL_TYPE_LONGLONG: if (bind.is_unsigned) s << *static_cast<long long unsigned*>(bind.buffer); else s << *static_cast<long long int*>(bind.buffer); break; case MYSQL_TYPE_FLOAT: s << *static_cast<float*>(bind.buffer); break; case MYSQL_TYPE_DOUBLE: s << *static_cast<double*>(bind.buffer); break; default: log_error("type-error in getString, type=" << bind.buffer_type); throw TypeError("type-error in getString"); } ret.assign(s.str()); } } }
Datetime Datetime::nextDay() const { bd::date today = date(); bd::date_duration dd(1); bd::date next = today + dd; return Datetime(next); }
Datetime Datetime::max() { bd::date d(bd::max_date_time); return Datetime(d.year(), d.month(), d.day()); }
Datetime Datetime::endOfYear() const { return *this == Null<Datetime>() ? Null<Datetime>() : Datetime(year(), 12, 31); }
Datetime Datetime::startOfYear() const { return *this == Null<Datetime>() ? *this : Datetime(year(), 1, 1); }
Datetime Datetime::now() { return Datetime(bt::microsec_clock::local_time()); }
Datetime Datetime::startOfHalfyear() const { if (*this == Null<Datetime>()) return *this; return month() <= 6 ? Datetime(year(), 1, 1) : Datetime(year(), 7, 1); }
Datetime Datetime::endOfHalfyear() const { if (*this == Null<Datetime>()) return *this; return month() <= 6 ? Datetime(year(), 6, 30) : Datetime(year(), 12, 31); }
void MySQLKDataDriver:: loadKData(const string& market, const string& code, KQuery::KType kType, size_t start_ix, size_t end_ix, KRecordListPtr out_buffer) { string func_name(" [MySQLKDataDriver::loadKData]"); if (!m_mysql) { //HKU_ERROR("Null m_mysql!" << func_name); return; } //if (kType >= KQuery::INVALID_KTYPE || start_ix >= end_ix) { if (start_ix >= end_ix) { HKU_WARN("ktype(" << kType << ") is invalid or start_ix(" << start_ix << ") >= endix(" << end_ix << ")" << func_name); return; } MYSQL_RES *result; MYSQL_ROW row; string table(_getTableName(market, code, kType)); std::stringstream buf (std::stringstream::out); buf << "select date, open, high, low, close, amount, count from " << table << " order by date limit " << start_ix << ", " << (end_ix - start_ix); if (!_query(buf.str())) { //HKU_ERROR("mysql_query error!" << func_name); return; } result = mysql_store_result(m_mysql.get()); if (!result) { HKU_ERROR("mysql_store_result error!" << func_name); return; } int i = 0; while ((row = mysql_fetch_row(result))) { try { KRecord k; hku_uint64 d = boost::lexical_cast<hku_uint64>(row[0]); k.datetime = Datetime(d); k.openPrice = boost::lexical_cast<price_t>(row[1]); k.highPrice = boost::lexical_cast<price_t>(row[2]); k.lowPrice = boost::lexical_cast<price_t>(row[3]); k.closePrice = boost::lexical_cast<price_t>(row[4]); k.transAmount = boost::lexical_cast<price_t>(row[5]); k.transCount = boost::lexical_cast<price_t>(row[6]); out_buffer->push_back(k); i++; } catch (...) { HKU_INFO("Can't fecth No." << i << " record in " << table << func_name); i++; continue; } } mysql_free_result(result); return; }