diff --git a/docs/source/trade_sys/environment.rst b/docs/source/trade_sys/environment.rst index 34d5dde71..be373e249 100644 --- a/docs/source/trade_sys/environment.rst +++ b/docs/source/trade_sys/environment.rst @@ -15,6 +15,13 @@ :param Indicator slow: 慢线指标 :param string market: 市场名称 +.. py:function:: EV_Bool(ind[, market = 'SH']) + + 布尔信号指标市场环境 + + :param Indicator ind: bool类型的指标, 指标中相应位置大于0则代表市场有效, 否则无效 + :param str market: 指定的市场,用于获取相应的交易日历 + 自定义市场环境判定策略 ---------------------- diff --git a/hikyuu/draw/drawplot/__init__.py b/hikyuu/draw/drawplot/__init__.py index 69dee4692..e4488e029 100644 --- a/hikyuu/draw/drawplot/__init__.py +++ b/hikyuu/draw/drawplot/__init__.py @@ -29,7 +29,7 @@ # 1. 20171122, Added by fasiondog # =============================================================================== -from hikyuu.core import KData, Indicator, SignalBase, ConditionBase, System +from hikyuu.core import KData, Indicator, SignalBase, ConditionBase, EnvironmentBase, System import matplotlib from matplotlib.pylab import gca as mpl_gca @@ -42,6 +42,7 @@ from .matplotlib_draw import ibar as mpl_ibar from .matplotlib_draw import sgplot as mpl_sgplot from .matplotlib_draw import cnplot as mpl_cnplot +from .matplotlib_draw import evplot as mpl_evplot from .matplotlib_draw import sysplot as mpl_sysplot from .matplotlib_draw import ax_draw_macd as mpl_ax_draw_macd from .matplotlib_draw import ax_draw_macd2 as mpl_ax_draw_macd2 @@ -117,6 +118,8 @@ def use_draw_with_matplotlib(): Indicator.bar = mpl_ibar SignalBase.plot = mpl_sgplot + + EnvironmentBase.plot = mpl_evplot ConditionBase.plot = mpl_cnplot System.plot = mpl_sysplot diff --git a/hikyuu/draw/drawplot/matplotlib_draw.py b/hikyuu/draw/drawplot/matplotlib_draw.py index 9844e3bf6..8ecafa024 100644 --- a/hikyuu/draw/drawplot/matplotlib_draw.py +++ b/hikyuu/draw/drawplot/matplotlib_draw.py @@ -619,6 +619,30 @@ def sgplot(sg, new=True, axes=None, style=1, kdata=None): ) +def evplot(ev, ref_kdata, new=True, axes=None): + """绘制市场有效判断 + + :param EnvironmentBase cn: 系统有效条件 + :param KData ref_kdata: 用于日期参考 + :param new: 仅在未指定axes的情况下生效,当为True时,创建新的窗口对象并在其中进行绘制 + :param axes: 指定在那个轴对象中进行绘制 + """ + refdates = ref_kdata.get_datetime_list() + if axes is None: + if new: + axes = create_figure(2) + kplot(ref_kdata, axes=axes[0]) + axes = axes[1] + else: + axes = gca() + + x = np.array([i for i in range(len(refdates))]) + y1 = np.array([1 if ev.is_valid(d) else -1 for d in refdates]) + y2 = np.array([-1 if ev.is_valid(d) else 1 for d in refdates]) + axes.fill_between(x, y1, y2, where=y2 > y1, facecolor='blue', alpha=0.6) + axes.fill_between(x, y1, y2, where=y2 < y1, facecolor='red', alpha=0.6) + + def cnplot(cn, new=True, axes=None, kdata=None): """绘制系统有效条件 @@ -634,8 +658,6 @@ def cnplot(cn, new=True, axes=None, kdata=None): cn.to = kdata refdates = kdata.get_datetime_list() - date_index = dict([(d, i) for i, d in enumerate(refdates)]) - if axes is None: if new: axes = create_figure(2) diff --git a/hikyuu_cpp/hikyuu/trade_sys/environment/build_in.h b/hikyuu_cpp/hikyuu/trade_sys/environment/build_in.h index c4a3e6023..463977384 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/environment/build_in.h +++ b/hikyuu_cpp/hikyuu/trade_sys/environment/build_in.h @@ -10,5 +10,6 @@ #define ENVIRONMENT_BUILD_IN_H_ #include "crt/EV_TwoLine.h" +#include "crt/EV_Bool.h" #endif /* ENVIRONMENT_BUILD_IN_H */ diff --git a/hikyuu_cpp/hikyuu/trade_sys/environment/crt/EV_Bool.h b/hikyuu_cpp/hikyuu/trade_sys/environment/crt/EV_Bool.h new file mode 100644 index 000000000..acf44bd83 --- /dev/null +++ b/hikyuu_cpp/hikyuu/trade_sys/environment/crt/EV_Bool.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2024 hikyuu.org + * + * Created on: 2024-02-03 + * Author: fasiondog + */ + +#pragma once + +#include "hikyuu/indicator/Indicator.h" +#include "hikyuu/trade_sys/environment/EnvironmentBase.h" + +namespace hku { + +/** + * 布尔信号指标市场环境 + * @param ind bool类型的指标,指标中相应位置>0则代表市场有效,否则无效 + * @param market 指定的市场,用于获取相应的交易日历 + * @return + */ +EVPtr HKU_API EV_Bool(const Indicator& ind, const string& market = "SH"); + +} \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/trade_sys/environment/crt/EV_TwoLine.h b/hikyuu_cpp/hikyuu/trade_sys/environment/crt/EV_TwoLine.h index 9053bd8ab..310c66562 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/environment/crt/EV_TwoLine.h +++ b/hikyuu_cpp/hikyuu/trade_sys/environment/crt/EV_TwoLine.h @@ -21,7 +21,7 @@ namespace hku { * @param market 市场名称,默认为"SH" * @return */ -EVPtr HKU_API EV_TwoLine(const Indicator& fast, const Indicator& slow, const string& market); +EVPtr HKU_API EV_TwoLine(const Indicator& fast, const Indicator& slow, const string& market = "SH"); } /* namespace hku */ diff --git a/hikyuu_cpp/hikyuu/trade_sys/environment/imp/BoolEnvironment.cpp b/hikyuu_cpp/hikyuu/trade_sys/environment/imp/BoolEnvironment.cpp new file mode 100644 index 000000000..1dfb3c2ab --- /dev/null +++ b/hikyuu_cpp/hikyuu/trade_sys/environment/imp/BoolEnvironment.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024 hikyuu.org + * + * Created on: 2024-02-03 + * Author: fasiondog + */ + +#include "hikyuu/StockManager.h" +#include "BoolEnvironment.h" + +#if HKU_SUPPORT_SERIALIZATION +BOOST_CLASS_EXPORT(hku::BoolEnvironment) +#endif + +namespace hku { + +BoolEnvironment::BoolEnvironment() : EnvironmentBase("EV_Bool") { + setParam("market", "SH"); +} + +BoolEnvironment::BoolEnvironment(const Indicator& ind) : EnvironmentBase("EV_Bool"), m_ind(ind) { + setParam("market", "SH"); +} + +BoolEnvironment::~BoolEnvironment() {} + +EnvironmentPtr BoolEnvironment::_clone() { + return make_shared(m_ind.clone()); +} + +void BoolEnvironment::_calculate() { + string market = getParam("market"); + const StockManager& sm = StockManager::instance(); + MarketInfo market_info = sm.getMarketInfo(market); + HKU_ERROR_IF_RETURN(market_info == Null(), void(), "Can't find maket({}) info!", + market); + + Stock stock = sm.getStock(market + market_info.code()); + KData kdata = stock.getKData(m_query); + + auto ds = kdata.getDatetimeList(); + m_ind.setContext(kdata); + for (size_t i = m_ind.discard(), len = m_ind.size(); i < len; i++) { + if (!std::isnan(m_ind[i]) && m_ind[i] > 0.) { + _addValid(ds[i]); + } + } +} + +EVPtr HKU_API EV_Bool(const Indicator& ind, const string& market) { + BoolEnvironment* p = new BoolEnvironment(ind); + p->setParam("market", market); + return EVPtr(p); +} + +} // namespace hku \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/trade_sys/environment/imp/BoolEnvironment.h b/hikyuu_cpp/hikyuu/trade_sys/environment/imp/BoolEnvironment.h new file mode 100644 index 000000000..7bd8a48c1 --- /dev/null +++ b/hikyuu_cpp/hikyuu/trade_sys/environment/imp/BoolEnvironment.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 hikyuu.org + * + * Created on: 2024-02-03 + * Author: fasiondog + */ + +#pragma once + +#include "hikyuu/indicator/Indicator.h" +#include "hikyuu/trade_sys/environment/EnvironmentBase.h" + +namespace hku { + +class BoolEnvironment : public EnvironmentBase { +public: + BoolEnvironment(); + BoolEnvironment(const Indicator& ind); + virtual ~BoolEnvironment(); + + virtual void _calculate() override; + virtual EnvironmentPtr _clone() override; + +private: + Indicator m_ind; + +//============================================ +// 序列化支持 +//============================================ +#if HKU_SUPPORT_SERIALIZATION + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(EnvironmentBase); + ar& BOOST_SERIALIZATION_NVP(m_ind); + } +#endif +}; + +} // namespace hku diff --git a/hikyuu_cpp/hikyuu/trade_sys/environment/imp/TwoLineEnvironment.cpp b/hikyuu_cpp/hikyuu/trade_sys/environment/imp/TwoLineEnvironment.cpp index 71ac9ac7c..95d00fac5 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/environment/imp/TwoLineEnvironment.cpp +++ b/hikyuu_cpp/hikyuu/trade_sys/environment/imp/TwoLineEnvironment.cpp @@ -15,12 +15,12 @@ BOOST_CLASS_EXPORT(hku::TwoLineEnvironment) namespace hku { -TwoLineEnvironment::TwoLineEnvironment() : EnvironmentBase("TwoLine") { +TwoLineEnvironment::TwoLineEnvironment() : EnvironmentBase("EV_TwoLine") { setParam("market", "SH"); } TwoLineEnvironment::TwoLineEnvironment(const Indicator& fast, const Indicator& slow) -: EnvironmentBase("TwoLine"), m_fast(fast), m_slow(slow) { +: EnvironmentBase("EV_TwoLine"), m_fast(fast), m_slow(slow) { setParam("market", "SH"); } diff --git a/hikyuu_pywrap/trade_sys/_Environment.cpp b/hikyuu_pywrap/trade_sys/_Environment.cpp index d9eca36c2..ccfd0698d 100644 --- a/hikyuu_pywrap/trade_sys/_Environment.cpp +++ b/hikyuu_pywrap/trade_sys/_Environment.cpp @@ -35,8 +35,9 @@ class PyEnvironmentBase : public EnvironmentBase { }; void export_Environment(py::module& m) { - py::class_(m, "EnvironmentBase", - R"(市场环境判定策略基类 + py::class_( + m, "EnvironmentBase", + R"(市场环境判定策略基类 自定义市场环境判定策略接口: @@ -101,4 +102,12 @@ void export_Environment(py::module& m) { :param Indicator fast: 快线指标 :param Indicator slow: 慢线指标 :param string market: 市场名称)"); + + m.def("EV_Bool", EV_Bool, py::arg("ind"), py::arg("market") = "SH", + R"(EV_Bool(ind, market='SH') + + 布尔信号指标市场环境 + + :param Indicator ind: bool类型的指标,指标中相应位置>0则代表市场有效,否则无效 + :param str market: 指定的市场,用于获取相应的交易日历)"); }