This commit is contained in:
fasiondog 2020-06-29 00:24:53 +08:00
parent eb6c85322d
commit acda4976e6
5 changed files with 373 additions and 79 deletions

View File

@ -2,6 +2,7 @@
# 对 C++ 引出类和函数进行扩展 # 对 C++ 引出类和函数进行扩展
# #
from datetime import *
from hikyuu.cpp.core import * from hikyuu.cpp.core import *
# ------------------------------------------------------------------ # ------------------------------------------------------------------
@ -16,4 +17,221 @@ constant = Constant()
Datetime.__hash__ = lambda self: self.number * 1000000 + self.millisecond * 1000 + self.microsecond Datetime.__hash__ = lambda self: self.number * 1000000 + self.millisecond * 1000 + self.microsecond
TimeDelta.__hash__ = lambda self: self.ticks TimeDelta.__hash__ = lambda self: self.ticks
Stock.__hash__ = lambda self: self.id Stock.__hash__ = lambda self: self.id
# ------------------------------------------------------------------
# 增强 Datetime
# ------------------------------------------------------------------
__old_Datetime_init__ = Datetime.__init__
__old_Datetime_add__ = Datetime.__add__
__old_Datetime_sub__ = Datetime.__sub__
def __new_Datetime_init__(self, *args, **kwargs):
"""
- Datetime("2010-1-1 10:00:00")
- Python dateDatetime(date(2010,1,1))
- Python datetimeDatetime(datetime(2010,1,1,10)
- YYYYMMDDHHMM Datetime(201001011000)
- Datetime(year, month, day, hour=0, minute=0, second=0, millisecond=0, microsecond=0)
:py:func:`getDateRange`
:py:meth:`StockManager.getTradingCalendar`
"""
if not args:
__old_Datetime_init__(self, **kwargs)
# datetime实例同时也是date的实例判断必须放在date之前
elif isinstance(args[0], datetime):
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
)
elif isinstance(args[0], date):
d = args[0]
__old_Datetime_init__(self, d.year, d.month, d.day, 0, 0, 0, 0)
elif isinstance(args[0], str):
__old_Datetime_init__(self, args[0])
else:
__old_Datetime_init__(self, *args)
def __new_Datetime_add__(self, td):
"""加上指定时长,时长对象可为 TimeDelta 或 datetime.timedelta 类型
:param TimeDelta td:
:rtype: Datetime
"""
if isinstance(td, TimeDelta):
return __old_Datetime_add__(self, td)
elif isinstance(td, timedelta):
return __old_Datetime_add__(self, TimeDelta(td))
else:
raise TypeError("unsupported operand type(s) for +: 'TimeDelta' and '{}'".format(type(td)))
def __new_Datetime_sub__(self, td):
"""减去指定的时长, 时长对象可为 TimeDelta 或 datetime.timedelta 类型
:param TimeDelta td:
:rtype: Datetime
"""
if isinstance(td, TimeDelta):
return __old_Datetime_sub__(self, td)
elif isinstance(td, timedelta):
return __old_Datetime_sub__(self, TimeDelta(td))
else:
raise TypeError("unsupported operand type(s) for +: 'TimeDelta' and '{}'".format(type(td)))
def Datetime_date(self):
"""转化生成 python 的 date"""
return date(self.year, self.month, self.day)
def Datetime_datetime(self):
"""转化生成 python 的 datetime"""
return datetime(
self.year, self.month, self.day, self.hour, self.minute, self.second, self.microsecond
)
Datetime.__init__ = __new_Datetime_init__
Datetime.__add__ = __new_Datetime_add__
Datetime.__radd__ = __new_Datetime_add__
Datetime.__sub__ = __new_Datetime_sub__
Datetime.date = Datetime_date
Datetime.datetime = Datetime_datetime
# ------------------------------------------------------------------
# 增强 TimeDelta
# ------------------------------------------------------------------
__old_TimeDelta_init__ = TimeDelta.__init__
__old_TimeDelta_add__ = TimeDelta.__add__
__old_TimeDelta_sub__ = TimeDelta.__sub__
def __new_TimeDelta_init__(self, *args, **kwargs):
"""
- datetime.timedelta TimdeDelta(timedelta实例)
- TimeDelta(days=0, hours=0, minutes=0, seconds=0, milliseconds=0, microseconds=0)
- -99999999 <= days <= 99999999
- -100000 <= hours <= 100000
- -100000 <= minutes <= 100000
- -8639900 <= seconds <= 8639900
- -86399000000 <= milliseconds <= 86399000000
- -86399000000 <= microseconds <= 86399000000
"""
if not args:
__old_TimeDelta_init__(self, **kwargs)
elif isinstance(args[0], timedelta):
days = args[0].days
secs = args[0].seconds
hours = secs // 3600
mins = secs // 60 - hours * 60
secs = secs - mins * 60 - hours * 3600
microsecs = args[0].microseconds
millisecs = microsecs // 1000
microsecs = microsecs - millisecs * 1000
__old_TimeDelta_init__(self, days, hours, mins, secs, millisecs, microsecs)
else:
__old_TimeDelta_init__(self, *args)
def __new_TimeDelta_add__(self, td):
"""可和 TimeDelta, datetime.timedelta, Datetime执行相加操作"""
if isinstance(td, TimeDelta):
return __old_TimeDelta_add__(self, td)
elif isinstance(td, timedelta):
return __old_TimeDelta_add__(self, TimeDelta(td))
elif isinstance(td, Datetime):
return td + self
elif isinstance(td, datetime):
return td + Datetime(datetime)
else:
raise TypeError("unsupported operand type(s) for +: 'TimeDelta' and '{}'".format(type(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)
)
def TimeDelta_timedelta(self):
""" 转化为 datetime.timedelta """
return timedelta(
days=self.days,
hours=self.hours,
minutes=self.minutes,
seconds=self.seconds,
milliseconds=self.milliseconds,
microseconds=self.microseconds
)
TimeDelta.__init__ = __new_TimeDelta_init__
TimeDelta.__add__ = __new_TimeDelta_add__
TimeDelta.__sub__ = __new_TimeDelta_sub__
TimeDelta.timedelta = TimeDelta_timedelta
# ------------------------------------------------------------------
# 增强 KData 的遍历
# ------------------------------------------------------------------
def KData_getitem(kdata, i):
"""
:param i: int | Datetime | slice | str
"""
if isinstance(i, int):
length = len(kdata)
index = length + i if i < 0 else i
if index < 0 or index >= length:
raise IndexError("index out of range: %d" % i)
return kdata.getKRecord(index)
elif isinstance(i, Datetime):
return kdata.getKRecordByDate(i)
elif isinstance(i, str):
return kdata.getKRecordByDate(Datetime(i))
elif isinstance(i, slice):
return [kdata.getKRecord(x) for x in range(*i.indices(len(kdata)))]
else:
raise IndexError("Error index type")
def KData_iter(kdata):
for i in range(len(kdata)):
yield kdata[i]
def KData_getPos(kdata, datetime):
"""
:param Datetime datetime:
:return: None
"""
pos = kdata._getPos(datetime)
return pos if pos != constant.null_size else None
KData.__getitem__ = KData_getitem
KData.__iter__ = KData_iter
KData.getPos = KData_getPos

View File

@ -1,32 +0,0 @@
#!/usr/bin/python
# -*- coding: utf8 -*-
# cp936
#===============================================================================
# 作者fasiondog
# 历史120130419, Added by fasiondog
#===============================================================================
#加入__unicode__和__repr__函数
import sys
if sys.version > '3':
IS_PY3 = True
else:
IS_PY3 = False
if IS_PY3:
unicodeFunc = str
def reprFunc(self):
return "<%s>"%str(self)
else:
if sys.platform == 'win32':
def unicodeFunc(self):
return str(self).decode('gb18030')
def reprFunc(self):
return "<%s>"%unicode(self).encode('gb18030')
else:
def unicodeFunc(self):
return str(self).decode('utf8')
def reprFunc(self):
return "<%s>"%unicode(self).encode('utf8')

View File

@ -94,7 +94,7 @@ void export_Datetime() {
.def(self < self) .def(self < self)
.def(self + other<TimeDelta>()) .def(self + other<TimeDelta>())
.def(other<TimeDelta>() + self) //.def(other<TimeDelta>() + self) 在python里扩展支持
.def(self - other<TimeDelta>()) .def(self - other<TimeDelta>())
#if HKU_PYTHON_SUPPORT_PICKLE #if HKU_PYTHON_SUPPORT_PICKLE

View File

@ -18,73 +18,183 @@ double (TimeDelta::*TimeDelta_div_1)(TimeDelta) const = &TimeDelta::operator/;
TimeDelta (TimeDelta::*TimeDelta_div_2)(double) const = &TimeDelta::operator/; TimeDelta (TimeDelta::*TimeDelta_div_2)(double) const = &TimeDelta::operator/;
TimeDelta (TimeDelta::*TimeDelta_pos)() const = &TimeDelta::operator+; TimeDelta (TimeDelta::*TimeDelta_pos)() const = &TimeDelta::operator+;
TimeDelta (TimeDelta::*TimeDelta_add)(TimeDelta) const = &TimeDelta::operator+;
TimeDelta (TimeDelta::*TimeDelta_neg)() const = &TimeDelta::operator-; TimeDelta (TimeDelta::*TimeDelta_neg)() const = &TimeDelta::operator-;
TimeDelta (TimeDelta::*TimeDelta_sub)(TimeDelta) const = &TimeDelta::operator-;
void export_TimeDelta() { void export_TimeDelta() {
class_<TimeDelta>("TimeDelta", init<>()) class_<TimeDelta>("TimeDelta",
R"(时间时长,用于时间计算。可通过以下方式构建:
- datetime.timedelta TimdeDelta(timedelta实例)
- TimeDelta(days=0, hours=0, minutes=0, seconds=0, milliseconds=0, microseconds=0)
- -99999999 <= days <= 99999999
- -100000 <= hours <= 100000
- -100000 <= minutes <= 100000
- -8639900 <= seconds <= 8639900
- -86399000000 <= milliseconds <= 86399000000
- -86399000000 <= microseconds <= 86399000000
使使
Days, Hours, Minutes, Seconds, Milliseconds, Microseconds)")
.def(init<>())
.def(init<int64_t, int64_t, int64_t, int64_t, int64_t, int64_t>( .def(init<int64_t, int64_t, int64_t, int64_t, int64_t, int64_t>(
(arg("days") = 0, arg("hours") = 0, arg("minutes") = 0, arg("seconds") = 0, arg("milliseconds") = 0, (arg("days") = 0, arg("hours") = 0, arg("minutes") = 0, arg("seconds") = 0,
arg("microseconds") = 0))) arg("milliseconds") = 0, arg("microseconds") = 0)))
//.def(self_ns::str(self))
.def("__str__", &TimeDelta::str) .def("__str__", &TimeDelta::str)
.def("__repr__", &TimeDelta::repr) .def("__repr__", &TimeDelta::repr)
.add_property("days", &TimeDelta::days)
.add_property("hours", &TimeDelta::hours)
.add_property("minutes", &TimeDelta::minutes)
.add_property("seconds", &TimeDelta::seconds)
.add_property("milliseconds", &TimeDelta::milliseconds)
.add_property("microseconds", &TimeDelta::microseconds)
.add_property("ticks", &TimeDelta::ticks)
.def("isNegative", &TimeDelta::isNegative)
.def("total_days", &TimeDelta::total_days)
.def("total_hours", &TimeDelta::total_hours)
.def("total_minutes", &TimeDelta::total_minutes)
.def("total_seconds", &TimeDelta::total_seconds)
.def("total_milliseconds", &TimeDelta::total_milliseconds)
.def("max", &TimeDelta::max) .add_property("days", &TimeDelta::days, "天数 [-99999999, 99999999]")
.add_property("hours", &TimeDelta::hours, "小时数 [0, 23]")
.add_property("minutes", &TimeDelta::minutes, "分钟数 [0, 59]")
.add_property("seconds", &TimeDelta::seconds, "秒数 [0, 59]")
.add_property("milliseconds", &TimeDelta::milliseconds, "毫秒数 [0, 999]")
.add_property("microseconds", &TimeDelta::microseconds, "微秒数 [0, 999]")
.add_property("ticks", &TimeDelta::ticks, "同总微秒数")
.def("isNegative", &TimeDelta::isNegative, R"(isNegative(self)
:rtype: bool)")
.def("total_days", &TimeDelta::total_days, R"(total_days(self)
:rtype: float)")
.def("total_hours", &TimeDelta::total_hours, R"(total_hours(self)
:rtype: float)")
.def("total_minutes", &TimeDelta::total_minutes, R"(total_minutes(self)
:rtype: float)")
.def("total_seconds", &TimeDelta::total_seconds, R"(total_seconds(self)
:rtype: float)")
.def("total_milliseconds", &TimeDelta::total_milliseconds, R"(total_milliseconds(self)
:rtype: float)")
.def("max", &TimeDelta::max, R"(max()
:return: TimeDelta(99999999, 23, 59, 59, 999, 999))")
.staticmethod("max") .staticmethod("max")
.def("min", &TimeDelta::min)
.def("min", &TimeDelta::min, R"(min()
:return: TimeDelta(-99999999, 0, 0, 0, 0, 0))")
.staticmethod("min") .staticmethod("min")
.def("resolution", &TimeDelta::resolution)
.def("resolution", &TimeDelta::resolution, R"(resolution()
:return: TimeDelta(0, 0, 0, 0, 0, 1))")
.staticmethod("resolution") .staticmethod("resolution")
.def("maxTicks", &TimeDelta::maxTicks)
.def("maxTicks", &TimeDelta::maxTicks, R"(maxTicks()
ticks
:rtype: int)")
.staticmethod("maxTicks") .staticmethod("maxTicks")
.def("minTicks", &TimeDelta::minTicks)
.def("minTicks", &TimeDelta::minTicks, R"(minTicks()
ticks
:rtype: int)")
.staticmethod("minTicks") .staticmethod("minTicks")
.def("fromTicks", &TimeDelta::fromTicks)
.def("fromTicks", &TimeDelta::fromTicks, R"(fromTicks(ticks)
使 ticks
:param int ticks:
:rtype: TimeDelta)")
.staticmethod("fromTicks") .staticmethod("fromTicks")
.def("__eq__", &TimeDelta::operator==) .def(self == self)
.def("__ne__", &TimeDelta::operator!=) .def(self != self)
.def("__gt__", &TimeDelta::operator>) .def(self >= self)
.def("__lt__", &TimeDelta::operator<) .def(self <= self)
.def("__ge__", &TimeDelta::operator>=) .def(self > self)
.def("__le__", &TimeDelta::operator>=) .def(self < self)
.def(-self)
.def(+self)
.def(self + self)
.def(self - self)
.def(self % self)
.def(self * float())
.def("__abs__", &TimeDelta::abs) .def("__abs__", &TimeDelta::abs)
.def("__add__", TimeDelta_add)
.def("__pos__", TimeDelta_pos)
.def("__sub__", TimeDelta_sub)
.def("__neg__", TimeDelta_neg)
.def("__mul__", &TimeDelta::operator*)
.def("__rmul__", &TimeDelta::operator*) .def("__rmul__", &TimeDelta::operator*)
.def("__truediv__", TimeDelta_div_1) .def("__truediv__", TimeDelta_div_1)
.def("__truediv__", TimeDelta_div_2) .def("__truediv__", TimeDelta_div_2)
.def("__floordiv__", &TimeDelta::floorDiv) .def("__floordiv__", &TimeDelta::floorDiv)
.def("__mod__", &TimeDelta::operator%)
#if HKU_PYTHON_SUPPORT_PICKLE #if HKU_PYTHON_SUPPORT_PICKLE
.def_pickle(normal_pickle_suite<TimeDelta>()) .def_pickle(normal_pickle_suite<TimeDelta>())
#endif #endif
; ;
def("Days", Days); def("Days", Days, R"(Days(days)
def("Hours", Hours);
def("Minutes", Minutes); TimeDelta
def("Seconds", Seconds);
def("Milliseconds", Milliseconds); :param int days: [-99999999, 99999999]
def("Microseconds", Microseconds); :rtype: TimeDelta)");
def("Hours", Hours, R"(Hours(hours)
TimeDelta
:param int hours:
:rtype: TimeDelta)");
def("Minutes", Minutes, R"(Minutes(mins)
TimeDelta
:param int mins:
:rtype: TimeDelta)");
def("Seconds", Seconds, R"(Seconds(secs)
TimeDelta
:param int secs:
:rtype: TimeDelta)");
def("Milliseconds", Milliseconds, R"(Milliseconds(milliseconds)
TimeDelta
:param int milliseconds:
:rtype: TimeDelta)");
def("Microseconds", Microseconds, R"(Microseconds(microsecs)
TimeDelta
:param int microsecs:
:rtype: TimeDelta)");
} }

View File

@ -20,5 +20,3 @@ void export_util() {
def("roundUp", roundUp, roundUp_overload()); def("roundUp", roundUp, roundUp_overload());
def("roundDown", roundDown, roundDown_overload()); def("roundDown", roundDown, roundDown_overload());
} }