hikyuu2/hikyuu_cpp/hikyuu/trade_sys/moneymanager/MoneyManagerBase.cpp

182 lines
6.4 KiB
C++
Raw Normal View History

2015-01-07 01:26:14 +08:00
/*
* MoneyManagerBase.cpp
*
* Created on: 2013-3-3
* Author: fasiondog
*/
#include "MoneyManagerBase.h"
namespace hku {
2019-11-10 23:31:41 +08:00
HKU_API std::ostream& operator<<(std::ostream& os, const MoneyManagerBase& mm) {
2015-01-07 01:26:14 +08:00
os << "MoneyManager(" << mm.name() << ", " << mm.getParameter() << ")";
return os;
}
2019-11-10 23:31:41 +08:00
HKU_API std::ostream& operator<<(std::ostream& os, const MoneyManagerPtr& mm) {
2015-01-07 01:26:14 +08:00
if (mm) {
os << *mm;
} else {
os << "MoneyManager(NULL)";
}
return os;
}
2019-11-10 23:31:41 +08:00
MoneyManagerBase::MoneyManagerBase() : m_name("MoneyManagerBase") {
2016-05-03 02:44:03 +08:00
setParam<bool>("auto-checkin", false);
setParam<int>("max-stock", 20000);
setParam<bool>("disable_ev_force_clean_position", false);
setParam<bool>("disable_cn_force_clean_position", false);
2016-04-28 02:39:49 +08:00
}
2019-11-10 23:31:41 +08:00
MoneyManagerBase::MoneyManagerBase(const string& name) : m_name(name) {
2016-05-03 02:44:03 +08:00
setParam<bool>("auto-checkin", false);
setParam<int>("max-stock", 20000);
setParam<bool>("disable_ev_force_clean_position", false);
setParam<bool>("disable_cn_force_clean_position", false);
2015-01-07 01:26:14 +08:00
}
2019-11-10 23:31:41 +08:00
MoneyManagerBase::~MoneyManagerBase() {}
2015-01-07 01:26:14 +08:00
2019-11-10 23:31:41 +08:00
void MoneyManagerBase::buyNotify(const TradeRecord&) {}
2015-01-07 01:26:14 +08:00
2019-11-10 23:31:41 +08:00
void MoneyManagerBase::sellNotify(const TradeRecord&) {}
2015-01-07 01:26:14 +08:00
MoneyManagerPtr MoneyManagerBase::clone() {
MoneyManagerPtr p;
try {
p = _clone();
2019-11-10 23:31:41 +08:00
} catch (...) {
2019-06-16 19:06:06 +08:00
HKU_ERROR("Subclass _clone failed!");
p = MoneyManagerPtr();
}
if (!p || p.get() == this) {
2019-11-10 23:31:41 +08:00
HKU_ERROR("Failed clone! Will use self-ptr!");
return shared_from_this();
}
2015-01-07 01:26:14 +08:00
p->m_params = m_params;
p->m_name = m_name;
2019-11-10 23:31:41 +08:00
// p->m_tm = m_tm;
2016-05-18 02:03:29 +08:00
p->m_query = m_query;
2015-01-07 01:26:14 +08:00
return p;
}
double MoneyManagerBase ::getSellNumber(const Datetime& datetime, const Stock& stock, price_t price,
2019-11-10 23:31:41 +08:00
price_t risk, SystemPart from) {
2020-11-22 18:34:37 +08:00
HKU_ERROR_IF_RETURN(!m_tm, 0.0,
"m_tm is null! Datetime({}) Stock({}) price({:<.4f}) risk({:<.2f})",
datetime, stock.market_code(), price, risk);
2016-04-03 00:08:31 +08:00
if (PART_ENVIRONMENT == from) {
2020-11-22 18:34:37 +08:00
//强制全部卖出
HKU_IF_RETURN(!getParam<bool>("disable_ev_force_clean_position"), MAX_DOUBLE);
}
if (PART_CONDITION == from) {
2020-11-22 18:34:37 +08:00
HKU_IF_RETURN(!getParam<bool>("disable_cn_force_clean_position"), MAX_DOUBLE);
2016-04-03 00:08:31 +08:00
}
2020-11-22 18:34:37 +08:00
HKU_IF_RETURN(risk <= 0.0, 0.0);
2019-11-10 23:31:41 +08:00
return _getSellNumber(datetime, stock, price, risk, from);
2016-04-03 00:08:31 +08:00
}
double MoneyManagerBase ::getBuyNumber(const Datetime& datetime, const Stock& stock, price_t price,
2019-11-10 23:31:41 +08:00
price_t risk, SystemPart from) {
2020-11-22 18:34:37 +08:00
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!");
2015-01-07 01:26:14 +08:00
2020-11-22 18:34:37 +08:00
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));
2016-04-03 00:08:31 +08:00
2020-11-22 18:34:37 +08:00
HKU_TRACE_IF_RETURN(m_tm->getStockNumber() >= getParam<int>("max-stock"), 0.0,
"Ignore! TM had max-stock number!");
2016-07-09 22:37:42 +08:00
double n = _getBuyNumber(datetime, stock, price, risk, from);
double min_trade = stock.minTradeNumber();
2019-11-10 23:31:41 +08:00
if (n < min_trade) {
HKU_TRACE("Ignore! Is less than the minimum number of transactions({})", min_trade);
2016-05-03 02:44:03 +08:00
return 0;
}
//转换为最小交易量的整数倍
n = long(n / min_trade) * min_trade;
double max_trade = stock.maxTradeNumber();
2016-05-03 02:44:03 +08:00
if (n > max_trade) {
n = max_trade;
HKU_INFO("Over stock.maxTradeNumber({})!", max_trade);
2016-05-16 01:45:01 +08:00
}
2016-05-03 02:44:03 +08:00
//在现金不足时,自动补充存入现金
if (getParam<bool>("auto-checkin")) {
price_t cash = m_tm->currentCash();
CostRecord cost = m_tm->getBuyCost(datetime, stock, price, n);
int precision = m_tm->precision();
price_t money = roundUp(price * n * stock.unit() + cost.total, precision);
2016-05-03 02:44:03 +08:00
if (money > cash) {
m_tm->checkin(datetime, roundUp(money - cash, precision));
2016-05-03 02:44:03 +08:00
}
} else {
CostRecord cost = m_tm->getBuyCost(datetime, stock, price, n);
price_t need_cash = n * price + cost.total;
price_t current_cash = m_tm->currentCash();
while (n > min_trade && need_cash > current_cash) {
n = n - min_trade;
cost = m_tm->getBuyCost(datetime, stock, price, n);
need_cash = n * price + cost.total;
}
n = need_cash > current_cash ? 0 : n;
2016-05-03 02:44:03 +08:00
}
return n;
2016-04-03 00:08:31 +08:00
}
double MoneyManagerBase ::getSellShortNumber(const Datetime& datetime, const Stock& stock,
2019-11-10 23:31:41 +08:00
price_t price, price_t risk, SystemPart from) {
2020-11-22 18:34:37 +08:00
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);
2016-04-03 00:08:31 +08:00
}
double MoneyManagerBase ::getBuyShortNumber(const Datetime& datetime, const Stock& stock,
2019-11-10 23:31:41 +08:00
price_t price, price_t risk, SystemPart from) {
2020-11-22 18:34:37 +08:00
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);
2016-04-03 00:08:31 +08:00
}
double MoneyManagerBase::_getSellNumber(const Datetime& datetime, const Stock& stock, price_t price,
2019-11-10 23:31:41 +08:00
price_t risk, SystemPart from) {
2016-04-03 00:08:31 +08:00
//默认卖出全部
return MAX_DOUBLE;
2016-04-03 00:08:31 +08:00
}
double MoneyManagerBase::_getSellShortNumber(const Datetime& datetime, const Stock& stock,
2019-11-10 23:31:41 +08:00
price_t price, price_t risk, SystemPart from) {
2016-04-03 00:08:31 +08:00
return 0;
}
double MoneyManagerBase::_getBuyShortNumber(const Datetime& datetime, const Stock& stock,
2019-11-10 23:31:41 +08:00
price_t price, price_t risk, SystemPart from) {
2016-04-03 00:08:31 +08:00
return 0;
2015-01-07 01:26:14 +08:00
}
} /* namespace hku */