代码优化

This commit is contained in:
fasiondog 2020-11-22 18:34:37 +08:00
parent 41a97a3932
commit 1c803c974d
83 changed files with 525 additions and 1557 deletions

View File

@ -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) {

View File

@ -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

View File

@ -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) {}

View File

@ -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) {}

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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);

View File

@ -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,"

View File

@ -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")

View File

@ -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();

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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();

View File

@ -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();

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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);

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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");

View File

@ -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();

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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);

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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);

View File

@ -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) {

View File

@ -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) {

View File

@ -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);

View File

@ -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) {

View File

@ -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");

View File

@ -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) {

View File

@ -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();

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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);

View File

@ -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 */

View File

@ -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;

View File

@ -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);

View File

@ -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");

View File

@ -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);

View File

@ -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 */

View File

@ -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();

View File

@ -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 */

View File

@ -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);

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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; //当前选中系统列表

View File

@ -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);

View File

@ -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()) {

View File

@ -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)

View File

@ -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] &&

View File

@ -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]) {

View File

@ -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) {

View File

@ -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;

View File

@ -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 */

View File

@ -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 */

View File

@ -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";
}

View File

@ -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;
}

View File

@ -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))) {