Merge pull request #6 from fasiondog/master

update 20220321
This commit is contained in:
pchaos 2022-03-21 15:28:29 +08:00 committed by GitHub
commit 2c16b090ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
226 changed files with 5432 additions and 3123 deletions

View File

@ -7,41 +7,42 @@
# History: 20160407, Added by fasiondog
#===============================================================================
from hikyuu.trade_sys.signal import SignalBase
from hikyuu.indicator import HHV, LLV, CLOSE, REF
from hikyuu import *
class TurtleSignal(SignalBase):
def __init__(self, n = 20):
def __init__(self, n=20):
super(TurtleSignal, self).__init__("TurtleSignal")
self.setParam("n", 20)
self.set_param("n", 20)
def _clone(self):
return TurtleSignal()
def _calculate(self):
n = self.getParam("n")
k = self.getTO()
n = self.get_param("n")
k = self.to
c = CLOSE(k)
h = REF(HHV(c, n), 1) #n日高点
L = REF(LLV(c, n), 1) #n日低点
h = REF(HHV(c, n), 1) #n日高点
L = REF(LLV(c, n), 1) #n日低点
for i in range(h.discard, len(k)):
if (c[i] >= h[i]):
self._addBuySignal(k[i].datetime)
self._add_buy_signal(k[i].datetime)
elif (c[i] <= L[i]):
self._addSellSignal(k[i].datetime)
self._add_sell_signal(k[i].datetime)
if __name__ == "__main__":
from examples_init import *
sg = TurtleSignal()
s = getStock("sh000001")
k = s.getKData(Query(-500))
s = get_stock("sh000001")
k = s.get_kdata(Query(-500))
#只有设置交易对象时,才会开始实际计算
sg.setTO(k)
dates = k.getDatetimeList()
sg.to = k
dates = k.get_datetime_list()
for d in dates:
if (sg.shouldBuy(d)):
if (sg.should_buy(d)):
print("买入:%s" % d)
elif (sg.shouldSell(d)):
elif (sg.should_sell(d)):
print("卖出: %s" % d)

View File

@ -9,16 +9,20 @@
from hikyuu import *
import os
curdir = os.path.dirname(os.path.realpath(__file__))
head, tail = os.path.split(curdir)
head, tail = os.path.split(head)
head, tail = os.path.split(head)
import sys
if sys.platform == 'win32':
config_file = os.path.join(head, "test/data/hikyuu_win.ini")
else:
config_file = os.path.join(head, "test/data/hikyuu_linux.ini")
config_file = os.path.expanduser('~') + "/.hikyuu/hikyuu.ini"
if not os.path.exists(config_file):
#检查老版本配置是否存在,如果存在可继续使用,否则异常终止
data_config_file = os.path.expanduser('~') + "/.hikyuu/data_dir.ini"
data_config = configparser.ConfigParser()
data_config.read(data_config_file)
data_dir = data_config['data_dir']['data_dir']
if sys.platform == 'win32':
config_file = data_dir + "\\hikyuu_win.ini"
else:
config_file = data_dir + "/hikyuu_linux.ini"
if not os.path.exists(config_file):
raise("未找到配置文件,请先使用数据导入工具导入数据(将自动生成配置文件)!!!")
#starttime = time.time()

View File

@ -7,33 +7,34 @@
# History: 20160407, Added by fasiondog
#===============================================================================
from hikyuu.trade_sys.signal import crtSG
from hikyuu.indicator import HHV, LLV, CLOSE, REF
from hikyuu import *
def TurtleSG(self):
n = self.getParam("n")
k = self.getTO()
c = CLOSE(k)
h = REF(HHV(c, n), 1) #n日高点
L = REF(LLV(c, n), 1) #n日低点
for i in range(h.discard, len(k)):
if (c[i] >= h[i]):
self._addBuySignal(k[i].datetime)
elif (c[i] <= L[i]):
self._addSellSignal(k[i].datetime)
n = self.get_param("n")
k = self.to
c = CLOSE(k)
h = REF(HHV(c, n), 1) #n日高点
L = REF(LLV(c, n), 1) #n日低点
for i in range(h.discard, len(k)):
if (c[i] >= h[i]):
self._add_buy_signal(k[i].datetime)
elif (c[i] <= L[i]):
self._add_sell_signal(k[i].datetime)
if __name__ == "__main__":
from examples_init import *
sg = crtSG(TurtleSG, {'n': 20}, 'TurtleSG')
s = getStock("sh000001")
k = s.getKData(Query(-500))
s = get_stock("sh000001")
k = s.get_kdata(Query(-500))
#只有设置交易对象时,才会开始实际计算
sg.setTO(k)
dates = k.getDatetimeList()
sg.to = k
dates = k.get_datetime_list()
for d in dates:
if (sg.shouldBuy(d)):
if (sg.should_buy(d)):
print("买入:%s" % d)
elif (sg.shouldSell(d)):
elif (sg.should_sell(d)):
print("卖出: %s" % d)

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View File

@ -104,7 +104,6 @@ pygments_style = 'sphinx'
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
@ -208,25 +207,24 @@ htmlhelp_basename = 'Hikyuudoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
# Latex figure (float) alignment
#'figure_align': 'htbp',
# Latex figure (float) alignment
#'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'Hikyuu.tex', 'Hikyuu Documentation',
'fasiondog', 'manual'),
(master_doc, 'Hikyuu.tex', 'Hikyuu Documentation', 'fasiondog', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
@ -249,29 +247,23 @@ latex_documents = [
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'hikyuu', 'Hikyuu Documentation',
[author], 1)
]
man_pages = [(master_doc, 'hikyuu', 'Hikyuu Documentation', [author], 1)]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'Hikyuu', 'Hikyuu Documentation',
author, 'Hikyuu', 'One line description of project.',
'Miscellaneous'),
(master_doc, 'Hikyuu', 'Hikyuu Documentation', author, 'Hikyuu',
'One line description of project.', 'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.

View File

@ -318,7 +318,7 @@
指数移动平均线(Exponential Moving Average)
:param data: 输入数据
:param int n: 计算均值的周期窗口必须为大于0的整数
:param int|Indciator|IndParam n: 计算均值的周期窗口必须为大于0的整数
:rtype: Indicator
@ -700,7 +700,7 @@
变动率指标: (price / prevPrice) * 100
:param data: 输入数据
:param int n: 时间窗口
:param int|Indicator|IndParam n: 时间窗口
:rtype: Indicator
@ -771,6 +771,16 @@
:rtype: Indicator
.. py:function:: SLICE(data, start, end, result_index=0)
获取某指标中指定范围 [start, end) 的数据,生成新的指标
:param Indicator|PriceList data: 输入数据
:param int start: 起始位置
:param int end: 终止位置(不包含本身)
:param int result_index: 原输入数据中的结果集
.. py:function:: SMA([data, n=22, m=2])
求移动平均
@ -800,7 +810,7 @@
计算N周期内样本标准差
:param Indicator data: 输入数据
:param int n: 时间窗口
:param int n|Indicator|IndParam: 时间窗口
:rtype: Indicator
@ -809,7 +819,7 @@
计算N周期内样本标准差
:param Indicator data: 输入数据
:param int n: 时间窗口
:param int|Indicator|IndParam n: 时间窗口
:rtype: Indicator
@ -818,7 +828,7 @@
总体标准差STDP(X,N)为X的N日总体标准差
:param data: 输入数据
:param int n: 时间窗口
:param int|Indicator|IndParam n: 时间窗口
:rtype: Indicator
@ -827,7 +837,7 @@
求总和。SUM(X,N),统计N周期中X的总和,N=0则从第一个有效值开始。
:param Indicator data: 输入数据
:param int n: 时间窗口
:param int|Indicator|IndParam n: 时间窗口
:rtype: Indicator
@ -840,7 +850,7 @@
例如SUMBARS(VOL,CAPITAL)求完全换手到现在的周期数
:param Indicator data: 输入数据
:param float a: 指定累加和
:param float|Indicator|IndParam a: 指定累加和
:rtype: Indicator
@ -873,7 +883,7 @@
连涨周期数, UPNDAY(CLOSE,M)表示连涨M个周期
:param Indicator data: 输入数据
:param int n: 时间窗口
:param int|Indicator|IndParam n: 时间窗口
:rtype: Indicator
@ -882,7 +892,7 @@
估算样本方差, VAR(X,N)为X的N日估算样本方差
:param Indicator data: 输入数据
:param int n: 时间窗口
:param int|Indicator|IndParam n: 时间窗口
:rtype: Indicator
@ -891,7 +901,7 @@
总体样本方差, VARP(X,N)为X的N日总体样本方差
:param Indicator data: 输入数据
:param int n: 时间窗口
:param int|Indicator|IndParam n: 时间窗口
:rtype: Indicator

View File

@ -1,7 +1,87 @@
版本发布说明
===============
=======================
1.2.0
1.2.3 - 2022年3月6日
-------------------------
1. 指标支持动态参数
在通道信等证券行情软件中,其技术指标中的窗口参数通常支持整数,也支持使用指标,如::
T1:=HHVBARS(H,120); {120内的最高点距今天的天数}
L120:=LLV(L,T1+1); {120内的最高点至今这个区间的最低点}
现在,在 Hikyuu 中,也可以使用指标作为参数::
T1 = HHVBARS(H, 120)
L120 = LLV(L, T1+1)
L120.set_context(k)
L120.plot()
.. figure:: _static/indparam.png
**注意事项**
由于无法区分 Indicator(ind) 形式时ind 究竟是指标参数还是待计算的输出数据,此时如果希望 ind 作为参数,需要通过 IndParam 进行显示指定EMA(IndParam(ind))。
最佳的的方式,则是通过指定参数名,来明确说明使用的是参数::
x = EMA(c) # 以收盘价作为计算的输入
y = EMA(IndParam(c)) # 以收盘价作为 n 参数
z = EMA(n=c) # 以收盘价作为参数 n
2. 完善 PF、AF、SE
现在可以正常使用资产组合。::
# 创建一个系统策略
my_mm = MM_FixedCount(100)
my_sg = my_sg = SG_Flex(EMA(n=5), slow_n=10)
my_sys = SYS_Simple(sg=my_sg, mm=my_mm)
# 创建一个选择算法,用于在每日选定交易系统
# 此处是固定选择器,即每日选出的都是指定的交易系统
my_se = SE_Fixed([s for s in blocka if s.valid], my_sys)
# 创建一个资产分配器,用于确定如何在选定的交易系统中进行资产分配
# 此处创建的是一个等比例分配资产的分配器,即按相同比例在选出的系统中进行资金分配
my_af = AF_EqualWeight()
# 创建资产组合
# 创建一个从2001年1月1日开始的账户初始资金200万元。这里由于使用的等比例分配器意味着将账户剩余资金在所有选中的系统中平均分配
# 如果初始资金过小,将导致每个系统都没有充足的资金完成交易。
my_tm = crtTM(Datetime(200101010000), 2000000)
my_pf = PF_Simple(tm=my_tm, af=my_af, se=my_se)
# 运行投资组合
q = Query(-500)
%time my_pf.run(Query(-500))
x = my_tm.get_funds_curve(sm.get_trading_calendar(q))
PRICELIST(x).plot()
.. figure:: _static/portfolio.png
3. 修复fedora 34编译找不到路径报错waning 提示
4. fixed mysql 升级脚本错误
5. fixed 复权后计算的净收益不对,并在使用前复权数据进行回测时给出警告(前复权回测属于未来函数)
1.2.1 - 2022年2月2日
-------------------------
1. 修复 importdata 无法导入的问题
2. 交易系统 System 支持使用复权数据
3. KData 增加 getPosInStock 方法
4. KQuery 的 recoverType 属性支持设定修改
5. 增加 2022 年假日
6. 修改 examples以便在新版本下执行
7. 修改其他文档帮助错误
1.2.0 - 2022年1月11日
-------------------------
1. HikyuuTdx 执行导入时自动保存配置,避免第一次使用 hikyuu 必须退出先退出 Hikyuutdx 的问题
@ -16,7 +96,7 @@
10. 优化 HikyuuTDX GUI控制台日志捕获子进程日志输出
1.1.9
1.1.9 - 2021年11月11日
-------------------------
1. 补充科创板
@ -30,13 +110,13 @@
9. 取消编译时指定的AVX指令集防止不支持的CPU架构
1.1.8
1.1.8 - 2021年2月27日
-------------------------
1. HikyuuTDX 切换mysql导入时错误提示目录不存在
2. tdx本地导入修复并支持导入MySQL
1.1.7
1.1.7 - 2021年2月13日
-------------------------
1. 更新examples/notebook相关示例

View File

@ -8,7 +8,6 @@
公共参数:
* **reinvest=False** *(bool)* : 红利是否再投资
* **precision=2** *(int)* : 价格计算精度
* **support_borrow_cash=False** *(bool)* : 是否自动融资
* **support_borrow_stock=False** *(bool)* : 是否自动融券
@ -174,10 +173,11 @@
:param Stock stock: 指定的证券
:rtype: int
.. py:method:: get_position(self, stock)
.. py:method:: get_position(self, date, stock)
获取指定证券的当前持仓记录如当前未持有该票返回PositionRecord()
获取指定时间证券持仓记录如当前未持有该票返回PositionRecord()
:param Datetime date: 指定时间
:param Stock stock: 指定的证券
:rtype: PositionRecord
@ -221,14 +221,7 @@
:param float num: 卖出数量
:rtype: CostRecord
.. py:method:: get_funds(self[,ktype = Query.DAY])
获取账户当前时刻的资产详情
:param Query.KType ktype: K线类型
:rtype: FundsRecord
get_funds(self, datetime, [ktype = Query.DAY])
.. py:method:: get_funds(self, datetime, [ktype = Query.DAY])
获取指定时刻的资产市值详情

View File

@ -0,0 +1,112 @@
.. py:currentmodule:: hikyuu.trade_sys
.. highlight:: python
资产分配算法组件
================
内建资产分配算法
------------------
.. py:function:: AF_FixedWeight(weight)
固定比例资产分配,每个选中的资产都只占总资产固定的比例
:param float weight: 指定的资产比例 [0, 1]
.. py:function:: AF_EqualWeight()
固定比例资产分配,对选中的资产进行等比例分配
系统权重系数结构
-----------------
.. py:class:: SystemWeight
系统权重系数结构,在资产分配时,指定对应系统的资产占比系数
.. py:attribute:: sys 对应的 System 实例
.. py:attribute:: weight 对应的权重系数,有效范围为 [0, 1]
.. py:class:: SystemWeightList
由系统权重系数结构组成的列表
.. py:attribute:: sys
对应的 System 实例
.. py::attribute weight
对应的权重系数,有效范围为 [0, 1]
资产分配算法基类
------------------
.. py:class:: AllocateFundsBase
资产分配算法基类, 子类接口:
- _allocateWeight : 【必须】子类资产分配调整实现
- _clone : 【必须】克隆接口
- _reset : 【可选】重载私有变量
.. py:attribute:: name 名称
.. py:method:: __init__(self[, name="AllocateFundsBase])
初始化构造函数
:param str name: 名称
.. py:method:: have_param(self, name)
指定的参数是否存在
:param str name: 参数名称
:return: True 存在 | False 不存在
.. py:method:: get_param(self, name)
获取指定的参数
:param str name: 参数名称
:return: 参数值
:raises out_of_range: 无此参数
.. py:method:: set_param(self, name, value)
设置参数
:param str name: 参数名称
:param value: 参数值
:type value: int | bool | float | string
:raises logic_error: Unsupported type! 不支持的参数类型
.. py:method:: reset(self)
复位操作
.. py:method:: clone(self)
克隆操作
.. py:method:: _calculate(self)
【重载接口】子类计算接口
.. py:method:: _reset(self)
【重载接口】子类复位接口,复位内部私有变量
.. py::method:: _allocate_weight(self, date, se_list)
【重载接口】子类分配权重接口,获取实际分配资产的系统实例及其权重
:param Datetime date: 当前时间
:param SystemList se_list: 当前选中的系统列表
:return: 系统权重分配信息列表
:rtype: SystemWeightList

View File

@ -6,13 +6,13 @@
目前仅实现了多标的、相同策略的投资组合,还需完善,未来接口可能变化(包括选择器策略)!
.. py:function:: PF_Simple([tm, sys, se])
.. py:function:: PF_Simple([tm, af, se])
创建一个多标的、单系统策略的投资组合
:param TradeManager tm: 交易管理
:param System sys: 系统策略
:param SelectorBase se: 选择器
:param AllocateFundsBase af: 资金分配算法
投资组合类定义
@ -22,18 +22,45 @@
实现多标的、多策略的投资组合
.. py:attribute:: name
.. py:attribute:: name 名称
名称
.. py:attribute:: tm
关联的交易管理实例
.. py:attribute:: query 运行条件
.. py:attribute:: tm 关联的交易管理实例
.. py:attribute:: se
选择器策略
.. py:attribute:: se 选择器策略
.. py:attribute:: af 资产分配算法
.. py:attribute:: proto_sys_list 原型系统列表
.. py:attribute:: real_sys_list 运行时的实际系统列表
.. py:method:: get_param(self, name)
获取指定的参数
:param str name: 参数名称
:return: 参数值
:raises out_of_range: 无此参数
.. py:method:: set_param(self, name, value)
设置参数
:param str name: 参数名称
:param value: 参数值
:type value: int | bool | float | string
:raises logic_error: Unsupported type! 不支持的参数类型
.. py:method:: reset(self)
复位操作
.. py:method:: clone(self)
克隆操作
.. py:method:: run(self, query)
运行投资组合策略

View File

@ -13,20 +13,32 @@
内建选择器
-----------
.. py:function:: SE_Fixed([stocklist, sys])
.. py:function:: SE_Fixed([stk_list, sys])
固定选择器,即始终选择初始划定的标的及其系统策略原型
:param StockList stocklist: 初始划定的标的
:param list stk_list: 初始划定的标的
:param System sys: 系统策略原型
:return: SE选择器实例
.. py:function:: SE_Signal([stk_list, sys])
信号选择器,仅依靠系统买入信号进行选中
:param list stk_list: 初始划定的标的
:param System sys: 系统策略原型
:return: SE选择器实例
自定义选择器策略
--------------------
自定义选择器策略接口:
* :py:meth:`SelectorBase.get_selected_system_list` - 【必须】获取指定时刻选择的系统实例列表
* :py:meth:`SelectorBase.is_match_af` - 【必须】判断是否和AF匹配
* :py:meth:`SelectorBase.get_selected_on_open` - 【必须】获取指定时刻开盘时选择的系统实例列表
* :py:meth:`SelectorBase.get_selected_on_close` - 【必须】获取指定时刻收盘时选择的系统实例列表
* :py:meth:`SelectorBase._calculate` - 【必须】计算接口
* :py:meth:`SelectorBase._reset` - 【可选】重置私有属性
* :py:meth:`SelectorBase._clone` - 【必须】克隆接口
@ -38,6 +50,10 @@
选择器策略基类,实现标的、系统策略的评估和选取算法
.. py:attribute:: name 名称
.. py:attribute:: proto_sys_list 原型系统列表
.. py:attribute:: real_sys_list 运行时的实际系统列表
.. py:method:: __init__(self[, name="SelectorBase])
@ -62,6 +78,14 @@
:type value: int | bool | float | string
:raises logic_error: Unsupported type! 不支持的参数类型
.. py:method:: reset(self)
复位操作
.. py:method:: clone(self)
克隆操作
.. py:method:: add_stock(self, stock, sys)
加入初始标的及其对应的系统策略原型
@ -76,25 +100,44 @@
:param StockList stk_list: 加入的初始标的列表
:param System sys: 系统策略原型
.. py:method:: clear(self)
.. py:method:: remove_all(self)
清除已加入的系统策略实例
清除所有已加入的原型系统
.. py:method:: is_match_af(self)
【重载接口】判断是否和 AF 匹配
:param AllocateFundsBase af: 资产分配算法
.. py:method:: get_selected_on_open(self, datetime)
.. py:method:: get_selected_system_list(self, datetime)
【重载接口】获取指定时刻选取的系统实例
【重载接口】获取指定时刻开盘时选取的系统实例
:param Datetime datetime: 指定时刻
:return: 选取的系统实例列表
:rtype: SystemList
.. py:method:: get_selected_on_close(self, datetime)
【重载接口】获取指定时刻收盘时选取的系统实例
:param Datetime datetime: 指定时刻
:return: 选取的系统实例列表
:rtype: SystemList
.. py:method:: _calculate(self)
【重载接口】子类计算接口
.. py:method:: _reset(self)
【重载接口】子类复位接口,复位内部私有变量
.. py:method:: _clone(self)
【重载接口】子类克隆接口
【重载接口】子类克隆接口

View File

@ -8,3 +8,4 @@
portfolio
selector
allocate_funds

View File

@ -172,7 +172,7 @@
.. py:method:: get_trade_record_list(self)
获取交易记录
获取实际执行的交易记录,和 TM 的区别是不包含权息调整带来的交易记录
:rtype: TradeRecordList

View File

@ -13,4 +13,4 @@
stoploss
money_manager
profitgoal
slippage
slippage

View File

@ -1,20 +1,20 @@
INSERT INTO `hku_base`."Holiday" (`date`) VALUES (20220103);
INSERT INTO `hku_base`."Holiday" (`date`) VALUES (20220131);
INSERT INTO `hku_base`."Holiday" (`date`) VALUES (20220201);
INSERT INTO `hku_base`."Holiday" (`date`) VALUES (20220202);
INSERT INTO `hku_base`."Holiday" (`date`) VALUES (20220203);
INSERT INTO `hku_base`."Holiday" (`date`) VALUES (20220204);
INSERT INTO `hku_base`."Holiday" (`date`) VALUES (20220205);
INSERT INTO `hku_base`."Holiday" (`date`) VALUES (20220404);
INSERT INTO `hku_base`."Holiday" (`date`) VALUES (20220405);
INSERT INTO `hku_base`."Holiday" (`date`) VALUES (20220502);
INSERT INTO `hku_base`."Holiday" (`date`) VALUES (20220503);
INSERT INTO `hku_base`."Holiday" (`date`) VALUES (20220504);
INSERT INTO `hku_base`."Holiday" (`date`) VALUES (20220603);
INSERT INTO `hku_base`."Holiday" (`date`) VALUES (20220912);
INSERT INTO `hku_base`."Holiday" (`date`) VALUES (20221003);
INSERT INTO `hku_base`."Holiday" (`date`) VALUES (20221004);
INSERT INTO `hku_base`."Holiday" (`date`) VALUES (20221005);
INSERT INTO `hku_base`."Holiday" (`date`) VALUES (20221006);
INSERT INTO `hku_base`."Holiday" (`date`) VALUES (20221007);
INSERT INTO `hku_base`.`Holiday` (`date`) VALUES (20220103);
INSERT INTO `hku_base`.`Holiday` (`date`) VALUES (20220131);
INSERT INTO `hku_base`.`Holiday` (`date`) VALUES (20220201);
INSERT INTO `hku_base`.`Holiday` (`date`) VALUES (20220202);
INSERT INTO `hku_base`.`Holiday` (`date`) VALUES (20220203);
INSERT INTO `hku_base`.`Holiday` (`date`) VALUES (20220204);
INSERT INTO `hku_base`.`Holiday` (`date`) VALUES (20220205);
INSERT INTO `hku_base`.`Holiday` (`date`) VALUES (20220404);
INSERT INTO `hku_base`.`Holiday` (`date`) VALUES (20220405);
INSERT INTO `hku_base`.`Holiday` (`date`) VALUES (20220502);
INSERT INTO `hku_base`.`Holiday` (`date`) VALUES (20220503);
INSERT INTO `hku_base`.`Holiday` (`date`) VALUES (20220504);
INSERT INTO `hku_base`.`Holiday` (`date`) VALUES (20220603);
INSERT INTO `hku_base`.`Holiday` (`date`) VALUES (20220912);
INSERT INTO `hku_base`.`Holiday` (`date`) VALUES (20221003);
INSERT INTO `hku_base`.`Holiday` (`date`) VALUES (20221004);
INSERT INTO `hku_base`.`Holiday` (`date`) VALUES (20221005);
INSERT INTO `hku_base`.`Holiday` (`date`) VALUES (20221006);
INSERT INTO `hku_base`.`Holiday` (`date`) VALUES (20221007);
UPDATE `hku_base`.`version` set `version` = 7;

View File

@ -1,22 +1,22 @@
BEGIN TRANSACTION;
INSERT INTO "Holiday" (`date`) VALUES (20220103);
INSERT INTO "Holiday" (`date`) VALUES (20220131);
INSERT INTO "Holiday" (`date`) VALUES (20220201);
INSERT INTO "Holiday" (`date`) VALUES (20220202);
INSERT INTO "Holiday" (`date`) VALUES (20220203);
INSERT INTO "Holiday" (`date`) VALUES (20220204);
INSERT INTO "Holiday" (`date`) VALUES (20220205);
INSERT INTO "Holiday" (`date`) VALUES (20220404);
INSERT INTO "Holiday" (`date`) VALUES (20220405);
INSERT INTO "Holiday" (`date`) VALUES (20220502);
INSERT INTO "Holiday" (`date`) VALUES (20220503);
INSERT INTO "Holiday" (`date`) VALUES (20220504);
INSERT INTO "Holiday" (`date`) VALUES (20220603);
INSERT INTO "Holiday" (`date`) VALUES (20220912);
INSERT INTO "Holiday" (`date`) VALUES (20221003);
INSERT INTO "Holiday" (`date`) VALUES (20221004);
INSERT INTO "Holiday" (`date`) VALUES (20221005);
INSERT INTO "Holiday" (`date`) VALUES (20221006);
INSERT INTO "Holiday" (`date`) VALUES (20221007);
INSERT INTO `Holiday` (`date`) VALUES (20220103);
INSERT INTO `Holiday` (`date`) VALUES (20220131);
INSERT INTO `Holiday` (`date`) VALUES (20220201);
INSERT INTO `Holiday` (`date`) VALUES (20220202);
INSERT INTO `Holiday` (`date`) VALUES (20220203);
INSERT INTO `Holiday` (`date`) VALUES (20220204);
INSERT INTO `Holiday` (`date`) VALUES (20220205);
INSERT INTO `Holiday` (`date`) VALUES (20220404);
INSERT INTO `Holiday` (`date`) VALUES (20220405);
INSERT INTO `Holiday` (`date`) VALUES (20220502);
INSERT INTO `Holiday` (`date`) VALUES (20220503);
INSERT INTO `Holiday` (`date`) VALUES (20220504);
INSERT INTO `Holiday` (`date`) VALUES (20220603);
INSERT INTO `Holiday` (`date`) VALUES (20220912);
INSERT INTO `Holiday` (`date`) VALUES (20221003);
INSERT INTO `Holiday` (`date`) VALUES (20221004);
INSERT INTO `Holiday` (`date`) VALUES (20221005);
INSERT INTO `Holiday` (`date`) VALUES (20221006);
INSERT INTO `Holiday` (`date`) VALUES (20221007);
UPDATE `version` set `version` = 8;
COMMIT;

View File

@ -30,9 +30,7 @@ def deprecated_attr(name_dict):
else:
print(
#'Deprecated warning: the "{}.{}" will be deprecated, please use: "{}.{}"'.
': "{}.{}" 使 "{}.{}" '.format(
clzname, name, clzname, name_dict[name]
)
': "{}.{}" 使 "{}.{}" '.format(clzname, name, clzname, name_dict[name])
)
return func(self, name_dict[name])
if name not in dir(self):
@ -529,13 +527,11 @@ def StockManager_getattr(self, name):
StockManager.__getattr__ = StockManager_getattr
@deprecated_attr(
{
'tickValue': 'tick_value',
'minTradeNumber': 'min_trade_num',
'maxTradeNumber': 'max_trade_num',
}
)
@deprecated_attr({
'tickValue': 'tick_value',
'minTradeNumber': 'min_trade_num',
'maxTradeNumber': 'max_trade_num',
})
def StockTypeInfo_getattr(self, name):
return getattr(self, name)

View File

@ -30,7 +30,8 @@
"* [006 TradeManager应用](006-TradeManager.ipynb?flush_cache=True)\n",
"* [007 系统策略演示](007-SystemDetails.ipynb?flush_cache=True)\n",
"* [008 序列化说明](008-Pickle.ipynb?flush_cache=True)\n",
"* [009_获取实时日线数据](009-RealData.ipynb?flush_cache=True)"
"* [009_获取实时日线数据](009-RealData.ipynb?flush_cache=True)\n",
"* [010_资产组合](010-Portfolio.ipynb?flush_cache=True)"
]
},
{
@ -53,7 +54,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
@ -67,7 +68,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.3"
"version": "3.9.7"
}
},
"nbformat": 4,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -246,18 +246,9 @@ KData.get_pos = KData_getPos
KData.get_pos_in_stock = KData_getPosInStock
# ------------------------------------------------------------------
# 封装增强其他C++ vector类型的遍历、打印
# 封装增强其他C++ vector打印
# ------------------------------------------------------------------
PriceList.__getitem__ = list_getitem
StringList.__getitem__ = list_getitem
DatetimeList.__getitem__ = list_getitem
BlockList.__getitem__ = list_getitem
KRecordList.__getitem__ = list_getitem
TransList.__getitem__ = list_getitem
TimeLineList.__getitem__ = list_getitem
StockWeightList.__getitem__ = list_getitem
PriceList.__str__ = lambda self: str(list(self))
PriceList.__repr__ = lambda self: repr(list(self))
StringList.__str__ = lambda self: str(list(self))

View File

@ -31,6 +31,7 @@ from hikyuu.util.singleton import SingletonType
from sqlalchemy import (create_engine, Sequence, Column, Integer, String, and_, UniqueConstraint)
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
@ -174,9 +175,7 @@ class HubManager(metaclass=SingletonType):
# 创建仓库数据库
engine = create_engine("sqlite:///{}/.hikyuu/hub.db".format(usr_dir))
Base.metadata.create_all(engine)
self._scoped_Session = scoped_session(
sessionmaker(autocommit=False, autoflush=False, bind=engine)
)
self._scoped_Session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine))
self._session = None
@dbsession
@ -185,9 +184,8 @@ class HubManager(metaclass=SingletonType):
usr_dir = os.path.expanduser('~')
# 检查并建立远端仓库的本地缓存目录
self.remote_cache_dir = self._session.query(ConfigModel.value
).filter(ConfigModel.key == 'remote_cache_dir'
).first()
self.remote_cache_dir = self._session.query(ConfigModel.value).filter(ConfigModel.key == 'remote_cache_dir'
).first()
if self.remote_cache_dir is None:
self.remote_cache_dir = "{}/.hikyuu/hub_cache".format(usr_dir)
record = ConfigModel(key='remote_cache_dir', value=self.remote_cache_dir)
@ -207,8 +205,7 @@ class HubManager(metaclass=SingletonType):
sys.path.append(os.path.dirname(model.local))
# 检查并下载 hikyuu 默认策略仓库, hikyuu_hub 避免导入时模块和 hikyuu 重名
hikyuu_hub_path = self._session.query(HubModel.local).filter(HubModel.name == 'default'
).first()
hikyuu_hub_path = self._session.query(HubModel.local).filter(HubModel.name == 'default').first()
if hikyuu_hub_path is None:
self.add_remote_hub('default', 'https://gitee.com/fasiondog/hikyuu_hub.git', 'master')
@ -236,18 +233,14 @@ class HubManager(metaclass=SingletonType):
record = self._session.query(HubModel).filter(HubModel.name == name).first()
checkif(record is not None, name, HubNameRepeatError)
record = self._session.query(HubModel).filter(
and_(HubModel.url == url, HubModel.branch == branch)
).first()
record = self._session.query(HubModel).filter(and_(HubModel.url == url, HubModel.branch == branch)).first()
# 下载远程仓库
local_dir = "{}/{}".format(self.remote_cache_dir, name)
self.download_remote_hub(local_dir, url, branch)
# 导入仓库各部件策略信息
record = HubModel(
name=name, hub_type='remote', url=url, branch=branch, local_base=name, local=local_dir
)
record = HubModel(name=name, hub_type='remote', url=url, branch=branch, local_base=name, local=local_dir)
self.import_part_to_db(record)
# 更新仓库记录
@ -332,9 +325,7 @@ class HubManager(metaclass=SingletonType):
local_dir = hub_model.local
if not os.path.lexists(local_dir):
self.logger.warning(
'The {} hub path ("{}") is not exists! Ignored this hub!'.format(
hub_model.name, hub_model.local
)
'The {} hub path ("{}") is not exists! Ignored this hub!'.format(hub_model.name, hub_model.local)
)
return
@ -346,12 +337,9 @@ class HubManager(metaclass=SingletonType):
try:
with os.scandir(path) as it:
for entry in it:
if (not entry.name.startswith('.')
) and entry.is_dir() and (entry.name != "__pycache__"):
if (not entry.name.startswith('.')) and entry.is_dir() and (entry.name != "__pycache__"):
# 计算实际的导入模块名
module_name = '{}.part.{}.{}.part'.format(
base_local, part, entry.name
) if part not in (
module_name = '{}.part.{}.{}.part'.format(base_local, part, entry.name) if part not in (
'prtflo', 'sys'
) else '{}.{}.{}.part'.format(base_local, part, entry.name)
@ -370,9 +358,7 @@ class HubManager(metaclass=SingletonType):
self.logger.error(' part ("{}")'.format(entry.path))
continue
name = '{}.{}.{}'.format(
hub_model.name, part, entry.name
) if part not in (
name = '{}.{}.{}'.format(hub_model.name, part, entry.name) if part not in (
'prtflo', 'sys'
) else '{}.{}.{}'.format(hub_model.name, part, entry.name)
@ -382,12 +368,9 @@ class HubManager(metaclass=SingletonType):
part=part,
name=name,
module_name=module_name,
author=part_module.author.strip()
if 'author' in module_vars else 'None',
version=part_module.version.strip()
if 'version' in module_vars else 'None',
doc=part_module.part.__doc__.strip()
if part_module.part.__doc__ else "None"
author=part_module.author.strip() if 'author' in module_vars else 'None',
version=part_module.version.strip() if 'version' in module_vars else 'None',
doc=part_module.part.__doc__.strip() if part_module.part.__doc__ else "None"
)
self._session.add(part_model)
except Exception as e:
@ -406,10 +389,9 @@ class HubManager(metaclass=SingletonType):
"""
name_parts = name.split('.')
checkif(
len(name_parts) < 2 or (
name_parts[-2]
not in ('af', 'cn', 'ev', 'mm', 'pg', 'se', 'sg', 'sp', 'st', 'prtflo', 'sys')
), name, PartNameError
len(name_parts) < 2
or (name_parts[-2] not in ('af', 'cn', 'ev', 'mm', 'pg', 'se', 'sg', 'sp', 'st', 'prtflo', 'sys')), name,
PartNameError
)
# 未指定仓库名,则默认使用 'default' 仓库
@ -422,6 +404,7 @@ class HubManager(metaclass=SingletonType):
raise PartNotFoundError(part_name, '')
part = part_module.part(**kwargs)
part.name = part_model.name
part.info = self.get_part_info(part.name)
return part
@dbsession
@ -482,9 +465,8 @@ class HubManager(metaclass=SingletonType):
elif part_type is None:
results = self._session.query(PartModel.name).filter_by(hub_name=hub).all()
else:
results = self._session.query(PartModel.name).filter(
and_(PartModel.hub_name == hub, PartModel.part == part_type)
).all()
results = self._session.query(PartModel.name
).filter(and_(PartModel.hub_name == hub, PartModel.part == part_type)).all()
return [record[0] for record in results]
@dbsession
@ -608,8 +590,7 @@ __all__ = [
if __name__ == "__main__":
logging.basicConfig(
level=logging.INFO,
format='%(asctime)-15s [%(levelname)s] - %(message)s [%(name)s::%(funcName)s]'
level=logging.INFO, format='%(asctime)-15s [%(levelname)s] - %(message)s [%(name)s::%(funcName)s]'
)
add_local_hub('dev', '/home/fasiondog/workspace/stockhouse')
#update_hub('test1')

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,25 @@
#!/usr/bin/python
# -*- coding: utf8 -*-
#
# Create on: 2022-02-20
# Author: fasiondog
import unittest
from test_init import *
class SystemWeightTest(unittest.TestCase):
def test_weight(self):
x = SystemWeight()
self.assertEqual(x.weight, 1.0)
try:
x.weight = 1.2
except:
self.assertEqual(x.weight, 1.0)
#print(x)
def suite():
return unittest.TestLoader().loadTestsFromTestCase(SystemWeightTest)

View File

@ -10,81 +10,86 @@
import unittest
from test_init import *
from hikyuu.trade_sys.condition import *
from hikyuu.trade_sys.signal import SignalBase
from hikyuu import *
class ConditionPython(ConditionBase):
def __init__(self):
super(ConditionPython, self).__init__("ConditionPython")
self.setParam("n", 10)
self.set_param("n", 10)
self._m_flag = False
def isValid(self, datetime):
def is_valid(self, datetime):
return self._m_flag
def _reset(self):
if self._m_flag:
self._m_flag = False
else:
self._m_flag = True
def _clone(self):
p = ConditionPython()
p._m_flag = self._m_flag
return p
class ConditionTest(unittest.TestCase):
def test_ConditionBase(self):
p = ConditionPython()
self.assertEqual(p.name, "ConditionPython")
self.assertEqual(p.getParam("n"), 10)
p.setParam("n",20)
self.assertEqual(p.getParam("n"), 20)
self.assertEqual(p.isValid(Datetime(200101010000)), False)
self.assertEqual(p.get_param("n"), 10)
p.set_param("n", 20)
self.assertEqual(p.get_param("n"), 20)
self.assertEqual(p.is_valid(Datetime(200101010000)), False)
p.reset()
self.assertEqual(p.isValid(Datetime(200101010000)), True)
self.assertEqual(p.is_valid(Datetime(200101010000)), True)
p_clone = p.clone()
self.assertEqual(p_clone.name, "ConditionPython")
self.assertEqual(p_clone.getParam("n"), 20)
self.assertEqual(p_clone.isValid(Datetime(200101010000)), True)
self.assertEqual(p_clone.get_param("n"), 20)
self.assertEqual(p_clone.is_valid(Datetime(200101010000)), True)
p.set_param("n", 1)
p_clone.set_param("n", 3)
self.assertEqual(p.get_param("n"), 1)
self.assertEqual(p_clone.get_param("n"), 3)
def testCondition(self):
self._add_valid(Datetime(200101010000))
self._add_valid(Datetime(200101020000))
p.setParam("n", 1)
p_clone.setParam("n", 3)
self.assertEqual(p.getParam("n"), 1)
self.assertEqual(p_clone.getParam("n"), 3)
def testCondition(self):
self._addValid(Datetime(200101010000))
self._addValid(Datetime(200101020000))
class TestCrtCN(unittest.TestCase):
def test_crtCN(self):
p = crtCN(testCondition, params={'n':10}, name='ConditionPython')
self.assertEqual(p.getParam("n"), 10)
p.setParam("n",20)
self.assertEqual(p.getParam("n"), 20)
p = crtCN(testCondition, params={'n': 10}, name='ConditionPython')
self.assertEqual(p.get_param("n"), 10)
p.set_param("n", 20)
self.assertEqual(p.get_param("n"), 20)
k = sm['sh000001'].getKData(Query(-100))
k = sm['sh000001'].get_kdata(Query(-100))
self.assertEqual(k.empty(), False)
p.setSG(SignalBase()) #cn设置交易对象时
p.setTO(k) #cn在设置交易对象时才会调用_caculate函数
self.assertEqual(p.isValid(Datetime(200101010000)), True)
self.assertEqual(p.isValid(Datetime(200101020000)), True)
self.assertEqual(p.isValid(Datetime(200101030000)), False)
p.sg = SignalBase() #cn设置交易对象时
p.to = k #cn在设置交易对象时才会调用_caculate函数
self.assertEqual(p.is_valid(Datetime(200101010000)), True)
self.assertEqual(p.is_valid(Datetime(200101020000)), True)
self.assertEqual(p.is_valid(Datetime(200101030000)), False)
p_clone = p.clone()
self.assertEqual(p_clone.name, "ConditionPython")
self.assertEqual(p_clone.getParam("n"), 20)
self.assertEqual(p_clone.isValid(Datetime(200101010000)), True)
self.assertEqual(p_clone.get_param("n"), 20)
self.assertEqual(p_clone.is_valid(Datetime(200101010000)), True)
p.set_param("n", 1)
p_clone.set_param("n", 3)
self.assertEqual(p.get_param("n"), 1)
self.assertEqual(p_clone.get_param("n"), 3)
p.setParam("n", 1)
p_clone.setParam("n", 3)
self.assertEqual(p.getParam("n"), 1)
self.assertEqual(p_clone.getParam("n"), 3)
def suite():
return unittest.TestLoader().loadTestsFromTestCase(ConditionTest)
def suiteTestCrtCN():
return unittest.TestLoader().loadTestsFromTestCase(TestCrtCN)

View File

@ -11,6 +11,7 @@ import unittest
from test_init import *
class DatetimeTest(unittest.TestCase):
def test_Datetime(self):
d = Datetime(201209272301)
@ -33,17 +34,17 @@ class DatetimeTest(unittest.TestCase):
self.assert_(d > Datetime(201209272259))
self.assert_(not (d < Datetime(201209272301)))
self.assert_(d < Datetime(201209272302))
d = Datetime(200101010159)
self.assertEqual(str(d), "2001-1-1 1:59:0")
self.assertEqual(str(d), "2001-01-01 01:59:00")
self.assertEqual(d, Datetime("2001-Jan-01 01:59:00"))
self.assertEqual(Datetime(), constant.null_datetime)
def test_pickle(self):
if not constant.pickle_support:
return
import pickle as pl
a = Datetime(201001010000)
filename = sm.tmpdir() + "/Datetime.plk"
@ -54,7 +55,7 @@ class DatetimeTest(unittest.TestCase):
b = pl.load(fh)
fh.close()
self.assertEqual(a, b)
def suite():
return unittest.TestLoader().loadTestsFromTestCase(DatetimeTest)
return unittest.TestLoader().loadTestsFromTestCase(DatetimeTest)

View File

@ -10,76 +10,79 @@
import unittest
from test_init import *
from hikyuu.trade_sys.environment import *
class EnvironmentPython(EnvironmentBase):
def __init__(self):
super(EnvironmentPython, self).__init__("EnvironmentPython")
self.setParam("n", 10)
self.set_param("n", 10)
self._m_flag = False
def isValid(self, market, datetime):
def is_valid(self, market, datetime):
return self._m_flag
def _reset(self):
if self._m_flag:
self._m_flag = False
else:
self._m_flag = True
def _clone(self):
p = EnvironmentPython()
p._m_flag = self._m_flag
return p
class EnvironmentTest(unittest.TestCase):
def test_EnvironmentBase(self):
p = EnvironmentPython()
self.assertEqual(p.name, "EnvironmentPython")
self.assertEqual(p.getParam("n"), 10)
p.setParam("n",20)
self.assertEqual(p.getParam("n"), 20)
self.assertEqual(p.isValid("SH", Datetime(200101010000)), False)
self.assertEqual(p.get_param("n"), 10)
p.set_param("n", 20)
self.assertEqual(p.get_param("n"), 20)
self.assertEqual(p.is_valid("SH", Datetime(200101010000)), False)
p.reset()
self.assertEqual(p.isValid("SH", Datetime(200101010000)), True)
self.assertEqual(p.is_valid("SH", Datetime(200101010000)), True)
p_clone = p.clone()
self.assertEqual(p_clone.name, "EnvironmentPython")
self.assertEqual(p_clone.getParam("n"), 20)
self.assertEqual(p_clone.isValid("SH", Datetime(200101010000)), True)
self.assertEqual(p_clone.get_param("n"), 20)
self.assertEqual(p_clone.is_valid("SH", Datetime(200101010000)), True)
p.set_param("n", 1)
p_clone.set_param("n", 3)
self.assertEqual(p.get_param("n"), 1)
self.assertEqual(p_clone.get_param("n"), 3)
p.setParam("n", 1)
p_clone.setParam("n", 3)
self.assertEqual(p.getParam("n"), 1)
self.assertEqual(p_clone.getParam("n"), 3)
def test_crtEV_func(self):
self._addValid(Datetime(200101010000))
self._add_valid(Datetime(200101010000))
class TestCrtEV(unittest.TestCase):
def test_crtEV(self):
p = crtEV(test_crtEV_func, params={'n':10}, name='EnvironmentPython')
p = crtEV(test_crtEV_func, params={'n': 10}, name='EnvironmentPython')
self.assertEqual(p.name, "EnvironmentPython")
self.assertEqual(p.getParam("n"), 10)
p.setParam("n",20)
self.assertEqual(p.getParam("n"), 20)
p.setQuery(Query(-100)) #ev在设置查询对象时才会调用_caculate函数
self.assertEqual(p.isValid(Datetime(200101010000)), True)
self.assertEqual(p.get_param("n"), 10)
p.set_param("n", 20)
self.assertEqual(p.get_param("n"), 20)
p.query = Query(-100) #ev在设置查询对象时才会调用_caculate函数
self.assertEqual(p.is_valid(Datetime(200101010000)), True)
p_clone = p.clone()
self.assertEqual(p_clone.name, "EnvironmentPython")
self.assertEqual(p_clone.getParam("n"), 20)
self.assertEqual(p_clone.isValid(Datetime(200101010000)), True)
self.assertEqual(p_clone.get_param("n"), 20)
self.assertEqual(p_clone.is_valid(Datetime(200101010000)), True)
p.set_param("n", 1)
p_clone.set_param("n", 3)
self.assertEqual(p.get_param("n"), 1)
self.assertEqual(p_clone.get_param("n"), 3)
p.setParam("n", 1)
p_clone.setParam("n", 3)
self.assertEqual(p.getParam("n"), 1)
self.assertEqual(p_clone.getParam("n"), 3)
def suite():
return unittest.TestLoader().loadTestsFromTestCase(EnvironmentTest)
def suiteTestCrtEV():
return unittest.TestLoader().loadTestsFromTestCase(TestCrtEV)

View File

@ -10,25 +10,30 @@
import unittest
from test_init import *
from hikyuu.indicator import *
class AddIndicator(IndicatorImp):
def __init__(self, indicator):
super(AddIndicator, self).__init__("AddIndicator")
self._readyBuffer(indicator.size(), 1)
self._ready_buffer(len(indicator), 1)
self.set_discard(0)
for i in range(len(indicator)):
self._set(indicator[i] + 1, i)
def __call__(self, ind):
return AddIndicator(ind)
def _clone(self):
return AddIndicator(Indicator())
def _calculate(self, ind):
self.set_discard(0)
for i in range(len(ind)):
self._set(ind[i] + 1, i)
class IndicatorTest(unittest.TestCase):
def test_PRICELIST(self):
a = toPriceList([0, 1, 2, 3])
x = PRICELIST(a)
self.assertEqual(x.size(), 4)
self.assertEqual(len(x), 4)
self.assertEqual(x.empty(), False)
self.assertEqual(x.discard, 0)
self.assertEqual(x[0], 0)
@ -41,7 +46,7 @@ class IndicatorTest(unittest.TestCase):
x = PRICELIST(a)
m = Indicator(AddIndicator(x))
self.assertEqual(m.name, "AddIndicator")
self.assertEqual(m.size(), 4)
self.assertEqual(len(m), 4)
self.assertEqual(m.empty(), False)
self.assert_(abs(m[0] - 1) < 0.0001)
self.assert_(abs(m[1] - 2) < 0.0001)
@ -50,15 +55,14 @@ class IndicatorTest(unittest.TestCase):
b = toPriceList([1, 2, 3, 4])
x = PRICELIST(b)
m.get_imp()._calculate(m)
m = m(x)
self.assertEqual(m.size(), 4)
self.assertEqual(len(m), 4)
self.assertEqual(m.empty(), False)
self.assert_(abs(m[0] - 2) < 0.0001)
self.assert_(abs(m[1] - 3) < 0.0001)
self.assert_(abs(m[2] - 4) < 0.0001)
self.assert_(abs(m[3] - 5) < 0.0001)
#print m.name
#print m
def test_operator(self):
a = toPriceList([0, 1, 2, 3])
@ -84,7 +88,7 @@ class IndicatorTest(unittest.TestCase):
self.assertEqual(a[3], 12)
a = x2 / x1
self.assertEqual(a[0], constant.null_price)
self.assert_(isnan(a[0]))
self.assertEqual(a[1], 2)
self.assertEqual(a[2], 1.5)
self.assertEqual(a[3], 4.0 / 3.0)
@ -92,7 +96,7 @@ class IndicatorTest(unittest.TestCase):
def test_IKDATA(self):
s = sm['sh000001']
q = Query(0, 10)
k = s.getKData(q)
k = s.get_kdata(q)
o = OPEN(k)
h = HIGH(k)
l = LOW(k)
@ -100,12 +104,12 @@ class IndicatorTest(unittest.TestCase):
a = AMO(k)
v = VOL(k)
self.assertEqual(o.size(), 10)
self.assertEqual(h.size(), 10)
self.assertEqual(l.size(), 10)
self.assertEqual(c.size(), 10)
self.assertEqual(a.size(), 10)
self.assertEqual(v.size(), 10)
self.assertEqual(len(o), 10)
self.assertEqual(len(h), 10)
self.assertEqual(len(l), 10)
self.assertEqual(len(c), 10)
self.assertEqual(len(a), 10)
self.assertEqual(len(v), 10)
self.assertEqual(o.empty(), False)
self.assertEqual(h.empty(), False)
@ -132,7 +136,7 @@ class IndicatorTest(unittest.TestCase):
a = toPriceList([0, 1, 2, 3])
x = PRICELIST(a)
m = MA(x, 2)
self.assertEqual(m.size(), 4)
self.assertEqual(len(m), 4)
self.assertEqual(m.discard, 0)
self.assert_(abs(m[0] - 0.0) < 0.0001)
self.assert_(abs(m[1] - 0.5) < 0.0001)

View File

@ -10,29 +10,28 @@
import unittest
from test_init import *
from hikyuu.trade_sys import *
class KDataTest(unittest.TestCase):
def test_null_kdata(self):
k = KData()
self.assertEqual(k.size(), 0)
self.assertEqual(len(k), 0)
self.assertEqual(k.empty(), True)
self.assertEqual(k.startPos, 0)
self.assertEqual(k.endPos, 0)
self.assertEqual(k.lastPos, 0)
stock = k.getStock()
self.assertEqual(stock.isNull(), True)
self.assertEqual(k.start_pos, 0)
self.assertEqual(k.end_pos, 0)
self.assertEqual(k.last_pos, 0)
stock = k.get_stock()
self.assertEqual(stock.is_null(), True)
def test_kdata(self):
stock = sm["Sh000001"]
q = Query(0, 10)
k = stock.getKData(q)
self.assertEqual(k.size(), 10)
k = stock.get_kdata(q)
self.assertEqual(len(k), 10)
self.assertEqual(k.empty(), False)
self.assertEqual(k.startPos, 0)
self.assertEqual(k.endPos, 10)
self.assertEqual(k.lastPos, 9)
self.assertEqual(k.start_pos, 0)
self.assertEqual(k.end_pos, 10)
self.assertEqual(k.last_pos, 9)
self.assertEqual(k[0].datetime, Datetime(199012190000))
self.assert_(abs(k[0].open - 96.05) < 0.0001)
self.assert_(abs(k[0].high - 99.980) < 0.0001)
@ -50,13 +49,13 @@ class KDataTest(unittest.TestCase):
import pickle as pl
filename = sm.tmpdir() + "/KData.plk"
fh = open(filename, 'wb')
kdata = sm['sh000001'].getKData(Query(10, 20))
kdata = sm['sh000001'].get_kdata(Query(10, 20))
pl.dump(kdata, fh)
fh.close()
fh = open(filename, 'rb')
b = pl.load(fh)
fh.close()
self.assertEqual(kdata.size(), b.size())
self.assertEqual(len(kdata), len(b))
for i in range(len(kdata)):
self.assertEqual(kdata[i], b[i])

View File

@ -14,12 +14,12 @@ from test_init import *
class MarketInfoTest(unittest.TestCase):
def test_market(self):
market = sm.getMarketInfo("Sh")
market = sm.get_market_info("Sh")
self.assertEqual(market.market, "SH")
self.assertEqual(market.name, u"上海证劵交易所")
self.assertEqual(market.description, u"上海市场")
self.assertEqual(market.code, "000001")
self.assertEqual(market.lastDate, Datetime(201112060000))
self.assertEqual(market.last_datetime, Datetime(201112060000))
def suite():

View File

@ -10,73 +10,79 @@
import unittest
from test_init import *
from hikyuu.trade_sys.moneymanager import *
class MoneyManagerPython(MoneyManagerBase):
def __init__(self):
super(MoneyManagerPython, self).__init__("MoneyManagerPython")
self.setParam("n", 10)
self.set_param("n", 10)
self._m_flag = False
def getBuyNumber(self, datetime, stock, price, risk):
if self._m_flag:
return 10
else:
return 20
def _reset(self):
if self._m_flag:
self._m_flag = False
else:
self._m_flag = True
def _clone(self):
p = MoneyManagerPython()
p._m_flag = self._m_flag
return p
class MoneyManagerTest(unittest.TestCase):
def test_ConditionBase(self):
stock = sm['sh000001']
p = MoneyManagerPython()
self.assertEqual(p.name, "MoneyManagerPython")
self.assertEqual(p.getParam("n"), 10)
p.setParam("n",20)
self.assertEqual(p.getParam("n"), 20)
self.assertEqual(p.get_param("n"), 10)
p.set_param("n", 20)
self.assertEqual(p.get_param("n"), 20)
self.assertEqual(p.getBuyNumber(Datetime(200101010000), stock, 10.0, 0.0), 20)
p.reset()
self.assertEqual(p.getBuyNumber(Datetime(200101010000), stock, 10.0, 0.0), 10)
p_clone = p.clone()
self.assertEqual(p_clone.name, "MoneyManagerPython")
self.assertEqual(p_clone.getParam("n"), 20)
self.assertEqual(p_clone.get_param("n"), 20)
self.assertEqual(p_clone.getBuyNumber(Datetime(200101010000), stock, 10, 0.0), 10)
p.setParam("n", 1)
p_clone.setParam("n", 3)
self.assertEqual(p.getParam("n"), 1)
self.assertEqual(p_clone.getParam("n"), 3)
p.set_param("n", 1)
p_clone.set_param("n", 3)
self.assertEqual(p.get_param("n"), 1)
self.assertEqual(p_clone.get_param("n"), 3)
def testCrtMM(self):
pass
def testgetBuyNumber(self, datetime, stock, price, risk):
return 10.0 if datetime == Datetime(200101010000) else 0.0
class TestCrtMM(unittest.TestCase):
def test_crt_mm(self):
p = crtMM(testCrtMM, params={'n':10}, name="TestMM")
p = crtMM(testCrtMM, params={'n': 10}, name="TestMM")
p.getBuyNumber = testgetBuyNumber
self.assertEqual(p.name, "TestMM")
stock = sm['sh000001']
self.assertEqual(p.getBuyNumber(p, Datetime(200101010000), stock, 1.0, 1.0), 10.0)
self.assertEqual(p.getBuyNumber(p, Datetime(200101020000), stock, 1.0, 1.0), 0.0)
p_clone = p.clone()
self.assertEqual(p_clone.name, "TestMM")
self.assertEqual(p_clone.name, "TestMM")
def suite():
return unittest.TestLoader().loadTestsFromTestCase(MoneyManagerTest)
def suiteTestCrtMM():
return unittest.TestLoader().loadTestsFromTestCase(TestCrtMM)

View File

@ -11,51 +11,52 @@ from test_init import *
import unittest
from hikyuu import Parameter
class ParameterTest(unittest.TestCase):
def test_Parameter(self):
p = Parameter()
self.assertEqual(p.have("n"), False)
self.assertEqual(p.have("b"), False)
self.assertEqual(p.have("d"), False)
self.assertEqual(p.have("s"), False)
p.set("n", 10)
p.set("b", True)
p.set("d", 10.01)
p.set("s", "string")
self.assertEqual(p.have("n"), True)
self.assertEqual(p.have("b"), True)
self.assertEqual(p.have("d"), True)
self.assertEqual(p.have("s"), True)
self.assertEqual(p.get("n"), 10)
self.assertEqual(p.get("b"), True)
self.assertEqual(p.get("d"), 10.01)
self.assertEqual(p.get("s"), "string")
p.set("n", 20)
p.set("b", False)
p.set("d", 10.001)
p.set("s", "string2")
self.assertEqual(p.get("n"), 20)
self.assertEqual(p.get("b"), False)
self.assertEqual(p.get("d"), 10.001)
self.assertEqual(p.get("s"), "string2")
def test_pickle(self):
if not constant.pickle_support:
return
tmpdir = sm.tmpdir()
fh = open(tmpdir + "/Parameter.plk", "wb")
a = Parameter()
a.set("bool", True)
a.set("string", "This is Parameter")
import pickle as pl
pl.dump(a, fh)
fh.close()
fh = open(tmpdir + "/Parameter.plk", "rb")
b = pl.load(fh)
self.assertEqual(b.get("bool"), True)
self.assertEqual(b.get("string"), "This is Parameter")
self.assertEqual("n" in p, False)
self.assertEqual("b" in p, False)
self.assertEqual("d" in p, False)
self.assertEqual("s" in p, False)
p["n"] = 10
p["b"] = True
p["d"] = 10.01
p["s"] = "string"
self.assertEqual("n" in p, True)
self.assertEqual("b" in p, True)
self.assertEqual("d" in p, True)
self.assertEqual("s" in p, True)
self.assertEqual(p["n"], 10)
self.assertEqual(p["b"], True)
self.assertEqual(p["d"], 10.01)
self.assertEqual(p["s"], "string")
p["n"] = 20
p["b"] = False
p["d"] = 10.001
p["s"] = "string2"
self.assertEqual(p["n"], 20)
self.assertEqual(p["b"], False)
self.assertEqual(p["d"], 10.001)
self.assertEqual(p["s"], "string2")
# def test_pickle(self):
# if not constant.pickle_support:
# return
# tmpdir = sm.tmpdir()
# fh = open(tmpdir + "/Parameter.plk", "wb")
# a = Parameter()
# a["bool"] = True
# a["string"] = "This is Parameter"
# import pickle as pl
# pl.dump(a, fh)
# fh.close()
# fh = open(tmpdir + "/Parameter.plk", "rb")
# b = pl.load(fh)
# self.assertEqual(b["bool"], True)
# self.assertEqual(b["string"], "This is Parameter")
def suite():
return unittest.TestLoader().loadTestsFromTestCase(ParameterTest)

View File

@ -10,42 +10,43 @@
import unittest
from test_init import *
from hikyuu.trade_sys.profitgoal import *
class ProfitGoalPython(ProfitGoalBase):
def __init__(self):
super(ProfitGoalPython, self).__init__("ProfitGoalPython")
self._x = 0
def getGoal(self, datetime, price):
if self._x < 10:
return 0.0
return 1.0
def _reset(self):
self._x = 0
def _clone(self):
p = ProfitGoalPython()
p._x = self._x
return p
def _calculate(self):
""" do nothing """
class ProfitGoalTest(unittest.TestCase):
def test_ProfitGoalBase(self):
p = ProfitGoalPython()
self.assertEqual(p.name, "ProfitGoalPython")
self.assertEqual(p.getGoal(Datetime(200101010000), 1.0), 0.0)
self.assertEqual(p._x, 0)
p._x = 10
self.assertEqual(p._x, 10)
self.assertEqual(p.getGoal(Datetime(200101010000), 1.0), 1.0)
p.reset()
self.assertEqual(p._x, 0)
p._x = 10
p_clone = p.clone()
self.assertEqual(p_clone._x, 10)
@ -57,22 +58,26 @@ class ProfitGoalTest(unittest.TestCase):
def testCrtPG(self):
pass
def testGetGoal(self, datetime, price):
return 10.0 if datetime == Datetime(200101010000) else 0.0
class TestCrtPG(unittest.TestCase):
def test_crt_pg(self):
p = crtPG(testCrtPG, params={'n':10}, name="ProfitGoalPython")
p = crtPG(testCrtPG, params={'n': 10}, name="ProfitGoalPython")
p.getGoal = testGetGoal
self.assertEqual(p.name, "ProfitGoalPython")
self.assertEqual(p.getGoal(p, Datetime(200101010000), 1.0), 10.0)
self.assertEqual(p.getGoal(p, Datetime(200101020000), 1.0), 0.0)
p_clone = p.clone()
self.assertEqual(p_clone.name, "ProfitGoalPython")
def suite():
return unittest.TestLoader().loadTestsFromTestCase(ProfitGoalTest)
def suiteTestCrtPG():
return unittest.TestLoader().loadTestsFromTestCase(TestCrtPG)

View File

@ -10,134 +10,136 @@
import unittest
from test_init import *
from hikyuu.trade_sys.signal import *
class SignalPython(SignalBase):
def __init__(self):
super(SignalPython, self).__init__("SignalPython")
self._x = 0
self.setParam("test", 30)
self.set_param("test", 30)
def _reset(self):
self._x = 0
def _clone(self):
p = SignalPython()
p._x = self._x
return p
def _calculate(self):
self._addBuySignal(Datetime(201201210000))
self._addSellSignal(Datetime(201201300000))
self._add_buy_signal(Datetime(201201210000))
self._add_sell_signal(Datetime(201201300000))
class SignalTest(unittest.TestCase):
def test_SignalBase(self):
p = SignalPython()
self.assertEqual(p.name, "SignalPython")
p.name = "SignalPythonTest"
self.assertEqual(p.name, "SignalPythonTest")
self.assertEqual(p.shouldBuy(Datetime(201201210000)), False)
self.assertEqual(p.shouldSell(Datetime(201201300000)), False)
k = sm['sh000001'].getKData(Query(-100))
self.assertEqual(p.should_buy(Datetime(201201210000)), False)
self.assertEqual(p.should_sell(Datetime(201201300000)), False)
k = sm['sh000001'].get_kdata(Query(-100))
self.assertEqual(k.empty(), False)
p.setTO(k)
self.assertEqual(p.shouldBuy(Datetime(201201210000)), True)
self.assertEqual(p.shouldSell(Datetime(201201300000)), True)
self.assertEqual(p.shouldBuy(Datetime(200101010000)), False)
p._addBuySignal(Datetime(200101010000))
self.assertEqual(p.shouldBuy(Datetime(200101010000)), True)
self.assertEqual(p.shouldSell(Datetime(200101030000)), False)
p._addSellSignal(Datetime(200101030000))
self.assertEqual(p.shouldSell(Datetime(200101030000)), True)
d = p.getBuySignal()
p.to = k
self.assertEqual(p.should_buy(Datetime(201201210000)), True)
self.assertEqual(p.should_sell(Datetime(201201300000)), True)
self.assertEqual(p.should_buy(Datetime(200101010000)), False)
p._add_buy_signal(Datetime(200101010000))
self.assertEqual(p.should_buy(Datetime(200101010000)), True)
self.assertEqual(p.should_sell(Datetime(200101030000)), False)
p._add_sell_signal(Datetime(200101030000))
self.assertEqual(p.should_sell(Datetime(200101030000)), True)
d = p.get_buy_signal()
for i in range(len(d)):
self.assertIn(d[i], [Datetime(201201210000), Datetime(200101010000)])
d = p.getSellSignal()
d = p.get_sell_signal()
for i in range(len(d)):
self.assertIn(d[i], [Datetime(201201300000), Datetime(200101030000)])
p_clone = p.clone()
d = p_clone.getBuySignal()
d = p_clone.get_buy_signal()
for i in range(len(d)):
self.assertIn(d[i], [Datetime(201201210000), Datetime(200101010000)])
d = p_clone.getSellSignal()
d = p_clone.get_sell_signal()
for i in range(len(d)):
self.assertIn(d[i], [Datetime(201201300000), Datetime(200101030000)])
self.assertEqual(p._x, 0)
p._x = 10
self.assertEqual(p._x, 10)
p.reset()
self.assertEqual(p._x, 0)
p._x = 20
p_clone = p.clone()
self.assertEqual(p_clone._x, 20)
p.reset()
self.assertEqual(p._x, 0)
self.assertEqual(p_clone._x, 20)
self.assertEqual(p.getParam("test"), 30)
self.assertEqual(p_clone.getParam("test"), 30)
p.setParam("test", 10)
self.assertEqual(p.getParam("test"), 10)
self.assertEqual(p_clone.getParam("test"), 30)
self.assertEqual(p.get_param("test"), 30)
self.assertEqual(p_clone.get_param("test"), 30)
p.set_param("test", 10)
self.assertEqual(p.get_param("test"), 10)
self.assertEqual(p_clone.get_param("test"), 30)
def testSignal(self):
self._addBuySignal(Datetime(201201210000))
self._addSellSignal(Datetime(201201300000))
class TestCrtSG(unittest.TestCase):
self._add_buy_signal(Datetime(201201210000))
self._add_sell_signal(Datetime(201201300000))
class TestCrtSG(unittest.TestCase):
def test_crtSG(self):
p = crtSG(testSignal, params={'test':30}, name='SG_TEST')
p = crtSG(testSignal, params={'test': 30}, name='SG_TEST')
self.assertEqual(p.name, "SG_TEST")
p.name = "SignalPythonTest"
self.assertEqual(p.name, "SignalPythonTest")
self.assertEqual(p.shouldBuy(Datetime(201201210000)), False)
self.assertEqual(p.shouldSell(Datetime(201201300000)), False)
k = sm['sh000001'].getKData(Query(-100))
self.assertEqual(p.should_buy(Datetime(201201210000)), False)
self.assertEqual(p.should_sell(Datetime(201201300000)), False)
k = sm['sh000001'].get_kdata(Query(-100))
self.assertEqual(k.empty(), False)
p.setTO(k)
self.assertEqual(p.shouldBuy(Datetime(201201210000)), True)
self.assertEqual(p.shouldSell(Datetime(201201300000)), True)
self.assertEqual(p.shouldBuy(Datetime(200101010000)), False)
p._addBuySignal(Datetime(200101010000))
self.assertEqual(p.shouldBuy(Datetime(200101010000)), True)
self.assertEqual(p.shouldSell(Datetime(200101030000)), False)
p._addSellSignal(Datetime(200101030000))
self.assertEqual(p.shouldSell(Datetime(200101030000)), True)
d = p.getBuySignal()
p.to = k
self.assertEqual(p.should_buy(Datetime(201201210000)), True)
self.assertEqual(p.should_sell(Datetime(201201300000)), True)
self.assertEqual(p.should_buy(Datetime(200101010000)), False)
p._add_buy_signal(Datetime(200101010000))
self.assertEqual(p.should_buy(Datetime(200101010000)), True)
self.assertEqual(p.should_sell(Datetime(200101030000)), False)
p._add_sell_signal(Datetime(200101030000))
self.assertEqual(p.should_sell(Datetime(200101030000)), True)
d = p.get_buy_signal()
for i in range(len(d)):
self.assertIn(d[i], [Datetime(201201210000), Datetime(200101010000)])
d = p.getSellSignal()
d = p.get_sell_signal()
for i in range(len(d)):
self.assertIn(d[i], [Datetime(201201300000), Datetime(200101030000)])
p_clone = p.clone()
d = p_clone.getBuySignal()
d = p_clone.get_buy_signal()
for i in range(len(d)):
self.assertIn(d[i], [Datetime(201201210000), Datetime(200101010000)])
d = p_clone.getSellSignal()
d = p_clone.get_sell_signal()
for i in range(len(d)):
self.assertIn(d[i], [Datetime(201201300000), Datetime(200101030000)])
def suite():
return unittest.TestLoader().loadTestsFromTestCase(SignalTest)
def suiteTestCrtSG():
return unittest.TestLoader().loadTestsFromTestCase(TestCrtSG)

View File

@ -10,41 +10,42 @@
import unittest
from test_init import *
from hikyuu.trade_sys.slippage import *
class SlippagePython(SlippageBase):
def __init__(self):
super(SlippagePython, self).__init__("SlippagePython")
self._x = 0
def getRealBuyPrice(self, datetime, price):
if self._x < 10:
return 0.0
return 1.0
def getRealSellPrice(self, datetime, price):
if self._x < 10:
return 0.0
return 1.0
return 1.0
def _reset(self):
self._x = 0
def _clone(self):
p = SlippagePython()
p._x = self._x
return p
def _calculate(self):
""" do nothin """
class SlippageTest(unittest.TestCase):
def test_SlippageBase(self):
p = SlippagePython()
self.assertEqual(p.name, "SlippagePython")
self.assertEqual(p.getRealBuyPrice(Datetime(200101010000), 1.0), 0.0)
self.assertEqual(p.getRealSellPrice(Datetime(200101010000), 1.0), 0.0)
self.assertEqual(p._x, 0)
p._x = 10
self.assertEqual(p._x, 10)
@ -52,7 +53,7 @@ class SlippageTest(unittest.TestCase):
self.assertEqual(p.getRealSellPrice(Datetime(200101010000), 1.0), 1.0)
p.reset()
self.assertEqual(p._x, 0)
p._x = 10
p_clone = p.clone()
self.assertEqual(p_clone._x, 10)
@ -60,26 +61,30 @@ class SlippageTest(unittest.TestCase):
self.assertEqual(p._x, 0)
self.assertEqual(p_clone._x, 10)
def test_crtSL_func(self):
pass
def test_getRealBuyPrice_func(self, datetime, price):
return 10.0 if datetime == Datetime(200101010000) else 0.0
class TestCrtSL(unittest.TestCase):
def test_crtSL(self):
p = crtSL(test_crtSL_func, params={'n':10}, name="TestSL")
p = crtSL(test_crtSL_func, params={'n': 10}, name="TestSL")
p.getRealBuyPrice = test_getRealBuyPrice_func
self.assertEqual(p.name, "TestSL")
self.assertEqual(p.getRealBuyPrice(p, Datetime(200101010000), 1.0), 10.0)
self.assertEqual(p.getRealBuyPrice(p, Datetime(200101020000), 1.0), 0.0)
p_clone = p.clone()
self.assertEqual(p_clone.name, "TestSL")
def suite():
return unittest.TestLoader().loadTestsFromTestCase(SlippageTest)
def suiteTestCrtSL():
return unittest.TestLoader().loadTestsFromTestCase(TestCrtSL)

View File

@ -20,19 +20,19 @@ class StockTest(unittest.TestCase):
self.assertEqual(stock.market_code, "SH000001")
self.assertEqual(stock.name, u"上证指数")
self.assertEqual(stock.type, 2)
self.assertEqual(stock.startDatetime, Datetime(199012190000))
self.assertEqual(stock.lastDatetime, constant.null_datetime)
self.assertEqual(stock.start_datetime, Datetime(199012190000))
self.assertEqual(stock.last_datetime, constant.null_datetime)
self.assertEqual(stock.tick, 0.001)
self.assertEqual(stock.tickValue, 0.001)
self.assertEqual(stock.tick_value, 0.001)
self.assertEqual(stock.unit, 1.0)
self.assertEqual(stock.precision, 3)
self.assertEqual(stock.atom, 1)
self.assertEqual(stock.minTradeNumber, 1)
self.assertEqual(stock.maxTradeNumber, 1000000)
self.assertEqual(stock.getCount(), 5121)
self.assertEqual(stock.getCount(Query.MIN), 682823)
self.assertEqual(stock.getKRecord(0).datetime, Datetime(199012190000))
self.assertEqual(stock.getKRecord(1, Query.MIN).datetime, Datetime(200001040932))
self.assertEqual(stock.min_trade_number, 1)
self.assertEqual(stock.max_trade_number, 1000000)
self.assertEqual(stock.get_count(), 5121)
self.assertEqual(stock.get_count(Query.MIN), 682823)
self.assertEqual(stock.get_krecord(0).datetime, Datetime(199012190000))
self.assertEqual(stock.get_krecord(1, Query.MIN).datetime, Datetime(200001040932))
s1 = sm['sh000001']
s2 = sm['sh000001']

View File

@ -14,15 +14,15 @@ from test_init import *
class StockTypeInfoTest(unittest.TestCase):
def test_stockType(self):
stockType = sm.getStockTypeInfo(1)
stockType = sm.get_stock_type_info(1)
self.assertEqual(stockType.type, 1)
self.assertEqual(stockType.description, u"A股")
self.assertEqual(stockType.tick, 0.01)
self.assertEqual(stockType.tickValue, 0.01)
self.assertEqual(stockType.tick_value, 0.01)
self.assertEqual(stockType.unit, 1.0)
self.assertEqual(stockType.precision, 2)
self.assertEqual(stockType.minTradeNumber, 100)
self.assertEqual(stockType.maxTradeNumber, 1000000)
self.assertEqual(stockType.min_trade_num, 100)
self.assertEqual(stockType.max_trade_num, 1000000)
def test_pickle(self):
if not constant.pickle_support:

View File

@ -10,45 +10,46 @@
import unittest
from test_init import *
from hikyuu.trade_sys.stoploss import *
class StoplossPython(StoplossBase):
def __init__(self):
super(StoplossPython, self).__init__()
self._x = 0
def name(self):
return "StoplossPython"
def getPrice(self, datetime, price):
if self._x < 10:
return 0.0
return 1.0
def _reset(self):
self._x = 0
def _clone(self):
p = StoplossPython()
p._x = self._x
return p
def _calculate(self):
""" do nothin """
class StoplossTest(unittest.TestCase):
def test_StoplossBase(self):
p = StoplossPython()
self.assertEqual(p.name(), "StoplossPython")
self.assertEqual(p.getPrice(Datetime(200101010000), 1.0), 0.0)
self.assertEqual(p._x, 0)
p._x = 10
self.assertEqual(p._x, 10)
self.assertEqual(p.getPrice(Datetime(200101010000), 1.0), 1.0)
p.reset()
self.assertEqual(p._x, 0)
p._x = 10
p_clone = p.clone()
self.assertEqual(p_clone._x, 10)
@ -60,22 +61,26 @@ class StoplossTest(unittest.TestCase):
def test_crtST_func(self):
pass
def test_getPrice_func(self, datetime, price):
return 10.0 if datetime == Datetime(200101010000) else 0.0
class TestCrtST(unittest.TestCase):
def test_crtST(self):
p = crtST(test_crtST_func, params={'n':10}, name="StoplossPython")
p = crtST(test_crtST_func, params={'n': 10}, name="StoplossPython")
p.getPrice = test_getPrice_func
self.assertEqual(p.name, "StoplossPython")
self.assertEqual(p.getPrice(p, Datetime(200101010000), 1.0), 10.0)
self.assertEqual(p.getPrice(p, Datetime(200101020000), 1.0), 0.0)
p_clone = p.clone()
self.assertEqual(p_clone.name, "StoplossPython")
def suite():
return unittest.TestLoader().loadTestsFromTestCase(StoplossTest)
def suiteTestCrtST():
return unittest.TestLoader().loadTestsFromTestCase(TestCrtST)

View File

@ -10,20 +10,17 @@
import unittest
from test_init import *
from hikyuu.trade_manage import *
class PythonTradeCost(TradeCostBase):
def __init__(self):
super(PythonTradeCost, self).__init__("PythonTradeCost")
def getBuyCost(self, date, stock, price, num):
return CostRecord(1.0, 1.0, 1.0, 1.0, 4.0)
def getSellCost(self, date, stock, price, num):
def get_sell_cost(self, date, stock, price, num):
return CostRecord(2.0, 2.0, 2.0, 2.0, 8.0)
def _clone(self):
return PythonTradeCost();
return PythonTradeCost()
class TradeCostTest(unittest.TestCase):
@ -31,49 +28,44 @@ class TradeCostTest(unittest.TestCase):
stock = sm['sh000001']
tc = PythonTradeCost()
self.assertEqual(tc.name, "PythonTradeCost")
cost = tc.getBuyCost(Datetime(201001010000), stock, 10.0, 100)
self.assertEqual(cost, CostRecord(1,1,1,1,4))
cost = tc.getSellCost(Datetime(201001010000), stock, 10.0, 100)
self.assertEqual(cost, CostRecord(2,2,2,2,8))
#print tc
cost = tc.get_sell_cost(Datetime(201001010000), stock, 10.0, 100)
self.assertEqual(cost, CostRecord(2, 2, 2, 2, 8))
#print tc
clone_tc = tc.clone()
self.assertEqual(clone_tc.name, "PythonTradeCost")
cost = clone_tc.getBuyCost(Datetime(201001010000), stock, 10.0, 100)
self.assertEqual(cost, CostRecord(1,1,1,1,4))
cost = clone_tc.getSellCost(Datetime(201001010000), stock, 10.0, 100)
self.assertEqual(cost, CostRecord(2,2,2,2,8))
cost = clone_tc.get_sell_cost(Datetime(201001010000), stock, 10.0, 100)
self.assertEqual(cost, CostRecord(2, 2, 2, 2, 8))
def test_ZeroTC(self):
stock = sm['sh000001']
tc = TC_Zero()
cost = tc.getBuyCost(Datetime(201001010000), stock, 10.0, 100)
self.assertEqual(cost, CostRecord(0,0,0,0,0))
cost = tc.getSellCost(Datetime(201001010000), stock, 10.0, 100)
self.assertEqual(cost, CostRecord(0,0,0,0,0))
cost = tc.get_sell_cost(Datetime(201001010000), stock, 10.0, 100)
self.assertEqual(cost, CostRecord(0, 0, 0, 0, 0))
cost = tc.get_sell_cost(Datetime(201001010000), stock, 10.0, 100)
self.assertEqual(cost, CostRecord(0, 0, 0, 0, 0))
clone_tc = tc.clone()
cost = clone_tc.getBuyCost(Datetime(201001010000), stock, 10.0, 100)
self.assertEqual(cost, CostRecord(0,0,0,0,0))
cost = clone_tc.getSellCost(Datetime(201001010000), stock, 10.0, 100)
self.assertEqual(cost, CostRecord(0,0,0,0,0))
cost = clone_tc.get_sell_cost(Datetime(201001010000), stock, 10.0, 100)
self.assertEqual(cost, CostRecord(0, 0, 0, 0, 0))
cost = clone_tc.get_sell_cost(Datetime(201001010000), stock, 10.0, 100)
self.assertEqual(cost, CostRecord(0, 0, 0, 0, 0))
def test_FixedATC(self):
stock = sm['sh000001']
tc = TC_FixedA()
cost = tc.getBuyCost(Datetime(200101010000), stock, 10.0, 2100)
cost = tc.get_sell_cost(Datetime(200101010000), stock, 10.0, 2100)
self.assertEqual(cost, CostRecord(37.8, 0, 2.1, 0, 39.9))
cost = tc.getSellCost(Datetime(200101010000), stock, 10.0, 2100)
cost = tc.get_sell_cost(Datetime(200101010000), stock, 10.0, 2100)
self.assertEqual(cost, CostRecord(37.8, 0, 2.1, 0, 39.9))
clone_tc = tc.clone()
cost = clone_tc.getBuyCost(Datetime(200101010000), stock, 10.0, 2100)
cost = clone_tc.get_sell_cost(Datetime(200101010000), stock, 10.0, 2100)
self.assertEqual(cost, CostRecord(37.8, 0, 2.1, 0, 39.9))
cost = clone_tc.getSellCost(Datetime(200101010000), stock, 10.0, 2100)
cost = clone_tc.get_sell_cost(Datetime(200101010000), stock, 10.0, 2100)
self.assertEqual(cost, CostRecord(37.8, 0, 2.1, 0, 39.9))
def suite():
return unittest.TestLoader().loadTestsFromTestCase(TradeCostTest)

View File

@ -25,21 +25,21 @@ import Signal
import Stoploss
import ProfitGoal
import Slippage
import AllocateFunds
if __name__ == "__main__":
suite = unittest.TestSuite()
suite.addTest(Datetime.suite())
suite.addTest(Parameter.suite())
suite.addTest(MarketInfo.suite())
suite.addTest(StockTypeInfo.suite())
suite.addTest(Stock.suite())
suite.addTest(KData.suite())
suite.addTest(Indicator.suite())
suite.addTest(TradeCost.suite())
suite.addTest(Environment.suite())
suite.addTest(Environment.suiteTestCrtEV())
suite.addTest(Condition.suite())
@ -54,6 +54,8 @@ if __name__ == "__main__":
suite.addTest(ProfitGoal.suiteTestCrtPG())
suite.addTest(Slippage.suite())
suite.addTest(Slippage.suiteTestCrtSL())
suite.addTest(AllocateFunds.suite())
unittest.TextTestRunner(verbosity=2).run(suite)
#unittest.main()

View File

@ -20,7 +20,7 @@ int main(int argc, char* argv[]) {
#endif
//配置文件的位置自行修改
hikyuu_init("C:\\Users\\Administrator\\.hikyuu\\hikyuu.ini");
hikyuu_init("C:\\Users\\admin\\.hikyuu\\hikyuu.ini");
StockManager& sm = StockManager::instance();
@ -42,6 +42,6 @@ int main(int argc, char* argv[]) {
#if defined(_WIN32)
SetConsoleOutputCP(old_cp);
#endif
#endif
return 0;
}

View File

@ -23,10 +23,12 @@ class HKU_API KData {
public:
KData() {}
KData(const KData&);
KData(KData&&);
KData(const Stock& stock, const KQuery& query);
virtual ~KData() {}
KData& operator=(const KData&);
KData& operator=(KData&&);
size_t size() const;
bool empty() const;
@ -149,6 +151,8 @@ KData HKU_API getKData(const string& market_code, int64_t start = 0, int64_t end
inline KData::KData(const KData& x) : m_imp(x.m_imp) {}
inline KData::KData(KData&& x) : m_imp(std::move(x.m_imp)) {}
inline KData& KData::operator=(const KData& x) {
if (this == &x)
return *this;
@ -156,6 +160,13 @@ inline KData& KData::operator=(const KData& x) {
return *this;
}
inline KData& KData::operator=(KData&& x) {
if (this == &x)
return *this;
m_imp = std::move(x.m_imp);
return *this;
}
inline DatetimeList KData::getDatetimeList() const {
DatetimeList result;
if (empty()) {

View File

@ -73,7 +73,7 @@ Stock::Data::Data()
Stock::Data::Data(const string& market, const string& code, const string& name, uint32_t type,
bool valid, const Datetime& startDate, const Datetime& lastDate, price_t tick,
price_t tickValue, int precision, size_t minTradeNumber, size_t maxTradeNumber)
price_t tickValue, int precision, double minTradeNumber, double maxTradeNumber)
: m_market(market),
m_code(code),
m_name(name),
@ -123,6 +123,8 @@ Stock::~Stock() {}
Stock::Stock(const Stock& x) : m_data(x.m_data), m_kdataDriver(x.m_kdataDriver) {}
Stock::Stock(Stock&& x) : m_data(std::move(x.m_data)), m_kdataDriver(std::move(x.m_kdataDriver)) {}
Stock& Stock::operator=(const Stock& x) {
HKU_IF_RETURN(this == &x, *this);
m_data = x.m_data;
@ -130,6 +132,13 @@ Stock& Stock::operator=(const Stock& x) {
return *this;
}
Stock& Stock::operator=(Stock&& x) {
HKU_IF_RETURN(this == &x, *this);
m_data = std::move(x.m_data);
m_kdataDriver = std::move(x.m_kdataDriver);
return *this;
}
Stock::Stock(const string& market, const string& code, const string& name) {
m_data =
shared_ptr<Data>(new Data(market, code, name, default_type, default_valid, default_startDate,
@ -206,15 +215,15 @@ int Stock::precision() const {
return m_data ? m_data->m_precision : default_precision;
}
size_t Stock::atom() const {
double Stock::atom() const {
return m_data ? m_data->m_minTradeNumber : default_minTradeNumber;
}
size_t Stock::minTradeNumber() const {
double Stock::minTradeNumber() const {
return m_data ? m_data->m_minTradeNumber : default_minTradeNumber;
}
size_t Stock::maxTradeNumber() const {
double Stock::maxTradeNumber() const {
return m_data ? m_data->m_maxTradeNumber : default_maxTradeNumber;
}

View File

@ -55,6 +55,7 @@ public:
Stock();
Stock(const Stock&);
Stock(Stock&&);
Stock(const string& market, const string& code, const string& name);
Stock(const string& market, const string& code, const string& name, uint32_t type, bool valid,
@ -64,6 +65,7 @@ public:
int precision, size_t minTradeNumber, size_t maxTradeNumber);
virtual ~Stock();
Stock& operator=(const Stock&);
Stock& operator=(Stock&&);
bool operator==(const Stock&) const;
bool operator!=(const Stock&) const;
@ -110,13 +112,13 @@ public:
int precision() const;
/** 获取最小交易数量同minTradeNumber */
size_t atom() const;
double atom() const;
/** 获取最小交易数量 */
size_t minTradeNumber() const;
double minTradeNumber() const;
/** 获取最大交易量 */
size_t maxTradeNumber() const;
double maxTradeNumber() const;
/**
* [start,end)
@ -247,8 +249,8 @@ struct HKU_API Stock::Data {
price_t m_tickValue;
price_t m_unit;
int m_precision;
size_t m_minTradeNumber;
size_t m_maxTradeNumber;
double m_minTradeNumber;
double m_maxTradeNumber;
unordered_map<string, KRecordList*> pKData;
unordered_map<string, std::shared_mutex*> pMutex;
@ -256,7 +258,7 @@ struct HKU_API Stock::Data {
Data();
Data(const string& market, const string& code, const string& name, uint32_t type, bool valid,
const Datetime& startDate, const Datetime& lastDate, price_t tick, price_t tickValue,
int precision, size_t minTradeNumber, size_t maxTradeNumber);
int precision, double minTradeNumber, double maxTradeNumber);
virtual ~Data();
};

View File

@ -32,7 +32,7 @@ public:
/**
*
* @param param pool
* @param prototype pool
* @param maxConnect 0
* @param maxIdleConnect 0 CPU数
*/

View File

@ -26,10 +26,10 @@ void hikyuu_init(const string& config_file_name, bool ignore_preload,
config.read(config_file_name);
} catch (std::invalid_argument& e) {
HKU_FATAL("Reading configure error!\n{}", e.what());
HKU_FATAL("Reading configure error! {}", e.what());
exit(1);
} catch (std::logic_error& e) {
HKU_FATAL("Reading configure error!\n{}", e.what());
HKU_FATAL("Reading configure error! {}", e.what());
exit(1);
} catch (...) {
HKU_WARN("Reading configure error! Don't know error!");

View File

@ -27,6 +27,7 @@ namespace hku {
* @param config_file_name
* @param ignore_preload
* hikyuu
* @param context
*/
void HKU_API hikyuu_init(const string& config_file_name, bool ignore_preload = false,
const StrategyContext& context = StrategyContext({"all"}));

View File

@ -19,6 +19,8 @@ Indicator::Indicator(const IndicatorImpPtr& imp) : m_imp(imp) {}
Indicator::Indicator(const Indicator& indicator) : m_imp(indicator.m_imp) {}
Indicator::Indicator(Indicator&& ind) : m_imp(std::move(ind.m_imp)) {}
Indicator::~Indicator() {}
string Indicator::formula() const {
@ -51,6 +53,12 @@ Indicator& Indicator::operator=(const Indicator& indicator) {
return *this;
}
Indicator& Indicator::operator=(Indicator&& indicator) {
HKU_IF_RETURN(this == &indicator, *this);
m_imp = std::move(indicator.m_imp);
return *this;
}
PriceList Indicator::getResultAsPriceList(size_t num) const {
HKU_WARN_IF_RETURN(!m_imp, PriceList(), "indicator imptr is null!");
return m_imp->getResultAsPriceList(num);

View File

@ -43,10 +43,12 @@ class HKU_API Indicator {
public:
Indicator() {}
Indicator(const IndicatorImpPtr& imp);
Indicator(const Indicator&);
Indicator(const Indicator& ind);
Indicator(Indicator&& ind);
virtual ~Indicator();
Indicator& operator=(const Indicator&);
Indicator& operator=(Indicator&&);
/** 使用已有参数计算新值返回全新的Indicator */
Indicator operator()(const Indicator& ind);

View File

@ -103,7 +103,7 @@ IndParam IndicatorImp::getIndParam(const string &name) const {
return IndParam(m_ind_params.at(name));
}
const IndicatorImpPtr IndicatorImp::getIndParamImp(const string &name) const {
const IndicatorImpPtr &IndicatorImp::getIndParamImp(const string &name) const {
return m_ind_params.at(name);
}
@ -1255,7 +1255,7 @@ void IndicatorImp::_dyn_calculate(const Indicator &ind) {
const auto &ind_param = getIndParamImp("n");
HKU_CHECK(ind_param->size() == ind.size(), "ind_param->size()={}, ind.size()={}!",
ind_param->size(), ind.size());
m_discard = ind.discard();
m_discard = std::max(ind.discard(), ind_param->discard());
size_t total = ind.size();
HKU_IF_RETURN(0 == total || m_discard >= total, void());
@ -1267,7 +1267,7 @@ void IndicatorImp::_dyn_calculate(const Indicator &ind) {
size_t step = size_t(ind_param->get(i));
_dyn_run_one_step(ind, i, step);
}
_after_dyn_calculate(ind);
_update_discard();
return;
}
@ -1302,7 +1302,23 @@ void IndicatorImp::_dyn_calculate(const Indicator &ind) {
task.get();
}
_after_dyn_calculate(ind);
_update_discard();
}
void IndicatorImp::_update_discard() {
size_t total = size();
for (size_t result_index = 0; result_index < m_result_num; result_index++) {
size_t discard = m_discard;
for (size_t i = m_discard; i < total; i++) {
if (!std::isnan(get(i, result_index))) {
break;
}
discard++;
}
if (discard > m_discard) {
m_discard = discard;
}
}
}
} /* namespace hku */

View File

@ -157,7 +157,7 @@ public:
void setIndParam(const string& name, const Indicator& ind);
void setIndParam(const string& name, const IndParam& ind);
IndParam getIndParam(const string& name) const;
const IndicatorImpPtr getIndParamImp(const string& name) const;
const IndicatorImpPtr& getIndParamImp(const string& name) const;
const unordered_map<string, IndicatorImpPtr>& getIndParams() const;
price_t* data(size_t result_num = 0);
@ -173,9 +173,6 @@ public:
virtual void _dyn_run_one_step(const Indicator& ind, size_t curPos, size_t step) {}
/** 动态指标参数计算完毕后处理,主要用于修正 m_discard */
virtual void _after_dyn_calculate(const Indicator& ind) {}
/** 是否支持指标动态参数 */
virtual bool supportIndParam() const {
return false;
@ -194,6 +191,8 @@ public:
return false;
}
virtual void _dyn_calculate(const Indicator&);
private:
void initContext();
bool needCalculate();
@ -212,11 +211,13 @@ private:
void execute_or();
void execute_weave();
void execute_if();
void _dyn_calculate(const Indicator&);
protected:
static size_t _get_step_start(size_t pos, size_t step, size_t discard);
// 用于动态参数时,更新 discard
void _update_discard();
protected:
string m_name;
size_t m_discard;
@ -346,7 +347,7 @@ public: \
return make_shared<classname>(); \
}
#define INDICATOR_IMP_SUPPORT_IND_PARAM(classname) \
#define INDICATOR_IMP_SUPPORT_DYNAMIC_STEP(classname) \
public: \
virtual bool check() override; \
virtual void _calculate(const Indicator& ind) override; \

View File

@ -76,6 +76,7 @@
#include "crt/ROUNDUP.h"
#include "crt/SAFTYLOSS.h"
#include "crt/SIN.h"
#include "crt/SLICE.h"
#include "crt/SGN.h"
#include "crt/SMA.h"
#include "crt/SQRT.h"

View File

@ -21,6 +21,14 @@ namespace hku {
* @ingroup Indicator 2result(0)AMAresult(1)ER
*/
Indicator HKU_API AMA(int n = 10, int fast_n = 2, int slow_n = 30);
Indicator HKU_API AMA(int n, int fast_n, const IndParam& slow_n);
Indicator HKU_API AMA(int n, const IndParam& fast_n, int slow_n = 30);
Indicator HKU_API AMA(int n, const IndParam& fast_n, const IndParam& slow_n);
Indicator HKU_API AMA(const IndParam& n, int fast_n = 2, int slow_n = 30);
Indicator HKU_API AMA(const IndParam& n, int fast_n, const IndParam& slow_n);
Indicator HKU_API AMA(const IndParam& n, const IndParam& fast_n, int slow_n = 30);
Indicator HKU_API AMA(const IndParam& n, const IndParam& fast_n, const IndParam& slow_n);
/**
* .J Perry J.Kaufman2006 广
@ -30,7 +38,75 @@ Indicator HKU_API AMA(int n = 10, int fast_n = 2, int slow_n = 30);
* @param slow_n EMA线的N值3060
* @ingroup Indicator
*/
Indicator HKU_API AMA(const Indicator& indicator, int n = 10, int fast_n = 2, int slow_n = 30);
inline Indicator HKU_API AMA(const Indicator& ind, int n = 10, int fast_n = 2, int slow_n = 30) {
return AMA(n, fast_n, slow_n)(ind);
}
inline Indicator HKU_API AMA(const Indicator& ind, int n, const IndParam& fast_n, int slow_n = 30) {
return AMA(n, fast_n, slow_n)(ind);
}
inline Indicator HKU_API AMA(const Indicator& ind, int n, int fast_n, const IndParam& slow_n) {
return AMA(n, fast_n, slow_n)(ind);
}
inline Indicator HKU_API AMA(const Indicator& ind, int n, const IndParam& fast_n,
const IndParam& slow_n) {
return AMA(n, fast_n, slow_n)(ind);
}
inline Indicator HKU_API AMA(const Indicator& ind, const IndParam& n, int fast_n = 2,
int slow_n = 30) {
return AMA(n, fast_n, slow_n)(ind);
}
inline Indicator HKU_API AMA(const Indicator& ind, const IndParam& n, const IndParam& fast_n,
int slow_n = 30) {
return AMA(n, fast_n, slow_n)(ind);
}
inline Indicator HKU_API AMA(const Indicator& ind, const IndParam& n, int fast_n,
const IndParam& slow_n) {
return AMA(n, fast_n, slow_n)(ind);
}
inline Indicator HKU_API AMA(const Indicator& ind, const IndParam& n, const IndParam& fast_n,
const IndParam& slow_n) {
return AMA(n, fast_n, slow_n)(ind);
}
inline Indicator HKU_API AMA(const Indicator& ind, int n, const Indicator& fast_n, int slow_n) {
return AMA(n, IndParam(fast_n), slow_n)(ind);
}
inline Indicator HKU_API AMA(const Indicator& ind, int n, int fast_n, const Indicator& slow_n) {
return AMA(n, fast_n, IndParam(slow_n))(ind);
}
inline Indicator HKU_API AMA(const Indicator& ind, int n, const Indicator& fast_n,
const Indicator& slow_n) {
return AMA(n, IndParam(fast_n), IndParam(slow_n))(ind);
}
inline Indicator HKU_API AMA(const Indicator& ind, const Indicator& n, int fast_n = 2,
int slow_n = 30) {
return AMA(IndParam(n), fast_n, slow_n)(ind);
}
inline Indicator HKU_API AMA(const Indicator& ind, const Indicator& n, const Indicator& fast_n,
int slow_n = 30) {
return AMA(IndParam(n), IndParam(fast_n), slow_n)(ind);
}
inline Indicator HKU_API AMA(const Indicator& ind, const Indicator& n, int fast_n,
const Indicator& slow_n) {
return AMA(IndParam(n), fast_n, IndParam(slow_n))(ind);
}
inline Indicator HKU_API AMA(const Indicator& ind, const Indicator& n, const Indicator& fast_n,
const Indicator& slow_n) {
return AMA(IndParam(n), IndParam(fast_n), IndParam(slow_n))(ind);
}
} // namespace hku

View File

@ -19,6 +19,7 @@ namespace hku {
* @ingroup Indicator
*/
Indicator HKU_API ATR(int n = 14);
Indicator HKU_API ATR(const IndParam& n);
/**
* (Average True Range)
@ -26,7 +27,17 @@ Indicator HKU_API ATR(int n = 14);
* @param n 1
* @ingroup Indicator
*/
Indicator HKU_API ATR(const Indicator& data, int n = 14);
inline Indicator HKU_API ATR(const Indicator& data, int n = 14) {
return ATR(n)(data);
}
inline Indicator HKU_API ATR(const Indicator& data, const IndParam& n) {
return ATR(n)(data);
}
inline Indicator HKU_API ATR(const Indicator& data, const Indicator& n) {
return ATR(IndParam(n))(data);
}
} // namespace hku

View File

@ -19,6 +19,7 @@ namespace hku {
* @ingroup Indicator
*/
Indicator HKU_API EMA(int n = 22);
Indicator HKU_API EMA(const IndParam& n);
/**
* 线(Exponential Moving Average)
@ -26,7 +27,17 @@ Indicator HKU_API EMA(int n = 22);
* @param n 0
* @ingroup Indicator
*/
Indicator HKU_API EMA(const Indicator& data, int n = 22);
inline Indicator HKU_API EMA(const Indicator& data, int n = 22) {
return EMA(n)(data);
}
inline Indicator HKU_API EMA(const Indicator& data, const IndParam& n) {
return EMA(n)(data);
}
inline Indicator HKU_API EMA(const Indicator& data, const Indicator& n) {
return EMA(IndParam(n))(data);
}
} // namespace hku

View File

@ -13,6 +13,9 @@
#include "EVERY.h"
#include "REF.h"
#include "MAX.h"
#include "MIN.h"
#include "CVAL.h"
namespace hku {
@ -26,10 +29,7 @@ namespace hku {
* </pre>
* @ingroup Indicator
*/
Indicator LAST(int m = 10, int n = 5);
Indicator LAST(const Indicator& ind, int m = 10, int n = 5);
inline Indicator LAST(int m, int n) {
inline Indicator LAST(int m = 10, int n = 5) {
int max = std::max(m, n);
int min = std::min(m, n);
Indicator result = REF(EVERY(max - min + 1), min);
@ -37,10 +37,64 @@ inline Indicator LAST(int m, int n) {
return result;
}
inline Indicator LAST(const Indicator& ind, int m, int n) {
inline Indicator LAST(const IndParam& m, int n = 5) {
Indicator ind_m = m.get();
Indicator ind_n = CVAL(ind_m, 5);
Indicator max = MAX(ind_m, ind_n);
Indicator min = MIN(ind_m, ind_n);
Indicator result = REF(EVERY(max - min + 1), min);
result.name("LAST");
return result;
}
inline Indicator LAST(int m, const IndParam& n) {
Indicator ind_n = n.get();
Indicator ind_m = CVAL(ind_n, 5);
Indicator max = MAX(ind_m, ind_n);
Indicator min = MIN(ind_m, ind_n);
Indicator result = REF(EVERY(max - min + 1), min);
result.name("LAST");
return result;
}
inline Indicator LAST(const IndParam& m, const IndParam& n) {
Indicator ind_m = m.get();
Indicator ind_n = n.get();
Indicator max = MAX(ind_m, ind_n);
Indicator min = MIN(ind_m, ind_n);
Indicator result = REF(EVERY(max - min + 1), min);
result.name("LAST");
return result;
}
inline Indicator LAST(const Indicator& ind, int m = 10, int n = 5) {
return LAST(m, n)(ind);
}
inline Indicator LAST(const Indicator& ind, const IndParam& m, int n = 5) {
return LAST(m, n)(ind);
}
inline Indicator LAST(const Indicator& ind, int m, const IndParam& n) {
return LAST(m, n)(ind);
}
inline Indicator LAST(const Indicator& ind, const IndParam& m, const IndParam& n) {
return LAST(m, n)(ind);
}
inline Indicator LAST(const Indicator& ind, const Indicator& m, int n = 5) {
return LAST(IndParam(m), n)(ind);
}
inline Indicator LAST(const Indicator& ind, int m, const Indicator& n) {
return LAST(m, IndParam(n))(ind);
}
inline Indicator LAST(const Indicator& ind, const Indicator& m, const Indicator& n) {
return LAST(IndParam(m), IndParam(n))(ind);
}
} // namespace hku
#endif /* INDICATOR_CRT_LAST_H_ */

View File

@ -26,26 +26,40 @@ namespace hku {
* </pre>
* @ingroup Indicator
*/
Indicator LONGCROSS(const Indicator& x, const Indicator& y, int n = 3);
Indicator LONGCROSS(const Indicator& x, price_t, int n = 3);
Indicator LONGCROSS(price_t, const Indicator& y, int n = 3);
Indicator LONGCROSS(price_t, price_t, int n = 3);
inline Indicator LONGCROSS(const Indicator& x, const Indicator& y, int n) {
inline Indicator LONGCROSS(const Indicator& x, const Indicator& y, int n = 3) {
Indicator result = EVERY((REF(x, 1) < REF(y, 1)), n) & (x > y);
result.name("LONGCROSS");
return result;
}
inline Indicator LONGCROSS(const Indicator& x, price_t y, int n) {
inline Indicator LONGCROSS(const Indicator& x, const Indicator& y, const Indicator& n) {
Indicator result = EVERY((REF(x, 1) < REF(y, 1)), n) & (x > y);
result.name("LONGCROSS");
return result;
}
inline Indicator LONGCROSS(const Indicator& x, price_t y, int n = 3) {
return LONGCROSS(x, CVAL(x, y), n);
}
inline Indicator LONGCROSS(price_t x, const Indicator& y, int n) {
inline Indicator LONGCROSS(const Indicator& x, price_t y, const Indicator& n) {
return LONGCROSS(x, CVAL(x, y), n);
}
inline Indicator LONGCROSS(price_t x, const Indicator& y, int n = 3) {
return LONGCROSS(CVAL(y, x), y, n);
}
inline Indicator LONGCROSS(price_t x, price_t y, int n) {
inline Indicator LONGCROSS(price_t x, const Indicator& y, const Indicator& n) {
return LONGCROSS(CVAL(y, x), y, n);
}
inline Indicator LONGCROSS(price_t x, price_t y, int n = 3) {
return LONGCROSS(CVAL(x), CVAL(y), n);
}
inline Indicator LONGCROSS(price_t x, price_t y, const Indicator& n) {
return LONGCROSS(CVAL(x), CVAL(y), n);
}

View File

@ -15,13 +15,18 @@ namespace hku {
/**
*
* @param data
* @param n n为0时从第一个有效数据开始计算
* @ingroup Indicator
*/
Indicator HKU_API MA(int n = 22);
Indicator HKU_API MA(const IndParam& n);
/**
*
* @param ind
* @param n n为0时从第一个有效数据开始计算
* @ingroup Indicator
*/
inline Indicator HKU_API MA(const Indicator& ind, int n = 22) {
return MA(n)(ind);
}

View File

@ -27,6 +27,7 @@ namespace hku {
* @ingroup Indicator
*/
Indicator HKU_API MACD(int n1 = 12, int n2 = 26, int n3 = 9);
Indicator HKU_API MACD(const IndParam& n1, const IndParam& n2, const IndParam& n3);
/**
* MACD平滑异同移动平均线
@ -42,7 +43,19 @@ Indicator HKU_API MACD(int n1 = 12, int n2 = 26, int n3 = 9);
* </pre>
* @ingroup Indicator
*/
Indicator HKU_API MACD(const Indicator& data, int n1 = 12, int n2 = 26, int n3 = 9);
inline Indicator MACD(const Indicator& data, int n1 = 12, int n2 = 26, int n3 = 9) {
return MACD(n1, n2, n3)(data);
}
inline Indicator MACD(const Indicator& data, const IndParam& n1, const IndParam& n2,
const IndParam& n3) {
return MACD(n1, n2, n3)(data);
}
inline Indicator MACD(const Indicator& data, const Indicator& n1, const Indicator& n2,
const Indicator& n3) {
return MACD(IndParam(n1), IndParam(n2), IndParam(n3))(data);
}
} // namespace hku

View File

@ -22,10 +22,6 @@ namespace hku {
* </pre>
* @ingroup Indicator
*/
Indicator MAX(const Indicator&, const Indicator&);
Indicator MAX(const Indicator&, price_t val);
Indicator MAX(price_t val, const Indicator& ind);
inline Indicator MAX(const Indicator& ind1, const Indicator& ind2) {
Indicator result = IF(ind1 > ind2, ind1, ind2);
result.name("MAX");

View File

@ -22,10 +22,6 @@ namespace hku {
* </pre>
* @ingroup Indicator
*/
Indicator MIN(const Indicator&, const Indicator&);
Indicator MIN(const Indicator&, price_t val);
Indicator MIN(price_t val, const Indicator& ind);
inline Indicator MIN(const Indicator& ind1, const Indicator& ind2) {
Indicator result = IF(ind1 < ind2, ind1, ind2);
result.name("MIN");

View File

@ -21,6 +21,7 @@ namespace hku {
* @ingroup Indicator
*/
Indicator HKU_API REF(int n);
Indicator HKU_API REF(const IndParam& n);
/**
* REF
@ -30,7 +31,17 @@ Indicator HKU_API REF(int n);
* @param n n周期前的值n位
* @ingroup Indicator
*/
Indicator HKU_API REF(const Indicator& ind, int n);
inline Indicator HKU_API REF(const Indicator& ind, int n) {
return REF(n)(ind);
}
inline Indicator HKU_API REF(const Indicator& ind, const IndParam& n) {
return REF(n)(ind);
}
inline Indicator HKU_API REF(const Indicator& ind, const Indicator& n) {
return REF(IndParam(n))(ind);
}
} /* namespace hku */

View File

@ -20,12 +20,20 @@ namespace hku {
* @ingroup Indicator
*/
Indicator HKU_API ROCR100(int n = 10);
Indicator ROCR100(const Indicator& ind, int n = 10);
Indicator HKU_API ROCR100(const IndParam& n);
inline Indicator ROCR100(const Indicator& ind, int n) {
inline Indicator ROCR100(const Indicator& ind, int n = 10) {
return ROCR100(n)(ind);
}
inline Indicator ROCR100(const Indicator& ind, const IndParam& n) {
return ROCR100(n)(ind);
}
inline Indicator ROCR100(const Indicator& ind, const Indicator& n) {
return ROCR100(IndParam(n))(ind);
}
} // namespace hku
#endif /* INDICATOR_CRT_ROCR100_H_ */

View File

@ -24,13 +24,14 @@ namespace hku {
* N日3
* </pre>
* @note
* @param data
* @param n1 10
* @param n2 线n2日内的最高值3
* @param p 2
* @ingroup Indicator
*/
Indicator HKU_API SAFTYLOSS(const Indicator& data, int n1 = 10, int n2 = 3, double p = 2.0);
Indicator HKU_API SAFTYLOSS(int n1 = 10, int n2 = 3, double p = 2.0);
Indicator HKU_API SAFTYLOSS(const IndParam& n1, const IndParam& n2, double p = 2.0);
Indicator HKU_API SAFTYLOSS(const IndParam& n1, const IndParam& n2, const IndParam& p);
/**
*
@ -43,12 +44,35 @@ Indicator HKU_API SAFTYLOSS(const Indicator& data, int n1 = 10, int n2 = 3, doub
* N日3
* </pre>
* @note
* @param data
* @param n1 10
* @param n2 线n2日内的最高值3
* @param p 2
* @ingroup Indicator
*/
Indicator HKU_API SAFTYLOSS(int n1 = 10, int n2 = 3, double p = 2.0);
inline Indicator SAFTYLOSS(const Indicator& data, int n1 = 10, int n2 = 3, double p = 2.0) {
return SAFTYLOSS(n1, n2, p)(data);
}
inline Indicator SAFTYLOSS(const Indicator& data, const IndParam& n1, const IndParam& n2,
double p = 2.0) {
return SAFTYLOSS(n1, n2, p)(data);
}
inline Indicator SAFTYLOSS(const Indicator& data, const IndParam& n1, const IndParam& n2,
const IndParam& p) {
return SAFTYLOSS(n1, n2, p)(data);
}
inline Indicator SAFTYLOSS(const Indicator& data, const Indicator& n1, const Indicator& n2,
double p = 2.0) {
return SAFTYLOSS(IndParam(n1), IndParam(n2), p)(data);
}
inline Indicator SAFTYLOSS(const Indicator& data, const Indicator& n1, const Indicator& n2,
const Indicator& p) {
return SAFTYLOSS(IndParam(n1), IndParam(n2), IndParam(p))(data);
}
} // namespace hku

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2019 hikyuu.org
*
* Created on: 2022-02-27
* Author: fasiondog
*/
#pragma once
#include "../Indicator.h"
namespace hku {
/**
* PriceList [start, end)
* @param data
* @param start
* @param end
* @ingroup Indicator
*/
Indicator HKU_API SLICE(const PriceList& data, int64_t start, int64_t end);
/**
*
* @param start
* @param end
* @param result_index
* @ingroup Indicator
*/
Indicator HKU_API SLICE(int64_t start, int64_t end, int result_index = 0);
/**
*
* @param ind
* @param start
* @param end
* @param result_index
* @ingroup Indicator
*/
inline Indicator SLICE(const Indicator& ind, int64_t start, int64_t end, int result_index = 0) {
return SLICE(start, end, result_index)(ind);
}
} // namespace hku

View File

@ -13,6 +13,21 @@
namespace hku {
/**
*
* @details
* <pre>
* Y=SMA(X,N,M) Y=[M*X+(N-M)*Y')/N,Y'Y值
* </pre>
* @param n 0
* @param m
* @ingroup Indicator
*/
Indicator HKU_API SMA(int n = 22, double m = 2.0);
Indicator HKU_API SMA(int, const IndParam& m);
Indicator HKU_API SMA(const IndParam& n, double m = 2.0);
Indicator HKU_API SMA(const IndParam& n, const IndParam& m);
/**
*
* @details
@ -24,13 +39,34 @@ namespace hku {
* @param m
* @ingroup Indicator
*/
Indicator SMA(const Indicator& data, int n = 22, double m = 2.0);
Indicator HKU_API SMA(int n = 22, double m = 2.0);
inline Indicator SMA(const Indicator& ind, int n, double m) {
inline Indicator SMA(const Indicator& ind, int n = 22, double m = 2.0) {
return SMA(n, m)(ind);
}
inline Indicator SMA(const Indicator& ind, int n, const IndParam& m) {
return SMA(n, m)(ind);
}
inline Indicator SMA(const Indicator& ind, const IndParam& n, double m = 2.0) {
return SMA(n, m)(ind);
}
inline Indicator SMA(const Indicator& ind, const IndParam& n, const IndParam& m) {
return SMA(n, m)(ind);
}
inline Indicator SMA(const Indicator& ind, int n, const Indicator& m) {
return SMA(n, IndParam(m))(ind);
}
inline Indicator SMA(const Indicator& ind, const Indicator& n, double m = 2.0) {
return SMA(IndParam(n), m)(ind);
}
inline Indicator SMA(const Indicator& ind, const Indicator& n, const Indicator& m) {
return SMA(IndParam(n), IndParam(m))(ind);
}
} // namespace hku
#endif /* INDICATOR_CRT_SMA_H_ */

View File

@ -19,6 +19,7 @@ namespace hku {
* @ingroup Indicator
*/
Indicator HKU_API STDEV(int n = 10);
Indicator HKU_API STDEV(const IndParam& n);
/**
* N周期内样本标准差
@ -26,7 +27,17 @@ Indicator HKU_API STDEV(int n = 10);
* @param n N日时间窗口
* @ingroup Indicator
*/
Indicator HKU_API STDEV(const Indicator& data, int n = 10);
inline Indicator HKU_API STDEV(const Indicator& data, int n = 10) {
return STDEV(n)(data);
}
inline Indicator HKU_API STDEV(const Indicator& data, const IndParam& n) {
return STDEV(n)(data);
}
inline Indicator HKU_API STDEV(const Indicator& data, const Indicator& n) {
return STDEV(IndParam(n))(data);
}
} // namespace hku

View File

@ -19,12 +19,20 @@ namespace hku {
* @ingroup Indicator
*/
Indicator HKU_API STDP(int n = 10);
Indicator STDP(const Indicator& data, int n = 10);
Indicator HKU_API STDP(const IndParam& n);
inline Indicator STDP(const Indicator& data, int n) {
inline Indicator STDP(const Indicator& data, int n = 10) {
return STDP(n)(data);
}
inline Indicator STDP(const Indicator& data, const IndParam& n) {
return STDP(n)(data);
}
inline Indicator STDP(const Indicator& data, const Indicator& n) {
return STDP(IndParam(n))(data);
}
} // namespace hku
#endif /* INDICATOR_CRT_STDP_H_ */

View File

@ -19,6 +19,7 @@ namespace hku {
* @ingroup Indicator
*/
Indicator HKU_API SUM(int n = 20);
Indicator HKU_API SUM(const IndParam& n);
/**
* SUM(X,N),N周期中X的总和,N=0
@ -26,12 +27,18 @@ Indicator HKU_API SUM(int n = 20);
* @param n N日时间窗口
* @ingroup Indicator
*/
Indicator SUM(const Indicator& ind, int n = 20);
inline Indicator SUM(const Indicator& ind, int n) {
inline Indicator SUM(const Indicator& ind, int n = 20) {
return SUM(n)(ind);
}
inline Indicator SUM(const Indicator& ind, const IndParam& n) {
return SUM(n)(ind);
}
inline Indicator SUM(const Indicator& ind, const Indicator& n) {
return SUM(IndParam(n))(ind);
}
} // namespace hku
#endif /* INDICATOR_CRT_SUM_H_ */

View File

@ -25,12 +25,20 @@ namespace hku {
* @ingroup Indicator
*/
Indicator HKU_API SUMBARS(double a);
Indicator SUMBARS(const Indicator& ind, double a);
Indicator HKU_API SUMBARS(const IndParam& a);
inline Indicator SUMBARS(const Indicator& ind, double a) {
return SUMBARS(a)(ind);
}
inline Indicator SUMBARS(const Indicator& ind, const IndParam& a) {
return SUMBARS(a)(ind);
}
inline Indicator SUMBARS(const Indicator& ind, const Indicator& a) {
return SUMBARS(IndParam(a))(ind);
}
} // namespace hku
#endif /* INDICATOR_CRT_SUMBARS_H_ */

View File

@ -20,9 +20,19 @@ namespace hku {
* , UPNDAY(CLOSE,M)M个周期
* @ingroup Indicator
*/
Indicator UPNDAY(const Indicator& ind, int n = 3);
inline Indicator UPNDAY(const Indicator& ind, int n = 3) {
Indicator result = EVERY(ind > REF(ind, 1), n);
result.name("UPDAY");
return result;
}
inline Indicator UPNDAY(const Indicator& ind, int n) {
inline Indicator UPNDAY(const Indicator& ind, const IndParam& n) {
Indicator result = EVERY(ind > REF(ind, 1), n);
result.name("UPDAY");
return result;
}
inline Indicator UPNDAY(const Indicator& ind, const Indicator& n) {
Indicator result = EVERY(ind > REF(ind, 1), n);
result.name("UPDAY");
return result;

View File

@ -21,12 +21,20 @@ namespace hku {
* @ingroup Indicator
*/
Indicator HKU_API VAR(int n = 10);
Indicator VAR(const Indicator& data, int n = 10);
Indicator HKU_API VAR(const IndParam& n);
inline Indicator VAR(const Indicator& data, int n) {
inline Indicator VAR(const Indicator& data, int n = 10) {
return VAR(n)(data);
}
inline Indicator VAR(const Indicator& data, const IndParam& n) {
return VAR(n)(data);
}
inline Indicator VAR(const Indicator& data, const Indicator& n) {
return VAR(IndParam(n))(data);
}
} // namespace hku
#endif /* INDICATOR_CRT_VAR_H_ */

View File

@ -21,12 +21,20 @@ namespace hku {
* @ingroup Indicator
*/
Indicator HKU_API VARP(int n = 10);
Indicator VARP(const Indicator& data, int n = 10);
Indicator HKU_API VARP(const IndParam& n);
inline Indicator VARP(const Indicator& data, int n) {
inline Indicator VARP(const Indicator& data, int n = 10) {
return VARP(n)(data);
}
inline Indicator VARP(const Indicator& data, const IndParam& n) {
return VARP(n)(data);
}
inline Indicator VARP(const Indicator& data, const Indicator& n) {
return VARP(IndParam(n))(data);
}
} // namespace hku
#endif /* INDICATOR_CRT_VARP_H_ */

View File

@ -6,6 +6,9 @@
*/
#include <cmath>
#include "../crt/AMA.h"
#include "../crt/CVAL.h"
#include "../crt/SLICE.h"
#include "IAma.h"
#if HKU_SUPPORT_SERIALIZATION
@ -76,6 +79,91 @@ void IAma::_calculate(const Indicator& data) {
}
}
void IAma::_dyn_one_circle(const Indicator& ind, size_t curPos, int n, int fast_n, int slow_n) {
if (n < 1) {
n = 1;
}
if (fast_n < 0) {
fast_n = 0;
}
if (slow_n < 0) {
slow_n = 0;
}
Indicator slice = SLICE(ind, 0, curPos + 1);
Indicator ama = AMA(slice, n, fast_n, slow_n);
if (ama.size() > 0) {
size_t index = ama.size() - 1;
_set(ama.get(index, 0), curPos, 0);
_set(ama.get(index, 1), curPos, 1);
}
}
void IAma::_dyn_calculate(const Indicator& ind) {
auto iter = m_ind_params.find("fast_n");
Indicator fast_n =
iter != m_ind_params.end() ? Indicator(iter->second) : CVAL(ind, getParam<int>("fast_n"));
iter = m_ind_params.find("slow_n");
Indicator slow_n =
iter != m_ind_params.end() ? Indicator(iter->second) : CVAL(ind, getParam<int>("slow_n"));
iter = m_ind_params.find("n");
Indicator n =
iter != m_ind_params.end() ? Indicator(iter->second) : CVAL(ind, getParam<int>("n"));
HKU_CHECK(fast_n.size() == ind.size(), "ind_param(fast_n).size()={}, ind.size()={}!",
fast_n.size(), ind.size());
HKU_CHECK(slow_n.size() == ind.size(), "ind_param(slow_n).size()={}, ind.size()={}!",
slow_n.size(), ind.size());
m_discard = std::max(ind.discard(), fast_n.discard());
m_discard = std::max(m_discard, slow_n.discard());
m_discard = std::max(m_discard, n.discard());
size_t total = ind.size();
HKU_IF_RETURN(0 == total || m_discard >= total, void());
static const size_t minCircleLength = 400;
size_t workerNum = ms_tg->worker_num();
if (total < minCircleLength || workerNum == 1) {
for (size_t i = ind.discard(); i < total; i++) {
_dyn_one_circle(ind, i, n[i], fast_n[i], slow_n[i]);
}
_update_discard();
return;
}
size_t circleLength = minCircleLength;
if (minCircleLength * workerNum >= total) {
circleLength = minCircleLength;
} else {
size_t tailCount = total % workerNum;
circleLength = tailCount == 0 ? total / workerNum : total / workerNum + 1;
}
std::vector<std::future<void>> tasks;
for (size_t group = 0; group < workerNum; group++) {
size_t first = circleLength * group;
if (first >= total) {
break;
}
tasks.push_back(ms_tg->submit([=, &ind, &n, &fast_n, &slow_n]() {
size_t endPos = first + circleLength;
if (endPos > total) {
endPos = total;
}
for (size_t i = circleLength * group; i < endPos; i++) {
_dyn_one_circle(ind, i, n[i], fast_n[i], slow_n[i]);
}
}));
}
for (auto& task : tasks) {
task.get();
}
_update_discard();
}
Indicator HKU_API AMA(int n, int fast_n, int slow_n) {
IndicatorImpPtr p = make_shared<IAma>();
p->setParam<int>("n", n);
@ -84,8 +172,60 @@ Indicator HKU_API AMA(int n, int fast_n, int slow_n) {
return Indicator(p);
}
Indicator HKU_API AMA(const Indicator& ind, int n, int fast_n, int slow_n) {
return AMA(n, fast_n, slow_n)(ind);
Indicator HKU_API AMA(int n, const IndParam& fast_n, int slow_n) {
IndicatorImpPtr p = make_shared<IAma>();
p->setParam<int>("n", n);
p->setIndParam("fast_n", fast_n);
p->setParam<int>("slow_n", slow_n);
return Indicator(p);
}
Indicator HKU_API AMA(int n, const IndParam& fast_n, const IndParam& slow_n) {
IndicatorImpPtr p = make_shared<IAma>();
p->setParam<int>("n", n);
p->setIndParam("fast_n", fast_n);
p->setIndParam("slow_n", slow_n);
return Indicator(p);
}
Indicator HKU_API AMA(int n, int fast_n, const IndParam& slow_n) {
IndicatorImpPtr p = make_shared<IAma>();
p->setParam<int>("n", n);
p->setParam<int>("fast_n", fast_n);
p->setIndParam("slow_n", slow_n);
return Indicator(p);
}
Indicator HKU_API AMA(const IndParam& n, int fast_n, int slow_n) {
IndicatorImpPtr p = make_shared<IAma>();
p->setIndParam("n", n);
p->setParam<int>("fast_n", fast_n);
p->setParam<int>("slow_n", slow_n);
return Indicator(p);
}
Indicator HKU_API AMA(const IndParam& n, const IndParam& fast_n, int slow_n) {
IndicatorImpPtr p = make_shared<IAma>();
p->setIndParam("n", n);
p->setIndParam("fast_n", fast_n);
p->setParam<int>("slow_n", slow_n);
return Indicator(p);
}
Indicator HKU_API AMA(const IndParam& n, int fast_n, const IndParam& slow_n) {
IndicatorImpPtr p = make_shared<IAma>();
p->setIndParam("n", n);
p->setParam<int>("fast_n", fast_n);
p->setIndParam("slow_n", slow_n);
return Indicator(p);
}
Indicator HKU_API AMA(const IndParam& n, const IndParam& fast_n, const IndParam& slow_n) {
IndicatorImpPtr p = make_shared<IAma>();
p->setIndParam("n", n);
p->setIndParam("fast_n", fast_n);
p->setIndParam("slow_n", slow_n);
return Indicator(p);
}
} /* namespace hku */

View File

@ -26,6 +26,11 @@ class IAma : public IndicatorImp {
public:
IAma();
virtual ~IAma();
virtual void _dyn_calculate(const Indicator&) override;
private:
void _dyn_one_circle(const Indicator& ind, size_t curPos, int n, int fast_n, int slow_n);
};
} /* namespace hku */

View File

@ -5,6 +5,8 @@
* Author: Administrator
*/
#include "../crt/ATR.h"
#include "../crt/SLICE.h"
#include "IAtr.h"
#if HKU_SUPPORT_SERIALIZATION
@ -43,14 +45,25 @@ void IAtr::_calculate(const Indicator& indicator) {
}
}
void IAtr::_dyn_run_one_step(const Indicator& ind, size_t curPos, size_t step) {
HKU_IF_RETURN(step < 1, void());
Indicator slice = SLICE(ind, 0, curPos + 1);
Indicator atr = ATR(slice, step);
if (atr.size() > 0) {
_set(atr[atr.size() - 1], curPos);
}
}
Indicator HKU_API ATR(int n) {
IndicatorImpPtr p = make_shared<IAtr>();
p->setParam<int>("n", n);
return Indicator(p);
}
Indicator HKU_API ATR(const Indicator& data, int n) {
return ATR(n)(data);
Indicator HKU_API ATR(const IndParam& n) {
IndicatorImpPtr p = make_shared<IAtr>();
p->setIndParam("n", n);
return Indicator(p);
}
} /* namespace hku */

View File

@ -14,7 +14,7 @@
namespace hku {
class IAtr : public IndicatorImp {
INDICATOR_IMP(IAtr)
INDICATOR_IMP_SUPPORT_DYNAMIC_STEP(IAtr)
INDICATOR_IMP_NO_PRIVATE_MEMBER_SERIALIZATION
public:

View File

@ -16,7 +16,7 @@
namespace hku {
class IBackset : public IndicatorImp {
INDICATOR_IMP_SUPPORT_IND_PARAM(IBackset)
INDICATOR_IMP_SUPPORT_DYNAMIC_STEP(IBackset)
INDICATOR_IMP_NO_PRIVATE_MEMBER_SERIALIZATION
public:

View File

@ -97,22 +97,6 @@ void ICount::_dyn_run_one_step(const Indicator& ind, size_t curPos, size_t step)
_set(count, curPos);
}
void ICount::_after_dyn_calculate(const Indicator& ind) {
size_t total = ind.size();
HKU_IF_RETURN(m_discard == total, void());
size_t discard = m_discard;
for (size_t i = total - 1; i > discard; i--) {
if (std::isnan(get(i))) {
m_discard = i + 1;
break;
}
}
if (m_discard == discard && std::isnan(get(discard))) {
m_discard = discard + 1;
}
}
Indicator HKU_API COUNT(int n) {
IndicatorImpPtr p = make_shared<ICount>();
p->setParam<int>("n", n);

View File

@ -19,14 +19,12 @@ namespace hku {
* COUNT(CLOSE>OPEN,20)20
*/
class ICount : public IndicatorImp {
INDICATOR_IMP_SUPPORT_IND_PARAM(ICount)
INDICATOR_IMP_SUPPORT_DYNAMIC_STEP(ICount)
INDICATOR_IMP_NO_PRIVATE_MEMBER_SERIALIZATION
public:
ICount();
virtual ~ICount();
virtual void _after_dyn_calculate(const Indicator& ind) override;
};
} /* namespace hku */

View File

@ -16,7 +16,7 @@
namespace hku {
class IDevsq : public hku::IndicatorImp {
INDICATOR_IMP_SUPPORT_IND_PARAM(IDevsq)
INDICATOR_IMP_SUPPORT_DYNAMIC_STEP(IDevsq)
INDICATOR_IMP_NO_PRIVATE_MEMBER_SERIALIZATION
public:

View File

@ -5,6 +5,8 @@
* Author: fasiondog
*/
#include "../crt/SLICE.h"
#include "../crt/EMA.h"
#include "IEma.h"
#if HKU_SUPPORT_SERIALIZATION
@ -43,14 +45,24 @@ void IEma::_calculate(const Indicator& indicator) {
}
}
void IEma::_dyn_run_one_step(const Indicator& ind, size_t curPos, size_t step) {
Indicator slice = SLICE(ind, 0, curPos + 1);
Indicator ema = EMA(slice, step);
if (ema.size() > 0) {
_set(ema[ema.size() - 1], curPos);
}
}
Indicator HKU_API EMA(int n) {
IndicatorImpPtr p = make_shared<IEma>();
p->setParam<int>("n", n);
return Indicator(p);
}
Indicator HKU_API EMA(const Indicator& data, int n) {
return EMA(n)(data);
Indicator HKU_API EMA(const IndParam& n) {
IndicatorImpPtr p = make_shared<IEma>();
p->setIndParam("n", n);
return Indicator(p);
}
} /* namespace hku */

View File

@ -17,7 +17,7 @@ namespace hku {
* = 0
*/
class IEma : public IndicatorImp {
INDICATOR_IMP(IEma)
INDICATOR_IMP_SUPPORT_DYNAMIC_STEP(IEma)
INDICATOR_IMP_NO_PRIVATE_MEMBER_SERIALIZATION
public:

View File

@ -107,22 +107,6 @@ void IEvery::_dyn_run_one_step(const Indicator& ind, size_t curPos, size_t step)
_set(every, curPos);
}
void IEvery::_after_dyn_calculate(const Indicator& ind) {
size_t total = ind.size();
HKU_IF_RETURN(m_discard == total, void());
size_t discard = m_discard;
for (size_t i = total - 1; i > discard; i--) {
if (std::isnan(get(i))) {
m_discard = i + 1;
break;
}
}
if (m_discard == discard && std::isnan(get(discard))) {
m_discard = discard + 1;
}
}
Indicator HKU_API EVERY(int n) {
IndicatorImpPtr p = make_shared<IEvery>();
p->setParam<int>("n", n);

View File

@ -19,14 +19,12 @@ namespace hku {
* , EVERY (X,N) X在N周期一直存在
*/
class IEvery : public IndicatorImp {
INDICATOR_IMP_SUPPORT_IND_PARAM(IEvery)
INDICATOR_IMP_SUPPORT_DYNAMIC_STEP(IEvery)
INDICATOR_IMP_NO_PRIVATE_MEMBER_SERIALIZATION
public:
IEvery();
virtual ~IEvery();
virtual void _after_dyn_calculate(const Indicator& ind) override;
};
} /* namespace hku */

View File

@ -107,22 +107,6 @@ void IExist::_dyn_run_one_step(const Indicator& ind, size_t curPos, size_t step)
_set(exist, curPos);
}
void IExist::_after_dyn_calculate(const Indicator& ind) {
size_t total = ind.size();
HKU_IF_RETURN(m_discard == total, void());
size_t discard = m_discard;
for (size_t i = total - 1; i > discard; i--) {
if (std::isnan(get(i))) {
m_discard = i + 1;
break;
}
}
if (m_discard == discard && std::isnan(get(discard))) {
m_discard = discard + 1;
}
}
Indicator HKU_API EXIST(int n) {
IndicatorImpPtr p = make_shared<IExist>();
p->setParam<int>("n", n);

View File

@ -19,14 +19,12 @@ namespace hku {
* , EXIST(X,N) X在N周期有存在
*/
class IExist : public IndicatorImp {
INDICATOR_IMP_SUPPORT_IND_PARAM(IExist)
INDICATOR_IMP_SUPPORT_DYNAMIC_STEP(IExist)
INDICATOR_IMP_NO_PRIVATE_MEMBER_SERIALIZATION
public:
IExist();
virtual ~IExist();
virtual void _after_dyn_calculate(const Indicator& ind) override;
};
} /* namespace hku */

View File

@ -16,7 +16,7 @@
namespace hku {
class IFilter : public IndicatorImp {
INDICATOR_IMP_SUPPORT_IND_PARAM(IFilter)
INDICATOR_IMP_SUPPORT_DYNAMIC_STEP(IFilter)
INDICATOR_IMP_NO_PRIVATE_MEMBER_SERIALIZATION
public:

View File

@ -16,7 +16,7 @@
namespace hku {
class IHhvbars : public IndicatorImp {
INDICATOR_IMP_SUPPORT_IND_PARAM(IHhvbars)
INDICATOR_IMP_SUPPORT_DYNAMIC_STEP(IHhvbars)
INDICATOR_IMP_NO_PRIVATE_MEMBER_SERIALIZATION
public:

View File

@ -20,7 +20,7 @@ namespace hku {
* n: N日时间窗口
*/
class IHighLine : public IndicatorImp {
INDICATOR_IMP_SUPPORT_IND_PARAM(IHighLine)
INDICATOR_IMP_SUPPORT_DYNAMIC_STEP(IHighLine)
INDICATOR_IMP_NO_PRIVATE_MEMBER_SERIALIZATION
public:

View File

@ -16,7 +16,7 @@
namespace hku {
class ILowLine : public IndicatorImp {
INDICATOR_IMP_SUPPORT_IND_PARAM(ILowLine)
INDICATOR_IMP_SUPPORT_DYNAMIC_STEP(ILowLine)
INDICATOR_IMP_NO_PRIVATE_MEMBER_SERIALIZATION
public:

View File

@ -16,7 +16,7 @@
namespace hku {
class ILowLineBars : public IndicatorImp {
INDICATOR_IMP_SUPPORT_IND_PARAM(ILowLineBars)
INDICATOR_IMP_SUPPORT_DYNAMIC_STEP(ILowLineBars)
INDICATOR_IMP_NO_PRIVATE_MEMBER_SERIALIZATION
public:

View File

@ -32,7 +32,7 @@ void IMa::_calculate(const Indicator& indicator) {
}
int n = getParam<int>("n");
if (0 == n) {
if (n <= 0) {
price_t sum = 0.0;
for (size_t i = m_discard; i < total; i++) {
sum += indicator[i];

View File

@ -14,7 +14,7 @@
namespace hku {
class IMa : public IndicatorImp {
INDICATOR_IMP_SUPPORT_IND_PARAM(IMa)
INDICATOR_IMP_SUPPORT_DYNAMIC_STEP(IMa)
INDICATOR_IMP_NO_PRIVATE_MEMBER_SERIALIZATION
public:

View File

@ -7,6 +7,9 @@
#include "IMacd.h"
#include "../crt/EMA.h"
#include "../crt/MACD.h"
#include "../crt/SLICE.h"
#include "../crt/CVAL.h"
#if HKU_SUPPORT_SERIALIZATION
BOOST_CLASS_EXPORT(hku::IMacd)
@ -66,6 +69,84 @@ void IMacd::_calculate(const Indicator& data) {
}
}
void IMacd::_dyn_one_circle(const Indicator& ind, size_t curPos, int n1, int n2, int n3) {
HKU_IF_RETURN(n1 <= 0 || n2 <= 0 || n3 <= 0, void());
Indicator slice = SLICE(ind, 0, curPos + 1);
Indicator macd = MACD(slice, n1, n2, n3);
if (macd.size() > 0) {
size_t index = macd.size() - 1;
_set(macd.get(index, 0), curPos, 0);
_set(macd.get(index, 1), curPos, 1);
_set(macd.get(index, 2), curPos, 2);
}
}
void IMacd::_dyn_calculate(const Indicator& ind) {
auto iter = m_ind_params.find("n1");
Indicator n1 =
iter != m_ind_params.end() ? Indicator(iter->second) : CVAL(ind, getParam<int>("n1"));
iter = m_ind_params.find("n2");
Indicator n2 =
iter != m_ind_params.end() ? Indicator(iter->second) : CVAL(ind, getParam<int>("n2"));
iter = m_ind_params.find("n3");
Indicator n3 =
iter != m_ind_params.end() ? Indicator(iter->second) : CVAL(ind, getParam<int>("n3"));
HKU_CHECK(n1.size() == ind.size(), "ind_param(n2).size()={}, ind.size()={}!", n2.size(),
ind.size());
HKU_CHECK(n2.size() == ind.size(), "ind_param(n2).size()={}, ind.size()={}!", n2.size(),
ind.size());
HKU_CHECK(n3.size() == ind.size(), "ind_param(n3).size()={}, ind.size()={}!", n3.size(),
ind.size());
m_discard = std::max(ind.discard(), n2.discard());
m_discard = std::max(m_discard, n3.discard());
m_discard = std::max(m_discard, n1.discard());
size_t total = ind.size();
HKU_IF_RETURN(0 == total || m_discard >= total, void());
static const size_t minCircleLength = 400;
size_t workerNum = ms_tg->worker_num();
if (total < minCircleLength || workerNum == 1) {
for (size_t i = ind.discard(); i < total; i++) {
_dyn_one_circle(ind, i, n1[i], n2[i], n3[i]);
}
_update_discard();
return;
}
size_t circleLength = minCircleLength;
if (minCircleLength * workerNum >= total) {
circleLength = minCircleLength;
} else {
size_t tailCount = total % workerNum;
circleLength = tailCount == 0 ? total / workerNum : total / workerNum + 1;
}
std::vector<std::future<void>> tasks;
for (size_t group = 0; group < workerNum; group++) {
size_t first = circleLength * group;
if (first >= total) {
break;
}
tasks.push_back(ms_tg->submit([=, &ind, &n1, &n2, &n3]() {
size_t endPos = first + circleLength;
if (endPos > total) {
endPos = total;
}
for (size_t i = circleLength * group; i < endPos; i++) {
_dyn_one_circle(ind, i, n1[i], n2[i], n3[i]);
}
}));
}
for (auto& task : tasks) {
task.get();
}
_update_discard();
}
Indicator HKU_API MACD(int n1, int n2, int n3) {
IndicatorImpPtr p = make_shared<IMacd>();
p->setParam<int>("n1", n1);
@ -74,8 +155,12 @@ Indicator HKU_API MACD(int n1, int n2, int n3) {
return Indicator(p);
}
Indicator HKU_API MACD(const Indicator& data, int n1, int n2, int n3) {
return MACD(n1, n2, n3)(data);
Indicator HKU_API MACD(const IndParam& n1, const IndParam& n2, const IndParam& n3) {
IndicatorImpPtr p = make_shared<IMacd>();
p->setIndParam("n1", n1);
p->setIndParam("n2", n2);
p->setIndParam("n3", n3);
return Indicator(p);
}
} /* namespace hku */

View File

@ -29,6 +29,11 @@ class IMacd : public IndicatorImp {
public:
IMacd();
virtual ~IMacd();
virtual void _dyn_calculate(const Indicator&) override;
private:
void _dyn_one_circle(const Indicator& ind, size_t curPos, int n1, int n2, int n3);
};
} /* namespace hku */

View File

@ -19,7 +19,7 @@ namespace hku {
*
*/
class IPow : public IndicatorImp {
INDICATOR_IMP_SUPPORT_IND_PARAM(IPow)
INDICATOR_IMP_SUPPORT_DYNAMIC_STEP(IPow)
INDICATOR_IMP_NO_PRIVATE_MEMBER_SERIALIZATION
public:

View File

@ -37,14 +37,22 @@ void IRef::_calculate(const Indicator& data) {
}
}
void IRef::_dyn_run_one_step(const Indicator& ind, size_t curPos, size_t step) {
if (curPos >= step) {
_set(ind[curPos - step], curPos);
}
}
Indicator HKU_API REF(int n) {
IndicatorImpPtr p = make_shared<IRef>();
p->setParam<int>("n", n);
return Indicator(p);
}
Indicator HKU_API REF(const Indicator& ind, int n) {
return REF(n)(ind);
Indicator HKU_API REF(const IndParam& n) {
IndicatorImpPtr p = make_shared<IRef>();
p->setIndParam("n", n);
return Indicator(p);
}
} /* namespace hku */

View File

@ -20,7 +20,7 @@ namespace hku {
*  REF(CLOSE1) 线
*/
class IRef : public IndicatorImp {
INDICATOR_IMP(IRef)
INDICATOR_IMP_SUPPORT_DYNAMIC_STEP(IRef)
INDICATOR_IMP_NO_PRIVATE_MEMBER_SERIALIZATION
public:

Some files were not shown because too many files have changed in this diff Show More