diff --git a/hikyuu_cpp/hikyuu/trade_sys/system/DelegateSystem.cpp b/hikyuu_cpp/hikyuu/trade_sys/system/DelegateSystem.cpp new file mode 100644 index 00000000..5a523931 --- /dev/null +++ b/hikyuu_cpp/hikyuu/trade_sys/system/DelegateSystem.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2024 hikyuu.org + * + * Created on: 2024-09-13 + * Author: fasiondog + */ + +#include "DelegateSystem.h" + +namespace hku { + +void DelegateSystem::_reset() { + if (m_sys) { + m_sys->reset(); + } +} + +void DelegateSystem::_forceResetAll() { + if (m_sys) { + m_sys->forceResetAll(); + } +} + +SystemPtr DelegateSystem::_clone() { + return m_sys ? make_shared(m_sys->clone()) : make_shared(); +} + +void DelegateSystem::run(const KData& kdata, bool reset, bool resetAll) { + HKU_WARN_IF_RETURN(!m_sys, void(), "No delegated system is specified!"); + m_kdata = kdata; + + m_sys->setTM(getTM()); + m_sys->setMM(getMM()); + m_sys->setEV(getEV()); + m_sys->setCN(getCN()); + m_sys->setSG(getSG()); + m_sys->setST(getST()); + m_sys->setTP(getTP()); + m_sys->setPG(getPG()); + m_sys->setSP(getSP()); + + m_sys->run(kdata, reset, resetAll); +} + +TradeRecord DelegateSystem::runMoment(const Datetime& datetime) { + HKU_WARN_IF_RETURN(!m_sys, TradeRecord(), "No delegated system is specified!"); + return m_sys->runMoment(datetime); +} + +TradeRecord DelegateSystem::sellForceOnOpen(const Datetime& date, double num, Part from) { + HKU_WARN_IF_RETURN(!m_sys, TradeRecord(), "No delegated system is specified!"); + return m_sys->sellForceOnOpen(date, num, from); +} + +TradeRecord DelegateSystem::sellForceOnClose(const Datetime& date, double num, Part from) { + HKU_WARN_IF_RETURN(!m_sys, TradeRecord(), "No delegated system is specified!"); + return m_sys->sellForceOnClose(date, num, from); +} + +void DelegateSystem::clearDelayBuyRequest() { + HKU_WARN_IF_RETURN(!m_sys, void(), "No delegated system is specified!"); + m_sys->clearDelayBuyRequest(); +} + +bool DelegateSystem::haveDelaySellRequest() const { + HKU_WARN_IF_RETURN(!m_sys, false, "No delegated system is specified!"); + return m_sys->haveDelaySellRequest(); +} + +TradeRecord DelegateSystem::pfProcessDelaySellRequest(const Datetime& date) { + HKU_WARN_IF_RETURN(!m_sys, TradeRecord(), "No delegated system is specified!"); + return m_sys->pfProcessDelaySellRequest(date); +} + +} // namespace hku \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/trade_sys/system/DelegateSystem.h b/hikyuu_cpp/hikyuu/trade_sys/system/DelegateSystem.h new file mode 100644 index 00000000..cc9e5c2f --- /dev/null +++ b/hikyuu_cpp/hikyuu/trade_sys/system/DelegateSystem.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 hikyuu.org + * + * Created on: 2024-09-13 + * Author: fasiondog + */ + +#include "System.h" + +namespace hku { + +class HKU_API DelegateSystem : public System { +public: + DelegateSystem() = default; + explicit DelegateSystem(const string& name) : System(name) {} + explicit DelegateSystem(const SystemPtr& sys) : m_sys(sys) {} + virtual ~DelegateSystem() = default; + + virtual void run(const KData& kdata, bool reset = true, bool resetAll = false) override; + virtual TradeRecord runMoment(const Datetime& datetime) override; + + virtual void _reset() override; + virtual void _forceResetAll() override; + virtual SystemPtr _clone() override; + +public: + virtual TradeRecord sellForceOnOpen(const Datetime& date, double num, Part from) override; + virtual TradeRecord sellForceOnClose(const Datetime& date, double num, Part from) override; + virtual void clearDelayBuyRequest() override; + virtual bool haveDelaySellRequest() const override; + virtual TradeRecord pfProcessDelaySellRequest(const Datetime& date) override; + +private: + SystemPtr m_sys; +}; + +} // namespace hku \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/trade_sys/system/System.cpp b/hikyuu_cpp/hikyuu/trade_sys/system/System.cpp index 4bdd4c6b..efb4bd81 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/system/System.cpp +++ b/hikyuu_cpp/hikyuu/trade_sys/system/System.cpp @@ -193,6 +193,8 @@ void System::reset() { m_sellRequest.clear(); m_sellShortRequest.clear(); m_buyShortRequest.clear(); + + _reset(); } void System::forceResetAll() { @@ -234,6 +236,8 @@ void System::forceResetAll() { m_sellRequest.clear(); m_sellShortRequest.clear(); m_buyShortRequest.clear(); + + _forceResetAll(); } void System::setTO(const KData& kdata) { @@ -279,7 +283,7 @@ void System::setTO(const KData& kdata) { } SystemPtr System::clone() { - SystemPtr p = make_shared(); + SystemPtr p = _clone(); if (m_tm) p->m_tm = getParam("shared_tm") ? m_tm : m_tm->clone(); if (m_ev) diff --git a/hikyuu_cpp/hikyuu/trade_sys/system/System.h b/hikyuu_cpp/hikyuu/trade_sys/system/System.h index 1dc484ff..12f60040 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/system/System.h +++ b/hikyuu_cpp/hikyuu/trade_sys/system/System.h @@ -63,6 +63,8 @@ public: const StoplossPtr& tp, const ProfitGoalPtr& pg, const SlippagePtr& sp, const string& name); + System(const System&) = default; + /** 析构函数 */ virtual ~System(); @@ -199,48 +201,56 @@ public: * @param reset 执行前是否依据系统部件共享属性复位 * @param resetAll 强制复位所有部件 */ - void run(const KData& kdata, bool reset = true, bool resetAll = false); + virtual void run(const KData& kdata, bool reset = true, bool resetAll = false); /** * @brief 在指定的日期执行一步,仅由 PF 调用 * @param datetime 指定的日期 * @return TradeRecord */ - TradeRecord runMoment(const Datetime& datetime); + virtual TradeRecord runMoment(const Datetime& datetime); // 运行前准备工作, 失败将抛出异常 void readyForRun(); - TradeRecord sell(const KRecord& today, const KRecord& src_today, Part from) { - return _sell(today, src_today, from); - } - // 由各个相关组件调用,用于组件参数变化时通知 sys,以便重算 void partChangedNotify() { m_calculated = false; } -private: + virtual void _reset() {} + virtual void _forceResetAll() {} + + /** 子类克隆接口 */ + virtual SystemPtr _clone() { + return make_shared(); + } + +public: + //------------------------- + // 仅供 PF/AF 内部调用 + //------------------------- + // 强制以开盘价卖出,仅供 PF/AF 内部调用 - TradeRecord sellForceOnOpen(const Datetime& date, double num, Part from) { + virtual TradeRecord sellForceOnOpen(const Datetime& date, double num, Part from) { HKU_ASSERT(from == PART_ALLOCATEFUNDS || from == PART_PORTFOLIO); return _sellForce(date, num, from, true); } // 强制以收盘价卖出,仅供 PF/AF 内部调用 - TradeRecord sellForceOnClose(const Datetime& date, double num, Part from) { + virtual TradeRecord sellForceOnClose(const Datetime& date, double num, Part from) { HKU_ASSERT(from == PART_ALLOCATEFUNDS || from == PART_PORTFOLIO); return _sellForce(date, num, from, false); } // 清除已有的交易请求,供Portfolio使用 - void clearDelayBuyRequest(); + virtual void clearDelayBuyRequest(); // 当前是否存在延迟的操作请求,供Portfolio - bool haveDelaySellRequest() const; + virtual bool haveDelaySellRequest() const; // 处理延迟买入请求,仅供 PF 调用 - TradeRecord pfProcessDelaySellRequest(const Datetime& date); + virtual TradeRecord pfProcessDelaySellRequest(const Datetime& date); private: bool _environmentIsValid(const Datetime& datetime); diff --git a/hikyuu_pywrap/trade_sys/_System.cpp b/hikyuu_pywrap/trade_sys/_System.cpp index d9c9d3fc..291c54ea 100644 --- a/hikyuu_pywrap/trade_sys/_System.cpp +++ b/hikyuu_pywrap/trade_sys/_System.cpp @@ -15,12 +15,6 @@ using namespace hku; #pragma warning(disable : 4267) #endif -void (System::*run_1)(const KQuery&, bool, bool) = &System::run; -void (System::*run_2)(const KData&, bool, bool) = &System::run; -void (System::*run_3)(const Stock&, const KQuery&, bool, bool) = &System::run; - -TradeRecord (System::*runMoment_1)(const Datetime&) = &System::runMoment; - void export_System(py::module& m) { m.def("get_system_part_name", getSystemPartName, R"(get_system_part_name(part) @@ -67,8 +61,9 @@ void export_System(py::module& m) { DEF_PICKLE(TradeRequest); //-------------------------------------------------------------------------------------- - py::class_(m, "System", - R"(系统基类。需要扩展或实现更复杂的系统交易行为,可从此类继承。 + py::class_( + m, "System", + R"(系统基类。需要扩展或实现更复杂的系统交易行为,可从此类继承。 系统是指针对单个交易对象的完整策略,包括环境判断、系统有效条件、资金管理、止损、止盈、盈利目标、移滑价差的完整策略,用于模拟回测。 @@ -84,6 +79,7 @@ void export_System(py::module& m) { - cn_open_position=False (bool): 是否使用系统有效性条件进行初始建仓)") .def(py::init()) + .def(py::init()) .def(py::init()) @@ -172,9 +168,12 @@ void export_System(py::module& m) { 克隆操作,会依据部件的共享特性进行克隆,共享部件不进行实际的克隆操作,保持共享。)") - .def("run", run_1, py::arg("query"), py::arg("reset") = true, py::arg("reset_all") = false) - .def("run", run_2, py::arg("kdata"), py::arg("reset") = true, py::arg("reset_all") = false) - .def("run", run_3, py::arg("stock"), py::arg("query"), py::arg("reset") = true, + .def("run", py::overload_cast(&System::run), py::arg("query"), + py::arg("reset") = true, py::arg("reset_all") = false) + .def("run", py::overload_cast(&System::run), py::arg("kdata"), + py::arg("reset") = true, py::arg("reset_all") = false) + .def("run", py::overload_cast(&System::run), + py::arg("stock"), py::arg("query"), py::arg("reset") = true, py::arg("reset_all") = false, R"(run(self, stock, query[, reset=True])