mirror of
https://gitee.com/fasiondog/hikyuu.git
synced 2024-11-29 18:39:10 +08:00
代码优化
This commit is contained in:
parent
41a97a3932
commit
1c803c974d
@ -65,17 +65,11 @@ string KQuery::getQueryTypeName(QueryType queryType) {
|
||||
}
|
||||
|
||||
KQuery::QueryType KQuery::getQueryTypeEnum(const string& arg) {
|
||||
QueryType result;
|
||||
string name(arg);
|
||||
to_upper(name);
|
||||
if ("INDEX" == name) {
|
||||
result = INDEX;
|
||||
} else if ("DATE" == name) {
|
||||
result = DATE;
|
||||
} else {
|
||||
result = INVALID;
|
||||
}
|
||||
return result;
|
||||
HKU_IF_RETURN("INDEX" == name, INDEX);
|
||||
HKU_IF_RETURN("DATE" == name, DATE);
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
string KQuery::getKTypeName(KType dataType) {
|
||||
@ -108,23 +102,14 @@ string KQuery::getRecoverTypeName(RecoverType recoverType) {
|
||||
}
|
||||
|
||||
KQuery::RecoverType KQuery::getRecoverTypeEnum(const string& arg) {
|
||||
RecoverType result;
|
||||
string name(arg);
|
||||
to_upper(name);
|
||||
if ("NO_RECOVER" == name) {
|
||||
result = NO_RECOVER;
|
||||
} else if ("FORWARD" == name) {
|
||||
result = FORWARD;
|
||||
} else if ("BACKWARD" == name) {
|
||||
result = BACKWARD;
|
||||
} else if ("EQUAL_FORWARD" == name) {
|
||||
result = EQUAL_FORWARD;
|
||||
} else if ("EQUAL_BACKWARD" == name) {
|
||||
result = EQUAL_BACKWARD;
|
||||
} else {
|
||||
result = INVALID_RECOVER_TYPE;
|
||||
}
|
||||
return result;
|
||||
HKU_IF_RETURN("NO_RECOVER" == name, NO_RECOVER);
|
||||
HKU_IF_RETURN("FORWARD" == name, FORWARD);
|
||||
HKU_IF_RETURN("BACKWARD" == name, BACKWARD);
|
||||
HKU_IF_RETURN("EQUAL_FORWARD" == name, EQUAL_FORWARD);
|
||||
HKU_IF_RETURN("EQUAL_BACKWARD" == name, EQUAL_BACKWARD);
|
||||
return INVALID_RECOVER_TYPE;
|
||||
}
|
||||
|
||||
HKU_API std::ostream& operator<<(std::ostream& os, const KQuery& query) {
|
||||
|
@ -22,15 +22,12 @@ HKU_API std::ostream& operator<<(std::ostream& os, const KRecord& record) {
|
||||
}
|
||||
|
||||
bool HKU_API operator==(const KRecord& d1, const KRecord& d2) {
|
||||
if (d1.datetime == d2.datetime && (std::fabs(d1.openPrice - d2.openPrice) < 0.0001) &&
|
||||
(std::fabs(d1.highPrice - d2.highPrice) < 0.0001) &&
|
||||
(std::fabs(d1.lowPrice - d2.lowPrice) < 0.0001) &&
|
||||
(std::fabs(d1.closePrice - d2.closePrice) < 0.0001) &&
|
||||
(std::fabs(d1.transAmount - d2.transAmount) < 0.0001) &&
|
||||
(std::fabs(d1.transCount - d2.transCount) < 0.0001)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return (d1.datetime == d2.datetime && (std::fabs(d1.openPrice - d2.openPrice) < 0.0001) &&
|
||||
(std::fabs(d1.highPrice - d2.highPrice) < 0.0001) &&
|
||||
(std::fabs(d1.lowPrice - d2.lowPrice) < 0.0001) &&
|
||||
(std::fabs(d1.closePrice - d2.closePrice) < 0.0001) &&
|
||||
(std::fabs(d1.transAmount - d2.transAmount) < 0.0001) &&
|
||||
(std::fabs(d1.transCount - d2.transCount) < 0.0001));
|
||||
}
|
||||
|
||||
} // namespace hku
|
||||
|
@ -31,12 +31,8 @@ HKU_API std::ostream& operator<<(std::ostream& os, const TimeLineList& data) {
|
||||
}
|
||||
|
||||
bool HKU_API operator==(const TimeLineRecord& d1, const TimeLineRecord& d2) {
|
||||
if (d1.datetime == d2.datetime && (std::fabs(d1.price - d2.price) < 0.0001) &&
|
||||
(std::fabs(d1.vol - d2.vol) < 0.0001)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return (d1.datetime == d2.datetime && (std::fabs(d1.price - d2.price) < 0.0001) &&
|
||||
(std::fabs(d1.vol - d2.vol) < 0.0001));
|
||||
}
|
||||
|
||||
TimeLineRecord::TimeLineRecord() : datetime(Datetime()), price(0.0), vol(0.0) {}
|
||||
|
@ -31,12 +31,8 @@ HKU_API std::ostream& operator<<(std::ostream& os, const TransList& data) {
|
||||
}
|
||||
|
||||
bool HKU_API operator==(const TransRecord& d1, const TransRecord& d2) {
|
||||
if (d1.datetime == d2.datetime && (std::fabs(d1.price - d2.price) < 0.0001) &&
|
||||
(std::fabs(d1.vol - d2.vol) < 0.0001) && (d1.direct == d2.direct)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return (d1.datetime == d2.datetime && (std::fabs(d1.price - d2.price) < 0.0001) &&
|
||||
(std::fabs(d1.vol - d2.vol) < 0.0001) && (d1.direct == d2.direct));
|
||||
}
|
||||
|
||||
TransRecord::TransRecord() : datetime(Datetime()), price(0.0), vol(0.0), direct(BUY) {}
|
||||
|
@ -50,40 +50,23 @@ bool BaseInfoDriver::checkType() {
|
||||
}
|
||||
|
||||
bool BaseInfoDriver::init(const Parameter& params) {
|
||||
if (m_params == params)
|
||||
return true;
|
||||
|
||||
HKU_IF_RETURN(m_params == params, true);
|
||||
m_params = params;
|
||||
if (!checkType()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(!checkType(), false);
|
||||
HKU_INFO("Using {} BaseInfoDriver", name());
|
||||
return _init();
|
||||
}
|
||||
|
||||
bool BaseInfoDriver::loadBaseInfo() {
|
||||
if (!checkType()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(!checkType(), false);
|
||||
HKU_INFO("Loading market information...");
|
||||
if (!_loadMarketInfo()) {
|
||||
HKU_FATAL("Can't load Market Information.");
|
||||
return false;
|
||||
}
|
||||
HKU_FATAL_IF_RETURN(!_loadMarketInfo(), false, "Can't load Market Information.");
|
||||
|
||||
HKU_INFO("Loading stock type information...");
|
||||
if (!_loadStockTypeInfo()) {
|
||||
HKU_FATAL("Can't load StockType Information.");
|
||||
return false;
|
||||
}
|
||||
HKU_FATAL_IF_RETURN(!_loadStockTypeInfo(), false, "Can't load StockType Information.");
|
||||
|
||||
HKU_INFO("Loading stock information...");
|
||||
if (!_loadStock()) {
|
||||
HKU_FATAL("Can't load Stock");
|
||||
return false;
|
||||
}
|
||||
HKU_FATAL_IF_RETURN(!_loadStock(), false, "Can't load Stock");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -50,13 +50,9 @@ bool BlockInfoDriver::checkType() {
|
||||
}
|
||||
|
||||
bool BlockInfoDriver::init(const Parameter& params) {
|
||||
if (m_params == params)
|
||||
return true;
|
||||
|
||||
HKU_IF_RETURN(m_params == params, true);
|
||||
m_params = params;
|
||||
if (!checkType()) {
|
||||
return false;
|
||||
}
|
||||
HKU_IF_RETURN(!checkType(), false);
|
||||
return _init();
|
||||
}
|
||||
|
||||
|
@ -23,10 +23,7 @@ PriceList HistoryFinanceReader ::getHistoryFinanceInfo(Datetime date, const stri
|
||||
|
||||
string filename(m_dir + "/gpcw" + boost::lexical_cast<string>(date.number() / 10000) + ".dat");
|
||||
FILE* fp = fopen(filename.c_str(), "rb");
|
||||
if (NULL == fp) {
|
||||
HKU_INFO("Can't found {}", filename);
|
||||
return result;
|
||||
}
|
||||
HKU_INFO_IF_RETURN(NULL == fp, result, "Can't found {}", filename);
|
||||
|
||||
unsigned int report_date = 0;
|
||||
unsigned short max_count = 0;
|
||||
|
@ -52,15 +52,9 @@ bool KDataDriver::checkType() {
|
||||
}
|
||||
|
||||
bool KDataDriver::init(const Parameter& params) {
|
||||
if (m_params == params) {
|
||||
return true;
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(m_params == params, true);
|
||||
m_params = params;
|
||||
if (!checkType()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(!checkType(), false);
|
||||
return _init();
|
||||
}
|
||||
|
||||
|
@ -43,10 +43,7 @@ bool MySQLBaseInfoDriver::_init() {
|
||||
}
|
||||
|
||||
bool MySQLBaseInfoDriver::_loadMarketInfo() {
|
||||
if (!m_pool) {
|
||||
HKU_ERROR("Connect pool ptr is null!");
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(!m_pool, false, "Connect pool ptr is null!");
|
||||
|
||||
try {
|
||||
auto con = m_pool->getConnect();
|
||||
@ -78,13 +75,8 @@ bool MySQLBaseInfoDriver::_loadMarketInfo() {
|
||||
}
|
||||
|
||||
bool MySQLBaseInfoDriver::_loadStockTypeInfo() {
|
||||
if (!m_pool) {
|
||||
HKU_ERROR("Connect pool ptr is null!");
|
||||
return false;
|
||||
}
|
||||
|
||||
HKU_ERROR_IF_RETURN(!m_pool, false, "Connect pool ptr is null!");
|
||||
auto con = m_pool->getConnect();
|
||||
|
||||
vector<StockTypeInfoTable> infoTables;
|
||||
try {
|
||||
con->batchLoad(infoTables);
|
||||
@ -152,13 +144,8 @@ StockWeightList MySQLBaseInfoDriver::getStockWeightList(const string &market, co
|
||||
}
|
||||
|
||||
bool MySQLBaseInfoDriver::_loadStock() {
|
||||
if (!m_pool) {
|
||||
HKU_ERROR("Connect pool ptr is null!");
|
||||
return false;
|
||||
}
|
||||
|
||||
HKU_ERROR_IF_RETURN(!m_pool, false, "Connect pool ptr is null!");
|
||||
auto con = m_pool->getConnect();
|
||||
|
||||
vector<MarketInfoTable> marketTable;
|
||||
try {
|
||||
con->batchLoad(marketTable);
|
||||
|
@ -26,25 +26,16 @@ SQLiteBaseInfoDriver::~SQLiteBaseInfoDriver() {
|
||||
}
|
||||
|
||||
bool SQLiteBaseInfoDriver::_init() {
|
||||
string dbname;
|
||||
try {
|
||||
dbname = getParam<string>("db");
|
||||
HKU_TRACE("SQLITE3: {}", dbname);
|
||||
} catch (...) {
|
||||
HKU_ERROR("Can't get Sqlite3 filename!");
|
||||
return false;
|
||||
}
|
||||
|
||||
string dbname = tryGetParam<string>("db", "");
|
||||
HKU_ERROR_IF_RETURN(dbname == "", false, "Can't get Sqlite3 filename!");
|
||||
HKU_TRACE("SQLITE3: {}", dbname);
|
||||
m_pool = new ConnectPool<SQLiteConnect>(m_params);
|
||||
HKU_CHECK(m_pool, "Failed malloc ConnectPool!");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SQLiteBaseInfoDriver::_loadMarketInfo() {
|
||||
if (!m_pool) {
|
||||
HKU_ERROR("Connect pool ptr is null!");
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(!m_pool, false, "Connect pool ptr is null!");
|
||||
|
||||
try {
|
||||
auto con = m_pool->getConnect();
|
||||
@ -76,13 +67,8 @@ bool SQLiteBaseInfoDriver::_loadMarketInfo() {
|
||||
}
|
||||
|
||||
bool SQLiteBaseInfoDriver::_loadStockTypeInfo() {
|
||||
if (!m_pool) {
|
||||
HKU_ERROR("Connect pool ptr is null!");
|
||||
return false;
|
||||
}
|
||||
|
||||
HKU_ERROR_IF_RETURN(!m_pool, false, "Connect pool ptr is null!");
|
||||
auto con = m_pool->getConnect();
|
||||
|
||||
vector<StockTypeInfoTable> infoTables;
|
||||
try {
|
||||
con->batchLoad(infoTables);
|
||||
@ -105,13 +91,8 @@ bool SQLiteBaseInfoDriver::_loadStockTypeInfo() {
|
||||
}
|
||||
|
||||
bool SQLiteBaseInfoDriver::_loadStock() {
|
||||
if (!m_pool) {
|
||||
HKU_ERROR("Connect pool ptr is null!");
|
||||
return false;
|
||||
}
|
||||
|
||||
HKU_ERROR_IF_RETURN(!m_pool, false, "Connect pool ptr is null!");
|
||||
auto con = m_pool->getConnect();
|
||||
|
||||
vector<MarketInfoTable> marketTable;
|
||||
try {
|
||||
con->batchLoad(marketTable);
|
||||
@ -222,9 +203,7 @@ StockWeightList SQLiteBaseInfoDriver::getStockWeightList(const string& market, c
|
||||
|
||||
Parameter SQLiteBaseInfoDriver ::getFinanceInfo(const string& market, const string& code) {
|
||||
Parameter result;
|
||||
if (!m_pool) {
|
||||
return result;
|
||||
}
|
||||
HKU_IF_RETURN(!m_pool, result);
|
||||
|
||||
std::stringstream buf;
|
||||
buf << "select f.updated_date, f.ipo_date, f.province,"
|
||||
|
@ -20,15 +20,8 @@ bool QLBlockInfoDriver::_init() {
|
||||
|
||||
Block QLBlockInfoDriver ::getBlock(const string& category, const string& name) {
|
||||
Block result(category, name);
|
||||
if (!haveParam("dir")) {
|
||||
HKU_ERROR("Missing 'dir' param!");
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!haveParam(category)) {
|
||||
HKU_INFO("No such category ({})!", category);
|
||||
return result;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(!haveParam("dir"), result, "Missing 'dir' param!");
|
||||
HKU_INFO_IF_RETURN(!haveParam(category), result, "No such category ({})!", category);
|
||||
|
||||
string filename;
|
||||
try {
|
||||
@ -39,10 +32,7 @@ Block QLBlockInfoDriver ::getBlock(const string& category, const string& name) {
|
||||
}
|
||||
|
||||
std::ifstream inifile(filename.c_str(), std::ifstream::in);
|
||||
if (!inifile) {
|
||||
HKU_ERROR("Can't open file({})!", filename);
|
||||
return result;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(!inifile, result, "Can't open file({})!", filename);
|
||||
|
||||
string line_str;
|
||||
string section, market, code;
|
||||
@ -106,15 +96,8 @@ Block QLBlockInfoDriver ::getBlock(const string& category, const string& name) {
|
||||
|
||||
BlockList QLBlockInfoDriver::getBlockList(const string& category) {
|
||||
BlockList result;
|
||||
if (!haveParam("dir")) {
|
||||
HKU_ERROR("Missing 'dir' param!");
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!haveParam(category)) {
|
||||
HKU_INFO("No such category ({})!", category);
|
||||
return result;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(!haveParam("dir"), result, "Missing 'dir' param!");
|
||||
HKU_INFO_IF_RETURN(!haveParam(category), result, "No such category ({})!", category);
|
||||
|
||||
string filename;
|
||||
try {
|
||||
@ -125,10 +108,7 @@ BlockList QLBlockInfoDriver::getBlockList(const string& category) {
|
||||
}
|
||||
|
||||
std::ifstream inifile(filename.c_str(), std::ifstream::in);
|
||||
if (!inifile) {
|
||||
HKU_ERROR("Can't open file({})!", filename);
|
||||
return result;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(!inifile, result, "Can't open file({})!", filename);
|
||||
|
||||
std::string section;
|
||||
std::string key;
|
||||
@ -195,11 +175,7 @@ BlockList QLBlockInfoDriver::getBlockList(const string& category) {
|
||||
|
||||
BlockList QLBlockInfoDriver::getBlockList() {
|
||||
BlockList result;
|
||||
if (!haveParam("dir")) {
|
||||
HKU_ERROR("Missing 'dir' param!");
|
||||
return result;
|
||||
}
|
||||
|
||||
HKU_ERROR_IF_RETURN(!haveParam("dir"), result, "Missing 'dir' param!");
|
||||
StringList category_list = m_params.getNameList();
|
||||
for (auto iter = category_list.begin(); iter != category_list.end(); ++iter) {
|
||||
if (*iter == "dir" || *iter == "type")
|
||||
|
@ -91,15 +91,11 @@ bool KDataTempCsvDriver::getIndexRangeByDate(const string& market, const string&
|
||||
|
||||
Datetime start_date = query.startDatetime();
|
||||
Datetime end_date = query.endDatetime();
|
||||
if (start_date >= end_date) {
|
||||
return false;
|
||||
}
|
||||
HKU_IF_RETURN(start_date >= end_date, false);
|
||||
|
||||
auto klist = getKRecordList(market, code, KQuery(0, Null<int64_t>(), query.kType()));
|
||||
size_t total = klist.size();
|
||||
if (total == 0) {
|
||||
return false;
|
||||
}
|
||||
HKU_IF_RETURN(total == 0, false);
|
||||
|
||||
for (size_t i = total - 1; i == 0; --i) {
|
||||
if (klist[i].datetime < end_date) {
|
||||
@ -155,11 +151,7 @@ KRecordList KDataTempCsvDriver::_getKRecordListByIndex(const string& market, con
|
||||
}
|
||||
|
||||
std::ifstream infile(filename.c_str());
|
||||
if (!infile) {
|
||||
HKU_ERROR("Can't open this file: {}", filename);
|
||||
return result;
|
||||
}
|
||||
|
||||
HKU_ERROR_IF_RETURN(!infile, result, "Can't open this file: {}", filename);
|
||||
string line;
|
||||
if (!std::getline(infile, line)) {
|
||||
infile.close();
|
||||
|
@ -271,12 +271,9 @@ bool H5KDataDriver::_getH5FileAndGroup(const string& market, const string& code,
|
||||
size_t H5KDataDriver::getCount(const string& market, const string& code, KQuery::KType kType) {
|
||||
H5FilePtr h5file;
|
||||
H5::Group group;
|
||||
if (!_getH5FileAndGroup(market, code, kType, h5file, group)) {
|
||||
return 0;
|
||||
}
|
||||
HKU_IF_RETURN(!_getH5FileAndGroup(market, code, kType, h5file, group), 0);
|
||||
|
||||
size_t total = 0;
|
||||
|
||||
try {
|
||||
string tablename(market + code);
|
||||
CHECK_DATASET_EXISTS_RET(group, tablename, total);
|
||||
@ -326,9 +323,7 @@ bool H5KDataDriver::_getBaseIndexRangeByDate(const string& market, const string&
|
||||
H5::Group group;
|
||||
bool success;
|
||||
success = _getH5FileAndGroup(market, code, query.kType(), h5file, group);
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
HKU_IF_RETURN(!success, false);
|
||||
|
||||
H5::DataSet dataset;
|
||||
H5::DataSpace dataspace;
|
||||
@ -439,18 +434,13 @@ bool H5KDataDriver::_getOtherIndexRangeByDate(const string& market, const string
|
||||
KQuery::MIN30 == query.kType() || KQuery::MIN60 == query.kType());
|
||||
out_start = 0;
|
||||
out_end = 0;
|
||||
if (query.startDatetime() >= query.endDatetime()) {
|
||||
return false;
|
||||
}
|
||||
HKU_IF_RETURN(query.startDatetime() >= query.endDatetime(), false);
|
||||
|
||||
H5FilePtr h5file;
|
||||
H5::Group group;
|
||||
if (!_getH5FileAndGroup(market, code, query.kType(), h5file, group)) {
|
||||
return false;
|
||||
}
|
||||
HKU_IF_RETURN(!_getH5FileAndGroup(market, code, query.kType(), h5file, group), false);
|
||||
|
||||
string _tablename(market + code);
|
||||
|
||||
try {
|
||||
CHECK_DATASET_EXISTS_RET(group, _tablename, false);
|
||||
H5::DataSet dataset(group.openDataSet(_tablename));
|
||||
@ -539,9 +529,7 @@ KRecordList H5KDataDriver::getKRecordList(const string& market, const string& co
|
||||
auto kType = query.kType();
|
||||
if (query.queryType() == KQuery::INDEX) {
|
||||
// 按索引方式查询
|
||||
if (query.start() >= query.end()) {
|
||||
return result;
|
||||
}
|
||||
HKU_IF_RETURN(query.start() >= query.end(), result);
|
||||
if (KQuery::DAY == kType || KQuery::MIN5 == kType || KQuery::MIN == kType) {
|
||||
result = _getBaseKRecordList(market, code, kType, query.start(), query.end());
|
||||
} else {
|
||||
@ -571,9 +559,7 @@ KRecordList H5KDataDriver::_getBaseKRecordList(const string& market, const strin
|
||||
KRecordList result;
|
||||
H5FilePtr h5file;
|
||||
H5::Group group;
|
||||
if (!_getH5FileAndGroup(market, code, kType, h5file, group)) {
|
||||
return result;
|
||||
}
|
||||
HKU_IF_RETURN(!_getH5FileAndGroup(market, code, kType, h5file, group), result);
|
||||
|
||||
try {
|
||||
string tablename(format("{}{}", market, code));
|
||||
@ -622,9 +608,7 @@ KRecordList H5KDataDriver::_getIndexKRecordList(const string& market, const stri
|
||||
string tablename(format("{}{}", market, code));
|
||||
H5FilePtr h5file;
|
||||
H5::Group index_group;
|
||||
if (!_getH5FileAndGroup(market, code, kType, h5file, index_group)) {
|
||||
return result;
|
||||
}
|
||||
HKU_IF_RETURN(!_getH5FileAndGroup(market, code, kType, h5file, index_group), result);
|
||||
|
||||
try {
|
||||
H5::Group base_group = h5file->openGroup("data");
|
||||
@ -708,9 +692,7 @@ TimeLineList H5KDataDriver::_getTimeLine(const string& market, const string& cod
|
||||
TimeLineList result;
|
||||
H5FilePtr h5file;
|
||||
H5::Group group;
|
||||
if (!_getH5FileAndGroup(market, code, "TIME", h5file, group)) {
|
||||
return result;
|
||||
}
|
||||
HKU_IF_RETURN(!_getH5FileAndGroup(market, code, "TIME", h5file, group), result);
|
||||
|
||||
try {
|
||||
string tablename(market + code);
|
||||
@ -777,17 +759,13 @@ TimeLineList H5KDataDriver::_getTimeLine(const string& market, const string& cod
|
||||
TimeLineList H5KDataDriver::_getTimeLine(const string& market, const string& code,
|
||||
const Datetime& start, const Datetime& end) {
|
||||
TimeLineList result;
|
||||
if (start >= end || start > Datetime::max()) {
|
||||
return result;
|
||||
}
|
||||
HKU_IF_RETURN(start >= end || start > Datetime::max(), result);
|
||||
|
||||
H5FilePtr h5file;
|
||||
H5::Group group;
|
||||
bool success;
|
||||
success = _getH5FileAndGroup(market, code, "TIME", h5file, group);
|
||||
if (!success) {
|
||||
return result;
|
||||
}
|
||||
HKU_IF_RETURN(!success, result);
|
||||
|
||||
H5::DataSet dataset;
|
||||
H5::DataSpace dataspace;
|
||||
@ -929,9 +907,7 @@ TransList H5KDataDriver::_getTransList(const string& market, const string& code,
|
||||
TransList result;
|
||||
H5FilePtr h5file;
|
||||
H5::Group group;
|
||||
if (!_getH5FileAndGroup(market, code, "TRANS", h5file, group)) {
|
||||
return result;
|
||||
}
|
||||
HKU_IF_RETURN(!_getH5FileAndGroup(market, code, "TRANS", h5file, group), result);
|
||||
|
||||
try {
|
||||
string tablename(market + code);
|
||||
@ -1005,17 +981,13 @@ TransList H5KDataDriver::_getTransList(const string& market, const string& code,
|
||||
TransList H5KDataDriver::_getTransList(const string& market, const string& code,
|
||||
const Datetime& start, const Datetime& end) {
|
||||
TransList result;
|
||||
if (start >= end || start > Datetime::max()) {
|
||||
return result;
|
||||
}
|
||||
HKU_IF_RETURN(start >= end || start > Datetime::max(), result);
|
||||
|
||||
H5FilePtr h5file;
|
||||
H5::Group group;
|
||||
bool success;
|
||||
success = _getH5FileAndGroup(market, code, "TRANS", h5file, group);
|
||||
if (!success) {
|
||||
return result;
|
||||
}
|
||||
HKU_IF_RETURN(!success, result);
|
||||
|
||||
H5::DataSet dataset;
|
||||
H5::DataSpace dataspace;
|
||||
|
@ -56,14 +56,10 @@ KRecordList MySQLKDataDriver::getKRecordList(const string& market, const string&
|
||||
KRecordList MySQLKDataDriver::_getKRecordList(const string& market, const string& code,
|
||||
KQuery::KType kType, size_t start_ix, size_t end_ix) {
|
||||
KRecordList result;
|
||||
if (start_ix >= end_ix)
|
||||
return result;
|
||||
HKU_IF_RETURN(start_ix >= end_ix, result);
|
||||
|
||||
auto con = m_pool->getConnect();
|
||||
if (!con) {
|
||||
HKU_ERROR("The acquisition connection failed.");
|
||||
return result;
|
||||
};
|
||||
HKU_ERROR_IF_RETURN(!con, result, "The acquisition connection failed.");
|
||||
|
||||
try {
|
||||
KRecordTable r(market, code, kType);
|
||||
@ -98,14 +94,10 @@ KRecordList MySQLKDataDriver::_getKRecordList(const string& market, const string
|
||||
KQuery::KType ktype, Datetime start_date,
|
||||
Datetime end_date) {
|
||||
KRecordList result;
|
||||
if (start_date >= end_date)
|
||||
return result;
|
||||
HKU_IF_RETURN(start_date >= end_date, result);
|
||||
|
||||
auto con = m_pool->getConnect();
|
||||
if (!con) {
|
||||
HKU_ERROR("The acquisition connection failed.");
|
||||
return result;
|
||||
};
|
||||
HKU_ERROR_IF_RETURN(!con, result, "The acquisition connection failed.");
|
||||
|
||||
try {
|
||||
KRecordTable r(market, code, ktype);
|
||||
@ -139,10 +131,7 @@ KRecordList MySQLKDataDriver::_getKRecordList(const string& market, const string
|
||||
size_t MySQLKDataDriver::getCount(const string& market, const string& code, KQuery::KType kType) {
|
||||
size_t result = 0;
|
||||
auto con = m_pool->getConnect();
|
||||
if (!con) {
|
||||
HKU_ERROR("The acquisition connection failed.");
|
||||
return result;
|
||||
};
|
||||
HKU_ERROR_IF_RETURN(!con, result, "The acquisition connection failed.");
|
||||
|
||||
try {
|
||||
result =
|
||||
@ -163,21 +152,13 @@ bool MySQLKDataDriver::getIndexRangeByDate(const string& market, const string& c
|
||||
size_t& out_end) {
|
||||
out_start = 0;
|
||||
out_end = 0;
|
||||
if (query.queryType() != KQuery::DATE) {
|
||||
HKU_ERROR("queryType must be KQuery::DATE");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (query.startDatetime() >= query.endDatetime() || query.startDatetime() > (Datetime::max)()) {
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(query.queryType() != KQuery::DATE, false, "queryType must be KQuery::DATE");
|
||||
HKU_IF_RETURN(
|
||||
query.startDatetime() >= query.endDatetime() || query.startDatetime() > (Datetime::max)(),
|
||||
false);
|
||||
|
||||
auto con = m_pool->getConnect();
|
||||
if (!con) {
|
||||
HKU_ERROR("The acquisition connection failed.");
|
||||
return false;
|
||||
};
|
||||
|
||||
HKU_ERROR_IF_RETURN(!con, false, "The acquisition connection failed.");
|
||||
string tablename = _getTableName(market, code, query.kType());
|
||||
try {
|
||||
out_start = con->queryInt(fmt::format("select count(1) from {} where date<{}", tablename,
|
||||
|
@ -90,10 +90,8 @@ KRecordList TdxKDataDriver::getKRecordList(const string& market, const string& c
|
||||
const KQuery& query) {
|
||||
KRecordList result;
|
||||
auto ktype = query.kType();
|
||||
if (!(ktype == KQuery::MIN || ktype == KQuery::MIN5 || ktype == KQuery::DAY)) {
|
||||
HKU_WARN("The driver({}) don't support the ktype: {}", name(), ktype);
|
||||
return result;
|
||||
}
|
||||
HKU_WARN_IF_RETURN(!(ktype == KQuery::MIN || ktype == KQuery::MIN5 || ktype == KQuery::DAY),
|
||||
result, "The driver({}) don't support the ktype: {}", name(), ktype);
|
||||
|
||||
if (query.queryType() == KQuery::INDEX) {
|
||||
if (ktype == KQuery::DAY) {
|
||||
@ -113,15 +111,11 @@ KRecordList TdxKDataDriver::_getDayKRecordList(const string& market, const strin
|
||||
size_t end_ix) {
|
||||
KRecordList result;
|
||||
size_t total = getCount(market, code, ktype);
|
||||
if (0 == total || start_ix >= total) {
|
||||
return result;
|
||||
}
|
||||
HKU_IF_RETURN(0 == total || start_ix >= total, result);
|
||||
|
||||
string filename = _getFileName(market, code, ktype);
|
||||
std::ifstream file(filename.c_str(), std::ios::binary | std::ios::in);
|
||||
if (!file) {
|
||||
return result;
|
||||
}
|
||||
HKU_IF_RETURN(!file, result);
|
||||
|
||||
struct TdxDayData tdx_data;
|
||||
file.seekg(start_ix * sizeof(tdx_data));
|
||||
@ -147,9 +141,7 @@ KRecordList TdxKDataDriver::_getMinKRecordList(const string& market, const strin
|
||||
KRecordList result;
|
||||
|
||||
size_t total = getCount(market, code, ktype);
|
||||
if (0 == total || start_ix >= total) {
|
||||
return result;
|
||||
}
|
||||
HKU_IF_RETURN(0 == total || start_ix >= total, result);
|
||||
|
||||
string filename = _getFileName(market, code, ktype);
|
||||
std::ifstream file(filename.c_str(), std::ios::binary | std::ios::in);
|
||||
@ -199,24 +191,17 @@ bool TdxKDataDriver::_getDayIndexRangeByDate(const string& market, const string&
|
||||
out_start = 0;
|
||||
out_end = 0;
|
||||
|
||||
if (query.kType() != KQuery::DAY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (query.startDatetime() >= query.endDatetime() || query.startDatetime() > Datetime::max()) {
|
||||
return false;
|
||||
}
|
||||
HKU_IF_RETURN(query.kType() != KQuery::DAY, false);
|
||||
HKU_IF_RETURN(
|
||||
query.startDatetime() >= query.endDatetime() || query.startDatetime() > Datetime::max(),
|
||||
false);
|
||||
|
||||
string filename = _getFileName(market, code, query.kType());
|
||||
std::ifstream file(filename.c_str(), std::ios::binary | std::ios::in);
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
HKU_IF_RETURN(!file, false);
|
||||
|
||||
size_t total = getCount(market, code, query.kType());
|
||||
if (0 == total) {
|
||||
return false;
|
||||
}
|
||||
HKU_IF_RETURN(0 == total, false);
|
||||
|
||||
Datetime start_number = query.startDatetime();
|
||||
Datetime end_number = query.endDatetime();
|
||||
@ -304,24 +289,17 @@ bool TdxKDataDriver::_getMinIndexRangeByDate(const string& market, const string&
|
||||
out_start = 0;
|
||||
out_end = 0;
|
||||
|
||||
if (query.kType() != KQuery::MIN && query.kType() != KQuery::MIN5) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (query.startDatetime() >= query.endDatetime() || query.startDatetime() > Datetime::max()) {
|
||||
return false;
|
||||
}
|
||||
HKU_IF_RETURN(query.kType() != KQuery::MIN && query.kType() != KQuery::MIN5, false);
|
||||
HKU_IF_RETURN(
|
||||
query.startDatetime() >= query.endDatetime() || query.startDatetime() > Datetime::max(),
|
||||
false);
|
||||
|
||||
string filename = _getFileName(market, code, query.kType());
|
||||
std::ifstream file(filename.c_str(), std::ios::binary | std::ios::in);
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
HKU_IF_RETURN(!file, false);
|
||||
|
||||
size_t total = getCount(market, code, query.kType());
|
||||
if (0 == total) {
|
||||
return false;
|
||||
}
|
||||
HKU_IF_RETURN(0 == total, false);
|
||||
|
||||
Datetime start_number = query.startDatetime();
|
||||
Datetime end_number = query.endDatetime();
|
||||
@ -433,9 +411,7 @@ size_t TdxKDataDriver::_getBaseCount(const string& market, const string& code,
|
||||
KQuery::KType ktype) {
|
||||
assert(KQuery::DAY == ktype || KQuery::MIN5 == ktype || KQuery::MIN == ktype);
|
||||
string filename = _getFileName(market, code, ktype);
|
||||
if (filename.empty()) {
|
||||
return 0;
|
||||
}
|
||||
HKU_IF_RETURN(filename.empty(), 0);
|
||||
|
||||
size_t count = 0;
|
||||
struct stat info;
|
||||
|
@ -110,86 +110,56 @@ std::string Datetime::str() const {
|
||||
}
|
||||
|
||||
std::string Datetime::repr() const {
|
||||
if (isNull()) {
|
||||
return "Datetime()";
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(isNull(), "Datetime()");
|
||||
return fmt::format("Datetime({},{},{},{},{},{},{},{})", year(), month(), day(), hour(),
|
||||
minute(), second(), millisecond(), microsecond());
|
||||
}
|
||||
|
||||
unsigned long long Datetime::number() const {
|
||||
if (m_data.date() == bd::date(bd::pos_infin)) {
|
||||
return Null<unsigned long long>();
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(m_data.date() == bd::date(bd::pos_infin), Null<unsigned long long>());
|
||||
return (unsigned long long)year() * 100000000 + (unsigned long long)month() * 1000000 +
|
||||
(unsigned long long)day() * 10000 + (unsigned long long)hour() * 100 +
|
||||
(unsigned long long)minute();
|
||||
}
|
||||
|
||||
long Datetime::year() const {
|
||||
if (isNull()) {
|
||||
HKU_THROW_EXCEPTION(std::logic_error, "This is Null Datetime!");
|
||||
} else {
|
||||
return m_data.date().year();
|
||||
}
|
||||
HKU_CHECK_THROW(!isNull(), std::logic_error, "This is Null Datetime!");
|
||||
return m_data.date().year();
|
||||
}
|
||||
|
||||
long Datetime::month() const {
|
||||
if (isNull()) {
|
||||
HKU_THROW_EXCEPTION(std::logic_error, "This is Null Datetime!");
|
||||
} else {
|
||||
return m_data.date().month();
|
||||
}
|
||||
HKU_CHECK_THROW(!isNull(), std::logic_error, "This is Null Datetime!");
|
||||
return m_data.date().month();
|
||||
}
|
||||
|
||||
long Datetime::day() const {
|
||||
if (isNull()) {
|
||||
HKU_THROW_EXCEPTION(std::logic_error, "This is Null Datetime!");
|
||||
} else {
|
||||
return m_data.date().day();
|
||||
}
|
||||
HKU_CHECK_THROW(!isNull(), std::logic_error, "This is Null Datetime!");
|
||||
return m_data.date().day();
|
||||
}
|
||||
|
||||
long Datetime::hour() const {
|
||||
if (isNull()) {
|
||||
HKU_THROW_EXCEPTION(std::logic_error, "This is Null Datetime!");
|
||||
} else {
|
||||
return long(m_data.time_of_day().hours());
|
||||
}
|
||||
HKU_CHECK_THROW(!isNull(), std::logic_error, "This is Null Datetime!");
|
||||
return long(m_data.time_of_day().hours());
|
||||
}
|
||||
|
||||
long Datetime::minute() const {
|
||||
if (isNull()) {
|
||||
HKU_THROW_EXCEPTION(std::logic_error, "This is Null Datetime!");
|
||||
} else {
|
||||
return long(m_data.time_of_day().minutes());
|
||||
}
|
||||
HKU_CHECK_THROW(!isNull(), std::logic_error, "This is Null Datetime!");
|
||||
return long(m_data.time_of_day().minutes());
|
||||
}
|
||||
|
||||
long Datetime::second() const {
|
||||
if (isNull()) {
|
||||
HKU_THROW_EXCEPTION(std::logic_error, "This is Null Datetime!");
|
||||
} else {
|
||||
return long(m_data.time_of_day().seconds());
|
||||
}
|
||||
HKU_CHECK_THROW(!isNull(), std::logic_error, "This is Null Datetime!");
|
||||
return long(m_data.time_of_day().seconds());
|
||||
}
|
||||
|
||||
long Datetime::millisecond() const {
|
||||
if (isNull()) {
|
||||
HKU_THROW_EXCEPTION(std::logic_error, "This is Null Datetime!");
|
||||
} else {
|
||||
return long(m_data.time_of_day().fractional_seconds()) / 1000;
|
||||
}
|
||||
HKU_CHECK_THROW(!isNull(), std::logic_error, "This is Null Datetime!");
|
||||
return long(m_data.time_of_day().fractional_seconds()) / 1000;
|
||||
}
|
||||
|
||||
long Datetime::microsecond() const {
|
||||
if (isNull()) {
|
||||
HKU_THROW_EXCEPTION(std::logic_error, "This is Null Datetime!");
|
||||
} else {
|
||||
return long(m_data.time_of_day().fractional_seconds()) % 1000;
|
||||
}
|
||||
HKU_CHECK_THROW(!isNull(), std::logic_error, "This is Null Datetime!");
|
||||
return long(m_data.time_of_day().fractional_seconds()) % 1000;
|
||||
}
|
||||
|
||||
Datetime Datetime::min() {
|
||||
@ -224,8 +194,7 @@ DatetimeList HKU_API getDateRange(const Datetime& start, const Datetime& end) {
|
||||
}
|
||||
|
||||
Datetime Datetime::dateOfWeek(int day) const {
|
||||
if (*this == Null<Datetime>())
|
||||
return *this;
|
||||
HKU_IF_RETURN(*this == Null<Datetime>(), *this);
|
||||
|
||||
int dd = day;
|
||||
if (dd < 0) {
|
||||
@ -260,10 +229,8 @@ Datetime Datetime::endOfYear() const {
|
||||
}
|
||||
|
||||
Datetime Datetime::startOfWeek() const {
|
||||
if (*this == Null<Datetime>())
|
||||
return *this;
|
||||
|
||||
Datetime result;
|
||||
HKU_IF_RETURN(*this == Null<Datetime>(), result);
|
||||
int today = dayOfWeek();
|
||||
if (today == 0) {
|
||||
result = Datetime(date() + bd::date_duration(-6));
|
||||
@ -279,10 +246,8 @@ Datetime Datetime::startOfWeek() const {
|
||||
}
|
||||
|
||||
Datetime Datetime::endOfWeek() const {
|
||||
if (*this == Null<Datetime>())
|
||||
return *this;
|
||||
|
||||
Datetime result;
|
||||
HKU_IF_RETURN(*this == Null<Datetime>(), result);
|
||||
int today = dayOfWeek();
|
||||
if (today == 0) {
|
||||
result = Datetime(date());
|
||||
@ -297,9 +262,7 @@ Datetime Datetime::endOfWeek() const {
|
||||
|
||||
Datetime Datetime::startOfQuarter() const {
|
||||
Datetime result;
|
||||
if (*this == Null<Datetime>())
|
||||
return result;
|
||||
|
||||
HKU_IF_RETURN(*this == Null<Datetime>(), result);
|
||||
int m = month();
|
||||
int y = year();
|
||||
if (m <= 3) {
|
||||
@ -317,9 +280,7 @@ Datetime Datetime::startOfQuarter() const {
|
||||
|
||||
Datetime Datetime::endOfQuarter() const {
|
||||
Datetime result;
|
||||
if (*this == Null<Datetime>())
|
||||
return result;
|
||||
|
||||
HKU_IF_RETURN(*this == Null<Datetime>(), result);
|
||||
int m = month();
|
||||
int y = year();
|
||||
if (m <= 3) {
|
||||
@ -336,30 +297,23 @@ Datetime Datetime::endOfQuarter() const {
|
||||
}
|
||||
|
||||
Datetime Datetime::startOfHalfyear() const {
|
||||
if (*this == Null<Datetime>())
|
||||
return *this;
|
||||
|
||||
HKU_IF_RETURN(*this == Null<Datetime>(), *this);
|
||||
return month() <= 6 ? Datetime(year(), 1, 1) : Datetime(year(), 7, 1);
|
||||
}
|
||||
|
||||
Datetime Datetime::endOfHalfyear() const {
|
||||
if (*this == Null<Datetime>())
|
||||
return *this;
|
||||
|
||||
HKU_IF_RETURN(*this == Null<Datetime>(), *this);
|
||||
return month() <= 6 ? Datetime(year(), 6, 30) : Datetime(year(), 12, 31);
|
||||
}
|
||||
|
||||
Datetime Datetime::nextDay() const {
|
||||
if (*this == Null<Datetime>() || *this == Datetime::max())
|
||||
return *this;
|
||||
HKU_IF_RETURN(*this == Null<Datetime>() || *this == Datetime::max(), *this);
|
||||
return Datetime(date() + bd::date_duration(1));
|
||||
}
|
||||
|
||||
Datetime Datetime::nextWeek() const {
|
||||
Datetime result;
|
||||
if (*this == Null<Datetime>())
|
||||
return result;
|
||||
|
||||
HKU_IF_RETURN(*this == Null<Datetime>(), result);
|
||||
result = Datetime(endOfWeek().date() + bd::date_duration(1));
|
||||
if (result > Datetime::max())
|
||||
result = Datetime::max();
|
||||
@ -369,9 +323,7 @@ Datetime Datetime::nextWeek() const {
|
||||
|
||||
Datetime Datetime::nextMonth() const {
|
||||
Datetime result;
|
||||
if (*this == Null<Datetime>())
|
||||
return result;
|
||||
|
||||
HKU_IF_RETURN(*this == Null<Datetime>(), result);
|
||||
result = Datetime(endOfMonth().date() + bd::date_duration(1));
|
||||
if (result > Datetime::max())
|
||||
result = Datetime::max();
|
||||
@ -381,9 +333,7 @@ Datetime Datetime::nextMonth() const {
|
||||
|
||||
Datetime Datetime::nextQuarter() const {
|
||||
Datetime result;
|
||||
if (*this == Null<Datetime>())
|
||||
return result;
|
||||
|
||||
HKU_IF_RETURN(*this == Null<Datetime>(), result);
|
||||
result = Datetime(endOfQuarter().date() + bd::date_duration(1));
|
||||
if (result > Datetime::max())
|
||||
result = Datetime::max();
|
||||
@ -393,9 +343,7 @@ Datetime Datetime::nextQuarter() const {
|
||||
|
||||
Datetime Datetime::nextHalfyear() const {
|
||||
Datetime result;
|
||||
if (*this == Null<Datetime>())
|
||||
return result;
|
||||
|
||||
HKU_IF_RETURN(*this == Null<Datetime>(), result);
|
||||
result = Datetime(endOfHalfyear().date() + bd::date_duration(1));
|
||||
if (result > Datetime::max())
|
||||
result = Datetime::max();
|
||||
@ -405,9 +353,7 @@ Datetime Datetime::nextHalfyear() const {
|
||||
|
||||
Datetime Datetime::nextYear() const {
|
||||
Datetime result;
|
||||
if (*this == Null<Datetime>())
|
||||
return result;
|
||||
|
||||
HKU_IF_RETURN(*this == Null<Datetime>(), result);
|
||||
result = Datetime(endOfYear().date() + bd::date_duration(1));
|
||||
if (result > Datetime::max())
|
||||
result = Datetime::max();
|
||||
@ -415,16 +361,13 @@ Datetime Datetime::nextYear() const {
|
||||
}
|
||||
|
||||
Datetime Datetime::preDay() const {
|
||||
if (*this == Null<Datetime>() || *this == Datetime::min())
|
||||
return *this;
|
||||
HKU_IF_RETURN(*this == Null<Datetime>() || *this == Datetime::min(), *this);
|
||||
return Datetime(date() - bd::date_duration(1));
|
||||
}
|
||||
|
||||
Datetime Datetime::preWeek() const {
|
||||
Datetime result;
|
||||
if (*this == Null<Datetime>())
|
||||
return result;
|
||||
|
||||
HKU_IF_RETURN(*this == Null<Datetime>(), result);
|
||||
try {
|
||||
result = Datetime(date() - bd::date_duration(7)).startOfWeek();
|
||||
} catch (...) {
|
||||
@ -435,9 +378,7 @@ Datetime Datetime::preWeek() const {
|
||||
|
||||
Datetime Datetime::preMonth() const {
|
||||
Datetime result;
|
||||
if (*this == Null<Datetime>())
|
||||
return result;
|
||||
|
||||
HKU_IF_RETURN(*this == Null<Datetime>(), result);
|
||||
try {
|
||||
int m = month();
|
||||
result = (m == 1) ? Datetime(year() - 1, 12, 1) : Datetime(year(), m - 1, 1);
|
||||
@ -449,9 +390,7 @@ Datetime Datetime::preMonth() const {
|
||||
|
||||
Datetime Datetime::preQuarter() const {
|
||||
Datetime result;
|
||||
if (*this == Null<Datetime>())
|
||||
return result;
|
||||
|
||||
HKU_IF_RETURN(*this == Null<Datetime>(), result);
|
||||
try {
|
||||
int m = startOfQuarter().month();
|
||||
result = (m == 1) ? Datetime(year() - 1, 10, 1) : Datetime(year(), m - 3, 1);
|
||||
@ -464,9 +403,7 @@ Datetime Datetime::preQuarter() const {
|
||||
|
||||
Datetime Datetime::preHalfyear() const {
|
||||
Datetime result;
|
||||
if (*this == Null<Datetime>())
|
||||
return result;
|
||||
|
||||
HKU_IF_RETURN(*this == Null<Datetime>(), result);
|
||||
try {
|
||||
int m = startOfHalfyear().month();
|
||||
result = (m <= 6) ? Datetime(year() - 1, 7, 1) : Datetime(year(), 1, 1);
|
||||
@ -479,9 +416,7 @@ Datetime Datetime::preHalfyear() const {
|
||||
|
||||
Datetime Datetime::preYear() const {
|
||||
Datetime result;
|
||||
if (*this == Null<Datetime>())
|
||||
return result;
|
||||
|
||||
HKU_IF_RETURN(*this == Null<Datetime>(), result);
|
||||
try {
|
||||
result = Datetime(year() - 1, 1, 1);
|
||||
} catch (...) {
|
||||
@ -493,10 +428,7 @@ Datetime Datetime::preYear() const {
|
||||
|
||||
Datetime Datetime::endOfDay() const {
|
||||
Datetime result;
|
||||
if (*this == Null<Datetime>()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(*this == Null<Datetime>(), result);
|
||||
result = date() != bd::date(bd::max_date_time) ? Datetime(year(), month(), day(), 23, 59, 59)
|
||||
: Datetime::max();
|
||||
return result;
|
||||
|
@ -46,165 +46,115 @@ KData Indicator::getContext() const {
|
||||
}
|
||||
|
||||
Indicator& Indicator::operator=(const Indicator& indicator) {
|
||||
if (this == &indicator)
|
||||
return *this;
|
||||
HKU_IF_RETURN(this == &indicator, *this);
|
||||
m_imp = indicator.m_imp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PriceList Indicator::getResultAsPriceList(size_t num) const {
|
||||
if (!m_imp) {
|
||||
HKU_WARN("indicator imptr is null!");
|
||||
return PriceList();
|
||||
}
|
||||
HKU_WARN_IF_RETURN(!m_imp, PriceList(), "indicator imptr is null!");
|
||||
return m_imp->getResultAsPriceList(num);
|
||||
}
|
||||
|
||||
Indicator Indicator::getResult(size_t num) const {
|
||||
if (!m_imp) {
|
||||
HKU_WARN("indicator imptr is null!");
|
||||
return Indicator();
|
||||
}
|
||||
HKU_WARN_IF_RETURN(!m_imp, Indicator(), "indicator imptr is null!");
|
||||
return m_imp->getResult(num);
|
||||
}
|
||||
|
||||
Indicator Indicator::operator()(const Indicator& ind) {
|
||||
if (!m_imp)
|
||||
return Indicator();
|
||||
|
||||
if (!ind.getImp())
|
||||
return Indicator(m_imp);
|
||||
|
||||
HKU_IF_RETURN(!m_imp, Indicator());
|
||||
HKU_IF_RETURN(!ind.getImp(), Indicator(m_imp));
|
||||
IndicatorImpPtr p = m_imp->clone();
|
||||
p->add(IndicatorImp::OP, IndicatorImpPtr(), ind.getImp());
|
||||
return p->calculate();
|
||||
}
|
||||
|
||||
HKU_API Indicator operator+(const Indicator& ind1, const Indicator& ind2) {
|
||||
if (!ind1.getImp() || !ind2.getImp()) {
|
||||
return Indicator();
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(!ind1.getImp() || !ind2.getImp(), Indicator());
|
||||
IndicatorImpPtr p = make_shared<IndicatorImp>();
|
||||
p->add(IndicatorImp::ADD, ind1.getImp(), ind2.getImp());
|
||||
return p->calculate();
|
||||
}
|
||||
|
||||
HKU_API Indicator operator-(const Indicator& ind1, const Indicator& ind2) {
|
||||
if (!ind1.getImp() || !ind2.getImp()) {
|
||||
return Indicator();
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(!ind1.getImp() || !ind2.getImp(), Indicator());
|
||||
IndicatorImpPtr p = make_shared<IndicatorImp>();
|
||||
p->add(IndicatorImp::SUB, ind1.getImp(), ind2.getImp());
|
||||
return p->calculate();
|
||||
}
|
||||
|
||||
HKU_API Indicator operator*(const Indicator& ind1, const Indicator& ind2) {
|
||||
if (!ind1.getImp() || !ind2.getImp()) {
|
||||
return Indicator();
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(!ind1.getImp() || !ind2.getImp(), Indicator());
|
||||
IndicatorImpPtr p = make_shared<IndicatorImp>();
|
||||
p->add(IndicatorImp::MUL, ind1.getImp(), ind2.getImp());
|
||||
return p->calculate();
|
||||
}
|
||||
|
||||
HKU_API Indicator operator/(const Indicator& ind1, const Indicator& ind2) {
|
||||
if (!ind1.getImp() || !ind2.getImp()) {
|
||||
return Indicator();
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(!ind1.getImp() || !ind2.getImp(), Indicator());
|
||||
IndicatorImpPtr p = make_shared<IndicatorImp>();
|
||||
p->add(IndicatorImp::DIV, ind1.getImp(), ind2.getImp());
|
||||
return p->calculate();
|
||||
}
|
||||
|
||||
HKU_API Indicator operator%(const Indicator& ind1, const Indicator& ind2) {
|
||||
if (!ind1.getImp() || !ind2.getImp()) {
|
||||
return Indicator();
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(!ind1.getImp() || !ind2.getImp(), Indicator());
|
||||
IndicatorImpPtr p = make_shared<IndicatorImp>();
|
||||
p->add(IndicatorImp::MOD, ind1.getImp(), ind2.getImp());
|
||||
return p->calculate();
|
||||
}
|
||||
|
||||
HKU_API Indicator operator==(const Indicator& ind1, const Indicator& ind2) {
|
||||
if (!ind1.getImp() || !ind2.getImp()) {
|
||||
return Indicator();
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(!ind1.getImp() || !ind2.getImp(), Indicator());
|
||||
IndicatorImpPtr p = make_shared<IndicatorImp>();
|
||||
p->add(IndicatorImp::EQ, ind1.getImp(), ind2.getImp());
|
||||
return p->calculate();
|
||||
}
|
||||
|
||||
HKU_API Indicator operator!=(const Indicator& ind1, const Indicator& ind2) {
|
||||
if (!ind1.getImp() || !ind2.getImp()) {
|
||||
return Indicator();
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(!ind1.getImp() || !ind2.getImp(), Indicator());
|
||||
IndicatorImpPtr p = make_shared<IndicatorImp>();
|
||||
p->add(IndicatorImp::NE, ind1.getImp(), ind2.getImp());
|
||||
return p->calculate();
|
||||
}
|
||||
|
||||
HKU_API Indicator operator>(const Indicator& ind1, const Indicator& ind2) {
|
||||
if (!ind1.getImp() || !ind2.getImp()) {
|
||||
return Indicator();
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(!ind1.getImp() || !ind2.getImp(), Indicator());
|
||||
IndicatorImpPtr p = make_shared<IndicatorImp>();
|
||||
p->add(IndicatorImp::GT, ind1.getImp(), ind2.getImp());
|
||||
return p->calculate();
|
||||
}
|
||||
|
||||
HKU_API Indicator operator<(const Indicator& ind1, const Indicator& ind2) {
|
||||
if (!ind1.getImp() || !ind2.getImp()) {
|
||||
return Indicator();
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(!ind1.getImp() || !ind2.getImp(), Indicator());
|
||||
IndicatorImpPtr p = make_shared<IndicatorImp>();
|
||||
p->add(IndicatorImp::LT, ind1.getImp(), ind2.getImp());
|
||||
return p->calculate();
|
||||
}
|
||||
|
||||
HKU_API Indicator operator>=(const Indicator& ind1, const Indicator& ind2) {
|
||||
if (!ind1.getImp() || !ind2.getImp()) {
|
||||
return Indicator();
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(!ind1.getImp() || !ind2.getImp(), Indicator());
|
||||
IndicatorImpPtr p = make_shared<IndicatorImp>();
|
||||
p->add(IndicatorImp::GE, ind1.getImp(), ind2.getImp());
|
||||
return p->calculate();
|
||||
}
|
||||
|
||||
HKU_API Indicator operator<=(const Indicator& ind1, const Indicator& ind2) {
|
||||
if (!ind1.getImp() || !ind2.getImp()) {
|
||||
return Indicator();
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(!ind1.getImp() || !ind2.getImp(), Indicator());
|
||||
IndicatorImpPtr p = make_shared<IndicatorImp>();
|
||||
p->add(IndicatorImp::LE, ind1.getImp(), ind2.getImp());
|
||||
return p->calculate();
|
||||
}
|
||||
|
||||
HKU_API Indicator operator&(const Indicator& ind1, const Indicator& ind2) {
|
||||
if (!ind1.getImp() || !ind2.getImp()) {
|
||||
return Indicator();
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(!ind1.getImp() || !ind2.getImp(), Indicator());
|
||||
IndicatorImpPtr p = make_shared<IndicatorImp>();
|
||||
p->add(IndicatorImp::AND, ind1.getImp(), ind2.getImp());
|
||||
return p->calculate();
|
||||
}
|
||||
|
||||
HKU_API Indicator operator|(const Indicator& ind1, const Indicator& ind2) {
|
||||
if (!ind1.getImp() || !ind2.getImp()) {
|
||||
return Indicator();
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(!ind1.getImp() || !ind2.getImp(), Indicator());
|
||||
IndicatorImpPtr p = make_shared<IndicatorImp>();
|
||||
p->add(IndicatorImp::OR, ind1.getImp(), ind2.getImp());
|
||||
return p->calculate();
|
||||
@ -315,21 +265,16 @@ HKU_API Indicator operator|(price_t val, const Indicator& ind) {
|
||||
}
|
||||
|
||||
Indicator HKU_API WEAVE(const Indicator& ind1, const Indicator& ind2) {
|
||||
if (!ind1.getImp() || !ind2.getImp()) {
|
||||
HKU_ERROR("ind1 or ind2 is Null Indicator!");
|
||||
return Indicator();
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(!ind1.getImp() || !ind2.getImp(), Indicator(),
|
||||
"ind1 or ind2 is Null Indicator!");
|
||||
IndicatorImpPtr p = make_shared<IndicatorImp>();
|
||||
p->add(IndicatorImp::WEAVE, ind1.getImp(), ind2.getImp());
|
||||
return p->calculate();
|
||||
}
|
||||
|
||||
Indicator HKU_API IF(const Indicator& ind1, const Indicator& ind2, const Indicator& ind3) {
|
||||
if (!ind1.getImp() || !ind2.getImp() || !ind3.getImp()) {
|
||||
HKU_ERROR("Exists null indicator!");
|
||||
return Indicator();
|
||||
}
|
||||
|
||||
HKU_ERROR_IF_RETURN(!ind1.getImp() || !ind2.getImp() || !ind3.getImp(), Indicator(),
|
||||
"Exists null indicator!");
|
||||
IndicatorImpPtr p = make_shared<IndicatorImp>();
|
||||
p->add_if(ind1.getImp(), ind2.getImp(), ind3.getImp());
|
||||
return p->calculate();
|
||||
|
@ -99,20 +99,11 @@ void IndicatorImp::setContext(const KData &k) {
|
||||
}
|
||||
|
||||
void IndicatorImp::_readyBuffer(size_t len, size_t result_num) {
|
||||
if (result_num > MAX_RESULT_NUM) {
|
||||
throw(
|
||||
std::invalid_argument("result_num oiverload MAX_RESULT_NUM! "
|
||||
"[IndicatorImp::_readyBuffer]" +
|
||||
name()));
|
||||
}
|
||||
|
||||
if (result_num == 0) {
|
||||
// HKU_TRACE("result_num is zeror! (" << name() << ") [IndicatorImp::_readyBuffer]")
|
||||
return;
|
||||
}
|
||||
HKU_CHECK_THROW(result_num <= MAX_RESULT_NUM, std::invalid_argument,
|
||||
"result_num oiverload MAX_RESULT_NUM! {}", name());
|
||||
HKU_IF_RETURN(result_num == 0, void());
|
||||
|
||||
price_t null_price = Null<price_t>();
|
||||
|
||||
for (size_t i = 0; i < result_num; ++i) {
|
||||
if (!m_pBuffer[i]) {
|
||||
m_pBuffer[i] = new PriceList(len, null_price);
|
||||
@ -195,18 +186,12 @@ string IndicatorImp::long_name() const {
|
||||
}
|
||||
|
||||
PriceList IndicatorImp::getResultAsPriceList(size_t result_num) {
|
||||
if (result_num >= m_result_num || m_pBuffer[result_num] == NULL) {
|
||||
return PriceList();
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(result_num >= m_result_num || m_pBuffer[result_num] == NULL, PriceList());
|
||||
return (*m_pBuffer[result_num]);
|
||||
}
|
||||
|
||||
IndicatorImpPtr IndicatorImp::getResult(size_t result_num) {
|
||||
if (result_num >= m_result_num || m_pBuffer[result_num] == NULL) {
|
||||
return IndicatorImpPtr();
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(result_num >= m_result_num || m_pBuffer[result_num] == NULL, IndicatorImpPtr());
|
||||
IndicatorImpPtr imp = make_shared<IndicatorImp>();
|
||||
size_t total = size();
|
||||
imp->_readyBuffer(total, 1);
|
||||
@ -219,33 +204,22 @@ IndicatorImpPtr IndicatorImp::getResult(size_t result_num) {
|
||||
|
||||
price_t IndicatorImp::get(size_t pos, size_t num) {
|
||||
#if CHECK_ACCESS_BOUND
|
||||
if ((m_pBuffer[num] == NULL) || pos >= m_pBuffer[num]->size()) {
|
||||
throw(std::out_of_range("Try to access value out of bounds! " + name() +
|
||||
" [IndicatorImp::get]"));
|
||||
return Null<price_t>();
|
||||
}
|
||||
HKU_CHECK_THROW((m_pBuffer[num] != NULL) && pos < m_pBuffer[num]->size(), std::out_of_range,
|
||||
"Try to access value out of bounds! {}", name());
|
||||
#endif
|
||||
return (*m_pBuffer[num])[pos];
|
||||
}
|
||||
|
||||
void IndicatorImp::_set(price_t val, size_t pos, size_t num) {
|
||||
#if CHECK_ACCESS_BOUND
|
||||
if ((m_pBuffer[num] == NULL) || pos >= m_pBuffer[num]->size()) {
|
||||
std::stringstream buf;
|
||||
buf << "Try to access value out of bounds! (pos=" << pos << ") " << name()
|
||||
<< " [IndicatorImp::_set]";
|
||||
throw(std::out_of_range(buf.str()));
|
||||
}
|
||||
(*m_pBuffer[num])[pos] = val;
|
||||
#else
|
||||
(*m_pBuffer[num])[pos] = val;
|
||||
HKU_CHECK_THROW((m_pBuffer[num] != NULL) && pos < m_pBuffer[num]->size(), std::out_of_range,
|
||||
"Try to access value out of bounds! (pos={}) {}", pos, name());
|
||||
#endif
|
||||
(*m_pBuffer[num])[pos] = val;
|
||||
}
|
||||
|
||||
DatetimeList IndicatorImp::getDatetimeList() const {
|
||||
if (haveParam("align_date_list")) {
|
||||
return getParam<DatetimeList>("align_date_list");
|
||||
}
|
||||
HKU_IF_RETURN(haveParam("align_date_list"), getParam<DatetimeList>("align_date_list"));
|
||||
return getContext().getDatetimeList();
|
||||
}
|
||||
|
||||
@ -357,11 +331,7 @@ string IndicatorImp::formula() const {
|
||||
}
|
||||
|
||||
void IndicatorImp::add(OPType op, IndicatorImpPtr left, IndicatorImpPtr right) {
|
||||
if (op == LEAF || op >= INVALID || !right) {
|
||||
HKU_ERROR("Wrong used!");
|
||||
return;
|
||||
}
|
||||
|
||||
HKU_ERROR_IF_RETURN(op == LEAF || op >= INVALID || !right, void(), "Wrong used!");
|
||||
if (OP == op && !isLeaf()) {
|
||||
if (m_left) {
|
||||
if (m_left->isNeedContext()) {
|
||||
@ -414,11 +384,7 @@ void IndicatorImp::add(OPType op, IndicatorImpPtr left, IndicatorImpPtr right) {
|
||||
}
|
||||
|
||||
void IndicatorImp::add_if(IndicatorImpPtr cond, IndicatorImpPtr left, IndicatorImpPtr right) {
|
||||
if (!cond || !left || !right) {
|
||||
HKU_ERROR("Wrong used!");
|
||||
return;
|
||||
}
|
||||
|
||||
HKU_ERROR_IF_RETURN(!cond || !left || !right, void(), "Wrong used!");
|
||||
m_need_calculate = true;
|
||||
m_optype = IndicatorImp::OP_IF;
|
||||
m_three = cond->clone();
|
||||
|
@ -23,15 +23,7 @@ Ama::Ama() : IndicatorImp("AMA", 2) {
|
||||
Ama::~Ama() {}
|
||||
|
||||
bool Ama::check() {
|
||||
int n = getParam<int>("n");
|
||||
int fast_n = getParam<int>("fast_n");
|
||||
int slow_n = getParam<int>("slow_n");
|
||||
if (n < 1 || fast_n < 0 || slow_n < 0) {
|
||||
HKU_ERROR("Invalid param! (n>=1, fast_n>0, slow_n>0) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return getParam<int>("n") >= 1 && getParam<int>("fast_n") >= 0 && getParam<int>("slow_n") >= 0;
|
||||
}
|
||||
|
||||
void Ama::_calculate(const Indicator& data) {
|
||||
|
@ -20,11 +20,7 @@ Atr::Atr() : IndicatorImp("ATR", 1) {
|
||||
Atr::~Atr() {}
|
||||
|
||||
bool Atr::check() {
|
||||
if (getParam<int>("n") < 1) {
|
||||
HKU_ERROR("Invalid param! (n>=1) ", m_params);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return getParam<int>("n") >= 1;
|
||||
}
|
||||
|
||||
void Atr::_calculate(const Indicator& indicator) {
|
||||
|
@ -20,13 +20,7 @@ Ema::Ema() : IndicatorImp("EMA", 1) {
|
||||
Ema::~Ema() {}
|
||||
|
||||
bool Ema::check() {
|
||||
int n = getParam<int>("n");
|
||||
if (n <= 0) {
|
||||
HKU_ERROR("Invalid param[n] must > 0 !");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return getParam<int>("n") > 0;
|
||||
}
|
||||
|
||||
void Ema::_calculate(const Indicator& indicator) {
|
||||
|
@ -29,16 +29,13 @@ bool IAd::check() {
|
||||
}
|
||||
|
||||
void IAd::_calculate(const Indicator& data) {
|
||||
if (!isLeaf() && !data.empty()) {
|
||||
HKU_WARN("The input is ignored because {} depends on the context!", m_name);
|
||||
}
|
||||
HKU_WARN_IF(!isLeaf() && !data.empty(),
|
||||
"The input is ignored because {} depends on the context!", m_name);
|
||||
|
||||
m_discard = 0;
|
||||
KData k = getContext();
|
||||
size_t total = k.size();
|
||||
if (total == 0) {
|
||||
return;
|
||||
}
|
||||
HKU_IF_RETURN(total == 0, void());
|
||||
|
||||
_readyBuffer(total, 1);
|
||||
|
||||
|
@ -22,11 +22,7 @@ IBackset::IBackset() : IndicatorImp("BACKSET", 1) {
|
||||
IBackset::~IBackset() {}
|
||||
|
||||
bool IBackset::check() {
|
||||
if (getParam<int>("n") < 1) {
|
||||
HKU_ERROR("Invalid param! (n>=1) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return getParam<int>("n") >= 1;
|
||||
}
|
||||
|
||||
void IBackset::_calculate(const Indicator& ind) {
|
||||
|
@ -20,13 +20,7 @@ ICount::ICount() : IndicatorImp("COUNT", 1) {
|
||||
ICount::~ICount() {}
|
||||
|
||||
bool ICount::check() {
|
||||
int n = getParam<int>("n");
|
||||
if (n < 0) {
|
||||
HKU_ERROR("Invalid param[n] ! (n >= 0)");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return getParam<int>("n") >= 0;
|
||||
}
|
||||
|
||||
void ICount::_calculate(const Indicator& data) {
|
||||
|
@ -23,13 +23,7 @@ IDevsq::IDevsq() : IndicatorImp("DEVSQ", 1) {
|
||||
IDevsq::~IDevsq() {}
|
||||
|
||||
bool IDevsq::check() {
|
||||
int n = getParam<int>("n");
|
||||
if (n < 2) {
|
||||
HKU_ERROR("Invalid param[n] ! (n >= 2) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return getParam<int>("n") >= 2;
|
||||
}
|
||||
|
||||
void IDevsq::_calculate(const Indicator& data) {
|
||||
|
@ -22,18 +22,12 @@ IEvery::IEvery() : IndicatorImp("EVERY", 1) {
|
||||
IEvery::~IEvery() {}
|
||||
|
||||
bool IEvery::check() {
|
||||
if (getParam<int>("n") < 0) {
|
||||
HKU_ERROR("Invalid param! (n>=0) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return getParam<int>("n") >= 0;
|
||||
}
|
||||
|
||||
void IEvery::_calculate(const Indicator& ind) {
|
||||
size_t total = ind.size();
|
||||
if (0 == total) {
|
||||
return;
|
||||
}
|
||||
HKU_IF_RETURN(0 == total, void());
|
||||
|
||||
int n = getParam<int>("n");
|
||||
if (0 == n) {
|
||||
|
@ -22,18 +22,12 @@ IExist::IExist() : IndicatorImp("EXIST", 1) {
|
||||
IExist::~IExist() {}
|
||||
|
||||
bool IExist::check() {
|
||||
if (getParam<int>("n") < 0) {
|
||||
HKU_ERROR("Invalid param! (n>=0) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return getParam<int>("n") >= 0;
|
||||
}
|
||||
|
||||
void IExist::_calculate(const Indicator& ind) {
|
||||
size_t total = ind.size();
|
||||
if (total == 0) {
|
||||
return;
|
||||
}
|
||||
HKU_IF_RETURN(total == 0, void());
|
||||
|
||||
int n = getParam<int>("n");
|
||||
if (n == 0) {
|
||||
|
@ -22,11 +22,7 @@ IFilter::IFilter() : IndicatorImp("FILTER", 1) {
|
||||
IFilter::~IFilter() {}
|
||||
|
||||
bool IFilter::check() {
|
||||
if (getParam<int>("n") < 1) {
|
||||
HKU_ERROR("Invalid param! (n>=1) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return getParam<int>("n") >= 1;
|
||||
}
|
||||
|
||||
void IFilter::_calculate(const Indicator& ind) {
|
||||
|
@ -22,11 +22,7 @@ IHhvbars::IHhvbars() : IndicatorImp("HHVBARS", 1) {
|
||||
IHhvbars::~IHhvbars() {}
|
||||
|
||||
bool IHhvbars::check() {
|
||||
if (getParam<int>("n") < 0) {
|
||||
HKU_ERROR("Invalid param! (n>=0) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return getParam<int>("n") >= 0;
|
||||
}
|
||||
|
||||
void IHhvbars::_calculate(const Indicator& ind) {
|
||||
|
@ -22,13 +22,7 @@ IHighLine::IHighLine() : IndicatorImp("HHV", 1) {
|
||||
IHighLine::~IHighLine() {}
|
||||
|
||||
bool IHighLine::check() {
|
||||
int n = getParam<int>("n");
|
||||
if (n < 0) {
|
||||
HKU_ERROR("Invalid param[n] ! (n >= 0) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return getParam<int>("n") >= 0;
|
||||
}
|
||||
|
||||
void IHighLine::_calculate(const Indicator& ind) {
|
||||
|
@ -30,26 +30,19 @@ IKData::~IKData() {}
|
||||
|
||||
bool IKData::check() {
|
||||
string part = getParam<string>("kpart");
|
||||
if ("KDATA" == part || "OPEN" == part || "HIGH" == part || "LOW" == part || "CLOSE" == part ||
|
||||
"AMO" == part || "VOL" == part) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return ("KDATA" == part || "OPEN" == part || "HIGH" == part || "LOW" == part ||
|
||||
"CLOSE" == part || "AMO" == part || "VOL" == part);
|
||||
}
|
||||
|
||||
//支持KDATA Indicator作为参数
|
||||
void IKData::_calculate(const Indicator& ind) {
|
||||
if (!isLeaf() && !ind.empty()) {
|
||||
HKU_WARN("The input is ignored because {} depends on the context!",
|
||||
getParam<string>("kpart"));
|
||||
}
|
||||
HKU_WARN_IF(!isLeaf() && !ind.empty(),
|
||||
"The input is ignored because {} depends on the context!",
|
||||
getParam<string>("kpart"));
|
||||
|
||||
KData kdata = getContext();
|
||||
size_t total = kdata.size();
|
||||
if (total == 0) {
|
||||
return;
|
||||
}
|
||||
HKU_IF_RETURN(total == 0, void());
|
||||
|
||||
string part_name = getParam<string>("kpart");
|
||||
|
||||
|
@ -27,9 +27,8 @@ bool ILiuTongPan::check() {
|
||||
}
|
||||
|
||||
void ILiuTongPan::_calculate(const Indicator& data) {
|
||||
if (!isLeaf() && !data.empty()) {
|
||||
HKU_WARN("The input is ignored because {} depends on the context!", m_name);
|
||||
}
|
||||
HKU_WARN_IF(!isLeaf() && !data.empty(),
|
||||
"The input is ignored because {} depends on the context!", m_name);
|
||||
|
||||
KData k = getContext();
|
||||
size_t total = k.size();
|
||||
|
@ -22,13 +22,7 @@ ILowLine::ILowLine() : IndicatorImp("LLV", 1) {
|
||||
ILowLine::~ILowLine() {}
|
||||
|
||||
bool ILowLine::check() {
|
||||
int n = getParam<int>("n");
|
||||
if (n < 0) {
|
||||
HKU_ERROR("Invalid param[n] ! (n >= 0) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return getParam<int>("n") >= 0;
|
||||
}
|
||||
|
||||
void ILowLine::_calculate(const Indicator& ind) {
|
||||
|
@ -22,11 +22,7 @@ ILowLineBars::ILowLineBars() : IndicatorImp("LLVBARS", 1) {
|
||||
ILowLineBars::~ILowLineBars() {}
|
||||
|
||||
bool ILowLineBars::check() {
|
||||
if (getParam<int>("n") < 0) {
|
||||
HKU_ERROR("Invalid param! (n>=0) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return getParam<int>("n") >= 0;
|
||||
}
|
||||
|
||||
void ILowLineBars::_calculate(const Indicator& ind) {
|
||||
|
@ -20,13 +20,7 @@ IMa::IMa() : IndicatorImp("MA", 1) {
|
||||
IMa::~IMa() {}
|
||||
|
||||
bool IMa::check() {
|
||||
int n = getParam<int>("n");
|
||||
if (n < 1) {
|
||||
HKU_ERROR("Invalid param! (n >= 1) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return getParam<int>("n") >= 1;
|
||||
}
|
||||
|
||||
void IMa::_calculate(const Indicator& indicator) {
|
||||
|
@ -28,11 +28,7 @@ IPriceList::IPriceList(const PriceList& data, int in_discard) : IndicatorImp("PR
|
||||
IPriceList::~IPriceList() {}
|
||||
|
||||
bool IPriceList::check() {
|
||||
if (getParam<int>("discard") < 0 || getParam<int>("result_index") < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return (getParam<int>("discard") >= 0 && getParam<int>("result_index") >= 0);
|
||||
}
|
||||
|
||||
void IPriceList::_calculate(const Indicator& data) {
|
||||
@ -60,10 +56,8 @@ void IPriceList::_calculate(const Indicator& data) {
|
||||
|
||||
//不在叶子节点上,则忽略本身的data参数,认为其输入实际为函数入参中的data
|
||||
int result_index = getParam<int>("result_index");
|
||||
if (result_index < 0 || result_index >= data.getResultNumber()) {
|
||||
HKU_ERROR("result_index out of range!");
|
||||
return;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(result_index < 0 || result_index >= data.getResultNumber(), void(),
|
||||
"result_index out of range!");
|
||||
|
||||
size_t total = data.size();
|
||||
_readyBuffer(total, 1);
|
||||
|
@ -22,13 +22,7 @@ IRoc::IRoc() : IndicatorImp("ROC", 1) {
|
||||
IRoc::~IRoc() {}
|
||||
|
||||
bool IRoc::check() {
|
||||
int n = getParam<int>("n");
|
||||
if (n < 1) {
|
||||
HKU_ERROR("Invalid param[n] ! (n >= 1) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return getParam<int>("n") >= 1;
|
||||
}
|
||||
|
||||
void IRoc::_calculate(const Indicator& ind) {
|
||||
|
@ -22,13 +22,7 @@ IRocp::IRocp() : IndicatorImp("ROCP", 1) {
|
||||
IRocp::~IRocp() {}
|
||||
|
||||
bool IRocp::check() {
|
||||
int n = getParam<int>("n");
|
||||
if (n < 1) {
|
||||
HKU_ERROR("Invalid param[n] ! (n >= 1) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return getParam<int>("n") >= 1;
|
||||
}
|
||||
|
||||
void IRocp::_calculate(const Indicator& ind) {
|
||||
|
@ -22,13 +22,7 @@ IRocr::IRocr() : IndicatorImp("ROCR", 1) {
|
||||
IRocr::~IRocr() {}
|
||||
|
||||
bool IRocr::check() {
|
||||
int n = getParam<int>("n");
|
||||
if (n < 1) {
|
||||
HKU_ERROR("Invalid param[n] ! (n >= 1) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return getParam<int>("n") >= 1;
|
||||
}
|
||||
|
||||
void IRocr::_calculate(const Indicator& ind) {
|
||||
|
@ -22,13 +22,7 @@ IRocr100::IRocr100() : IndicatorImp("ROCR100", 1) {
|
||||
IRocr100::~IRocr100() {}
|
||||
|
||||
bool IRocr100::check() {
|
||||
int n = getParam<int>("n");
|
||||
if (n < 1) {
|
||||
HKU_ERROR("Invalid param[n] ! (n >= 1) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return getParam<int>("n") >= 1;
|
||||
}
|
||||
|
||||
void IRocr100::_calculate(const Indicator& ind) {
|
||||
|
@ -23,11 +23,7 @@ IRound::IRound() : IndicatorImp("ROUND", 1) {
|
||||
IRound::~IRound() {}
|
||||
|
||||
bool IRound::check() {
|
||||
if (getParam<int>("ndigits") < 0) {
|
||||
HKU_ERROR("Invalid param[ndigits] ! (n >= 0) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return getParam<int>("ndigits") >= 0;
|
||||
}
|
||||
|
||||
void IRound::_calculate(const Indicator& data) {
|
||||
|
@ -23,11 +23,7 @@ IRoundDown::IRoundDown() : IndicatorImp("ROUNDDOWN", 1) {
|
||||
IRoundDown::~IRoundDown() {}
|
||||
|
||||
bool IRoundDown::check() {
|
||||
if (getParam<int>("ndigits") < 0) {
|
||||
HKU_ERROR("Invalid param[ndigits] ! (n >= 0) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return getParam<int>("ndigits") >= 0;
|
||||
}
|
||||
|
||||
void IRoundDown::_calculate(const Indicator& data) {
|
||||
|
@ -23,11 +23,7 @@ IRoundUp::IRoundUp() : IndicatorImp("ROUNDUP", 1) {
|
||||
IRoundUp::~IRoundUp() {}
|
||||
|
||||
bool IRoundUp::check() {
|
||||
if (getParam<int>("ndigits") < 0) {
|
||||
HKU_ERROR("Invalid param[ndigits] ! (n >= 0) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return getParam<int>("ndigits") >= 0;
|
||||
}
|
||||
|
||||
void IRoundUp::_calculate(const Indicator& data) {
|
||||
|
@ -23,12 +23,7 @@ ISma::ISma() : IndicatorImp("SMA", 1) {
|
||||
ISma::~ISma() {}
|
||||
|
||||
bool ISma::check() {
|
||||
int n = getParam<int>("n");
|
||||
if (n < 1) {
|
||||
HKU_ERROR("Invalid param! (n >= 1)");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return getParam<int>("n") >= 1;
|
||||
}
|
||||
|
||||
void ISma::_calculate(const Indicator& ind) {
|
||||
|
@ -23,13 +23,7 @@ IStdp::IStdp() : IndicatorImp("STDP", 1) {
|
||||
IStdp::~IStdp() {}
|
||||
|
||||
bool IStdp::check() {
|
||||
int n = getParam<int>("n");
|
||||
if (n < 2) {
|
||||
HKU_ERROR("Invalid param[n] ! (n >= 2) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return getParam<int>("n") >= 2;
|
||||
}
|
||||
|
||||
void IStdp::_calculate(const Indicator& data) {
|
||||
|
@ -20,12 +20,7 @@ ISum::ISum() : IndicatorImp("SUM", 1) {
|
||||
ISum::~ISum() {}
|
||||
|
||||
bool ISum::check() {
|
||||
int n = getParam<int>("n");
|
||||
if (n < 0) {
|
||||
HKU_ERROR("Invalid param[n] ! (n >= 0) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return getParam<int>("n") >= 0;
|
||||
}
|
||||
|
||||
void ISum::_calculate(const Indicator& ind) {
|
||||
|
@ -29,13 +29,12 @@ ITimeLine::ITimeLine(const KData& k) : IndicatorImp("TIMELINE", 1) {
|
||||
|
||||
bool ITimeLine::check() {
|
||||
string part = getParam<string>("part");
|
||||
return part != "price" && part != "vol" ? false : true;
|
||||
return part == "price" || part == "vol";
|
||||
}
|
||||
|
||||
void ITimeLine::_calculate(const Indicator& data) {
|
||||
if (!isLeaf() && !data.empty()) {
|
||||
HKU_WARN("The input is ignored because {} depends on the context!", m_name);
|
||||
}
|
||||
HKU_WARN_IF(!isLeaf() && !data.empty(),
|
||||
"The input is ignored because {} depends on the context!", m_name);
|
||||
|
||||
KData k = getContext();
|
||||
KQuery q = k.getQuery();
|
||||
@ -43,9 +42,7 @@ void ITimeLine::_calculate(const Indicator& data) {
|
||||
|
||||
TimeLineList time_line = stk.getTimeLineList(q);
|
||||
size_t total = time_line.size();
|
||||
if (total == 0) {
|
||||
return;
|
||||
}
|
||||
HKU_IF_RETURN(total == 0, void());
|
||||
|
||||
_readyBuffer(total, 1);
|
||||
|
||||
|
@ -23,13 +23,7 @@ IVar::IVar() : IndicatorImp("VAR", 1) {
|
||||
IVar::~IVar() {}
|
||||
|
||||
bool IVar::check() {
|
||||
int n = getParam<int>("n");
|
||||
if (n < 2) {
|
||||
HKU_ERROR("Invalid param[n] ! (n >= 2) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return getParam<int>("n") >= 2;
|
||||
}
|
||||
|
||||
void IVar::_calculate(const Indicator& data) {
|
||||
|
@ -23,13 +23,7 @@ IVarp::IVarp() : IndicatorImp("VARP", 1) {
|
||||
IVarp::~IVarp() {}
|
||||
|
||||
bool IVarp::check() {
|
||||
int n = getParam<int>("n");
|
||||
if (n < 2) {
|
||||
HKU_ERROR("Invalid param[n] ! (n >= 2) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return getParam<int>("n") >= 2;
|
||||
}
|
||||
|
||||
void IVarp::_calculate(const Indicator& data) {
|
||||
|
@ -23,20 +23,12 @@ Macd::Macd() : IndicatorImp("MACD", 3) {
|
||||
Macd::~Macd() {}
|
||||
|
||||
bool Macd::check() {
|
||||
int n1 = getParam<int>("n1");
|
||||
int n2 = getParam<int>("n2");
|
||||
int n3 = getParam<int>("n3");
|
||||
if (n1 <= 0 || n2 <= 0 || n3 <= 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return getParam<int>("n1") > 0 && getParam<int>("n2") > 0 && getParam<int>("n3") > 0;
|
||||
}
|
||||
|
||||
void Macd::_calculate(const Indicator& data) {
|
||||
size_t total = data.size();
|
||||
if (total == 0) {
|
||||
return;
|
||||
}
|
||||
HKU_IF_RETURN(total == 0, void());
|
||||
|
||||
_readyBuffer(total, 3);
|
||||
|
||||
|
@ -20,13 +20,7 @@ RightShift::RightShift() : IndicatorImp("REF", 1) {
|
||||
RightShift::~RightShift() {}
|
||||
|
||||
bool RightShift::check() {
|
||||
int n = getParam<int>("n");
|
||||
if (n < 0) {
|
||||
HKU_ERROR("Invalid param! (n>=0) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return getParam<int>("n") >= 0;
|
||||
}
|
||||
|
||||
void RightShift::_calculate(const Indicator& data) {
|
||||
|
@ -22,27 +22,12 @@ SaftyLoss::SaftyLoss() : IndicatorImp("SAFTYLOSS", 1) {
|
||||
SaftyLoss::~SaftyLoss() {}
|
||||
|
||||
bool SaftyLoss::check() {
|
||||
int n1 = getParam<int>("n1");
|
||||
int n2 = getParam<int>("n2");
|
||||
|
||||
if (n1 < 2) {
|
||||
HKU_ERROR("Invalid param[n1] must >= 2 !");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (n2 < 1) {
|
||||
HKU_ERROR("Invalid param[n2] must >= 1 !");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return getParam<int>("n1") >= 2 && getParam<int>("n2") >= 1;
|
||||
}
|
||||
|
||||
void SaftyLoss::_calculate(const Indicator& data) {
|
||||
size_t total = data.size();
|
||||
if (total == 0) {
|
||||
return;
|
||||
}
|
||||
HKU_IF_RETURN(total == 0, void());
|
||||
_readyBuffer(total, 1);
|
||||
|
||||
int n1 = getParam<int>("n1");
|
||||
|
@ -21,13 +21,7 @@ StdDeviation::StdDeviation() : IndicatorImp("STD", 1) {
|
||||
StdDeviation::~StdDeviation() {}
|
||||
|
||||
bool StdDeviation::check() {
|
||||
int n = getParam<int>("n");
|
||||
if (n < 2) {
|
||||
HKU_ERROR("Invalid param[n] ! (n >= 2) {}", m_params);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return getParam<int>("n") >= 2;
|
||||
}
|
||||
|
||||
void StdDeviation::_calculate(const Indicator& data) {
|
||||
|
@ -28,19 +28,12 @@ Vigor::Vigor(int n) : IndicatorImp("VIGOR") {
|
||||
Vigor::~Vigor() {}
|
||||
|
||||
bool Vigor::check() {
|
||||
int n = getParam<int>("n");
|
||||
if (n < 1) {
|
||||
HKU_ERROR("Invalide param[n] must >= 1 !");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return getParam<int>("n") >= 1;
|
||||
}
|
||||
|
||||
void Vigor::_calculate(const Indicator& ind) {
|
||||
if (!isLeaf() && !ind.empty()) {
|
||||
HKU_WARN("The input is ignored because {} depends on the context!", m_name);
|
||||
}
|
||||
HKU_WARN_IF(!isLeaf() && !ind.empty(),
|
||||
"The input is ignored because {} depends on the context!", m_name);
|
||||
|
||||
KData kdata = getContext();
|
||||
size_t total = kdata.size();
|
||||
|
@ -37,13 +37,10 @@ std::string CostRecord::toString() const {
|
||||
}
|
||||
|
||||
bool HKU_API operator==(const CostRecord& d1, const CostRecord& d2) {
|
||||
if (std::fabs(d1.commission - d2.commission) < 0.0001 &&
|
||||
std::fabs(d1.stamptax - d2.stamptax) < 0.0001 &&
|
||||
std::fabs(d1.transferfee - d2.transferfee) < 0.0001 &&
|
||||
std::fabs(d1.others - d2.others) < 0.0001 && std::fabs(d1.total - d2.total) < 0.0001) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return (std::fabs(d1.commission - d2.commission) < 0.0001 &&
|
||||
std::fabs(d1.stamptax - d2.stamptax) < 0.0001 &&
|
||||
std::fabs(d1.transferfee - d2.transferfee) < 0.0001 &&
|
||||
std::fabs(d1.others - d2.others) < 0.0001 && std::fabs(d1.total - d2.total) < 0.0001);
|
||||
}
|
||||
|
||||
} /* namespace hku */
|
||||
|
@ -67,16 +67,13 @@ FundsRecord& FundsRecord::operator+=(const FundsRecord other) {
|
||||
}
|
||||
|
||||
bool HKU_API operator==(const FundsRecord& d1, const FundsRecord& d2) {
|
||||
if (std::fabs(d1.cash - d2.cash) < 0.0001 &&
|
||||
std::fabs(d1.market_value - d2.market_value) < 0.0001 &&
|
||||
std::fabs(d1.short_market_value - d2.short_market_value) < 0.0001 &&
|
||||
std::fabs(d1.base_cash - d2.base_cash) < 0.0001 &&
|
||||
std::fabs(d1.base_asset - d2.base_asset) < 0.0001 &&
|
||||
std::fabs(d1.borrow_cash - d2.borrow_cash) < 0.0001 &&
|
||||
std::fabs(d1.borrow_asset - d2.borrow_asset) < 0.0001) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return (std::fabs(d1.cash - d2.cash) < 0.0001 &&
|
||||
std::fabs(d1.market_value - d2.market_value) < 0.0001 &&
|
||||
std::fabs(d1.short_market_value - d2.short_market_value) < 0.0001 &&
|
||||
std::fabs(d1.base_cash - d2.base_cash) < 0.0001 &&
|
||||
std::fabs(d1.base_asset - d2.base_asset) < 0.0001 &&
|
||||
std::fabs(d1.borrow_cash - d2.borrow_cash) < 0.0001 &&
|
||||
std::fabs(d1.borrow_asset - d2.borrow_asset) < 0.0001);
|
||||
}
|
||||
|
||||
} /* namespace hku */
|
||||
|
@ -96,15 +96,12 @@ string PositionRecord::toString() const {
|
||||
}
|
||||
|
||||
bool HKU_API operator==(const PositionRecord& d1, const PositionRecord& d2) {
|
||||
if (d1.stock == d2.stock && d1.takeDatetime == d2.takeDatetime &&
|
||||
d1.cleanDatetime == d2.cleanDatetime && fabs(d1.number - d2.number) < 0.00001 &&
|
||||
fabs(d1.stoploss - d2.stoploss) < 0.0001 && fabs(d1.goalPrice - d2.goalPrice) < 0.0001 &&
|
||||
fabs(d1.totalNumber - d2.totalNumber) < 0.00001 &&
|
||||
fabs(d1.buyMoney - d2.buyMoney) < 0.0001 && fabs(d1.totalCost - d2.totalCost) < 0.0001 &&
|
||||
fabs(d1.sellMoney - d2.sellMoney) < 0.0001) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return d1.stock == d2.stock && d1.takeDatetime == d2.takeDatetime &&
|
||||
d1.cleanDatetime == d2.cleanDatetime && fabs(d1.number - d2.number) < 0.00001 &&
|
||||
fabs(d1.stoploss - d2.stoploss) < 0.0001 && fabs(d1.goalPrice - d2.goalPrice) < 0.0001 &&
|
||||
fabs(d1.totalNumber - d2.totalNumber) < 0.00001 &&
|
||||
fabs(d1.buyMoney - d2.buyMoney) < 0.0001 && fabs(d1.totalCost - d2.totalCost) < 0.0001 &&
|
||||
fabs(d1.sellMoney - d2.sellMoney) < 0.0001;
|
||||
}
|
||||
|
||||
} /* namespace hku */
|
||||
|
@ -238,9 +238,7 @@ Datetime TradeManager::firstDatetime() const {
|
||||
|
||||
double TradeManager ::getHoldNumber(const Datetime& datetime, const Stock& stock) {
|
||||
//日期小于账户建立日期,返回0
|
||||
if (datetime < m_init_datetime) {
|
||||
return 0.0;
|
||||
}
|
||||
HKU_IF_RETURN(datetime < m_init_datetime, 0.0);
|
||||
|
||||
//根据权息信息调整持仓数量
|
||||
_update(datetime);
|
||||
@ -282,9 +280,7 @@ double TradeManager ::getHoldNumber(const Datetime& datetime, const Stock& stock
|
||||
|
||||
double TradeManager ::getShortHoldNumber(const Datetime& datetime, const Stock& stock) {
|
||||
//日期小于账户建立日期,返回0
|
||||
if (datetime < m_init_datetime) {
|
||||
return 0;
|
||||
}
|
||||
HKU_IF_RETURN(datetime < m_init_datetime, 0.0);
|
||||
|
||||
//根据权息信息调整持仓数量
|
||||
_update(datetime);
|
||||
@ -323,9 +319,7 @@ double TradeManager ::getShortHoldNumber(const Datetime& datetime, const Stock&
|
||||
}
|
||||
|
||||
double TradeManager ::getDebtNumber(const Datetime& datetime, const Stock& stock) {
|
||||
if (datetime < m_init_datetime) {
|
||||
return 0;
|
||||
}
|
||||
HKU_IF_RETURN(datetime < m_init_datetime, 0.0);
|
||||
|
||||
//根据权息信息调整持仓数量
|
||||
_update(datetime);
|
||||
@ -357,16 +351,12 @@ double TradeManager ::getDebtNumber(const Datetime& datetime, const Stock& stock
|
||||
}
|
||||
|
||||
price_t TradeManager::getDebtCash(const Datetime& datetime) {
|
||||
if (datetime < m_init_datetime) {
|
||||
return 0.0;
|
||||
}
|
||||
HKU_IF_RETURN(datetime < m_init_datetime, 0.0);
|
||||
|
||||
//根据权息信息调整持仓数量
|
||||
_update(datetime);
|
||||
|
||||
if (datetime >= lastDatetime()) {
|
||||
return m_borrow_cash;
|
||||
}
|
||||
HKU_IF_RETURN(datetime >= lastDatetime(), m_borrow_cash);
|
||||
|
||||
price_t debt_cash = 0.0;
|
||||
TradeRecordList::const_iterator iter = m_trade_list.begin();
|
||||
@ -386,14 +376,10 @@ price_t TradeManager::getDebtCash(const Datetime& datetime) {
|
||||
TradeRecordList TradeManager ::getTradeList(const Datetime& start_date,
|
||||
const Datetime& end_date) const {
|
||||
TradeRecordList result;
|
||||
if (start_date >= end_date) {
|
||||
return result;
|
||||
}
|
||||
HKU_IF_RETURN(start_date >= end_date, result);
|
||||
|
||||
size_t total = m_trade_list.size();
|
||||
if (total == 0) {
|
||||
return result;
|
||||
}
|
||||
HKU_IF_RETURN(total == 0, result);
|
||||
|
||||
TradeRecord temp_record;
|
||||
temp_record.datetime = start_date;
|
||||
@ -432,27 +418,17 @@ PositionRecordList TradeManager::getShortPositionList() const {
|
||||
}
|
||||
|
||||
PositionRecord TradeManager::getPosition(const Stock& stock) const {
|
||||
if (stock.isNull()) {
|
||||
return PositionRecord();
|
||||
}
|
||||
HKU_IF_RETURN(stock.isNull(), PositionRecord());
|
||||
position_map_type::const_iterator iter;
|
||||
iter = m_position.find(stock.id());
|
||||
if (iter == m_position.end()) {
|
||||
return PositionRecord();
|
||||
}
|
||||
return iter->second;
|
||||
return iter == m_position.end() ? PositionRecord() : iter->second;
|
||||
}
|
||||
|
||||
PositionRecord TradeManager::getShortPosition(const Stock& stock) const {
|
||||
if (stock.isNull()) {
|
||||
return PositionRecord();
|
||||
}
|
||||
HKU_IF_RETURN(stock.isNull(), PositionRecord());
|
||||
position_map_type::const_iterator iter;
|
||||
iter = m_short_position.find(stock.id());
|
||||
if (iter == m_short_position.end()) {
|
||||
return PositionRecord();
|
||||
}
|
||||
return iter->second;
|
||||
return iter == m_short_position.end() ? PositionRecord() : iter->second;
|
||||
}
|
||||
|
||||
BorrowRecordList TradeManager::getBorrowStockList() const {
|
||||
@ -465,15 +441,9 @@ BorrowRecordList TradeManager::getBorrowStockList() const {
|
||||
}
|
||||
|
||||
bool TradeManager::checkin(const Datetime& datetime, price_t cash) {
|
||||
if (cash <= 0.0) {
|
||||
HKU_ERROR("{} cash({:<.3f}) must be > 0! ", datetime, cash);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (datetime < lastDatetime()) {
|
||||
HKU_ERROR("{} datetime must be >= lastDatetime({})!", datetime, lastDatetime());
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(cash <= 0.0, false, "{} cash({:<.3f}) must be > 0! ", datetime, cash);
|
||||
HKU_ERROR_IF_RETURN(datetime < lastDatetime(), false,
|
||||
"{} datetime must be >= lastDatetime({})!", datetime, lastDatetime());
|
||||
|
||||
//根据权息调整当前持仓情况
|
||||
_update(datetime);
|
||||
@ -489,25 +459,18 @@ bool TradeManager::checkin(const Datetime& datetime, price_t cash) {
|
||||
}
|
||||
|
||||
bool TradeManager::checkout(const Datetime& datetime, price_t cash) {
|
||||
if (cash <= 0.0) {
|
||||
HKU_ERROR("{} cash({:<.4f}) must be > 0! ", datetime, cash);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (datetime < lastDatetime()) {
|
||||
HKU_ERROR("{} datetime must be >= lastDatetime({})!", datetime, lastDatetime());
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(cash <= 0.0, false, "{} cash({:<.4f}) must be > 0! ", datetime, cash);
|
||||
HKU_ERROR_IF_RETURN(datetime < lastDatetime(), false,
|
||||
"{} datetime must be >= lastDatetime({})!", datetime, lastDatetime());
|
||||
|
||||
//根据权息调整当前持仓情况
|
||||
_update(datetime);
|
||||
|
||||
int precision = getParam<int>("precision");
|
||||
price_t out_cash = roundEx(cash, precision);
|
||||
if (out_cash > m_cash) {
|
||||
HKU_ERROR("{} cash({:<.4f}) must be <= current cash({:<.4f})!", datetime, cash, m_cash);
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(out_cash > m_cash, false,
|
||||
"{} cash({:<.4f}) must be <= current cash({:<.4f})!", datetime, cash,
|
||||
m_cash);
|
||||
|
||||
m_cash = roundEx(m_cash - out_cash, precision);
|
||||
m_checkout_cash = roundEx(m_checkout_cash + out_cash, precision);
|
||||
@ -519,26 +482,13 @@ bool TradeManager::checkout(const Datetime& datetime, price_t cash) {
|
||||
|
||||
bool TradeManager ::checkinStock(const Datetime& datetime, const Stock& stock, price_t price,
|
||||
double number) {
|
||||
if (stock.isNull()) {
|
||||
HKU_ERROR("{} Try checkin Null stock!", datetime);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (number == 0) {
|
||||
HKU_ERROR("{} {} number is zero!", datetime, stock.market_code());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (price <= 0) {
|
||||
HKU_ERROR("{} {} price({:<.4f}) must be > 0!", datetime, stock.market_code(), price);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (datetime < lastDatetime()) {
|
||||
HKU_ERROR("{} {} datetime must be >= lastDatetime({})!", datetime, stock.market_code(),
|
||||
lastDatetime());
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(stock.isNull(), false, "{} Try checkin Null stock!", datetime);
|
||||
HKU_ERROR_IF_RETURN(number == 0, false, "{} {} number is zero!", datetime, stock.market_code());
|
||||
HKU_ERROR_IF_RETURN(price <= 0, false, "{} {} price({:<.4f}) must be > 0!", datetime,
|
||||
stock.market_code(), price);
|
||||
HKU_ERROR_IF_RETURN(datetime < lastDatetime(), false,
|
||||
"{} {} datetime must be >= lastDatetime({})!", datetime,
|
||||
stock.market_code(), lastDatetime());
|
||||
|
||||
//根据权息调整当前持仓情况
|
||||
_update(datetime);
|
||||
@ -573,45 +523,27 @@ bool TradeManager ::checkinStock(const Datetime& datetime, const Stock& stock, p
|
||||
|
||||
bool TradeManager ::checkoutStock(const Datetime& datetime, const Stock& stock, price_t price,
|
||||
double number) {
|
||||
if (stock.isNull()) {
|
||||
HKU_ERROR("{} Try checkout Null stock!", datetime);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (number == 0) {
|
||||
HKU_ERROR("{} {} checkout number is zero!", datetime, stock.market_code());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (price <= 0.0) {
|
||||
HKU_ERROR("{} {} checkout price({:<.4f}) must be > 0.0! ", datetime, stock.market_code(),
|
||||
price);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (datetime < lastDatetime()) {
|
||||
HKU_ERROR("{} {} datetime must be >= lastDatetime({})!", datetime, stock.market_code(),
|
||||
lastDatetime());
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(stock.isNull(), false, "{} Try checkout Null stock!", datetime);
|
||||
HKU_ERROR_IF_RETURN(number == 0, false, "{} {} checkout number is zero!", datetime,
|
||||
stock.market_code());
|
||||
HKU_ERROR_IF_RETURN(price <= 0.0, false, "{} {} checkout price({:<.4f}) must be > 0.0! ",
|
||||
datetime, stock.market_code(), price);
|
||||
HKU_ERROR_IF_RETURN(datetime < lastDatetime(), false,
|
||||
"{} {} datetime must be >= lastDatetime({})!", datetime,
|
||||
stock.market_code(), lastDatetime());
|
||||
|
||||
//根据权息调整当前持仓情况
|
||||
_update(datetime);
|
||||
|
||||
//当前是否有持仓
|
||||
position_map_type::iterator pos_iter = m_position.find(stock.id());
|
||||
if (pos_iter == m_position.end()) {
|
||||
HKU_ERROR("Try to checkout nonexistent stock!");
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(pos_iter == m_position.end(), false, "Try to checkout nonexistent stock!");
|
||||
|
||||
PositionRecord& pos = pos_iter->second;
|
||||
//取出数量超出了当前持仓数量
|
||||
if (number > pos.number) {
|
||||
HKU_ERROR("{} {} Try to checkout number({}) beyond position number({})!", datetime,
|
||||
stock.market_code(), number, pos.number);
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(number > pos.number, false,
|
||||
"{} {} Try to checkout number({}) beyond position number({})!", datetime,
|
||||
stock.market_code(), number, pos.number);
|
||||
|
||||
int precision = getParam<int>("precision");
|
||||
pos.number -= number;
|
||||
@ -634,15 +566,9 @@ bool TradeManager ::checkoutStock(const Datetime& datetime, const Stock& stock,
|
||||
}
|
||||
|
||||
bool TradeManager::borrowCash(const Datetime& datetime, price_t cash) {
|
||||
if (cash <= 0.0) {
|
||||
HKU_ERROR("{} cash({:<.4f}) must be > 0!", datetime, cash);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (datetime < lastDatetime()) {
|
||||
HKU_ERROR("{} datetime must be >= lastDatetime({})!", datetime, lastDatetime());
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(cash <= 0.0, false, "{} cash({:<.4f}) must be > 0!", datetime, cash);
|
||||
HKU_ERROR_IF_RETURN(datetime < lastDatetime(), false,
|
||||
"{} datetime must be >= lastDatetime({})!", datetime, lastDatetime());
|
||||
|
||||
//根据权息调整当前持仓情况
|
||||
_update(datetime);
|
||||
@ -659,26 +585,13 @@ bool TradeManager::borrowCash(const Datetime& datetime, price_t cash) {
|
||||
}
|
||||
|
||||
bool TradeManager::returnCash(const Datetime& datetime, price_t cash) {
|
||||
if (cash <= 0.0) {
|
||||
HKU_ERROR("{} cash({:<.4f}) must be > 0! ", datetime, cash);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (datetime < lastDatetime()) {
|
||||
HKU_ERROR("{} datetime must be >= lastDatetime({})!", datetime, lastDatetime());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_loan_list.empty()) {
|
||||
HKU_ERROR("{} not borrow any cash!", datetime);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (datetime < m_loan_list.back().datetime) {
|
||||
HKU_ERROR("{} must be >= the datetime({}) of last loan record!", datetime,
|
||||
m_loan_list.back().datetime);
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(cash <= 0.0, false, "{} cash({:<.4f}) must be > 0! ", datetime, cash);
|
||||
HKU_ERROR_IF_RETURN(datetime < lastDatetime(), false,
|
||||
"{} datetime must be >= lastDatetime({})!", datetime, lastDatetime());
|
||||
HKU_ERROR_IF_RETURN(m_loan_list.empty(), false, "{} not borrow any cash!", datetime);
|
||||
HKU_ERROR_IF_RETURN(datetime < m_loan_list.back().datetime, false,
|
||||
"{} must be >= the datetime({}) of last loan record!", datetime,
|
||||
m_loan_list.back().datetime);
|
||||
|
||||
//根据权息调整当前持仓情况
|
||||
_update(datetime);
|
||||
@ -707,17 +620,14 @@ bool TradeManager::returnCash(const Datetime& datetime, price_t cash) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (return_cash != 0.0) {
|
||||
//欲归还的钱多余实际欠款
|
||||
HKU_ERROR("{} return cash must <= borrowed cash!", datetime);
|
||||
return false;
|
||||
}
|
||||
//欲归还的钱多余实际欠款
|
||||
HKU_ERROR_IF_RETURN(return_cash != 0.0, false, "{} return cash must <= borrowed cash!",
|
||||
datetime);
|
||||
|
||||
price_t out_cash = roundEx(in_cash + cost.total, precision);
|
||||
if (out_cash > m_cash) {
|
||||
HKU_ERROR("{} cash({:<.4f}) must be <= current cash({:<.4f})!", datetime, cash, m_cash);
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(out_cash > m_cash, false,
|
||||
"{} cash({:<.4f}) must be <= current cash({:<.4f})!", datetime, cash,
|
||||
m_cash);
|
||||
|
||||
return_cash = in_cash;
|
||||
do {
|
||||
@ -743,26 +653,14 @@ bool TradeManager::returnCash(const Datetime& datetime, price_t cash) {
|
||||
|
||||
bool TradeManager ::borrowStock(const Datetime& datetime, const Stock& stock, price_t price,
|
||||
double number) {
|
||||
if (stock.isNull()) {
|
||||
HKU_ERROR("{} Try checkin Null stock!", datetime);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (datetime < lastDatetime()) {
|
||||
HKU_ERROR("{} {} datetime must be >= lastDatetime({})!", datetime, stock.market_code(),
|
||||
lastDatetime());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (number == 0) {
|
||||
HKU_ERROR("{} {} Try to borrow number is zero!", datetime, stock.market_code());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (price <= 0.0) {
|
||||
HKU_ERROR("{} {} price({:<.4f}) must be > 0!", datetime, stock.market_code(), price);
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(stock.isNull(), false, "{} Try checkin Null stock!", datetime);
|
||||
HKU_ERROR_IF_RETURN(datetime < lastDatetime(), false,
|
||||
"{} {} datetime must be >= lastDatetime({})!", datetime,
|
||||
stock.market_code(), lastDatetime());
|
||||
HKU_ERROR_IF_RETURN(number == 0, false, "{} {} Try to borrow number is zero!", datetime,
|
||||
stock.market_code());
|
||||
HKU_ERROR_IF_RETURN(price <= 0.0, false, "{} {} price({:<.4f}) must be > 0!", datetime,
|
||||
stock.market_code(), price);
|
||||
|
||||
//根据权息调整当前持仓情况
|
||||
_update(datetime);
|
||||
@ -799,45 +697,31 @@ bool TradeManager ::borrowStock(const Datetime& datetime, const Stock& stock, pr
|
||||
|
||||
bool TradeManager ::returnStock(const Datetime& datetime, const Stock& stock, price_t price,
|
||||
double number) {
|
||||
if (stock.isNull()) {
|
||||
HKU_ERROR("{} Try checkout Null stock!", datetime);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (datetime < lastDatetime()) {
|
||||
HKU_ERROR("{} {} datetime must be >= lastDatetime({})!", datetime, stock.market_code(),
|
||||
lastDatetime());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (number == 0) {
|
||||
HKU_ERROR("{} {} return stock number is zero!", datetime, stock.market_code());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (price <= 0.0) {
|
||||
HKU_ERROR("{} {} price({:<.4f}) must be > 0!", datetime, stock.market_code(), price);
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(stock.isNull(), false, "{} Try checkout Null stock!", datetime);
|
||||
HKU_ERROR_IF_RETURN(datetime < lastDatetime(), false,
|
||||
"{} {} datetime must be >= lastDatetime({})!", datetime,
|
||||
stock.market_code(), lastDatetime());
|
||||
HKU_ERROR_IF_RETURN(number == 0, false, "{} {} return stock number is zero!", datetime,
|
||||
stock.market_code());
|
||||
HKU_ERROR_IF_RETURN(price <= 0.0, false, "{} {} price({:<.4f}) must be > 0!", datetime,
|
||||
stock.market_code(), price);
|
||||
|
||||
//根据权息调整当前持仓情况
|
||||
_update(datetime);
|
||||
|
||||
//查询借入股票信息
|
||||
borrow_stock_map_type::iterator bor_iter = m_borrow_stock.find(stock.id());
|
||||
if (bor_iter == m_borrow_stock.end()) {
|
||||
//并未借入股票
|
||||
HKU_ERROR("{} {} Try to return nonborrowed stock! ", datetime, stock.market_code());
|
||||
return false;
|
||||
}
|
||||
|
||||
//并未借入股票
|
||||
HKU_ERROR_IF_RETURN(bor_iter == m_borrow_stock.end(), false,
|
||||
"{} {} Try to return nonborrowed stock! ", datetime, stock.market_code());
|
||||
|
||||
BorrowRecord& bor = bor_iter->second;
|
||||
if (number > bor.number) {
|
||||
//欲归还的数量大于借入的数量
|
||||
HKU_ERROR("{} {} Try to return number({}) > borrow number({})!", datetime,
|
||||
stock.market_code(), number, bor.number);
|
||||
return false;
|
||||
}
|
||||
|
||||
//欲归还的数量大于借入的数量
|
||||
HKU_ERROR_IF_RETURN(number > bor.number, false,
|
||||
"{} {} Try to return number({}) > borrow number({})!", datetime,
|
||||
stock.market_code(), number, bor.number);
|
||||
|
||||
//更新借入股票信息
|
||||
int precision = getParam<int>("precision");
|
||||
@ -905,33 +789,17 @@ TradeRecord TradeManager::buy(const Datetime& datetime, const Stock& stock, pric
|
||||
TradeRecord result;
|
||||
result.business = BUSINESS_INVALID;
|
||||
|
||||
if (stock.isNull()) {
|
||||
HKU_ERROR("{} Stock is Null!", datetime);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (datetime < lastDatetime()) {
|
||||
HKU_ERROR("{} {} datetime must be >= lastDatetime({})!", datetime, stock.market_code(),
|
||||
lastDatetime());
|
||||
return result;
|
||||
}
|
||||
|
||||
if (number == 0) {
|
||||
HKU_ERROR("{} {} numer is zero!", datetime, stock.market_code());
|
||||
return result;
|
||||
}
|
||||
|
||||
if (number < stock.minTradeNumber()) {
|
||||
HKU_ERROR("{} {} Buy number({}) must be >= minTradeNumber({})!", datetime,
|
||||
stock.market_code(), number, stock.minTradeNumber());
|
||||
return result;
|
||||
}
|
||||
|
||||
if (number > stock.maxTradeNumber()) {
|
||||
HKU_ERROR("{} {} Buy number({}) must be <= maxTradeNumber({})!", datetime,
|
||||
stock.market_code(), number, stock.maxTradeNumber());
|
||||
return result;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(stock.isNull(), result, "{} Stock is Null!", datetime);
|
||||
HKU_ERROR_IF_RETURN(datetime < lastDatetime(), result,
|
||||
"{} {} datetime must be >= lastDatetime({})!", datetime,
|
||||
stock.market_code(), lastDatetime());
|
||||
HKU_ERROR_IF_RETURN(number == 0, result, "{} {} numer is zero!", datetime, stock.market_code());
|
||||
HKU_ERROR_IF_RETURN(number < stock.minTradeNumber(), result,
|
||||
"{} {} Buy number({}) must be >= minTradeNumber({})!", datetime,
|
||||
stock.market_code(), number, stock.minTradeNumber());
|
||||
HKU_ERROR_IF_RETURN(number > stock.maxTradeNumber(), result,
|
||||
"{} {} Buy number({}) must be <= maxTradeNumber({})!", datetime,
|
||||
stock.market_code(), number, stock.maxTradeNumber());
|
||||
|
||||
#if 0 //取消此处的检查,放松限制,另外也可以提高效率。另外,TM只负责交易管理,不许检查
|
||||
//检查当日是否存在日线数据,不存在则认为不可交易
|
||||
@ -979,11 +847,9 @@ TradeRecord TradeManager::buy(const Datetime& datetime, const Stock& stock, pric
|
||||
borrowCash(datetime, roundUp(money, precision));
|
||||
}
|
||||
|
||||
if (m_cash < roundEx(money + cost.total, precision)) {
|
||||
HKU_WARN("{} {} Can't buy, need cash({:<.4f}) > current cash({:<.4f})!", datetime,
|
||||
stock.market_code(), roundEx(money + cost.total, precision), m_cash);
|
||||
return result;
|
||||
}
|
||||
HKU_WARN_IF_RETURN(m_cash < roundEx(money + cost.total, precision), result,
|
||||
"{} {} Can't buy, need cash({:<.4f}) > current cash({:<.4f})!", datetime,
|
||||
stock.market_code(), roundEx(money + cost.total, precision), m_cash);
|
||||
|
||||
//更新现金
|
||||
m_cash = roundEx(m_cash - money - cost.total, precision);
|
||||
@ -1032,42 +898,26 @@ TradeRecord TradeManager::sell(const Datetime& datetime, const Stock& stock, pri
|
||||
HKU_CHECK(!std::isnan(number), "sell number should be a valid double!");
|
||||
TradeRecord result;
|
||||
|
||||
if (stock.isNull()) {
|
||||
HKU_ERROR("{} Stock is Null!", datetime);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (datetime < lastDatetime()) {
|
||||
HKU_ERROR("{} {} datetime must be >= lastDatetime({})!", datetime, stock.market_code(),
|
||||
lastDatetime());
|
||||
return result;
|
||||
}
|
||||
|
||||
if (number == 0) {
|
||||
HKU_ERROR("{} {} number is zero!", datetime, stock.market_code());
|
||||
return result;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(stock.isNull(), result, "{} Stock is Null!", datetime);
|
||||
HKU_ERROR_IF_RETURN(datetime < lastDatetime(), result,
|
||||
"{} {} datetime must be >= lastDatetime({})!", datetime,
|
||||
stock.market_code(), lastDatetime());
|
||||
HKU_ERROR_IF_RETURN(number == 0, result, "{} {} number is zero!", datetime,
|
||||
stock.market_code());
|
||||
|
||||
//对于分红扩股造成不满足最小交易量整数倍的情况,只能通过number=MAX_DOUBLE的方式全仓卖出
|
||||
if (number < stock.minTradeNumber()) {
|
||||
HKU_ERROR("{} {} Sell number({}) must be >= minTradeNumber({})!", datetime,
|
||||
stock.market_code(), number, stock.minTradeNumber());
|
||||
return result;
|
||||
}
|
||||
|
||||
if (number != MAX_DOUBLE && number > stock.maxTradeNumber()) {
|
||||
HKU_ERROR("{} {} Sell number({}) must be <= maxTradeNumber({})!", datetime,
|
||||
stock.market_code(), number, stock.maxTradeNumber());
|
||||
return result;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(number < stock.minTradeNumber(), result,
|
||||
"{} {} Sell number({}) must be >= minTradeNumber({})!", datetime,
|
||||
stock.market_code(), number, stock.minTradeNumber());
|
||||
HKU_ERROR_IF_RETURN(number != MAX_DOUBLE && number > stock.maxTradeNumber(), result,
|
||||
"{} {} Sell number({}) must be <= maxTradeNumber({})!", datetime,
|
||||
stock.market_code(), number, stock.maxTradeNumber());
|
||||
|
||||
//未持仓
|
||||
position_map_type::iterator pos_iter = m_position.find(stock.id());
|
||||
if (pos_iter == m_position.end()) {
|
||||
HKU_WARN("{} {} This stock was not bought never! ({}, {:<.4f}, {}, {})", datetime,
|
||||
stock.market_code(), datetime, realPrice, number, from);
|
||||
return result;
|
||||
}
|
||||
HKU_WARN_IF_RETURN(pos_iter == m_position.end(), result,
|
||||
"{} {} This stock was not bought never! ({}, {:<.4f}, {}, {})", datetime,
|
||||
stock.market_code(), datetime, realPrice, number, from);
|
||||
|
||||
//根据权息调整当前持仓情况
|
||||
_update(datetime);
|
||||
@ -1076,12 +926,11 @@ TradeRecord TradeManager::sell(const Datetime& datetime, const Stock& stock, pri
|
||||
|
||||
//调整欲卖出的数量,如果卖出数量等于MAX_DOUBLE,则表示卖出全部
|
||||
double real_number = number == MAX_DOUBLE ? position.number : number;
|
||||
if (position.number < real_number) {
|
||||
//欲卖出的数量大于当前持仓的数量
|
||||
HKU_ERROR("{} {} Try to sell number({}) > number of position({})!", datetime,
|
||||
stock.market_code(), real_number, position.number);
|
||||
return result;
|
||||
}
|
||||
|
||||
//欲卖出的数量大于当前持仓的数量
|
||||
HKU_ERROR_IF_RETURN(position.number < real_number, result,
|
||||
"{} {} Try to sell number({}) > number of position({})!", datetime,
|
||||
stock.market_code(), real_number, position.number);
|
||||
|
||||
CostRecord cost = getSellCost(datetime, stock, realPrice, real_number);
|
||||
|
||||
@ -1136,39 +985,22 @@ TradeRecord TradeManager::sellShort(const Datetime& datetime, const Stock& stock
|
||||
TradeRecord result;
|
||||
result.business = BUSINESS_INVALID;
|
||||
|
||||
if (stock.isNull()) {
|
||||
HKU_ERROR("{} Stock is Null!", datetime);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (datetime < lastDatetime()) {
|
||||
HKU_ERROR("{} {} datetime must be >= lastDatetime({})!", datetime, stock.market_code(),
|
||||
lastDatetime());
|
||||
return result;
|
||||
}
|
||||
|
||||
if (number == 0) {
|
||||
HKU_ERROR("{} {} numer is zero! ", datetime, stock.market_code());
|
||||
return result;
|
||||
}
|
||||
|
||||
if (number < stock.minTradeNumber()) {
|
||||
HKU_ERROR("{} {} Buy number({}) must be >= minTradeNumber({})!", datetime,
|
||||
stock.market_code(), number, stock.minTradeNumber());
|
||||
return result;
|
||||
}
|
||||
|
||||
if (number > stock.maxTradeNumber()) {
|
||||
HKU_ERROR("{} {} Buy number({}) must be <= maxTradeNumber({})!", datetime,
|
||||
stock.market_code(), number, stock.maxTradeNumber());
|
||||
return result;
|
||||
}
|
||||
|
||||
if (stoploss != 0.0 && stoploss < realPrice) {
|
||||
HKU_ERROR("{} {} Sell short's stoploss({:<.4f}) must be > realPrice({:<.4f}) or = 0! ",
|
||||
datetime, stock.market_code(), stoploss, realPrice);
|
||||
return result;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(stock.isNull(), result, "{} Stock is Null!", datetime);
|
||||
HKU_ERROR_IF_RETURN(datetime < lastDatetime(), result,
|
||||
"{} {} datetime must be >= lastDatetime({})!", datetime,
|
||||
stock.market_code(), lastDatetime());
|
||||
HKU_ERROR_IF_RETURN(number == 0, result, "{} {} numer is zero! ", datetime,
|
||||
stock.market_code());
|
||||
HKU_ERROR_IF_RETURN(number < stock.minTradeNumber(), result,
|
||||
"{} {} Buy number({}) must be >= minTradeNumber({})!", datetime,
|
||||
stock.market_code(), number, stock.minTradeNumber());
|
||||
HKU_ERROR_IF_RETURN(number > stock.maxTradeNumber(), result,
|
||||
"{} {} Buy number({}) must be <= maxTradeNumber({})!", datetime,
|
||||
stock.market_code(), number, stock.maxTradeNumber());
|
||||
HKU_ERROR_IF_RETURN(
|
||||
stoploss != 0.0 && stoploss < realPrice, result,
|
||||
"{} {} Sell short's stoploss({:<.4f}) must be > realPrice({:<.4f}) or = 0! ", datetime,
|
||||
stock.market_code(), stoploss, realPrice);
|
||||
|
||||
//根据权息调整当前持仓情况
|
||||
_update(datetime);
|
||||
@ -1189,10 +1021,8 @@ TradeRecord TradeManager::sellShort(const Datetime& datetime, const Stock& stock
|
||||
//判断是否存在已借入的股票及其数量
|
||||
borrow_stock_map_type::const_iterator bor_iter;
|
||||
bor_iter = m_borrow_stock.find(stock.id());
|
||||
if (bor_iter == m_borrow_stock.end()) {
|
||||
HKU_ERROR("{} {} Non borrowed, can't sell short! ", datetime, stock.market_code());
|
||||
return result;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(bor_iter == m_borrow_stock.end(), result,
|
||||
"{} {} Non borrowed, can't sell short! ", datetime, stock.market_code());
|
||||
|
||||
double total_borrow_num = bor_iter->second.number;
|
||||
double can_sell_num = 0;
|
||||
@ -1203,10 +1033,8 @@ TradeRecord TradeManager::sellShort(const Datetime& datetime, const Stock& stock
|
||||
|
||||
} else {
|
||||
//借入的股票已经卖出过
|
||||
if (pos_iter->second.number >= total_borrow_num) {
|
||||
HKU_ERROR("{} {} Borrowed Stock had all selled!", datetime, stock.market_code());
|
||||
return result;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(pos_iter->second.number >= total_borrow_num, result,
|
||||
"{} {} Borrowed Stock had all selled!", datetime, stock.market_code());
|
||||
|
||||
//可以卖出的数量 = 借入的总数 - 已卖出的数量
|
||||
can_sell_num = total_borrow_num - pos_iter->second.number;
|
||||
@ -1256,41 +1084,23 @@ TradeRecord TradeManager::buyShort(const Datetime& datetime, const Stock& stock,
|
||||
double number, price_t stoploss, price_t goalPrice,
|
||||
price_t planPrice, SystemPart from) {
|
||||
TradeRecord result;
|
||||
|
||||
if (stock.isNull()) {
|
||||
HKU_ERROR("{} Stock is Null!", datetime);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (datetime < lastDatetime()) {
|
||||
HKU_ERROR("{} {} datetime must be >= lastDatetime({})!", datetime, stock.market_code(),
|
||||
lastDatetime());
|
||||
return result;
|
||||
}
|
||||
|
||||
if (number == 0) {
|
||||
HKU_ERROR("{} {} number is zero!", datetime, stock.market_code());
|
||||
return result;
|
||||
}
|
||||
|
||||
if (number < stock.minTradeNumber()) {
|
||||
HKU_ERROR("{} {} buyShort number({}) must be >= minTradeNumber({})!", datetime,
|
||||
stock.market_code(), number, stock.minTradeNumber());
|
||||
return result;
|
||||
}
|
||||
|
||||
if (number != MAX_DOUBLE && number > stock.maxTradeNumber()) {
|
||||
HKU_ERROR("{} {} buyShort number({}) must be <= maxTradeNumber({})!", datetime,
|
||||
stock.market_code(), number, stock.maxTradeNumber());
|
||||
return result;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(stock.isNull(), result, "{} Stock is Null!", datetime);
|
||||
HKU_ERROR_IF_RETURN(datetime < lastDatetime(), result,
|
||||
"{} {} datetime must be >= lastDatetime({})!", datetime,
|
||||
stock.market_code(), lastDatetime());
|
||||
HKU_ERROR_IF_RETURN(number == 0, result, "{} {} number is zero!", datetime,
|
||||
stock.market_code());
|
||||
HKU_ERROR_IF_RETURN(number < stock.minTradeNumber(), result,
|
||||
"{} {} buyShort number({}) must be >= minTradeNumber({})!", datetime,
|
||||
stock.market_code(), number, stock.minTradeNumber());
|
||||
HKU_ERROR_IF_RETURN(number != MAX_DOUBLE && number > stock.maxTradeNumber(), result,
|
||||
"{} {} buyShort number({}) must be <= maxTradeNumber({})!", datetime,
|
||||
stock.market_code(), number, stock.maxTradeNumber());
|
||||
|
||||
//未持有空头仓位
|
||||
position_map_type::iterator pos_iter = m_short_position.find(stock.id());
|
||||
if (pos_iter == m_short_position.end()) {
|
||||
HKU_WARN("{} {} This stock was not sell never! ", datetime, stock.market_code());
|
||||
return result;
|
||||
}
|
||||
HKU_WARN_IF_RETURN(pos_iter == m_short_position.end(), result,
|
||||
"{} {} This stock was not sell never! ", datetime, stock.market_code());
|
||||
|
||||
//根据权息调整当前持仓情况
|
||||
_update(datetime);
|
||||
@ -1382,9 +1192,7 @@ FundsRecord TradeManager ::getFunds(const Datetime& indatetime, KQuery::KType kt
|
||||
int precision = getParam<int>("precision");
|
||||
|
||||
// datetime为Null时,直接返回当前账户中的现金和买入时占用的资金,以及累计存取资金
|
||||
if (indatetime == Null<Datetime>() || indatetime == lastDatetime()) {
|
||||
return getFunds(ktype);
|
||||
}
|
||||
HKU_IF_RETURN(indatetime == Null<Datetime>() || indatetime == lastDatetime(), getFunds(ktype));
|
||||
|
||||
Datetime datetime(indatetime.year(), indatetime.month(), indatetime.day(), 11, 59);
|
||||
price_t market_value = 0.0;
|
||||
@ -1683,14 +1491,10 @@ PriceList TradeManager::getProfitCurve() {
|
||||
* 历史记录: 1) 2009/12/22 added
|
||||
*****************************************************************************/
|
||||
void TradeManager::_update(const Datetime& datetime) {
|
||||
if (!getParam<bool>("reinvest")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (datetime < lastDatetime()) {
|
||||
HKU_ERROR("{} update datetime should be < lastDatetime({})!", datetime, lastDatetime());
|
||||
return;
|
||||
}
|
||||
HKU_IF_RETURN(!getParam<bool>("reinvest"), void());
|
||||
HKU_ERROR_IF_RETURN(datetime < lastDatetime(), void(),
|
||||
"{} update datetime should be < lastDatetime({})!", datetime,
|
||||
lastDatetime());
|
||||
|
||||
//权息信息查询日期范围
|
||||
Datetime start_date(lastDatetime().date() + bd::days(1));
|
||||
@ -1761,9 +1565,7 @@ void TradeManager::_update(const Datetime& datetime) {
|
||||
}
|
||||
|
||||
void TradeManager::_saveAction(const TradeRecord& record) {
|
||||
if (getParam<bool>("save_action") == false)
|
||||
return;
|
||||
|
||||
HKU_IF_RETURN(getParam<bool>("save_action") == false, void());
|
||||
std::stringstream buf(std::stringstream::out);
|
||||
string my_tm("td = my_tm.");
|
||||
string sep(", ");
|
||||
@ -1833,10 +1635,7 @@ void TradeManager::tocsv(const string& path) {
|
||||
|
||||
//导出交易记录
|
||||
std::ofstream file(filename1.c_str());
|
||||
if (!file) {
|
||||
HKU_ERROR("Can't create file {}!", filename1);
|
||||
return;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(!file, void(), "Can't create file {}!", filename1);
|
||||
|
||||
file.setf(std::ios_base::fixed);
|
||||
file.precision(3);
|
||||
@ -1878,11 +1677,7 @@ void TradeManager::tocsv(const string& path) {
|
||||
|
||||
//导出已平仓记录
|
||||
file.open(filename2.c_str());
|
||||
if (!file) {
|
||||
HKU_ERROR("Can't create file {}!", filename2);
|
||||
return;
|
||||
}
|
||||
|
||||
HKU_ERROR_IF_RETURN(!file, void(), "Can't create file {}!", filename2);
|
||||
file << "#建仓日期,平仓日期,证券代码,证券名称,累计持仓数量,"
|
||||
"累计花费资金,累计交易成本,已转化资金,总盈利,累积风险"
|
||||
<< std::endl;
|
||||
@ -1899,11 +1694,7 @@ void TradeManager::tocsv(const string& path) {
|
||||
|
||||
//导出未平仓记录
|
||||
file.open(filename3.c_str());
|
||||
if (!file) {
|
||||
HKU_ERROR("Can't create file {}!", filename3);
|
||||
return;
|
||||
}
|
||||
|
||||
HKU_ERROR_IF_RETURN(!file, void(), "Can't create file {}!", filename3);
|
||||
file << "#建仓日期,平仓日期,证券代码,证券名称,当前持仓数量,累计持仓数量,"
|
||||
"累计花费资金,累计交易成本,已转化资金,累积风险,"
|
||||
"累计浮动盈亏,当前盈亏成本价"
|
||||
@ -1928,11 +1719,7 @@ void TradeManager::tocsv(const string& path) {
|
||||
//到处执行命令
|
||||
//导出已平仓记录
|
||||
file.open(filename4.c_str());
|
||||
if (!file) {
|
||||
HKU_ERROR("Can't create file {}!", filename4);
|
||||
return;
|
||||
}
|
||||
|
||||
HKU_ERROR_IF_RETURN(!file, void(), "Can't create file {}!", filename4);
|
||||
list<string>::const_iterator action_iter = m_actions.begin();
|
||||
for (; action_iter != m_actions.end(); ++action_iter) {
|
||||
file << *action_iter << std::endl;
|
||||
@ -1941,14 +1728,9 @@ void TradeManager::tocsv(const string& path) {
|
||||
}
|
||||
|
||||
bool TradeManager::addTradeRecord(const TradeRecord& tr) {
|
||||
if (BUSINESS_INIT == tr.business) {
|
||||
return _add_init_tr(tr);
|
||||
}
|
||||
|
||||
if (tr.datetime < lastDatetime()) {
|
||||
HKU_ERROR("tr.datetime must be >= lastDatetime({})!", lastDatetime());
|
||||
return false;
|
||||
}
|
||||
HKU_IF_RETURN(BUSINESS_INIT == tr.business, _add_init_tr(tr));
|
||||
HKU_ERROR_IF_RETURN(tr.datetime < lastDatetime(), false,
|
||||
"tr.datetime must be >= lastDatetime({})!", lastDatetime());
|
||||
|
||||
switch (tr.business) {
|
||||
case BUSINESS_INIT:
|
||||
@ -2016,29 +1798,18 @@ bool TradeManager::_add_init_tr(const TradeRecord& tr) {
|
||||
}
|
||||
|
||||
bool TradeManager::_add_buy_tr(const TradeRecord& tr) {
|
||||
if (tr.stock.isNull()) {
|
||||
HKU_ERROR("tr.stock is null!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tr.number == 0) {
|
||||
HKU_ERROR("tr.number is zero!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tr.number < tr.stock.minTradeNumber() || tr.number > tr.stock.maxTradeNumber()) {
|
||||
HKU_ERROR("tr.number out of range!");
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(tr.stock.isNull(), false, "tr.stock is null!");
|
||||
HKU_ERROR_IF_RETURN(tr.number == 0, false, "tr.number is zero!");
|
||||
HKU_ERROR_IF_RETURN(
|
||||
tr.number < tr.stock.minTradeNumber() || tr.number > tr.stock.maxTradeNumber(), false,
|
||||
"tr.number out of range!");
|
||||
|
||||
int precision = getParam<int>("precision");
|
||||
TradeRecord new_tr(tr);
|
||||
price_t money = roundEx(tr.realPrice * tr.number * tr.stock.unit(), precision);
|
||||
|
||||
if (m_cash < roundEx(money + tr.cost.total, precision)) {
|
||||
HKU_WARN("Don't have enough money!");
|
||||
return false;
|
||||
}
|
||||
HKU_WARN_IF_RETURN(m_cash < roundEx(money + tr.cost.total, precision), false,
|
||||
"Don't have enough money!");
|
||||
|
||||
m_cash = roundEx(m_cash - money - tr.cost.total, precision);
|
||||
new_tr.cash = m_cash;
|
||||
@ -2070,30 +1841,17 @@ bool TradeManager::_add_buy_tr(const TradeRecord& tr) {
|
||||
}
|
||||
|
||||
bool TradeManager::_add_sell_tr(const TradeRecord& tr) {
|
||||
if (tr.stock.isNull()) {
|
||||
HKU_ERROR("tr.stock is Null!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tr.number == 0) {
|
||||
HKU_ERROR("tr.number is zero!");
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(tr.stock.isNull(), false, "tr.stock is Null!");
|
||||
HKU_ERROR_IF_RETURN(tr.number == 0, false, "tr.number is zero!");
|
||||
|
||||
//未持仓
|
||||
position_map_type::iterator pos_iter = m_position.find(tr.stock.id());
|
||||
if (pos_iter == m_position.end()) {
|
||||
HKU_ERROR("No position!");
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(pos_iter == m_position.end(), false, "No position!");
|
||||
|
||||
PositionRecord& position = pos_iter->second;
|
||||
|
||||
if (position.number < tr.number) {
|
||||
//欲卖出的数量大于当前持仓的数量
|
||||
HKU_ERROR("Try sell number greater position!");
|
||||
return false;
|
||||
}
|
||||
//欲卖出的数量大于当前持仓的数量
|
||||
HKU_ERROR_IF_RETURN(position.number < tr.number, false, "Try sell number greater position!");
|
||||
|
||||
int precision = getParam<int>("precision");
|
||||
price_t money = roundEx(tr.realPrice * tr.number * tr.stock.unit(), precision);
|
||||
@ -2127,10 +1885,7 @@ bool TradeManager::_add_sell_tr(const TradeRecord& tr) {
|
||||
}
|
||||
|
||||
bool TradeManager::_add_gift_tr(const TradeRecord& tr) {
|
||||
if (tr.stock.isNull()) {
|
||||
HKU_ERROR("tr.stock is null!");
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(tr.stock.isNull(), false, "tr.stock is null!");
|
||||
|
||||
position_map_type::iterator pos_iter = m_position.find(tr.stock.id());
|
||||
if (pos_iter == m_position.end()) {
|
||||
@ -2149,21 +1904,11 @@ bool TradeManager::_add_gift_tr(const TradeRecord& tr) {
|
||||
}
|
||||
|
||||
bool TradeManager::_add_bonus_tr(const TradeRecord& tr) {
|
||||
if (tr.stock.isNull()) {
|
||||
HKU_ERROR("tr.stock is null!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tr.realPrice <= 0.0) {
|
||||
HKU_ERROR("tr.realPrice <= 0.0!");
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(tr.stock.isNull(), false, "tr.stock is null!");
|
||||
HKU_ERROR_IF_RETURN(tr.realPrice <= 0.0, false, "tr.realPrice <= 0.0!");
|
||||
|
||||
position_map_type::iterator pos_iter = m_position.find(tr.stock.id());
|
||||
if (pos_iter == m_position.end()) {
|
||||
HKU_ERROR("No position!");
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(pos_iter == m_position.end(), false, "No position!");
|
||||
|
||||
PositionRecord& position = pos_iter->second;
|
||||
position.sellMoney += tr.realPrice;
|
||||
@ -2176,11 +1921,7 @@ bool TradeManager::_add_bonus_tr(const TradeRecord& tr) {
|
||||
}
|
||||
|
||||
bool TradeManager::_add_checkin_tr(const TradeRecord& tr) {
|
||||
if (tr.realPrice <= 0.0) {
|
||||
HKU_ERROR("tr.realPrice <= 0.0!");
|
||||
return false;
|
||||
}
|
||||
|
||||
HKU_ERROR_IF_RETURN(tr.realPrice <= 0.0, false, "tr.realPrice <= 0.0!");
|
||||
int precision = getParam<int>("precision");
|
||||
price_t in_cash = roundEx(tr.realPrice, precision);
|
||||
m_cash = roundEx(m_cash + in_cash, precision);
|
||||
@ -2192,17 +1933,11 @@ bool TradeManager::_add_checkin_tr(const TradeRecord& tr) {
|
||||
}
|
||||
|
||||
bool TradeManager::_add_checkout_tr(const TradeRecord& tr) {
|
||||
if (tr.realPrice <= 0.0) {
|
||||
HKU_ERROR("tr.realPrice <= 0.0!");
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(tr.realPrice <= 0.0, false, "tr.realPrice <= 0.0!");
|
||||
|
||||
int precision = getParam<int>("precision");
|
||||
price_t out_cash = roundEx(tr.realPrice, precision);
|
||||
if (out_cash > m_cash) {
|
||||
HKU_ERROR("Checkout money > current cash!");
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(out_cash > m_cash, false, "Checkout money > current cash!");
|
||||
|
||||
m_cash = roundEx(m_cash - out_cash, precision);
|
||||
m_checkout_cash = roundEx(m_checkout_cash + out_cash, precision);
|
||||
|
@ -179,14 +179,12 @@ bool TradeRecord::isNull() const {
|
||||
}
|
||||
|
||||
bool HKU_API operator==(const TradeRecord& d1, const TradeRecord& d2) {
|
||||
if (d1.stock == d2.stock && d1.datetime == d2.datetime && d1.business == d2.business &&
|
||||
fabs(d1.planPrice - d2.planPrice) < 0.0001 && fabs(d1.realPrice - d2.realPrice) < 0.0001 &&
|
||||
fabs(d1.goalPrice - d2.goalPrice) < 0.0001 && fabs(d1.number - d2.number) < 0.000001 &&
|
||||
d1.cost == d2.cost && fabs(d1.stoploss - d2.stoploss) < 0.0001 &&
|
||||
fabs(d1.cash - d2.cash) < 0.0001 && d1.from == d2.from) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return d1.stock == d2.stock && d1.datetime == d2.datetime && d1.business == d2.business &&
|
||||
fabs(d1.planPrice - d2.planPrice) < 0.0001 &&
|
||||
fabs(d1.realPrice - d2.realPrice) < 0.0001 &&
|
||||
fabs(d1.goalPrice - d2.goalPrice) < 0.0001 && fabs(d1.number - d2.number) < 0.000001 &&
|
||||
d1.cost == d2.cost && fabs(d1.stoploss - d2.stoploss) < 0.0001 &&
|
||||
fabs(d1.cash - d2.cash) < 0.0001 && d1.from == d2.from;
|
||||
}
|
||||
|
||||
} /* namespace hku */
|
||||
|
@ -22,10 +22,7 @@ FixedA2015TradeCost::~FixedA2015TradeCost() {}
|
||||
CostRecord FixedA2015TradeCost::getBuyCost(const Datetime& datetime, const Stock& stock,
|
||||
price_t price, double num) const {
|
||||
CostRecord result;
|
||||
if (stock.isNull()) {
|
||||
HKU_WARN("Stock is Null!");
|
||||
return result;
|
||||
}
|
||||
HKU_WARN_IF_RETURN(stock.isNull(), result, "Stock is Null!");
|
||||
|
||||
int precision = stock.precision();
|
||||
price_t value = price * num;
|
||||
@ -47,10 +44,7 @@ CostRecord FixedA2015TradeCost::getBuyCost(const Datetime& datetime, const Stock
|
||||
CostRecord FixedA2015TradeCost::getSellCost(const Datetime& datetime, const Stock& stock,
|
||||
price_t price, double num) const {
|
||||
CostRecord result;
|
||||
if (stock.isNull()) {
|
||||
HKU_WARN("Stock is NULL!");
|
||||
return result;
|
||||
}
|
||||
HKU_WARN_IF_RETURN(stock.isNull(), result, "Stock is Null!");
|
||||
|
||||
int precision = stock.precision();
|
||||
price_t value = price * num;
|
||||
|
@ -22,11 +22,7 @@ FixedA2017TradeCost::~FixedA2017TradeCost() {}
|
||||
CostRecord FixedA2017TradeCost::getBuyCost(const Datetime& datetime, const Stock& stock,
|
||||
price_t price, double num) const {
|
||||
CostRecord result;
|
||||
if (stock.isNull()) {
|
||||
HKU_WARN("Stock is Null!");
|
||||
return result;
|
||||
}
|
||||
|
||||
HKU_WARN_IF_RETURN(stock.isNull(), result, "Stock is Null!");
|
||||
int precision = stock.precision();
|
||||
price_t value = price * num;
|
||||
result.commission = roundEx(value * getParam<price_t>("commission"), precision);
|
||||
|
@ -34,11 +34,7 @@ FixedATradeCost::~FixedATradeCost() {}
|
||||
CostRecord FixedATradeCost::getBuyCost(const Datetime& datetime, const Stock& stock, price_t price,
|
||||
double num) const {
|
||||
CostRecord result;
|
||||
if (stock.isNull()) {
|
||||
HKU_WARN("Stock is Null!");
|
||||
return result;
|
||||
}
|
||||
|
||||
HKU_WARN_IF_RETURN(stock.isNull(), result, "Stock is Null!");
|
||||
int precision = stock.precision();
|
||||
result.commission = roundEx(price * num * getParam<price_t>("commission"), precision);
|
||||
price_t lowestCommission = getParam<price_t>("lowest_commission");
|
||||
|
@ -86,10 +86,7 @@ void AllocateFundsBase::setReservePercent(double percent) {
|
||||
void AllocateFundsBase ::adjustFunds(const Datetime& date, const SystemList& se_list,
|
||||
const std::list<SYSPtr>& running_list) {
|
||||
int max_num = getParam<int>("max_sys_num");
|
||||
if (max_num <= 0) {
|
||||
HKU_ERROR("param(max_sys_num) need > 0!");
|
||||
return;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(max_num <= 0, void(), "param(max_sys_num) need > 0!");
|
||||
|
||||
if (getParam<bool>("adjust_running_sys")) {
|
||||
_adjust_with_running(date, se_list, running_list);
|
||||
@ -120,15 +117,11 @@ void AllocateFundsBase::_adjust_with_running(const Datetime& date, const SystemL
|
||||
const std::list<SYSPtr>& running_list) {
|
||||
// 计算当前选中系统列表的权重
|
||||
SystemWeightList sw_list = _allocateWeight(date, se_list);
|
||||
if (sw_list.size() == 0) {
|
||||
return;
|
||||
}
|
||||
HKU_IF_RETURN(sw_list.size() == 0, void());
|
||||
|
||||
// 如果运行中的系统数已大于等于允许的最大系统数,直接返回
|
||||
int max_num = getParam<int>("max_sys_num");
|
||||
if (running_list.size() >= max_num) {
|
||||
return;
|
||||
}
|
||||
HKU_IF_RETURN(running_list.size() >= max_num, void());
|
||||
|
||||
//构建实际分配权重大于零的的系统集合
|
||||
std::set<SYSPtr> selected_sets;
|
||||
@ -338,15 +331,11 @@ void AllocateFundsBase::_adjust_with_running(const Datetime& date, const SystemL
|
||||
|
||||
void AllocateFundsBase::_adjust_without_running(const Datetime& date, const SystemList& se_list,
|
||||
const std::list<SYSPtr>& running_list) {
|
||||
if (se_list.size() == 0) {
|
||||
return;
|
||||
}
|
||||
HKU_IF_RETURN(se_list.size() == 0, void());
|
||||
|
||||
//如果运行中的系统数已大于等于允许的最大系统数,直接返回
|
||||
int max_num = getParam<int>("max_sys_num");
|
||||
if (running_list.size() >= max_num) {
|
||||
return;
|
||||
}
|
||||
HKU_IF_RETURN(running_list.size() >= max_num, void());
|
||||
|
||||
// 计算选中系统中当前正在运行中的子系统
|
||||
std::set<SYSPtr> hold_sets;
|
||||
@ -364,9 +353,7 @@ void AllocateFundsBase::_adjust_without_running(const Datetime& date, const Syst
|
||||
|
||||
//获取计划分配的资产权重
|
||||
SystemWeightList sw_list = _allocateWeight(date, pure_se_list);
|
||||
if (sw_list.size() == 0) {
|
||||
return;
|
||||
}
|
||||
HKU_IF_RETURN(sw_list.size() == 0, void());
|
||||
|
||||
//按权重升序排序(注意:无法保证等权重的相对顺序,即使用stable_sort也一样,后面要倒序遍历)
|
||||
std::sort(
|
||||
@ -395,9 +382,7 @@ void AllocateFundsBase::_adjust_without_running(const Datetime& date, const Syst
|
||||
price_t reserve_funds = total_funds * m_reserve_percent;
|
||||
|
||||
// 如果当前现金小于等于需保留的资产,则直接返回
|
||||
if (m_shadow_tm->currentCash() <= reserve_funds) {
|
||||
return;
|
||||
}
|
||||
HKU_IF_RETURN(m_shadow_tm->currentCash() <= reserve_funds, void());
|
||||
|
||||
// 计算可用于分配的现金
|
||||
price_t can_allocate_cash = roundDown(m_shadow_tm->currentCash() - reserve_funds, precision);
|
||||
|
@ -62,10 +62,7 @@ ConditionPtr ConditionBase::clone() {
|
||||
void ConditionBase::setTO(const KData& kdata) {
|
||||
reset();
|
||||
m_kdata = kdata;
|
||||
if (!m_sg) {
|
||||
HKU_WARN("m_sg is NULL!");
|
||||
return;
|
||||
}
|
||||
HKU_WARN_IF_RETURN(!m_sg, void(), "m_sg is NULL!");
|
||||
if (!kdata.empty()) {
|
||||
_calculate();
|
||||
}
|
||||
@ -76,10 +73,7 @@ void ConditionBase::_addValid(const Datetime& datetime) {
|
||||
}
|
||||
|
||||
bool ConditionBase::isValid(const Datetime& datetime) {
|
||||
if (m_valid.count(datetime) != 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return m_valid.count(datetime) != 0;
|
||||
}
|
||||
|
||||
} /* namespace hku */
|
||||
|
@ -28,9 +28,7 @@ ConditionPtr OPLineCondition::_clone() {
|
||||
void OPLineCondition::_reset() {}
|
||||
|
||||
void OPLineCondition::_calculate() {
|
||||
if (m_kdata.size() == 0)
|
||||
return;
|
||||
|
||||
HKU_IF_RETURN(m_kdata.size() == 0, void());
|
||||
Stock stock = m_kdata.getStock();
|
||||
KQuery query = m_kdata.getQuery();
|
||||
SYSPtr sys = SYS_Simple();
|
||||
|
@ -65,10 +65,7 @@ void EnvironmentBase::_addValid(const Datetime& datetime) {
|
||||
}
|
||||
|
||||
bool EnvironmentBase::isValid(const Datetime& datetime) {
|
||||
if (m_valid.count(datetime) != 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return m_valid.count(datetime) != 0;
|
||||
}
|
||||
|
||||
} /* namespace hku */
|
||||
|
@ -33,9 +33,7 @@ void TwoLineEnvironment::_calculate() {
|
||||
string market = getParam<string>("market");
|
||||
const StockManager& sm = StockManager::instance();
|
||||
MarketInfo market_info = sm.getMarketInfo(market);
|
||||
if (market_info == Null<MarketInfo>()) {
|
||||
return;
|
||||
}
|
||||
HKU_IF_RETURN(market_info == Null<MarketInfo>(), void());
|
||||
|
||||
Stock stock = sm.getStock(market + market_info.code());
|
||||
KData kdata = stock.getKData(m_query);
|
||||
|
@ -67,55 +67,37 @@ MoneyManagerPtr MoneyManagerBase::clone() {
|
||||
|
||||
double MoneyManagerBase ::getSellNumber(const Datetime& datetime, const Stock& stock, price_t price,
|
||||
price_t risk, SystemPart from) {
|
||||
if (!m_tm) {
|
||||
HKU_ERROR("m_tm is null! Datetime({}) Stock({}) price({:<.4f}) risk({:<.2f})", datetime,
|
||||
stock.market_code(), price, risk);
|
||||
return 0;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(!m_tm, 0.0,
|
||||
"m_tm is null! Datetime({}) Stock({}) price({:<.4f}) risk({:<.2f})",
|
||||
datetime, stock.market_code(), price, risk);
|
||||
|
||||
if (PART_ENVIRONMENT == from) {
|
||||
if (false == getParam<bool>("disable_ev_force_clean_position")) {
|
||||
//强制全部卖出
|
||||
return MAX_DOUBLE;
|
||||
}
|
||||
//强制全部卖出
|
||||
HKU_IF_RETURN(!getParam<bool>("disable_ev_force_clean_position"), MAX_DOUBLE);
|
||||
}
|
||||
|
||||
if (PART_CONDITION == from) {
|
||||
if (false == getParam<bool>("disable_cn_force_clean_position")) {
|
||||
return MAX_DOUBLE;
|
||||
}
|
||||
}
|
||||
|
||||
if (risk <= 0.0) {
|
||||
return 0;
|
||||
HKU_IF_RETURN(!getParam<bool>("disable_cn_force_clean_position"), MAX_DOUBLE);
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(risk <= 0.0, 0.0);
|
||||
return _getSellNumber(datetime, stock, price, risk, from);
|
||||
}
|
||||
|
||||
double MoneyManagerBase ::getBuyNumber(const Datetime& datetime, const Stock& stock, price_t price,
|
||||
price_t risk, SystemPart from) {
|
||||
if (!m_tm) {
|
||||
HKU_ERROR("m_tm is null! Datetime({}) Stock({}) price({:<.3f}) risk({:<.2f})", datetime,
|
||||
stock.market_code(), price, risk);
|
||||
return 0;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(!m_tm, 0.0,
|
||||
"m_tm is null! Datetime({}) Stock({}) price({:<.3f}) risk({:<.2f})",
|
||||
datetime, stock.market_code(), price, risk);
|
||||
HKU_ERROR_IF_RETURN(stock.isNull(), 0.0, "stock is Null!");
|
||||
|
||||
if (stock.isNull()) {
|
||||
HKU_ERROR("stock is Null!");
|
||||
return 0;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(
|
||||
risk <= 0.0, 0.0,
|
||||
"risk is zero! Datetime({}) Stock({}) price({:<.3f}) risk({:<.2f}) Part({})", datetime,
|
||||
stock.market_code(), price, risk, getSystemPartName(from));
|
||||
|
||||
if (risk <= 0.0) {
|
||||
HKU_ERROR("risk is zero! Datetime({}) Stock({}) price({:<.3f}) risk({:<.2f}) Part({})",
|
||||
datetime, stock.market_code(), price, risk, getSystemPartName(from));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (m_tm->getStockNumber() >= getParam<int>("max-stock")) {
|
||||
HKU_TRACE("Ignore! TM had max-stock number!");
|
||||
return 0;
|
||||
}
|
||||
HKU_TRACE_IF_RETURN(m_tm->getStockNumber() >= getParam<int>("max-stock"), 0.0,
|
||||
"Ignore! TM had max-stock number!");
|
||||
|
||||
double n = _getBuyNumber(datetime, stock, price, risk, from);
|
||||
double min_trade = stock.minTradeNumber();
|
||||
@ -160,35 +142,23 @@ double MoneyManagerBase ::getBuyNumber(const Datetime& datetime, const Stock& st
|
||||
|
||||
double MoneyManagerBase ::getSellShortNumber(const Datetime& datetime, const Stock& stock,
|
||||
price_t price, price_t risk, SystemPart from) {
|
||||
if (!m_tm) {
|
||||
HKU_ERROR("m_tm is null! Datetime({}) Stock({}) price({:<.3f}) risk({:<.2f})", datetime,
|
||||
stock.market_code(), price, risk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (risk <= 0.0) {
|
||||
HKU_ERROR("risk is zero! Datetime({}) Stock({}) price({:<.3f}) risk({:<.2f})", datetime,
|
||||
stock.market_code(), price, risk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
HKU_ERROR_IF_RETURN(!m_tm, 0.0,
|
||||
"m_tm is null! Datetime({}) Stock({}) price({:<.3f}) risk({:<.2f})",
|
||||
datetime, stock.market_code(), price, risk);
|
||||
HKU_ERROR_IF_RETURN(risk <= 0.0, 0.0,
|
||||
"risk is zero! Datetime({}) Stock({}) price({:<.3f}) risk({:<.2f})",
|
||||
datetime, stock.market_code(), price, risk);
|
||||
return _getSellShortNumber(datetime, stock, price, risk, from);
|
||||
}
|
||||
|
||||
double MoneyManagerBase ::getBuyShortNumber(const Datetime& datetime, const Stock& stock,
|
||||
price_t price, price_t risk, SystemPart from) {
|
||||
if (!m_tm) {
|
||||
HKU_ERROR("m_tm is null! Datetime({}) Stock({}) price({:<.3f}) risk({:<.2f})", datetime,
|
||||
stock.market_code(), price, risk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (risk <= 0.0) {
|
||||
HKU_ERROR("m_tm is null! Datetime({}) Stock({}) price({:<.3f}) risk({:<.2f})", datetime,
|
||||
stock.market_code(), price, risk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
HKU_ERROR_IF_RETURN(!m_tm, 0.0,
|
||||
"m_tm is null! Datetime({}) Stock({}) price({:<.3f}) risk({:<.2f})",
|
||||
datetime, stock.market_code(), price, risk);
|
||||
HKU_ERROR_IF_RETURN(risk <= 0.0, 0.0,
|
||||
"m_tm is null! Datetime({}) Stock({}) price({:<.3f}) risk({:<.2f})",
|
||||
datetime, stock.market_code(), price, risk);
|
||||
return _getBuyShortNumber(datetime, stock, price, risk, from);
|
||||
}
|
||||
|
||||
|
@ -18,16 +18,8 @@ FixedPercentMoneyManager::~FixedPercentMoneyManager() {}
|
||||
double FixedPercentMoneyManager ::_getBuyNumber(const Datetime& datetime, const Stock& stock,
|
||||
price_t price, price_t risk, SystemPart from) {
|
||||
double p = getParam<double>("p");
|
||||
if (p <= 0.0 || p > 1.0) {
|
||||
HKU_ERROR("Error param (p = {:<.4f})", p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (risk == 0.0) {
|
||||
HKU_ERROR("risk is zero!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
HKU_ERROR_IF_RETURN(p <= 0.0 || p > 1.0, 0.0, "Error param (p = {:<.4f})", p);
|
||||
HKU_ERROR_IF_RETURN(risk == 0.0, 0.0, "risk is zero!");
|
||||
return m_tm->currentCash() * p / risk;
|
||||
}
|
||||
|
||||
|
@ -20,11 +20,7 @@ WilliamsFixedRiskMoneyManager::~WilliamsFixedRiskMoneyManager() {}
|
||||
double WilliamsFixedRiskMoneyManager ::_getBuyNumber(const Datetime& datetime, const Stock& stock,
|
||||
price_t price, price_t risk, SystemPart from) {
|
||||
price_t max_loss = getParam<price_t>("max_loss");
|
||||
if (max_loss <= 0.0) {
|
||||
HKU_WARN("max_loss is zero!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
HKU_WARN_IF_RETURN(max_loss <= 0.0, 0.0, "max_loss is zero!");
|
||||
return m_tm->currentCash() * getParam<double>("p") / max_loss;
|
||||
}
|
||||
|
||||
|
@ -135,9 +135,7 @@ void Portfolio::runMoment(const Datetime& date) {
|
||||
HKU_CHECK(isReady(), "Not ready to run! Please perform readyForRun() first!");
|
||||
|
||||
// 当前日期小于账户建立日期,直接忽略
|
||||
if (date < m_shadow_tm->initDatetime()) {
|
||||
return;
|
||||
}
|
||||
HKU_IF_RETURN(date < m_shadow_tm->initDatetime(), void());
|
||||
|
||||
int precision = m_shadow_tm->getParam<int>("precision");
|
||||
SystemList cur_selected_list; //当前选中系统列表
|
||||
|
@ -18,10 +18,7 @@ FixedHoldDays::~FixedHoldDays() {}
|
||||
void FixedHoldDays::_calculate() {}
|
||||
|
||||
price_t FixedHoldDays::getGoal(const Datetime& datetime, price_t price) {
|
||||
if (getParam<int>("days") <= 0) {
|
||||
HKU_WARN("param days <= 0! Are you sure?");
|
||||
return 0.0;
|
||||
}
|
||||
HKU_WARN_IF_RETURN(getParam<int>("days") <= 0, 0.0, "param days <= 0! Are you sure?");
|
||||
|
||||
Stock stk = m_kdata.getStock();
|
||||
PositionRecord position = m_tm->getPosition(stk);
|
||||
|
@ -79,31 +79,15 @@ SelectorPtr SelectorBase::clone() {
|
||||
}
|
||||
|
||||
bool SelectorBase::addSystem(const SystemPtr& sys) {
|
||||
if (!sys) {
|
||||
HKU_WARN("Try add null sys, will be discard!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sys->getStock().isNull()) {
|
||||
HKU_WARN("sys has not bind stock!");
|
||||
return false;
|
||||
}
|
||||
|
||||
HKU_WARN_IF_RETURN(!sys, false, "Try add null sys, will be discard!");
|
||||
HKU_WARN_IF_RETURN(sys->getStock().isNull(), false, "sys has not bind stock!");
|
||||
m_sys_list.push_back(sys);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SelectorBase::addStock(const Stock& stock, const SystemPtr& protoSys) {
|
||||
if (stock.isNull()) {
|
||||
HKU_WARN("Try add Null stock, will be discard!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!protoSys) {
|
||||
HKU_WARN("Try add Null protoSys, will be discard!");
|
||||
return false;
|
||||
}
|
||||
|
||||
HKU_WARN_IF_RETURN(stock.isNull(), false, "Try add Null stock, will be discard!");
|
||||
HKU_WARN_IF_RETURN(!protoSys, false, "Try add Null protoSys, will be discard!");
|
||||
SYSPtr sys = protoSys->clone();
|
||||
sys->setStock(stock);
|
||||
m_sys_list.push_back(sys);
|
||||
@ -111,11 +95,7 @@ bool SelectorBase::addStock(const Stock& stock, const SystemPtr& protoSys) {
|
||||
}
|
||||
|
||||
bool SelectorBase::addStockList(const StockList& stkList, const SystemPtr& protoSys) {
|
||||
if (!protoSys) {
|
||||
HKU_WARN("Try add Null protoSys, will be discard!");
|
||||
return false;
|
||||
}
|
||||
|
||||
HKU_WARN_IF_RETURN(!protoSys, false, "Try add Null protoSys, will be discard!");
|
||||
StockList::const_iterator iter = stkList.begin();
|
||||
for (; iter != stkList.end(); ++iter) {
|
||||
if (iter->isNull()) {
|
||||
|
@ -33,13 +33,9 @@ void BoolSignal::_calculate() {
|
||||
Indicator kdata = KDATA_PART(m_kdata, kpart);
|
||||
Indicator buy = m_bool_buy(kdata);
|
||||
Indicator sell = m_bool_sell(kdata);
|
||||
if (buy.size() != sell.size()) {
|
||||
HKU_ERROR("buy.size() != sell.size()");
|
||||
return;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(buy.size() != sell.size(), void(), "buy.size() != sell.size()");
|
||||
|
||||
size_t discard = buy.discard() > sell.discard() ? buy.discard() : sell.discard();
|
||||
|
||||
size_t total = buy.size();
|
||||
for (size_t i = discard; i < total; ++i) {
|
||||
if (buy[i] > 0.0)
|
||||
|
@ -33,13 +33,9 @@ void CrossGoldSignal::_calculate() {
|
||||
Indicator kdata = KDATA_PART(m_kdata, kpart);
|
||||
Indicator fast = m_fast(kdata);
|
||||
Indicator slow = m_slow(kdata);
|
||||
if (fast.size() != slow.size()) {
|
||||
HKU_ERROR("fast.size() != slow.size()");
|
||||
return;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(fast.size() != slow.size(), void(), "fast.size() != slow.size()");
|
||||
|
||||
size_t discard = fast.discard() > slow.discard() ? fast.discard() : slow.discard();
|
||||
|
||||
size_t total = fast.size();
|
||||
for (size_t i = discard + 1; i < total; ++i) {
|
||||
if (fast[i - 1] < slow[i - 1] && fast[i] > slow[i] && fast[i - 1] < fast[i] &&
|
||||
|
@ -33,13 +33,9 @@ void CrossSignal::_calculate() {
|
||||
Indicator kdata = KDATA_PART(m_kdata, kpart);
|
||||
Indicator fast = m_fast(kdata);
|
||||
Indicator slow = m_slow(kdata);
|
||||
if (fast.size() != slow.size()) {
|
||||
HKU_ERROR("fast.size() != slow.size()");
|
||||
return;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(fast.size() != slow.size(), void(), "fast.size() != slow.size()");
|
||||
|
||||
size_t discard = fast.discard() > slow.discard() ? fast.discard() : slow.discard();
|
||||
|
||||
size_t total = fast.size();
|
||||
for (size_t i = discard + 1; i < total; ++i) {
|
||||
if (fast[i - 1] < slow[i - 1] && fast[i] > slow[i]) {
|
||||
|
@ -41,9 +41,7 @@ void SingleSignal::_calculate() {
|
||||
Indicator dev = STDEV(DIFF(ind), filter_n);
|
||||
|
||||
size_t start = dev.discard();
|
||||
if (start < 3) {
|
||||
return;
|
||||
}
|
||||
HKU_IF_RETURN(start < 3, void());
|
||||
|
||||
size_t total = dev.size();
|
||||
for (size_t i = start; i < total; ++i) {
|
||||
|
@ -44,9 +44,7 @@ void SingleSignal2::_calculate() {
|
||||
Indicator dev = REF(STDEV(DIFF(ind), filter_n), 1);
|
||||
|
||||
size_t start = dev.discard();
|
||||
if (start < 3) {
|
||||
return;
|
||||
}
|
||||
HKU_IF_RETURN(start < 3, void());
|
||||
|
||||
Indicator buy = ind - REF(LLV(ind, filter_n), 1);
|
||||
Indicator sell = REF(HHV(ind, filter_n), 1) - ind;
|
||||
|
@ -231,20 +231,9 @@ void System::_sellNotifyAll(const TradeRecord& record) {
|
||||
}
|
||||
|
||||
bool System::readyForRun() {
|
||||
if (!m_tm) {
|
||||
HKU_ERROR("Not setTradeManager!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_mm) {
|
||||
HKU_ERROR("Not setMoneyManager!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_sg) {
|
||||
HKU_ERROR("Not setSignal!");
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(!m_tm, false, "Not setTradeManager!");
|
||||
HKU_ERROR_IF_RETURN(!m_mm, false, "Not setMoneyManager!");
|
||||
HKU_ERROR_IF_RETURN(!m_sg, false, "Not setSignal!");
|
||||
|
||||
//如果存在市场环境判断策略,则需要将默认的前一日市场有效标志置为false
|
||||
//因为需要由市场环境判断策略全权判定市场是否有效
|
||||
@ -273,25 +262,17 @@ bool System::readyForRun() {
|
||||
}
|
||||
|
||||
void System::run(const KQuery& query, bool reset) {
|
||||
if (m_stock.isNull()) {
|
||||
HKU_ERROR("m_stock is NULL!");
|
||||
return;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(m_stock.isNull(), void(), "m_stock is NULL!");
|
||||
|
||||
// reset必须在readyForRun之前,否则m_pre_cn_valid、m_pre_ev_valid将会被赋为错误的初值
|
||||
if (reset)
|
||||
this->reset(true, true);
|
||||
|
||||
if (!readyForRun()) {
|
||||
return;
|
||||
}
|
||||
HKU_IF_RETURN(!readyForRun(), void());
|
||||
|
||||
// m_stock = stock; 在setTO里赋值
|
||||
KData kdata = m_stock.getKData(query);
|
||||
if (kdata.empty()) {
|
||||
HKU_INFO("KData is empty!");
|
||||
return;
|
||||
}
|
||||
HKU_INFO_IF_RETURN(kdata.empty(), void(), "KData is empty!");
|
||||
|
||||
setTO(kdata);
|
||||
size_t total = kdata.size();
|
||||
@ -1031,32 +1012,16 @@ void System::_submitSellShortRequest(const KRecord& today, Part from) {
|
||||
}
|
||||
|
||||
TradeRecord System::_processRequest(const KRecord& today) {
|
||||
if (m_buyRequest.valid) {
|
||||
return _buyDelay(today);
|
||||
}
|
||||
|
||||
if (m_sellRequest.valid) {
|
||||
return _sellDelay(today);
|
||||
}
|
||||
|
||||
if (m_sellShortRequest.valid) {
|
||||
return _sellShortDelay(today);
|
||||
}
|
||||
|
||||
if (m_buyShortRequest.valid) {
|
||||
return _buyShortDelay(today);
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(m_buyRequest.valid, _buyDelay(today));
|
||||
HKU_IF_RETURN(m_sellRequest.valid, _sellDelay(today));
|
||||
HKU_IF_RETURN(m_sellShortRequest.valid, _sellShortDelay(today));
|
||||
HKU_IF_RETURN(m_buyShortRequest.valid, _buyShortDelay(today));
|
||||
return TradeRecord();
|
||||
}
|
||||
|
||||
bool System::haveDelayRequest() const {
|
||||
if (m_buyRequest.valid || m_sellRequest.valid || m_sellShortRequest.valid ||
|
||||
m_buyShortRequest.valid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return (m_buyRequest.valid || m_sellRequest.valid || m_sellShortRequest.valid ||
|
||||
m_buyShortRequest.valid);
|
||||
}
|
||||
|
||||
} /* namespace hku */
|
||||
|
@ -38,36 +38,16 @@ string HKU_API getSystemPartName(int part) {
|
||||
SystemPart HKU_API getSystemPartEnum(const string& arg) {
|
||||
string name(arg);
|
||||
to_upper(name);
|
||||
if ("EV" == name) {
|
||||
return PART_ENVIRONMENT;
|
||||
|
||||
} else if ("CN" == name) {
|
||||
return PART_CONDITION;
|
||||
|
||||
} else if ("SG" == name) {
|
||||
return PART_SIGNAL;
|
||||
|
||||
} else if ("ST" == name) {
|
||||
return PART_STOPLOSS;
|
||||
|
||||
} else if ("TP" == name) {
|
||||
return PART_TAKEPROFIT;
|
||||
|
||||
} else if ("PG" == name) {
|
||||
return PART_PROFITGOAL;
|
||||
|
||||
} else if ("SP" == name) {
|
||||
return PART_SLIPPAGE;
|
||||
|
||||
} else if ("MM" == name) {
|
||||
return PART_MONEYMANAGER;
|
||||
|
||||
} else if ("AF" == name) {
|
||||
return PART_ALLOCATEFUNDS;
|
||||
|
||||
} else {
|
||||
return PART_INVALID;
|
||||
}
|
||||
HKU_IF_RETURN("EV" == name, PART_ENVIRONMENT);
|
||||
HKU_IF_RETURN("CN" == name, PART_CONDITION);
|
||||
HKU_IF_RETURN("SG" == name, PART_SIGNAL);
|
||||
HKU_IF_RETURN("ST" == name, PART_STOPLOSS);
|
||||
HKU_IF_RETURN("TP" == name, PART_TAKEPROFIT);
|
||||
HKU_IF_RETURN("PG" == name, PART_PROFITGOAL);
|
||||
HKU_IF_RETURN("SP" == name, PART_SLIPPAGE);
|
||||
HKU_IF_RETURN("MM" == name, PART_MONEYMANAGER);
|
||||
HKU_IF_RETURN("AF" == name, PART_ALLOCATEFUNDS);
|
||||
return PART_INVALID;
|
||||
}
|
||||
|
||||
} /* namespace hku */
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include "../Log.h"
|
||||
#include "Parameter.h"
|
||||
|
||||
namespace hku {
|
||||
@ -67,43 +68,26 @@ Parameter& Parameter::operator=(const Parameter& p) {
|
||||
}
|
||||
|
||||
bool Parameter::support(const boost::any& value) {
|
||||
if (value.type() == typeid(int) || value.type() == typeid(bool) ||
|
||||
value.type() == typeid(double) || value.type() == typeid(string) ||
|
||||
value.type() == typeid(Stock) || value.type() == typeid(KQuery) ||
|
||||
value.type() == typeid(KData) || value.type() == typeid(PriceList) ||
|
||||
value.type() == typeid(DatetimeList)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return value.type() == typeid(int) || value.type() == typeid(bool) ||
|
||||
value.type() == typeid(double) || value.type() == typeid(string) ||
|
||||
value.type() == typeid(Stock) || value.type() == typeid(KQuery) ||
|
||||
value.type() == typeid(KData) || value.type() == typeid(PriceList) ||
|
||||
value.type() == typeid(DatetimeList);
|
||||
}
|
||||
|
||||
string Parameter::type(const string& name) const {
|
||||
auto iter = m_params.find(name);
|
||||
if (iter == m_params.end()) {
|
||||
throw std::out_of_range("out_of_range in Parameter::get : " + name);
|
||||
}
|
||||
|
||||
if (iter->second.type() == typeid(int)) {
|
||||
return "int";
|
||||
} else if (iter->second.type() == typeid(bool)) {
|
||||
return "bool";
|
||||
} else if (iter->second.type() == typeid(double)) {
|
||||
return "double";
|
||||
} else if (iter->second.type() == typeid(string)) {
|
||||
return "string";
|
||||
} else if (iter->second.type() == typeid(Stock)) {
|
||||
return "Stock";
|
||||
} else if (iter->second.type() == typeid(KQuery)) {
|
||||
return "KQuery";
|
||||
} else if (iter->second.type() == typeid(KData)) {
|
||||
return "KData";
|
||||
} else if (iter->second.type() == typeid(PriceList)) {
|
||||
return "PriceList";
|
||||
} else if (iter->second.type() == typeid(DatetimeList)) {
|
||||
return "DatetimeList";
|
||||
}
|
||||
|
||||
HKU_CHECK_THROW(iter != m_params.end(), std::out_of_range,
|
||||
"out_of_range in Parameter::get : {}", name);
|
||||
HKU_IF_RETURN(iter->second.type() == typeid(int), "int");
|
||||
HKU_IF_RETURN(iter->second.type() == typeid(bool), "bool");
|
||||
HKU_IF_RETURN(iter->second.type() == typeid(double), "double");
|
||||
HKU_IF_RETURN(iter->second.type() == typeid(string), "string");
|
||||
HKU_IF_RETURN(iter->second.type() == typeid(Stock), "Stock");
|
||||
HKU_IF_RETURN(iter->second.type() == typeid(KQuery), "KQuery");
|
||||
HKU_IF_RETURN(iter->second.type() == typeid(KData), "KData");
|
||||
HKU_IF_RETURN(iter->second.type() == typeid(PriceList), "PriceList");
|
||||
HKU_IF_RETURN(iter->second.type() == typeid(DatetimeList), "DatetimeList");
|
||||
return "Unknow";
|
||||
}
|
||||
|
||||
|
@ -56,15 +56,10 @@ void MySQLConnect::close() {
|
||||
}
|
||||
|
||||
bool MySQLConnect::ping() {
|
||||
if (!m_mysql) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(!m_mysql, false);
|
||||
auto ret = mysql_ping(m_mysql);
|
||||
if (ret) {
|
||||
HKU_ERROR("mysql_ping error code: {}, msg: {}", ret, mysql_error(m_mysql));
|
||||
return false;
|
||||
}
|
||||
HKU_ERROR_IF_RETURN(ret, false, "mysql_ping error code: {}, msg: {}", ret,
|
||||
mysql_error(m_mysql));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -82,10 +82,7 @@ void MySQLStatement::sub_exec() {
|
||||
}
|
||||
|
||||
void MySQLStatement::_bindResult() {
|
||||
if (!m_meta_result) {
|
||||
return;
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(!m_meta_result, void());
|
||||
MYSQL_FIELD* field;
|
||||
int idx = 0;
|
||||
while ((field = mysql_fetch_field(m_meta_result))) {
|
||||
|
Loading…
Reference in New Issue
Block a user