mirror of
https://gitee.com/fasiondog/hikyuu.git
synced 2024-12-04 12:57:45 +08:00
Merge pull request #202 from fasiondog/feature/param
策略组件参数检查与更新优化; fixed system 止盈延迟参数未生效
This commit is contained in:
commit
f6c8869ea5
@ -50,7 +50,7 @@
|
||||
|
||||
.. py:function:: MM_FixedCapital([capital = 10000.0])
|
||||
|
||||
固定资本资金管理策略
|
||||
固定资本资金管理策略, 即控制每次买入投入的总资金
|
||||
|
||||
:param float capital: 固定资本单位
|
||||
:return: 资金管理策略实例
|
||||
|
@ -31,6 +31,9 @@ TradeCostBase::TradeCostBase(const string& name) : m_name(name) {}
|
||||
|
||||
TradeCostBase::~TradeCostBase() {}
|
||||
|
||||
void TradeCostBase::baseCheckParam(const string& name) const {}
|
||||
void TradeCostBase::paramChanged() {}
|
||||
|
||||
TradeCostPtr TradeCostBase::clone() {
|
||||
TradeCostPtr result = _clone();
|
||||
TradeCostBase* p = result.get();
|
||||
|
@ -20,7 +20,7 @@ namespace hku {
|
||||
* @ingroup TradeCost
|
||||
*/
|
||||
class HKU_API TradeCostBase {
|
||||
PARAMETER_SUPPORT
|
||||
PARAMETER_SUPPORT_WITH_CHECK
|
||||
|
||||
public:
|
||||
TradeCostBase(const string& name);
|
||||
|
@ -23,6 +23,18 @@ FixedA2015TradeCost::FixedA2015TradeCost() : TradeCostBase("TC_FixedA2015") {
|
||||
|
||||
FixedA2015TradeCost::~FixedA2015TradeCost() {}
|
||||
|
||||
void FixedA2015TradeCost::_checkParam(const string& name) const {
|
||||
if ("commission" == name) {
|
||||
HKU_ASSERT(getParam<price_t>("commission") >= 0.0);
|
||||
} else if ("lowest_commission" == name) {
|
||||
HKU_ASSERT(getParam<price_t>("lowest_commission") >= 0.0);
|
||||
} else if ("stamptax" == name) {
|
||||
HKU_ASSERT(getParam<price_t>("stamptax") >= 0.0);
|
||||
} else if ("transferfee" == name) {
|
||||
HKU_ASSERT(getParam<price_t>("transferfee") >= 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
CostRecord FixedA2015TradeCost::getBuyCost(const Datetime& datetime, const Stock& stock,
|
||||
price_t price, double num) const {
|
||||
CostRecord result;
|
||||
|
@ -20,6 +20,8 @@ public:
|
||||
FixedA2015TradeCost();
|
||||
virtual ~FixedA2015TradeCost();
|
||||
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
|
||||
/**
|
||||
* 计算买入成本
|
||||
* @param datetime 交易日期
|
||||
|
@ -23,6 +23,18 @@ FixedA2017TradeCost::FixedA2017TradeCost() : TradeCostBase("TC_FixedA2017") {
|
||||
|
||||
FixedA2017TradeCost::~FixedA2017TradeCost() {}
|
||||
|
||||
void FixedA2017TradeCost::_checkParam(const string& name) const {
|
||||
if ("commission" == name) {
|
||||
HKU_ASSERT(getParam<price_t>("commission") >= 0.0);
|
||||
} else if ("lowest_commission" == name) {
|
||||
HKU_ASSERT(getParam<price_t>("lowest_commission") >= 0.0);
|
||||
} else if ("stamptax" == name) {
|
||||
HKU_ASSERT(getParam<price_t>("stamptax") >= 0.0);
|
||||
} else if ("transferfee" == name) {
|
||||
HKU_ASSERT(getParam<price_t>("transferfee") >= 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
CostRecord FixedA2017TradeCost::getBuyCost(const Datetime& datetime, const Stock& stock,
|
||||
price_t price, double num) const {
|
||||
CostRecord result;
|
||||
|
@ -23,6 +23,8 @@ public:
|
||||
FixedA2017TradeCost();
|
||||
virtual ~FixedA2017TradeCost();
|
||||
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
|
||||
/**
|
||||
* 计算买入成本
|
||||
* @param datetime 交易日期
|
||||
|
@ -35,6 +35,20 @@ FixedATradeCost::FixedATradeCost(price_t commission, price_t lowestCommission, p
|
||||
|
||||
FixedATradeCost::~FixedATradeCost() {}
|
||||
|
||||
void FixedATradeCost::_checkParam(const string& name) const {
|
||||
if ("commission" == name) {
|
||||
HKU_ASSERT(getParam<price_t>("commission") >= 0.0);
|
||||
} else if ("lowest_commission" == name) {
|
||||
HKU_ASSERT(getParam<price_t>("lowest_commission") >= 0.0);
|
||||
} else if ("stamptax" == name) {
|
||||
HKU_ASSERT(getParam<price_t>("stamptax") >= 0.0);
|
||||
} else if ("transferfee" == name) {
|
||||
HKU_ASSERT(getParam<price_t>("transferfee") >= 0.0);
|
||||
} else if ("lowest_transferfee" == name) {
|
||||
HKU_ASSERT(getParam<price_t>("lowest_transferfee") >= 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
CostRecord FixedATradeCost::getBuyCost(const Datetime& datetime, const Stock& stock, price_t price,
|
||||
double num) const {
|
||||
CostRecord result;
|
||||
|
@ -56,6 +56,8 @@ public:
|
||||
price_t transferfee, price_t lowestTransferfee);
|
||||
virtual ~FixedATradeCost();
|
||||
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
|
||||
/**
|
||||
* 计算买入成本
|
||||
* @param datetime 交易日期
|
||||
|
@ -56,6 +56,9 @@ AllocateFundsBase::AllocateFundsBase(const string& name)
|
||||
|
||||
AllocateFundsBase::~AllocateFundsBase() {}
|
||||
|
||||
void AllocateFundsBase::baseCheckParam(const string& name) const {}
|
||||
void AllocateFundsBase::paramChanged() {}
|
||||
|
||||
void AllocateFundsBase::reset() {
|
||||
// 参数检查
|
||||
double default_reserve_percent = getParam<double>("default_reserve_percent");
|
||||
|
@ -20,7 +20,7 @@ namespace hku {
|
||||
* @ingroup AllocateFunds
|
||||
*/
|
||||
class HKU_API AllocateFundsBase : public enable_shared_from_this<AllocateFundsBase> {
|
||||
PARAMETER_SUPPORT
|
||||
PARAMETER_SUPPORT_WITH_CHECK
|
||||
|
||||
public:
|
||||
/** 默认构造函数 */
|
||||
|
@ -19,6 +19,13 @@ FixedWeightAllocateFunds::FixedWeightAllocateFunds() : AllocateFundsBase("AF_Fix
|
||||
|
||||
FixedWeightAllocateFunds::~FixedWeightAllocateFunds() {}
|
||||
|
||||
void FixedWeightAllocateFunds::_checkParam(const string& name) const {
|
||||
if ("weight" == name) {
|
||||
double weight = getParam<double>("weight");
|
||||
HKU_ASSERT(weight > 0.0 && weight <= 1.);
|
||||
}
|
||||
}
|
||||
|
||||
SystemWeightList FixedWeightAllocateFunds ::_allocateWeight(const Datetime& date,
|
||||
const SystemWeightList& se_list) {
|
||||
SystemWeightList result;
|
||||
|
@ -20,6 +20,7 @@ class FixedWeightAllocateFunds : public AllocateFundsBase {
|
||||
public:
|
||||
FixedWeightAllocateFunds();
|
||||
virtual ~FixedWeightAllocateFunds();
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
};
|
||||
|
||||
} /* namespace hku */
|
||||
|
@ -30,6 +30,9 @@ ConditionBase::ConditionBase(const string& name) : m_name(name) {}
|
||||
|
||||
ConditionBase::~ConditionBase() {}
|
||||
|
||||
void ConditionBase::baseCheckParam(const string& name) const {}
|
||||
void ConditionBase::paramChanged() {}
|
||||
|
||||
void ConditionBase::reset() {
|
||||
m_kdata = Null<KData>();
|
||||
m_tm.reset();
|
||||
|
@ -22,7 +22,7 @@ namespace hku {
|
||||
* @ingroup Condition
|
||||
*/
|
||||
class HKU_API ConditionBase : public enable_shared_from_this<ConditionBase> {
|
||||
PARAMETER_SUPPORT
|
||||
PARAMETER_SUPPORT_WITH_CHECK
|
||||
|
||||
public:
|
||||
ConditionBase();
|
||||
|
@ -29,6 +29,9 @@ EnvironmentBase::EnvironmentBase(const string& name) : m_name(name) {}
|
||||
|
||||
EnvironmentBase::~EnvironmentBase() {}
|
||||
|
||||
void EnvironmentBase::baseCheckParam(const string& name) const {}
|
||||
void EnvironmentBase::paramChanged() {}
|
||||
|
||||
void EnvironmentBase::reset() {
|
||||
std::unique_lock<std::shared_mutex> lock(m_mutex);
|
||||
m_query = Null<KQuery>();
|
||||
|
@ -22,7 +22,7 @@ namespace hku {
|
||||
* @ingroup Environment
|
||||
*/
|
||||
class HKU_API EnvironmentBase : public enable_shared_from_this<EnvironmentBase> {
|
||||
PARAMETER_SUPPORT
|
||||
PARAMETER_SUPPORT_WITH_CHECK
|
||||
|
||||
public:
|
||||
EnvironmentBase();
|
||||
|
@ -24,6 +24,14 @@ BoolEnvironment::BoolEnvironment(const Indicator& ind) : EnvironmentBase("EV_Boo
|
||||
|
||||
BoolEnvironment::~BoolEnvironment() {}
|
||||
|
||||
void BoolEnvironment::_checkParam(const string& name) const {
|
||||
if ("market" == name) {
|
||||
string market = getParam<string>(name);
|
||||
auto market_info = StockManager::instance().getMarketInfo(name);
|
||||
HKU_CHECK(market_info == Null<MarketInfo>(), "Invalid market: {}", market);
|
||||
}
|
||||
}
|
||||
|
||||
EnvironmentPtr BoolEnvironment::_clone() {
|
||||
return make_shared<BoolEnvironment>(m_ind.clone());
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ public:
|
||||
explicit BoolEnvironment(const Indicator& ind);
|
||||
virtual ~BoolEnvironment();
|
||||
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
virtual void _calculate() override;
|
||||
virtual EnvironmentPtr _clone() override;
|
||||
|
||||
|
@ -26,6 +26,14 @@ TwoLineEnvironment::TwoLineEnvironment(const Indicator& fast, const Indicator& s
|
||||
|
||||
TwoLineEnvironment::~TwoLineEnvironment() {}
|
||||
|
||||
void TwoLineEnvironment::_checkParam(const string& name) const {
|
||||
if ("market" == name) {
|
||||
string market = getParam<string>(name);
|
||||
auto market_info = StockManager::instance().getMarketInfo(name);
|
||||
HKU_CHECK(market_info == Null<MarketInfo>(), "Invalid market: {}", market);
|
||||
}
|
||||
}
|
||||
|
||||
EnvironmentPtr TwoLineEnvironment::_clone() {
|
||||
TwoLineEnvironment* ptr = new TwoLineEnvironment;
|
||||
ptr->m_fast = m_fast.clone();
|
||||
|
@ -20,6 +20,7 @@ public:
|
||||
TwoLineEnvironment(const Indicator& fast, const Indicator& slow);
|
||||
virtual ~TwoLineEnvironment();
|
||||
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
virtual void _calculate() override;
|
||||
virtual EnvironmentPtr _clone() override;
|
||||
|
||||
|
@ -102,7 +102,7 @@ void MultiFactorBase::initParam() {
|
||||
setParam<double>("zscore_nsigma", 3.0);
|
||||
}
|
||||
|
||||
void MultiFactorBase::checkParam(const string& name) const {
|
||||
void MultiFactorBase::baseCheckParam(const string& name) const {
|
||||
if ("ic_n" == name) {
|
||||
HKU_ASSERT(getParam<int>("ic_n") >= 1);
|
||||
} else if ("zscore_nsigma" == name) {
|
||||
|
@ -29,8 +29,7 @@ ICIRMultiFactor::ICIRMultiFactor(const vector<Indicator>& inds, const StockList&
|
||||
checkParam("ic_rolling_n");
|
||||
}
|
||||
|
||||
void ICIRMultiFactor::checkParam(const string& name) const {
|
||||
MultiFactorBase::checkParam(name);
|
||||
void ICIRMultiFactor::_checkParam(const string& name) const {
|
||||
if ("ic_rolling_n" == name) {
|
||||
HKU_ASSERT(getParam<int>("ic_rolling_n") >= 1);
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ public:
|
||||
const Stock& ref_stk, int ic_n, int ic_rolling_n);
|
||||
virtual ~ICIRMultiFactor() = default;
|
||||
|
||||
virtual void checkParam(const string& name) const override;
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
};
|
||||
|
||||
} // namespace hku
|
@ -28,8 +28,7 @@ ICMultiFactor::ICMultiFactor(const IndicatorList& inds, const StockList& stks, c
|
||||
checkParam("ic_rolling_n");
|
||||
}
|
||||
|
||||
void ICMultiFactor::checkParam(const string& name) const {
|
||||
MultiFactorBase::checkParam(name);
|
||||
void ICMultiFactor::_checkParam(const string& name) const {
|
||||
if ("ic_rolling_n" == name) {
|
||||
HKU_ASSERT(getParam<int>("ic_rolling_n") >= 1);
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ public:
|
||||
const Stock& ref_stk, int ic_n, int ic_rolling_n);
|
||||
virtual ~ICMultiFactor() = default;
|
||||
|
||||
virtual void checkParam(const string& name) const override;
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
};
|
||||
|
||||
} // namespace hku
|
@ -40,6 +40,14 @@ MoneyManagerBase::MoneyManagerBase(const string& name) : m_name(name) {
|
||||
|
||||
MoneyManagerBase::~MoneyManagerBase() {}
|
||||
|
||||
void MoneyManagerBase::baseCheckParam(const string& name) const {
|
||||
if ("max-stock" == name) {
|
||||
HKU_ASSERT(getParam<int>("max-stock") >= 1);
|
||||
}
|
||||
}
|
||||
|
||||
void MoneyManagerBase::paramChanged() {}
|
||||
|
||||
void MoneyManagerBase::buyNotify(const TradeRecord&) {}
|
||||
|
||||
void MoneyManagerBase::sellNotify(const TradeRecord&) {}
|
||||
@ -110,21 +118,16 @@ double MoneyManagerBase::getBuyNumber(const Datetime& datetime, const Stock& sto
|
||||
|
||||
double n = _getBuyNumber(datetime, stock, price, risk, from);
|
||||
double min_trade = stock.minTradeNumber();
|
||||
|
||||
if (n < min_trade) {
|
||||
HKU_TRACE("Ignore! Is less than the minimum number of transactions({}<{}) {}", n, min_trade,
|
||||
stock.market_code());
|
||||
return 0;
|
||||
}
|
||||
HKU_TRACE_IF_RETURN(n < min_trade, 0.0,
|
||||
"Ignore! Is less than the minimum number of transactions({}<{}) {}", n,
|
||||
min_trade, stock.market_code());
|
||||
|
||||
// 转换为最小交易量的整数倍
|
||||
n = long(n / min_trade) * min_trade;
|
||||
double max_trade = stock.maxTradeNumber();
|
||||
n = int64_t(n / min_trade) * min_trade;
|
||||
|
||||
if (n > max_trade) {
|
||||
n = max_trade;
|
||||
HKU_INFO("Over stock.maxTradeNumber({})!", max_trade);
|
||||
}
|
||||
double max_trade = stock.maxTradeNumber();
|
||||
HKU_WARN_IF_RETURN(n > max_trade, max_trade,
|
||||
"Over stock.maxTradeNumber({}), will use maxTradeNumber", max_trade);
|
||||
|
||||
// 在现金不足时,自动补充存入现金
|
||||
if (getParam<bool>("auto-checkin")) {
|
||||
|
@ -20,7 +20,7 @@ namespace hku {
|
||||
* @ingroup MoneyManager
|
||||
*/
|
||||
class HKU_API MoneyManagerBase : public enable_shared_from_this<MoneyManagerBase> {
|
||||
PARAMETER_SUPPORT
|
||||
PARAMETER_SUPPORT_WITH_CHECK
|
||||
|
||||
public:
|
||||
MoneyManagerBase();
|
||||
|
@ -19,6 +19,13 @@ FixedCapitalMoneyManager::FixedCapitalMoneyManager() : MoneyManagerBase("MM_Fixe
|
||||
|
||||
FixedCapitalMoneyManager::~FixedCapitalMoneyManager() {}
|
||||
|
||||
void FixedCapitalMoneyManager::_checkParam(const string& name) const {
|
||||
if ("capital" == name) {
|
||||
double capital = getParam<double>("capital");
|
||||
HKU_ASSERT(capital > 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
double FixedCapitalMoneyManager ::_getBuyNumber(const Datetime& datetime, const Stock& stock,
|
||||
price_t price, price_t risk, SystemPart from) {
|
||||
double capital = getParam<double>("capital");
|
||||
|
@ -20,6 +20,7 @@ class FixedCapitalMoneyManager : public MoneyManagerBase {
|
||||
public:
|
||||
FixedCapitalMoneyManager();
|
||||
virtual ~FixedCapitalMoneyManager();
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
};
|
||||
|
||||
} /* namespace hku */
|
||||
|
@ -19,6 +19,13 @@ FixedCountMoneyManager::FixedCountMoneyManager() : MoneyManagerBase("MM_FixedCou
|
||||
|
||||
FixedCountMoneyManager::~FixedCountMoneyManager() {}
|
||||
|
||||
void FixedCountMoneyManager::_checkParam(const string& name) const {
|
||||
if ("n" == name) {
|
||||
double n = getParam<double>("n");
|
||||
HKU_ASSERT(n > 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
double FixedCountMoneyManager ::_getBuyNumber(const Datetime& datetime, const Stock& stock,
|
||||
price_t price, price_t risk, SystemPart from) {
|
||||
return getParam<double>("n");
|
||||
|
@ -31,6 +31,7 @@ class FixedCountMoneyManager : public MoneyManagerBase {
|
||||
public:
|
||||
FixedCountMoneyManager();
|
||||
virtual ~FixedCountMoneyManager();
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
};
|
||||
|
||||
} /* namespace hku */
|
||||
|
@ -19,11 +19,16 @@ FixedPercentMoneyManager::FixedPercentMoneyManager() : MoneyManagerBase("MM_Fixe
|
||||
|
||||
FixedPercentMoneyManager::~FixedPercentMoneyManager() {}
|
||||
|
||||
void FixedPercentMoneyManager::_checkParam(const string& name) const {
|
||||
if ("p" == name) {
|
||||
double p = getParam<double>("p");
|
||||
HKU_ASSERT(p > 0 && p <= 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
double FixedPercentMoneyManager ::_getBuyNumber(const Datetime& datetime, const Stock& stock,
|
||||
price_t price, price_t risk, SystemPart from) {
|
||||
double p = getParam<double>("p");
|
||||
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->cash(datetime, m_query.kType()) * p / risk;
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ class HKU_API FixedPercentMoneyManager : public MoneyManagerBase {
|
||||
public:
|
||||
FixedPercentMoneyManager();
|
||||
virtual ~FixedPercentMoneyManager();
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
};
|
||||
|
||||
} /* namespace hku */
|
||||
|
@ -20,6 +20,13 @@ FixedRatioMoneyManager::FixedRatioMoneyManager()
|
||||
|
||||
FixedRatioMoneyManager::~FixedRatioMoneyManager() {}
|
||||
|
||||
void FixedRatioMoneyManager::_checkParam(const string& name) const {
|
||||
if ("delta" == name) {
|
||||
double delta = getParam<double>("delta");
|
||||
HKU_ASSERT(delta > 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void FixedRatioMoneyManager::_reset() {
|
||||
m_current_num = 1;
|
||||
m_pre_cash = 0.0;
|
||||
|
@ -18,6 +18,7 @@ public:
|
||||
FixedRatioMoneyManager();
|
||||
virtual ~FixedRatioMoneyManager();
|
||||
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
virtual void _reset() override;
|
||||
virtual MoneyManagerPtr _clone() override;
|
||||
virtual double _getBuyNumber(const Datetime& datetime, const Stock& stock, price_t price,
|
||||
|
@ -19,6 +19,13 @@ FixedRiskMoneyManager::FixedRiskMoneyManager() : MoneyManagerBase("MM_FixedRisk"
|
||||
|
||||
FixedRiskMoneyManager::~FixedRiskMoneyManager() {}
|
||||
|
||||
void FixedRiskMoneyManager::_checkParam(const string& name) const {
|
||||
if ("risk" == name) {
|
||||
double risk = getParam<double>("risk");
|
||||
HKU_ASSERT(risk > 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
double FixedRiskMoneyManager ::_getBuyNumber(const Datetime& datetime, const Stock& stock,
|
||||
price_t price, price_t risk, SystemPart from) {
|
||||
return getParam<double>("risk") / risk;
|
||||
|
@ -20,6 +20,7 @@ class FixedRiskMoneyManager : public MoneyManagerBase {
|
||||
public:
|
||||
FixedRiskMoneyManager();
|
||||
virtual ~FixedRiskMoneyManager();
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
};
|
||||
|
||||
} /* namespace hku */
|
||||
|
@ -19,6 +19,13 @@ FixedUnitsMoneyManager::FixedUnitsMoneyManager() : MoneyManagerBase("MM_FixedUni
|
||||
|
||||
FixedUnitsMoneyManager::~FixedUnitsMoneyManager() {}
|
||||
|
||||
void FixedUnitsMoneyManager::_checkParam(const string& name) const {
|
||||
if ("n" == name) {
|
||||
int n = getParam<int>("n");
|
||||
HKU_ASSERT(n > 0);
|
||||
}
|
||||
}
|
||||
|
||||
double FixedUnitsMoneyManager ::_getBuyNumber(const Datetime& datetime, const Stock& stock,
|
||||
price_t price, price_t risk, SystemPart from) {
|
||||
int n = getParam<int>("n");
|
||||
|
@ -20,6 +20,7 @@ class FixedUnitsMoneyManager : public MoneyManagerBase {
|
||||
public:
|
||||
FixedUnitsMoneyManager();
|
||||
virtual ~FixedUnitsMoneyManager();
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
};
|
||||
|
||||
} /* namespace hku */
|
||||
|
@ -21,8 +21,18 @@ WilliamsFixedRiskMoneyManager::WilliamsFixedRiskMoneyManager()
|
||||
|
||||
WilliamsFixedRiskMoneyManager::~WilliamsFixedRiskMoneyManager() {}
|
||||
|
||||
double WilliamsFixedRiskMoneyManager ::_getBuyNumber(const Datetime& datetime, const Stock& stock,
|
||||
price_t price, price_t risk, SystemPart from) {
|
||||
void WilliamsFixedRiskMoneyManager::_checkParam(const string& name) const {
|
||||
if ("p" == name) {
|
||||
double p = getParam<double>("p");
|
||||
HKU_ASSERT(p > 0.0);
|
||||
} else if ("max_loss" == name) {
|
||||
price_t max_loss = getParam<price_t>("max_loss");
|
||||
HKU_ASSERT(max_loss > 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
HKU_WARN_IF_RETURN(max_loss <= 0.0, 0.0, "max_loss is zero!");
|
||||
return m_tm->cash(datetime, m_query.kType()) * getParam<double>("p") / max_loss;
|
||||
|
@ -20,6 +20,7 @@ class WilliamsFixedRiskMoneyManager : public MoneyManagerBase {
|
||||
public:
|
||||
WilliamsFixedRiskMoneyManager();
|
||||
virtual ~WilliamsFixedRiskMoneyManager();
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
};
|
||||
|
||||
} /* namespace hku */
|
||||
|
@ -29,6 +29,9 @@ ProfitGoalBase::ProfitGoalBase(const string& name) : m_name(name) {}
|
||||
|
||||
ProfitGoalBase::~ProfitGoalBase() {}
|
||||
|
||||
void ProfitGoalBase::baseCheckParam(const string& name) const {}
|
||||
void ProfitGoalBase::paramChanged() {}
|
||||
|
||||
void ProfitGoalBase::reset() {
|
||||
m_kdata = Null<KData>();
|
||||
m_tm.reset();
|
||||
|
@ -21,7 +21,7 @@ namespace hku {
|
||||
* @ingroup ProfitGoal
|
||||
*/
|
||||
class HKU_API ProfitGoalBase : public enable_shared_from_this<ProfitGoalBase> {
|
||||
PARAMETER_SUPPORT
|
||||
PARAMETER_SUPPORT_WITH_CHECK
|
||||
|
||||
public:
|
||||
ProfitGoalBase();
|
||||
|
@ -19,11 +19,16 @@ FixedHoldDays::FixedHoldDays() : ProfitGoalBase("PG_FixedHoldDays") {
|
||||
|
||||
FixedHoldDays::~FixedHoldDays() {}
|
||||
|
||||
void FixedHoldDays::_checkParam(const string& name) const {
|
||||
if ("days" == name) {
|
||||
int days = getParam<int>(name);
|
||||
HKU_ASSERT(days > 0);
|
||||
}
|
||||
}
|
||||
|
||||
void FixedHoldDays::_calculate() {}
|
||||
|
||||
price_t FixedHoldDays::getGoal(const Datetime& datetime, price_t price) {
|
||||
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(datetime, stk);
|
||||
Datetime take_date = position.takeDatetime;
|
||||
|
@ -20,6 +20,8 @@ class FixedHoldDays : public ProfitGoalBase {
|
||||
public:
|
||||
FixedHoldDays();
|
||||
virtual ~FixedHoldDays();
|
||||
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
};
|
||||
|
||||
} /* namespace hku */
|
||||
|
@ -21,6 +21,13 @@ FixedPercentProfitGoal::~FixedPercentProfitGoal() {}
|
||||
|
||||
void FixedPercentProfitGoal::_calculate() {}
|
||||
|
||||
void FixedPercentProfitGoal::_checkParam(const string& name) const {
|
||||
if ("p" == name) {
|
||||
double p = getParam<double>(name);
|
||||
HKU_ASSERT(p > 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
price_t FixedPercentProfitGoal::getGoal(const Datetime& datetime, price_t price) {
|
||||
Stock stock = getTO().getStock();
|
||||
PositionRecord position = getTM()->getPosition(datetime, stock);
|
||||
|
@ -20,6 +20,7 @@ class FixedPercentProfitGoal : public ProfitGoalBase {
|
||||
public:
|
||||
FixedPercentProfitGoal();
|
||||
virtual ~FixedPercentProfitGoal();
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
};
|
||||
|
||||
} /* namespace hku */
|
||||
|
@ -36,6 +36,9 @@ SelectorBase::SelectorBase(const string& name) : m_name(name) {
|
||||
|
||||
SelectorBase::~SelectorBase() {}
|
||||
|
||||
void SelectorBase::baseCheckParam(const string& name) const {}
|
||||
void SelectorBase::paramChanged() {}
|
||||
|
||||
void SelectorBase::removeAll() {
|
||||
m_pro_sys_list = SystemList();
|
||||
m_real_sys_list = SystemList();
|
||||
|
@ -24,7 +24,7 @@ class HKU_API Portfolio;
|
||||
* @ingroup Selector
|
||||
*/
|
||||
class HKU_API SelectorBase : public enable_shared_from_this<SelectorBase> {
|
||||
PARAMETER_SUPPORT
|
||||
PARAMETER_SUPPORT_WITH_CHECK
|
||||
|
||||
public:
|
||||
/** 默认构造函数 */
|
||||
|
@ -36,6 +36,9 @@ SignalBase::SignalBase(const string& name) : m_name(name), m_hold_long(false), m
|
||||
|
||||
SignalBase::~SignalBase() {}
|
||||
|
||||
void SignalBase::baseCheckParam(const string& name) const {}
|
||||
void SignalBase::paramChanged() {}
|
||||
|
||||
SignalPtr SignalBase::clone() {
|
||||
SignalPtr p;
|
||||
try {
|
||||
|
@ -22,7 +22,7 @@ namespace hku {
|
||||
* @ingroup Signal
|
||||
*/
|
||||
class HKU_API SignalBase : public enable_shared_from_this<SignalBase> {
|
||||
PARAMETER_SUPPORT
|
||||
PARAMETER_SUPPORT_WITH_CHECK
|
||||
|
||||
public:
|
||||
SignalBase();
|
||||
|
@ -17,7 +17,7 @@ BandSignal::BandSignal() : SignalBase("SG_Band") {}
|
||||
|
||||
BandSignal::BandSignal(const Indicator& ind, price_t lower, price_t upper)
|
||||
: SignalBase("SG_Band"), m_ind(ind), m_lower(lower), m_upper(upper) {
|
||||
HKU_ERROR_IF(lower > upper, "BandSignal: lower track is greater than upper track");
|
||||
HKU_CHECK(lower > upper, "BandSignal: lower track is greater than upper track");
|
||||
}
|
||||
|
||||
BandSignal::~BandSignal() {}
|
||||
|
@ -1,12 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2024 hikyuu.org
|
||||
*
|
||||
* Created on: 2024-03-12
|
||||
* Author: fasiondog
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../SignalBase.h"
|
||||
|
||||
namespace hku {}
|
@ -28,6 +28,15 @@ SingleSignal::SingleSignal(const Indicator& ind) : SignalBase("SG_Single"), m_in
|
||||
|
||||
SingleSignal::~SingleSignal() {}
|
||||
|
||||
void SingleSignal::_checkParam(const string& name) const {
|
||||
if ("filter_n" == name) {
|
||||
HKU_ASSERT(getParam<int>("filter_n") >= 3);
|
||||
} else if ("filter_p" == name) {
|
||||
double filter_p = getParam<double>(name);
|
||||
HKU_ASSERT(filter_p > 0.0 && filter_p < 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
SignalPtr SingleSignal::_clone() {
|
||||
SingleSignal* p = new SingleSignal();
|
||||
p->m_ind = m_ind.clone();
|
||||
|
@ -20,6 +20,7 @@ public:
|
||||
explicit SingleSignal(const Indicator& ind);
|
||||
virtual ~SingleSignal();
|
||||
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
virtual SignalPtr _clone() override;
|
||||
virtual void _calculate() override;
|
||||
|
||||
|
@ -31,6 +31,15 @@ SingleSignal2::SingleSignal2(const Indicator& ind) : SignalBase("SG_Single2"), m
|
||||
|
||||
SingleSignal2::~SingleSignal2() {}
|
||||
|
||||
void SingleSignal2::_checkParam(const string& name) const {
|
||||
if ("filter_n" == name) {
|
||||
HKU_ASSERT(getParam<int>("filter_n") >= 3);
|
||||
} else if ("filter_p" == name) {
|
||||
double filter_p = getParam<double>(name);
|
||||
HKU_ASSERT(filter_p > 0.0 && filter_p < 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
SignalPtr SingleSignal2::_clone() {
|
||||
SingleSignal2* p = new SingleSignal2();
|
||||
p->m_ind = m_ind.clone();
|
||||
|
@ -20,6 +20,7 @@ public:
|
||||
explicit SingleSignal2(const Indicator&);
|
||||
virtual ~SingleSignal2();
|
||||
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
virtual SignalPtr _clone() override;
|
||||
virtual void _calculate() override;
|
||||
|
||||
|
@ -27,6 +27,9 @@ SlippageBase::SlippageBase() : m_name("SlippageBase") {}
|
||||
|
||||
SlippageBase::SlippageBase(const string& name) : m_name(name) {}
|
||||
|
||||
void SlippageBase::baseCheckParam(const string& name) const {}
|
||||
void SlippageBase::paramChanged() {}
|
||||
|
||||
void SlippageBase::reset() {
|
||||
m_kdata = Null<KData>();
|
||||
_reset();
|
||||
|
@ -19,7 +19,7 @@ namespace hku {
|
||||
* @ingroup Slippage
|
||||
*/
|
||||
class HKU_API SlippageBase : public enable_shared_from_this<SlippageBase> {
|
||||
PARAMETER_SUPPORT
|
||||
PARAMETER_SUPPORT_WITH_CHECK
|
||||
|
||||
public:
|
||||
SlippageBase();
|
||||
|
@ -19,6 +19,13 @@ FixedPercentSlippage::FixedPercentSlippage() : SlippageBase("FixedPercent") {
|
||||
|
||||
FixedPercentSlippage::~FixedPercentSlippage() {}
|
||||
|
||||
void FixedPercentSlippage::_checkParam(const string& name) const {
|
||||
if ("p" == name) {
|
||||
double p = getParam<double>(name);
|
||||
HKU_ASSERT(p >= 0.0 && p < 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
price_t FixedPercentSlippage ::getRealBuyPrice(const Datetime& datetime, price_t price) {
|
||||
return price * (1 + getParam<double>("p"));
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ class FixedPercentSlippage : public SlippageBase {
|
||||
public:
|
||||
FixedPercentSlippage();
|
||||
virtual ~FixedPercentSlippage();
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
};
|
||||
|
||||
} /* namespace hku */
|
||||
|
@ -19,6 +19,12 @@ FixedValueSlippage::FixedValueSlippage() {
|
||||
|
||||
FixedValueSlippage::~FixedValueSlippage() {}
|
||||
|
||||
void FixedValueSlippage::_checkParam(const string& name) const {
|
||||
if ("p" == name) {
|
||||
HKU_ASSERT(getParam<double>(name) >= 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
price_t FixedValueSlippage ::getRealBuyPrice(const Datetime& datetime, price_t price) {
|
||||
return price + getParam<double>("value");
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ class FixedValueSlippage : public SlippageBase {
|
||||
public:
|
||||
FixedValueSlippage();
|
||||
virtual ~FixedValueSlippage();
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
};
|
||||
|
||||
} /* namespace hku */
|
||||
|
@ -29,6 +29,9 @@ StoplossBase::StoplossBase(const string& name) : m_name(name) {}
|
||||
|
||||
StoplossBase::~StoplossBase() {}
|
||||
|
||||
void StoplossBase::baseCheckParam(const string& name) const {}
|
||||
void StoplossBase::paramChanged() {}
|
||||
|
||||
void StoplossBase::reset() {
|
||||
m_kdata = Null<KData>();
|
||||
m_tm.reset();
|
||||
|
@ -21,7 +21,7 @@ namespace hku {
|
||||
* @ingroup Stoploss
|
||||
*/
|
||||
class HKU_API StoplossBase : public enable_shared_from_this<StoplossBase> {
|
||||
PARAMETER_SUPPORT
|
||||
PARAMETER_SUPPORT_WITH_CHECK
|
||||
|
||||
public:
|
||||
StoplossBase();
|
||||
|
@ -19,6 +19,13 @@ FixedPercentStoploss::FixedPercentStoploss() : StoplossBase("ST_FixedPercent") {
|
||||
|
||||
FixedPercentStoploss::~FixedPercentStoploss() {}
|
||||
|
||||
void FixedPercentStoploss::_checkParam(const string& name) const {
|
||||
if ("p" == name) {
|
||||
double p = getParam<double>("p");
|
||||
HKU_ASSERT(p > 0.0 && p <= 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
price_t FixedPercentStoploss ::getPrice(const Datetime& datetime, price_t price) {
|
||||
Stock stock = m_kdata.getStock();
|
||||
int precision = stock.isNull() ? 2 : stock.precision();
|
||||
|
@ -23,6 +23,7 @@ class FixedPercentStoploss : public StoplossBase {
|
||||
public:
|
||||
FixedPercentStoploss();
|
||||
virtual ~FixedPercentStoploss();
|
||||
virtual void _checkParam(const string& name) const;
|
||||
};
|
||||
|
||||
} /* namespace hku */
|
||||
|
@ -21,10 +21,19 @@ IndicatorStoploss::IndicatorStoploss() : StoplossBase("IndicatorStoploss") {
|
||||
IndicatorStoploss::IndicatorStoploss(const Indicator& op, const string& kdata_part)
|
||||
: StoplossBase("IndicatorStoploss"), m_op(op) {
|
||||
setParam<string>("kpart", "CLOSE");
|
||||
checkParam("kpart");
|
||||
}
|
||||
|
||||
IndicatorStoploss::~IndicatorStoploss() {}
|
||||
|
||||
void IndicatorStoploss::_checkParam(const string& name) const {
|
||||
if ("kpart" == name) {
|
||||
string kpart = getParam<string>("kpart");
|
||||
HKU_ASSERT("CLOSE" == kpart || "OPEN" == kpart || "HIGH" == kpart || "LOW" == kpart ||
|
||||
"AMO" == kpart || "VOL" == kpart);
|
||||
}
|
||||
}
|
||||
|
||||
price_t IndicatorStoploss::getPrice(const Datetime& datetime, price_t price) {
|
||||
return m_result.count(datetime) ? m_result[datetime] : 0.0;
|
||||
}
|
||||
|
@ -16,9 +16,10 @@ namespace hku {
|
||||
|
||||
class IndicatorStoploss : public StoplossBase {
|
||||
public:
|
||||
IndicatorStoploss(); //仅用于序列化默认构造函数
|
||||
IndicatorStoploss(); // 仅用于序列化默认构造函数
|
||||
IndicatorStoploss(const Indicator& op, const string& kdata_part);
|
||||
virtual ~IndicatorStoploss();
|
||||
virtual void _checkParam(const string& name) const;
|
||||
|
||||
virtual price_t getPrice(const Datetime& datetime, price_t price) override;
|
||||
virtual void _reset() override;
|
||||
@ -30,7 +31,7 @@ private:
|
||||
map<Datetime, price_t> m_result;
|
||||
|
||||
//========================================
|
||||
//序列化支持
|
||||
// 序列化支持
|
||||
//========================================
|
||||
#if HKU_SUPPORT_SERIALIZATION
|
||||
private:
|
||||
|
@ -33,7 +33,7 @@ HKU_API std::ostream& operator<<(std::ostream& os, const SystemPtr& sys) {
|
||||
|
||||
System::System()
|
||||
: m_name("SYS_Simple"),
|
||||
m_part_changed(true),
|
||||
m_calculated(false),
|
||||
m_pre_ev_valid(true), // must true
|
||||
m_pre_cn_valid(true), // must true
|
||||
m_buy_days(0),
|
||||
@ -45,7 +45,7 @@ System::System()
|
||||
|
||||
System::System(const string& name)
|
||||
: m_name(name),
|
||||
m_part_changed(true),
|
||||
m_calculated(false),
|
||||
m_pre_ev_valid(true),
|
||||
m_pre_cn_valid(true),
|
||||
m_buy_days(0),
|
||||
@ -69,7 +69,7 @@ System::System(const TradeManagerPtr& tm, const MoneyManagerPtr& mm, const Envir
|
||||
m_pg(pg),
|
||||
m_sp(sp),
|
||||
m_name(name),
|
||||
m_part_changed(true),
|
||||
m_calculated(false),
|
||||
m_pre_ev_valid(true),
|
||||
m_pre_cn_valid(true),
|
||||
m_buy_days(0),
|
||||
@ -123,6 +123,18 @@ void System::initParam() {
|
||||
setParam<bool>("shared_sp", false);
|
||||
}
|
||||
|
||||
void System::baseCheckParam(const string& name) const {
|
||||
if ("max_delay_count" == name) {
|
||||
HKU_ASSERT(getParam<int>("max_delay_count") >= 0);
|
||||
} else if ("tp_delay_n" == name) {
|
||||
HKU_ASSERT(getParam<int>("tp_delay_n") >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
void System::paramChanged() {
|
||||
m_calculated = false;
|
||||
}
|
||||
|
||||
void System::reset() {
|
||||
if (m_tm && !getParam<bool>("shared_tm"))
|
||||
m_tm->reset();
|
||||
@ -148,7 +160,7 @@ void System::reset() {
|
||||
// 一个sys实例绑定stock后,除非主动改变,否则不应该被reset
|
||||
// m_stock
|
||||
|
||||
m_part_changed = true;
|
||||
m_calculated = false;
|
||||
m_pre_ev_valid = false; // true;
|
||||
m_pre_cn_valid = false; // true;
|
||||
|
||||
@ -189,7 +201,7 @@ void System::forceResetAll() {
|
||||
m_src_kdata = Null<KData>();
|
||||
m_kdata = Null<KData>();
|
||||
|
||||
m_part_changed = true;
|
||||
m_calculated = false;
|
||||
m_pre_ev_valid = false; // true;
|
||||
m_pre_cn_valid = false; // true;
|
||||
|
||||
@ -206,10 +218,14 @@ void System::forceResetAll() {
|
||||
}
|
||||
|
||||
void System::setTO(const KData& kdata) {
|
||||
HKU_TRACE_IF_RETURN(!m_part_changed && m_kdata == kdata, void(), "No need to calcule!");
|
||||
m_kdata = kdata;
|
||||
m_stock = kdata.getStock();
|
||||
if (m_kdata != kdata) {
|
||||
m_calculated = false;
|
||||
m_kdata = kdata;
|
||||
}
|
||||
|
||||
HKU_TRACE_IF_RETURN(m_calculated, void(), "No need to calcule!");
|
||||
|
||||
m_stock = kdata.getStock();
|
||||
KQuery query = kdata.getQuery();
|
||||
if (m_stock.isNull() || query.recoverType() == KQuery::NO_RECOVER) {
|
||||
m_src_kdata = m_kdata;
|
||||
@ -270,7 +286,7 @@ SystemPtr System::clone() {
|
||||
p->m_kdata = m_kdata;
|
||||
p->m_src_kdata = m_src_kdata;
|
||||
|
||||
p->m_part_changed = m_part_changed;
|
||||
p->m_calculated = m_calculated;
|
||||
p->m_pre_ev_valid = m_pre_ev_valid;
|
||||
p->m_pre_cn_valid = m_pre_cn_valid;
|
||||
|
||||
@ -334,7 +350,7 @@ bool System::readyForRun() {
|
||||
}
|
||||
|
||||
void System::run(const KQuery& query, bool reset, bool resetAll) {
|
||||
HKU_ERROR_IF_RETURN(m_stock.isNull(), void(), "m_stock is NULL!");
|
||||
HKU_CHECK(!m_stock.isNull(), "m_stock is NULL!");
|
||||
|
||||
// reset必须在readyForRun之前,否则m_pre_cn_valid、m_pre_ev_valid将会被赋为错误的初值
|
||||
if (resetAll) {
|
||||
@ -343,11 +359,10 @@ void System::run(const KQuery& query, bool reset, bool resetAll) {
|
||||
this->reset();
|
||||
}
|
||||
|
||||
HKU_IF_RETURN(!readyForRun(), void());
|
||||
|
||||
KData kdata = m_stock.getKData(query);
|
||||
HKU_IF_RETURN(kdata.empty(), void());
|
||||
HKU_DEBUG_IF_RETURN(!m_part_changed && m_kdata == kdata, void(), "Not need calculate.");
|
||||
HKU_DEBUG_IF_RETURN(m_calculated && m_kdata == kdata, void(), "Not need calculate.");
|
||||
|
||||
HKU_IF_RETURN(!readyForRun(), void());
|
||||
|
||||
setTO(kdata);
|
||||
size_t total = kdata.size();
|
||||
@ -358,7 +373,7 @@ void System::run(const KQuery& query, bool reset, bool resetAll) {
|
||||
_runMoment(ks[i], src_ks[i]);
|
||||
}
|
||||
}
|
||||
m_part_changed = false;
|
||||
m_calculated = true;
|
||||
}
|
||||
|
||||
void System::run(const Stock& stock, const KQuery& query, bool reset, bool resetAll) {
|
||||
@ -367,9 +382,6 @@ void System::run(const Stock& stock, const KQuery& query, bool reset, bool reset
|
||||
}
|
||||
|
||||
void System::run(const KData& kdata, bool reset, bool resetAll) {
|
||||
HKU_INFO_IF_RETURN(kdata.empty(), void(), "Input kdata is empty!");
|
||||
HKU_DEBUG_IF_RETURN(!m_part_changed && m_kdata == kdata, void(), "Not need calculate.");
|
||||
|
||||
// reset必须在readyForRun之前,否则m_pre_cn_valid、m_pre_ev_valid将会被赋为错误的初值
|
||||
if (resetAll) {
|
||||
this->forceResetAll();
|
||||
@ -378,6 +390,8 @@ void System::run(const KData& kdata, bool reset, bool resetAll) {
|
||||
this->reset();
|
||||
}
|
||||
|
||||
HKU_DEBUG_IF_RETURN(m_calculated && m_kdata == kdata, void(), "Not need calculate.");
|
||||
|
||||
HKU_IF_RETURN(!readyForRun(), void());
|
||||
|
||||
setTO(kdata);
|
||||
@ -389,7 +403,7 @@ void System::run(const KData& kdata, bool reset, bool resetAll) {
|
||||
_runMoment(ks[i], src_ks[i]);
|
||||
}
|
||||
}
|
||||
m_part_changed = false;
|
||||
m_calculated = true;
|
||||
}
|
||||
|
||||
void System::clearDelayRequest() {
|
||||
@ -530,7 +544,12 @@ TradeRecord System::_runMoment(const KRecord& today, const KRecord& src_today) {
|
||||
} else {
|
||||
m_lastTakeProfit = current_take_profile;
|
||||
}
|
||||
if (current_price <= current_take_profile) {
|
||||
|
||||
int tp_delay_n = getParam<int>("tp_delay_n");
|
||||
size_t pos = m_kdata.getPos(today.datetime);
|
||||
size_t position_pos = m_kdata.getPos(position.takeDatetime);
|
||||
// 如果当前价格小于等于止盈价,且满足止盈延迟条件则卖出
|
||||
if (pos - position_pos >= tp_delay_n && current_price <= current_take_profile) {
|
||||
tr = _sell(today, src_today, PART_TAKEPROFIT);
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ namespace hku {
|
||||
* @ingroup System
|
||||
*/
|
||||
class HKU_API System {
|
||||
PARAMETER_SUPPORT
|
||||
PARAMETER_SUPPORT_WITH_CHECK
|
||||
|
||||
public:
|
||||
/** 默认构造函数 */
|
||||
@ -223,6 +223,11 @@ public:
|
||||
return _sellForce(date, num, from, false);
|
||||
}
|
||||
|
||||
// 由各个相关组件调用,用于组件参数变化时通知 sys,以便重算
|
||||
void partChangedNotify() {
|
||||
m_calculated = false;
|
||||
}
|
||||
|
||||
private:
|
||||
bool _environmentIsValid(const Datetime& datetime);
|
||||
bool _conditionIsValid(const Datetime& datetime);
|
||||
@ -292,7 +297,7 @@ protected:
|
||||
KData m_kdata;
|
||||
KData m_src_kdata; // 未复权的原始 K 线数据
|
||||
|
||||
bool m_part_changed; // 记录部件是否发生变化,控制是否需要重新计算
|
||||
bool m_calculated; // 控制是否需要重新计算
|
||||
bool m_pre_ev_valid;
|
||||
bool m_pre_cn_valid;
|
||||
|
||||
@ -334,7 +339,7 @@ private:
|
||||
// m_kdata中包含了stock和query的信息,不用保存m_stock
|
||||
ar& BOOST_SERIALIZATION_NVP(m_kdata);
|
||||
|
||||
ar& BOOST_SERIALIZATION_NVP(m_part_changed);
|
||||
ar& BOOST_SERIALIZATION_NVP(m_calculated);
|
||||
ar& BOOST_SERIALIZATION_NVP(m_pre_ev_valid);
|
||||
ar& BOOST_SERIALIZATION_NVP(m_pre_cn_valid);
|
||||
|
||||
@ -369,7 +374,7 @@ private:
|
||||
ar& BOOST_SERIALIZATION_NVP(m_kdata);
|
||||
m_stock = m_kdata.getStock();
|
||||
|
||||
ar& BOOST_SERIALIZATION_NVP(m_part_changed);
|
||||
ar& BOOST_SERIALIZATION_NVP(m_calculated);
|
||||
ar& BOOST_SERIALIZATION_NVP(m_pre_ev_valid);
|
||||
ar& BOOST_SERIALIZATION_NVP(m_pre_cn_valid);
|
||||
|
||||
@ -451,63 +456,63 @@ inline SlippagePtr System::getSP() const {
|
||||
inline void System::setTM(const TradeManagerPtr& tm) {
|
||||
if (m_tm != tm) {
|
||||
m_tm = tm;
|
||||
m_part_changed = true;
|
||||
m_calculated = false;
|
||||
}
|
||||
}
|
||||
|
||||
inline void System::setMM(const MoneyManagerPtr& mm) {
|
||||
if (m_mm != mm) {
|
||||
m_mm = mm;
|
||||
m_part_changed = true;
|
||||
m_calculated = false;
|
||||
}
|
||||
}
|
||||
|
||||
inline void System::setEV(const EnvironmentPtr& ev) {
|
||||
if (m_ev != ev) {
|
||||
m_ev = ev;
|
||||
m_part_changed = true;
|
||||
m_calculated = false;
|
||||
}
|
||||
}
|
||||
|
||||
inline void System::setCN(const ConditionPtr& cn) {
|
||||
if (m_cn != cn) {
|
||||
m_cn = cn;
|
||||
m_part_changed = true;
|
||||
m_calculated = false;
|
||||
}
|
||||
}
|
||||
|
||||
inline void System::setSG(const SignalPtr& sg) {
|
||||
if (m_sg != sg) {
|
||||
m_sg = sg;
|
||||
m_part_changed = true;
|
||||
m_calculated = false;
|
||||
}
|
||||
}
|
||||
|
||||
inline void System::setST(const StoplossPtr& st) {
|
||||
if (m_st != st) {
|
||||
m_st = st;
|
||||
m_part_changed = true;
|
||||
m_calculated = false;
|
||||
}
|
||||
}
|
||||
|
||||
inline void System::setTP(const StoplossPtr& tp) {
|
||||
if (m_tp != tp) {
|
||||
m_tp = tp;
|
||||
m_part_changed = true;
|
||||
m_calculated = false;
|
||||
}
|
||||
}
|
||||
|
||||
inline void System::setPG(const ProfitGoalPtr& pg) {
|
||||
if (m_pg != pg) {
|
||||
m_pg = pg;
|
||||
m_part_changed = true;
|
||||
m_calculated = false;
|
||||
}
|
||||
}
|
||||
|
||||
inline void System::setSP(const SlippagePtr& sp) {
|
||||
if (m_sp != sp) {
|
||||
m_sp = sp;
|
||||
m_part_changed = true;
|
||||
m_calculated = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -516,7 +521,10 @@ inline Stock System::getStock() const {
|
||||
}
|
||||
|
||||
inline void System::setStock(const Stock& stk) {
|
||||
m_stock = stk;
|
||||
if (m_stock != stk) {
|
||||
m_stock = stk;
|
||||
m_calculated = false;
|
||||
}
|
||||
}
|
||||
|
||||
inline const TradeRecordList& System::getTradeRecordList() const {
|
||||
|
@ -352,21 +352,23 @@ public: \
|
||||
|
||||
/**
|
||||
* 支持自定义类参数检查及变化通知
|
||||
* 需要实现重载以下虚函数接口:
|
||||
* virtual void checkParam(const string& name) -- 内部实现对应参数的检查,如果不合法需抛出异常
|
||||
* virtual void paramChanged() -- 参数变化时调用该函数
|
||||
* 注意:由于默认参数一般在类的构造函数中设置,此时由于 checkParam 和 paramChanged
|
||||
* 均为虚函数,实际上是调用的是基类的虚函数。一般构造函数设置初始的默认参数时,
|
||||
* 子类的 checkParam 和 paramChanged 即使没有被调用也没有影响。但如果需要用到
|
||||
* 构造函数中带入的参数值,则需要在 setParam 执行后,自行调用 checkParam, 或者
|
||||
* 在 setParam 执行之前,直接对构造函数传入的参数进行检查(子类和基类均是如此)
|
||||
* 另:python 中一般不用引出这里个函数,python 类继承时可以自己进行检查
|
||||
* 子类需要实现重载以下虚函数接口:
|
||||
* virtual void _checkParam(const string& name) -- 内部实现对应参数的检查,如果不合法需抛出异常
|
||||
* 另:python 中一般不需要引出 paramChanged/checkParam/_checkParam,python
|
||||
* 类继承时可以自己在初始化时进行检查
|
||||
*/
|
||||
#define PARAMETER_SUPPORT_WITH_CHECK \
|
||||
protected: \
|
||||
Parameter m_params; \
|
||||
virtual void checkParam(const string& name) const; \
|
||||
virtual void paramChanged(); \
|
||||
void paramChanged(); \
|
||||
void checkParam(const string& name) const { \
|
||||
baseCheckParam(name); \
|
||||
_checkParam(name); \
|
||||
} \
|
||||
virtual void _checkParam(const string& name) const {} \
|
||||
\
|
||||
private: \
|
||||
void baseCheckParam(const string& name) const; \
|
||||
\
|
||||
public: \
|
||||
const Parameter& getParameter() const { \
|
||||
|
@ -26,15 +26,12 @@ TEST_CASE("test_MM_FixedCount") {
|
||||
TradeManagerPtr tm = crtTM(Datetime(199001010000LL), 0.0, TC_FixedA());
|
||||
|
||||
/** @arg n < 1 */
|
||||
MoneyManagerPtr mm = MM_FixedCount(0);
|
||||
mm->setTM(tm);
|
||||
int result = mm->getBuyNumber(Datetime(200101010000), stock, 10.0, 10.0, PART_SIGNAL);
|
||||
CHECK_EQ(result, 0);
|
||||
CHECK_THROWS_AS(MM_FixedCount(0), std::exception);
|
||||
|
||||
/** @arg n = 100, 一个初始资金为0的交易账户,能够执行买入操作 */
|
||||
tm = crtTM(Datetime(199001010000LL), 0.0, TC_FixedA());
|
||||
CHECK_EQ(tm->initCash(), 0.0);
|
||||
mm = MM_FixedCount(100);
|
||||
auto mm = MM_FixedCount(100);
|
||||
mm->setTM(tm);
|
||||
mm->setParam<bool>("auto-checkin", true);
|
||||
mm->getBuyNumber(Datetime(200001200000), stock, 24.11, 24.11, PART_SIGNAL);
|
||||
|
@ -23,8 +23,8 @@ TEST_CASE("test_PG_FixedHoldDays") {
|
||||
StockManager& sm = StockManager::instance();
|
||||
TMPtr tm = crtTM(Datetime(199001010000LL), 100000);
|
||||
|
||||
Datetime start_date(199911100000LL); //测试起始日期
|
||||
Datetime end_date(200002250000LL); //测试结束日期
|
||||
Datetime start_date(199911100000LL); // 测试起始日期
|
||||
Datetime end_date(200002250000LL); // 测试结束日期
|
||||
KQuery query = KQueryByDate(start_date, end_date, KQuery::DAY);
|
||||
|
||||
Stock stk = sm.getStock("sh600000");
|
||||
@ -40,10 +40,7 @@ TEST_CASE("test_PG_FixedHoldDays") {
|
||||
CHECK_EQ(pg->getParam<int>("days"), 5);
|
||||
|
||||
/** @arg days = 0 */
|
||||
pg->setParam<int>("days", 0);
|
||||
CHECK_EQ(pg->getGoal(Datetime(199911100000LL), 0.0), 0.0);
|
||||
CHECK_EQ(pg->getGoal(Datetime(199911110000LL), 0.0), 0.0);
|
||||
CHECK_EQ(pg->getGoal(Datetime(199911120000LL), 0.0), 0.0);
|
||||
CHECK_THROWS_AS(pg->setParam<int>("days", 0), std::exception);
|
||||
|
||||
/** @arg days = 1 */
|
||||
pg->setParam<int>("days", 1);
|
||||
|
@ -32,15 +32,20 @@ TEST_CASE("test_FixedPercent_SL") {
|
||||
result = sp->getPrice(Datetime(199101030000), 66.4);
|
||||
CHECK_LT(std::fabs(result - 53.12), 0.01);
|
||||
|
||||
/** @arg p = 0.0 */
|
||||
sp = ST_FixedPercent(0.0);
|
||||
/** @arg p = 0.99 */
|
||||
sp = ST_FixedPercent(0.99);
|
||||
result = sp->getPrice(Datetime(199101030000), 66.397);
|
||||
CHECK_LT(std::fabs(result - 66.4), 0.01);
|
||||
CHECK_EQ(result, doctest::Approx(roundEx(66.397 * 0.01, 2)));
|
||||
|
||||
/** @arg p = 1.0 */
|
||||
sp = ST_FixedPercent(1.0);
|
||||
result = sp->getPrice(Datetime(199101030000), 66.397);
|
||||
CHECK_LT(std::fabs(result - 0), 0.01);
|
||||
CHECK_EQ(result, doctest::Approx(0.0));
|
||||
|
||||
/** @arg 非法参数 */
|
||||
CHECK_THROWS_AS(ST_FixedPercent(0.0), std::exception);
|
||||
CHECK_THROWS_AS(ST_FixedPercent(1.01), std::exception);
|
||||
CHECK_THROWS_AS(ST_FixedPercent(-1.0), std::exception);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
Loading…
Reference in New Issue
Block a user