From 3c51c375c25e304e4291d4929912fec147a0bd0a Mon Sep 17 00:00:00 2001 From: fasiondog Date: Tue, 25 Jan 2022 01:08:08 +0800 Subject: [PATCH] =?UTF-8?q?KData=20=E6=B7=BB=E5=8A=A0=20getPosInStock=20?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/source/base/datatype.rst | 9 ++++++++- hikyuu/extend.py | 37 ++++++++++++++++------------------- hikyuu_cpp/hikyuu/KData.cpp | 5 +++++ hikyuu_cpp/hikyuu/KData.h | 5 ++++- hikyuu_pywrap/_KData.cpp | 2 ++ 5 files changed, 36 insertions(+), 22 deletions(-) diff --git a/docs/source/base/datatype.rst b/docs/source/base/datatype.rst index 786cf9fe..daf369ea 100644 --- a/docs/source/base/datatype.rst +++ b/docs/source/base/datatype.rst @@ -403,7 +403,14 @@ K线数据 :param Datetime datetime: 指定的时间 :return: 对应的索引位置,如果不在数据范围内,则返回 None - + + .. py:method:: get_pos_in_stock(datetime) + + 获取指定时间对应原始 K 线中的索引位置 + + :param Datetime datetime: 指定的时间 + :return: 对应的索引位置,如果不在数据范围内,则返回 None + .. py:method:: empty() 判断是否为空 diff --git a/hikyuu/extend.py b/hikyuu/extend.py index 100c21ad..91cc15d2 100644 --- a/hikyuu/extend.py +++ b/hikyuu/extend.py @@ -51,9 +51,7 @@ def __new_Datetime_init__(self, *args, **kwargs): d = args[0] milliseconds = d.microsecond // 1000 microseconds = d.microsecond - milliseconds * 1000 - __old_Datetime_init__( - self, d.year, d.month, d.day, d.hour, d.minute, d.second, milliseconds, microseconds - ) + __old_Datetime_init__(self, d.year, d.month, d.day, d.hour, d.minute, d.second, milliseconds, microseconds) elif isinstance(args[0], date): d = args[0] __old_Datetime_init__(self, d.year, d.month, d.day, 0, 0, 0, 0) @@ -101,9 +99,7 @@ def Datetime_date(self): def Datetime_datetime(self): """转化生成 python 的 datetime""" - return datetime( - self.year, self.month, self.day, self.hour, self.minute, self.second, self.microsecond - ) + return datetime(self.year, self.month, self.day, self.hour, self.minute, self.second, self.microsecond) Datetime.__init__ = __new_Datetime_init__ @@ -168,9 +164,7 @@ def __new_TimeDelta_add__(self, td): def __new_TimeDelta_sub__(self, td): """可减去TimeDelta, datetime.timedelta""" - return __old_TimeDelta_sub__(self, td) if isinstance(td, TimeDelta) else __old_TimeDelta_sub__( - self, TimeDelta(td) - ) + return __old_TimeDelta_sub__(self, td) if isinstance(td, TimeDelta) else __old_TimeDelta_sub__(self, TimeDelta(td)) def TimeDelta_timedelta(self): @@ -235,9 +229,21 @@ def KData_getPos(kdata, datetime): return pos if pos != constant.null_size else None +def KData_getPosInStock(kdata, datetime): + """ + 获取指定时间对应的原始K线中的索引位置 + + :param Datetime datetime: 指定的时间 + :return: 对应的索引位置,如果不在数据范围内,则返回 None + """ + pos = kdata._getPosInStock(datetime) + return pos if pos != constant.null_size else None + + KData.__getitem__ = KData_getitem KData.__iter__ = KData_iter KData.get_pos = KData_getPos +KData.get_pos_in_stock = KData_getPosInStock # ------------------------------------------------------------------ # 封装增强其他C++ vector类型的遍历、打印 @@ -346,11 +352,7 @@ try: } ) return np.array( - [ - (k.datetime.datetime(), k.open, k.high, k.low, k.close, k.amount, k.volume) - for k in kdata - ], - dtype=k_type + [(k.datetime.datetime(), k.open, k.high, k.low, k.close, k.amount, k.volume) for k in kdata], dtype=k_type ) def KData_to_df(kdata): @@ -384,12 +386,7 @@ try: def TimeLine_to_np(data): """转化为numpy结构数组""" - t_type = np.dtype( - { - 'names': ['datetime', 'price', 'vol'], - 'formats': ['datetime64[ms]', 'd', 'd'] - } - ) + t_type = np.dtype({'names': ['datetime', 'price', 'vol'], 'formats': ['datetime64[ms]', 'd', 'd']}) return np.array([(t.date.datetime(), t.price, t.vol) for t in data], dtype=t_type) def TimeLine_to_df(kdata): diff --git a/hikyuu_cpp/hikyuu/KData.cpp b/hikyuu_cpp/hikyuu/KData.cpp index 80dee529..89c1f175 100644 --- a/hikyuu_cpp/hikyuu/KData.cpp +++ b/hikyuu_cpp/hikyuu/KData.cpp @@ -37,6 +37,11 @@ bool KData::operator==(const KData& thr) { (getStock() == thr.getStock() && getQuery() == thr.getQuery()); } +size_t KData::getPosInstock(Datetime datetime) const { + size_t pos = getPos(datetime); + return pos == Null() ? Null() : pos + startPos(); +} + void KData::tocsv(const string& filename) { std::ofstream file(filename.c_str()); HKU_ERROR_IF_RETURN(!file, void(), "Can't open file! ({})", filename); diff --git a/hikyuu_cpp/hikyuu/KData.h b/hikyuu_cpp/hikyuu/KData.h index 679a47f8..84f276cf 100644 --- a/hikyuu_cpp/hikyuu/KData.h +++ b/hikyuu_cpp/hikyuu/KData.h @@ -51,9 +51,12 @@ public: return getKRecord(datetime); } - /** 按日期查询对应的索引位置 */ + /** 按日期查询对应的索引位置,注:是 KData 中的位置,不是在 Stock 中原始K记录的位置 */ size_t getPos(const Datetime& datetime) const; + /** 按日期获取在原始 K 线记录中的位置 */ + size_t getPosInstock(Datetime datetime) const; + /** 获取关联的KQuery */ KQuery getQuery() const; diff --git a/hikyuu_pywrap/_KData.cpp b/hikyuu_pywrap/_KData.cpp index 7b1620f0..53651c5d 100644 --- a/hikyuu_pywrap/_KData.cpp +++ b/hikyuu_pywrap/_KData.cpp @@ -61,6 +61,8 @@ void export_KData() { .def("_getPos", &KData::getPos) // python中需要将Null的情况改写为None + .def("_getPosInStock", &KData::getPosInstock) + .def("empty", &KData::empty, R"(empty(self) 判断是否为空