From 9653d44ea224179d3717e992dda65ca6dfd5bbcc Mon Sep 17 00:00:00 2001 From: fasiondog Date: Sat, 14 Sep 2024 12:48:09 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=81=E8=AE=B8=20Selector=20=E6=8F=92?= =?UTF-8?q?=E5=85=A5=20null=20sys=20=E7=9A=84=20SystemWeight=20=E8=BF=9B?= =?UTF-8?q?=E8=A1=8C=E5=8D=A0=E4=BD=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../allocatefunds/AllocateFundsBase.cpp | 34 ++++++++------ .../allocatefunds/AllocateFundsBase.h | 3 -- .../hikyuu/trade_sys/portfolio/Portfolio.cpp | 47 +++++++++++-------- 3 files changed, 46 insertions(+), 38 deletions(-) diff --git a/hikyuu_cpp/hikyuu/trade_sys/allocatefunds/AllocateFundsBase.cpp b/hikyuu_cpp/hikyuu/trade_sys/allocatefunds/AllocateFundsBase.cpp index 8b3652cce..106bbb9b8 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/allocatefunds/AllocateFundsBase.cpp +++ b/hikyuu_cpp/hikyuu/trade_sys/allocatefunds/AllocateFundsBase.cpp @@ -100,16 +100,6 @@ AFPtr AllocateFundsBase::clone() { return p; } -void AllocateFundsBase::_check_weight(const SystemWeightList& sw_list) { - price_t sum_weight = 0.0; - for (const auto& sw : sw_list) { - HKU_CHECK(!std::isnan(sw.weight) && sw.weight >= 0.0 && sw.weight <= 1.0, - "Invalid weight ({}, {})", sw.sys->name(), sw.weight); - sum_weight += sw.weight; - } - HKU_CHECK(sum_weight <= 1.001, "The cumulative weight exceeds 1! sum_weight: {}", sum_weight); -} - SystemWeightList AllocateFundsBase::adjustFunds(const Datetime& date, const SystemWeightList& se_list, const std::unordered_set& running_list) { @@ -211,6 +201,10 @@ void AllocateFundsBase::_adjust_without_running(const Datetime& date, break; } + if (!iter->sys) { + continue; + } + // 如果是运行中系统,不使用计算的权重,更新累积权重和 if (running_set.find(iter->sys) != running_set.cend()) { FundsRecord sub_funds = m_tm->getFunds(date, m_query.kType()); @@ -274,11 +268,13 @@ SystemWeightList AllocateFundsBase::_adjust_with_running( // 回收所有运行中系统剩余资金,用于重新分配 //----------------------------------------------------------------- for (const auto& sys : running_set) { - auto sub_tm = sys->getTM(); - auto sub_cash = sub_tm->currentCash(); - if (sub_cash > 0.0 && sub_tm->checkout(date, sub_cash)) { - m_cash_tm->checkin(date, sub_cash); - HKU_INFO_IF(trace, "[AF] Recycle cash: {:<.2f} from {}", sub_cash, sys->name()); + if (sys) { + auto sub_tm = sys->getTM(); + auto sub_cash = sub_tm->currentCash(); + if (sub_cash > 0.0 && sub_tm->checkout(date, sub_cash)) { + m_cash_tm->checkin(date, sub_cash); + HKU_INFO_IF(trace, "[AF] Recycle cash: {:<.2f} from {}", sub_cash, sys->name()); + } } } @@ -336,6 +332,10 @@ SystemWeightList AllocateFundsBase::_adjust_with_running( std::unordered_set reduced_running_set; // 缓存已执行过减仓的运行中系统 for (auto iter = sw_list.begin(), end_iter = sw_list.end(); iter != end_iter; ++iter) { + if (!iter->sys) { + continue; + } + // 如果当前系统是运行中的系统 if (running_set.find(iter->sys) != running_set.cend()) { TMPtr sub_tm = iter->sys->getTM(); @@ -418,6 +418,10 @@ SystemWeightList AllocateFundsBase::_adjust_with_running( break; } + if (!iter->sys) { + continue; + } + // 系统期望分配的资产额 price_t will_funds = roundUp(total_funds * iter->weight, precision); diff --git a/hikyuu_cpp/hikyuu/trade_sys/allocatefunds/AllocateFundsBase.h b/hikyuu_cpp/hikyuu/trade_sys/allocatefunds/AllocateFundsBase.h index 79cf05cd8..f3d450e95 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/allocatefunds/AllocateFundsBase.h +++ b/hikyuu_cpp/hikyuu/trade_sys/allocatefunds/AllocateFundsBase.h @@ -112,9 +112,6 @@ class HKU_API AllocateFundsBase : public enable_shared_from_this& running_list); - /* 检查分配的权重是否在 0 和 1 之间,如果存在错误,抛出异常,仅在 trace 时生效*/ - void _check_weight(const SystemWeightList&); - private: string m_name; // 组件名称 KQuery m_query; // 查询条件 diff --git a/hikyuu_cpp/hikyuu/trade_sys/portfolio/Portfolio.cpp b/hikyuu_cpp/hikyuu/trade_sys/portfolio/Portfolio.cpp index daabbdb1d..f8630352f 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/portfolio/Portfolio.cpp +++ b/hikyuu_cpp/hikyuu/trade_sys/portfolio/Portfolio.cpp @@ -143,20 +143,22 @@ void Portfolio::_readyForRun() { m_real_sys_list.reserve(total); for (size_t i = 0; i < total; i++) { SystemPtr& pro_sys = pro_sys_list[i]; - SystemPtr sys = pro_sys->clone(); - m_se->bindRealToProto(sys, pro_sys); - m_real_sys_list.emplace_back(sys); - - // 为内部实际执行的系统创建初始资金为0的子账户 - sys->setTM(pro_tm->clone()); - string sys_name = fmt::format("{}_{}_{}", sys->name(), sys->getStock().market_code(), - sys->getStock().name()); - sys->getTM()->name(fmt::format("TM_SUB_{}", sys_name)); - sys->name(fmt::format("PF_{}", sys_name)); - - sys->readyForRun(); - KData k = sys->getStock().getKData(m_query); - sys->setTO(k); + if (pro_sys) { + SystemPtr sys = pro_sys->clone(); + m_se->bindRealToProto(sys, pro_sys); + m_real_sys_list.emplace_back(sys); + + // 为内部实际执行的系统创建初始资金为0的子账户 + sys->setTM(pro_tm->clone()); + string sys_name = fmt::format("{}_{}_{}", sys->name(), sys->getStock().market_code(), + sys->getStock().name()); + sys->getTM()->name(fmt::format("TM_SUB_{}", sys_name)); + sys->name(fmt::format("PF_{}", sys_name)); + + sys->readyForRun(); + KData k = sys->getStock().getKData(m_query); + sys->setTO(k); + } } // 告知 se 当前实际运行的系统列表 @@ -325,14 +327,17 @@ void Portfolio::_runMoment(const Datetime& date, const Datetime& nextCycle, bool // 如果选中的系统不在已有列表中, 则先清除其延迟买入操作,防止在调仓日出现未来信号 for (auto& sys : m_tmp_selected_list) { - if (m_running_sys_set.find(sys.sys) == m_running_sys_set.end()) { - sys.sys->clearDelayBuyRequest(); + if (sys.sys) { + if (m_running_sys_set.find(sys.sys) == m_running_sys_set.end()) { + sys.sys->clearDelayBuyRequest(); + } } } if (trace && !m_tmp_selected_list.empty()) { for (auto& sys : m_tmp_selected_list) { - HKU_INFO("[PF] select: {}, score: {:<.4f}", sys.sys->name(), sys.weight); + HKU_INFO_IF(sys.sys, "[PF] select: {}, score: {:<.4f}", sys.sys->name(), + sys.weight); } } @@ -350,9 +355,11 @@ void Portfolio::_runMoment(const Datetime& date, const Datetime& nextCycle, bool // 如果选中的系统不在已有列表中,且账户已经被分配了资金,则将其加入运行系统列表 for (auto& sys : m_tmp_selected_list) { - if (m_running_sys_set.find(sys.sys) == m_running_sys_set.end()) { - if (sys.sys->getTM()->cash(date, m_query.kType()) > 0.0) { - m_running_sys_set.insert(sys.sys); + if (sys.sys) { + if (m_running_sys_set.find(sys.sys) == m_running_sys_set.end()) { + if (sys.sys->getTM()->cash(date, m_query.kType()) > 0.0) { + m_running_sys_set.insert(sys.sys); + } } } }