hikyuu2/hikyuu_cpp/hikyuu/Stock.h

308 lines
9.3 KiB
C++
Raw Normal View History

2019-02-08 22:41:20 +08:00
/*
2015-01-07 01:26:14 +08:00
* Stock.h
*
* Created on: 2011-11-9
* Author: fasiondog
*/
#pragma once
2015-01-07 01:26:14 +08:00
#ifndef STOCK_H_
#define STOCK_H_
2020-11-11 00:07:56 +08:00
#include <shared_mutex>
2015-01-07 01:26:14 +08:00
#include "StockWeight.h"
#include "KQuery.h"
2019-02-08 22:41:20 +08:00
#include "TimeLineRecord.h"
2019-02-11 21:13:06 +08:00
#include "TransRecord.h"
2015-01-07 01:26:14 +08:00
namespace hku {
class HKU_API StockManager;
2021-01-24 20:47:38 +08:00
class KDataDriverConnect;
2021-01-22 00:39:37 +08:00
2021-01-24 20:47:38 +08:00
template <class DriverConnectT>
class DriverConnectPool;
2021-01-22 00:39:37 +08:00
2021-01-24 20:47:38 +08:00
typedef DriverConnectPool<KDataDriverConnect> KDataDriverConnectPool;
typedef shared_ptr<KDataDriverConnectPool> KDataDriverConnectPoolPtr;
2015-01-07 01:26:14 +08:00
class HKU_API KData;
class HKU_API Parameter;
2015-01-07 01:26:14 +08:00
/**
* Stock基类Application中一般使用StockPtr进行操作
* @ingroup StockManage
*/
class HKU_API Stock {
friend class StockManager;
private:
static const string default_market;
static const string default_code;
static const string default_market_code;
static const string default_name;
static const uint32_t default_type;
2015-01-07 01:26:14 +08:00
static const bool default_valid;
static const Datetime default_startDate;
static const Datetime default_lastDate;
static const price_t default_tick;
static const price_t default_tickValue;
static const price_t default_unit;
static const int default_precision;
static const size_t default_minTradeNumber;
static const size_t default_maxTradeNumber;
public:
Stock();
Stock(const Stock&);
Stock(const string& market, const string& code, const string& name);
Stock(const string& market, const string& code, const string& name, uint32_t type, bool valid,
2015-01-07 01:26:14 +08:00
const Datetime& startDate, const Datetime& lastDate);
Stock(const string& market, const string& code, const string& name, uint32_t type, bool valid,
const Datetime& startDate, const Datetime& lastDate, price_t tick, price_t tickValue,
int precision, size_t minTradeNumber, size_t maxTradeNumber);
2015-01-07 01:26:14 +08:00
virtual ~Stock();
Stock& operator=(const Stock&);
bool operator==(const Stock&) const;
bool operator!=(const Stock&) const;
2021-01-29 00:18:01 +08:00
/**
* idmap的键值使用id实际为m_data的内存地址
* @note stockid
*/
uint64_t id() const;
2015-01-07 01:26:14 +08:00
/** 获取所属市场简称,市场简称是市场的唯一标识 */
const string& market() const;
/** 获取证券代码 */
const string& code() const;
/** 市场简称+证券代码,如: sh000001 */
const string& market_code() const;
/** 获取证券名称 */
const string& name() const;
/** 获取证券类型 */
uint32_t type() const;
2015-01-07 01:26:14 +08:00
/** 该证券当前是否有效 */
bool valid() const;
/** 获取证券起始日期 */
Datetime startDatetime() const;
/** 获取证券最后日期 */
Datetime lastDatetime() const;
/** 获取最小跳动量 */
price_t tick() const;
/** 最小跳动量价值 */
price_t tickValue() const;
/** 每单位价值 = tickValue / tick */
price_t unit() const;
/** 获取价格精度 */
int precision() const;
/** 获取最小交易数量同minTradeNumber */
size_t atom() const;
/** 获取最小交易数量 */
size_t minTradeNumber() const;
/** 获取最大交易量 */
size_t maxTradeNumber() const;
/**
* [start,end)
* @param start
* @param end
* @return
*/
StockWeightList getWeight(const Datetime& start = Datetime::min(),
const Datetime& end = Null<Datetime>()) const;
2015-01-07 01:26:14 +08:00
/** 获取不同类型K线数据量 */
size_t getCount(KQuery::KType dataType = KQuery::DAY) const;
/** 获取指定日期时刻的市值,即小于等于指定日期的最后一条记录的收盘价 */
price_t getMarketValue(const Datetime&, KQuery::KType) const;
/**
* KQuery指定的条件K线位置范围
* @param query [in]
* @param out_start [out] K线起始范围
* @param out_end [out] K线结束范围
* @return true | false
*/
2019-08-03 15:14:39 +08:00
bool getIndexRange(const KQuery& query, size_t& out_start, size_t& out_end) const;
2015-01-07 01:26:14 +08:00
/** 获取指定索引的K线数据记录未作越界检查 */
2019-11-10 19:45:57 +08:00
KRecord getKRecord(size_t pos, KQuery::KType dataType = KQuery::DAY) const;
2015-01-07 01:26:14 +08:00
/** 根据数据类型(日线/周线等获取指定日期的KRecord */
2020-10-09 01:02:52 +08:00
KRecord getKRecord(const Datetime&, KQuery::KType ktype = KQuery::DAY) const;
2015-01-07 01:26:14 +08:00
/** 获取K线数据 */
KData getKData(const KQuery&) const;
2020-10-03 00:02:03 +08:00
/**
2020-10-03 23:58:04 +08:00
* KRecordList使
2020-10-05 00:07:29 +08:00
* @note
2020-10-03 00:02:03 +08:00
* @param query
*/
KRecordList getKRecordList(const KQuery& query) const;
2016-04-25 01:39:07 +08:00
/** 获取日期列表 */
DatetimeList getDatetimeList(const KQuery& query) const;
2019-02-08 22:41:20 +08:00
/** 获取分时线 */
2019-02-11 16:33:55 +08:00
TimeLineList getTimeLineList(const KQuery& query) const;
2019-02-08 22:41:20 +08:00
2019-02-11 21:13:06 +08:00
/** 获取历史分笔数据 */
TransList getTransList(const KQuery& query) const;
/**
*
*/
Parameter getFinanceInfo() const;
2019-11-10 19:45:57 +08:00
/**
2019-04-06 02:40:53 +08:00
*
* @param date 0331063009301231 Datetime(201109300000)
*/
PriceList getHistoryFinanceInfo(const Datetime& date) const;
/** 设置权息信息, 仅供初始化时调用 */
2015-01-07 01:26:14 +08:00
void setWeightList(const StockWeightList&);
2021-01-06 00:06:58 +08:00
/**
*
* @param time
*/
bool isTransactionTime(Datetime time);
/** 设置K线数据驱动 */
2021-01-24 20:47:38 +08:00
void setKDataDriver(const KDataDriverConnectPoolPtr& kdataDriver);
2015-01-07 01:26:14 +08:00
/** 获取K线驱动*/
KDataDriverConnectPoolPtr getKDataDirver() const;
2015-01-07 01:26:14 +08:00
/**
* K线数据做自身缓存
2019-02-08 22:41:20 +08:00
* @note
2015-01-07 01:26:14 +08:00
*/
void loadKDataToBuffer(KQuery::KType);
/** 释放对应的K线缓存 */
void releaseKDataBuffer(KQuery::KType);
/** 指定类型的K线数据是否被缓存 */
bool isBuffer(KQuery::KType) const;
/** 是否为Null */
bool isNull() const;
2016-04-03 00:08:31 +08:00
/** (临时函数)只用于更新缓存中的日线数据 **/
2020-12-19 23:57:24 +08:00
void realtimeUpdate(KRecord, KQuery::KType ktype = KQuery::DAY);
2016-04-03 00:08:31 +08:00
/** 仅用于python的__str__ */
string toString() const;
2015-01-07 01:26:14 +08:00
private:
bool _getIndexRangeByIndex(const KQuery&, size_t& out_start, size_t& out_end) const;
2020-11-11 23:58:08 +08:00
// 以下函数属于基础操作添加了读锁
2020-11-11 23:58:08 +08:00
size_t _getCountFromBuffer(KQuery::KType ktype) const;
KRecord _getKRecordFromBuffer(size_t pos, KQuery::KType ktype) const;
KRecordList _getKRecordListFromBuffer(size_t start_ix, size_t end_ix,
KQuery::KType ktype) const;
2015-01-07 01:26:14 +08:00
bool _getIndexRangeByDateFromBuffer(const KQuery&, size_t&, size_t&) const;
private:
struct HKU_API Data;
shared_ptr<Data> m_data;
2021-01-24 20:47:38 +08:00
KDataDriverConnectPoolPtr m_kdataDriver;
2015-01-07 01:26:14 +08:00
};
struct HKU_API Stock::Data {
2019-11-10 19:45:57 +08:00
string m_market; //所属的市场简称
string m_code; //证券代码
string m_market_code; //市场简称证券代码
string m_name; //证券名称
uint32_t m_type; //证券类型
2019-11-10 19:45:57 +08:00
bool m_valid; //当前证券是否有效
Datetime m_startDate; //证券起始日期
Datetime m_lastDate; //证券最后日期
2015-01-07 01:26:14 +08:00
StockWeightList m_weightList; //权息信息列表
std::mutex m_weight_mutex;
2015-01-07 01:26:14 +08:00
price_t m_tick;
price_t m_tickValue;
price_t m_unit;
2019-11-10 19:45:57 +08:00
int m_precision;
size_t m_minTradeNumber;
size_t m_maxTradeNumber;
2015-01-07 01:26:14 +08:00
2020-10-05 18:04:53 +08:00
unordered_map<string, KRecordList*> pKData;
2020-11-11 00:07:56 +08:00
unordered_map<string, std::shared_mutex*> pMutex;
2015-01-07 01:26:14 +08:00
Data();
Data(const string& market, const string& code, const string& name, uint32_t type, bool valid,
const Datetime& startDate, const Datetime& lastDate, price_t tick, price_t tickValue,
int precision, size_t minTradeNumber, size_t maxTradeNumber);
2015-01-07 01:26:14 +08:00
virtual ~Data();
};
/**
* Stock信息Stock(market, code, name, type, valid, startDatetime, lastDatetime)
* @ingroup StockManage
*/
2019-11-10 19:45:57 +08:00
HKU_API std::ostream& operator<<(std::ostream& os, const Stock& stock);
2015-01-07 01:26:14 +08:00
/** @ingroup StockManage */
typedef vector<Stock> StockList;
2019-03-03 20:47:28 +08:00
/**
* StockStockManager使StockManager对象
* @param querystr "sh000001"
* @return Null<Stock>()
* @ingroup StockManage
*/
Stock HKU_API getStock(const string& querystr);
2015-01-07 01:26:14 +08:00
/* 用于将Stock实例作为map的key一般建议使用stock.id做键值
* map还要利用拷贝构造函数 */
2019-11-10 19:45:57 +08:00
bool operator<(const Stock& s1, const Stock& s2);
inline bool operator<(const Stock& s1, const Stock& s2) {
2015-01-07 01:26:14 +08:00
return s1.id() < s2.id();
}
inline uint64_t Stock::id() const {
return isNull() ? 0 : (int64_t)m_data.get();
2015-01-07 01:26:14 +08:00
}
inline bool Stock::operator==(const Stock& stock) const {
return (*this != stock) ? false : true;
}
2019-11-10 19:45:57 +08:00
} // namespace hku
2015-01-07 01:26:14 +08:00
namespace std {
template <>
struct std::hash<hku::Stock> {
std::size_t operator()(hku::Stock const& stk) const noexcept {
return stk.id(); // or use boost::hash_combine
}
};
} // namespace std
2015-01-07 01:26:14 +08:00
#endif /* STOCK_H_ */