hikyuu入门
目录
交互式工具示
获取股票对象
获取并绘制K线数据
计算并绘制技术指标
绘制组合图形
TradeManager应用
系统策略演示
序列化说明
获取实时日线数据
**************交互式工具示例************
1、引入交互式工具
%matplotlib inline
%time from hikyuu.interactive import *
#use_draw_engine('echarts') #use_draw_engine('matplotlib') #默认为'matplotlib'绘图
2、创建交易系统并运行
#创建模拟交易账户进行回测,初始资金30万
my_tm = crtTM(init_cash = 300000)
#创建信号指示器(以5日EMA为快线,5日EMA自身的10日EMA最为慢线,快线向上穿越慢线时买入,反之卖出)
my_sg = SG_Flex(EMA(n=5), slow_n=10)
#固定每次买入1000股
my_mm = MM_FixedCount(1000)
#创建交易系统并运行
sys = SYS_Simple(tm = my_tm, sg = my_sg, mm = my_mm)
sys.run(sm['sz000001'], Query(-150))
3、绘制曲线观察
#绘制系统信号
sys.plot()
k = sm['sz000001'].get_kdata(Query(-150))
c = CLOSE(k)
fast = EMA(c, 5)
slow = EMA(fast, 10)
4、绘制资金收益曲线
#绘制信号指示器使用两个指标
fast.plot(new=False)
slow.plot(new=False)
5、回测统计报告
#回测统计
from datetime import datetime
per = Performance()
print(per.report(my_tm, Datetime(datetime.today())))
6、关于性能
下面这段的代码使用之前的系统示例,遍历指定板块的所有股票,计算他们的“盈利交易比例%”(即胜率)。
def test_func(stock, query): """计算指定stock的系统策略胜率,系统策略为之前的简单双均线交叉系统(每次固定买入100股) """ #创建模拟交易账户进行回测,初始资金30万 my_tm = crtTM(init_cash = 1000000) #创建信号指示器(以5日EMA为快线,5日EMA自身的10日EMA最为慢线,快线向上穿越慢线时买入,反之卖出) my_sg = SG_Flex(EMA(n=5), slow_n=10) #固定每次买入1000股 my_mm = MM_FixedCount(100) #创建交易系统并运行 sys = SYS_Simple(tm = my_tm, sg = my_sg, mm = my_mm) sys.run(stock, query) per = Performance() per.statistics(my_tm, Datetime(datetime.today())) return per["赢利交易比例%".encode('gb2312')] def total_func(blk, query): """遍历指定板块的所有的股票,计算系统胜率""" result = {} for s in blk: if s.valid and s.type != constant.STOCKTYPE_INDEX: result[s.name] = test_func(s, query) return result
%time a = total_func(sm, Query(-500))
len(a)
****************获取股票对象**************
%matplotlib inline %time from hikyuu.interactive import *
1 全局获取股票对象
通过全局管理对象 sm,或使用函数 get_stock。股票标识格式“市场标识+股票代码”,市场标识:沪市sh,深市sz。
#s = getStock('sh000001')
s = sm['sh000001']
print(s)
i = 0
#遍历所有股票
for s in sm:
i += 1
#print(s)
print("全部数量:", i)
len(sm)
2 通过板块(Block)遍历股票对象
2.1 通过 sm.get_stock("板块分类", "板块名称") 获取相应板块
blk = sm.get_block("指数板块", "上证380")
for s in blk:
if not s.valid:
print(s)
2.1 获取自定义板块
自定义板块的板块分类固定为 “self”
blk = sm.get_block("self", "1")
for s in blk:
print(s)
2.2 板块信息的配置
板块信息在数据存放路径中 “block” 子目录下,目前采用的是钱龙的格式,你也可从钱龙相应的目录下拷贝最新的板块配置信息。
![]()
3 查看权息信息
ws = sm['sz000001'].get_weight()
for w in ws:
print(w)
**************获取并绘制k线数据*************
%matplotlib inline
%time from hikyuu.interactive import *
#use_draw_engine('echarts') #use_draw_engine('matplotlib') #默认为'matplotlib'绘图
查询并绘制上证指数最后100个交易日的K线数据
s = sm['sh600703']
k = s.get_kdata(Query(-100))
k.plot()
K线数据可以象list一样遍历和查看具体值
s = sm['sh000001'] k = s.get_kdata(Query(-100)) print(k)
#查看最后5个交易日的K线值
k[-5:]
#遍历查询最大收盘价 max_close = 0 for v in k: if v.close > max_close: max_close = v.close print(max_close)
K线数据(KData)其实是有KRecord组成的数组,KRecord的属性如下:
print("日期 - ", k[0].datetime)
print("开盘价 - ", k[0].open)
print("最高价 - ", k[0].high)
print("最低价 - ", k[0].low)
print("收盘价 - ", k[0].close)
print("成交金额 - ", k[0].amount)
print("成交量 - ", k[0].volume)
Query详解
获取Stock的K线数据,需要指定查询条件,可按索引和日期两种方式查询。
构建按索引方式查询条件:Query(start=0, end=None , kType=Query.DAY, recoverType=Query.NO_RECOVER)
构建按日期方式查询条件:QueryByDate(start=None, end=None, kType=Query.DAY, recoverType=Query.NO_RECOVER)
其中,索引遵循Python的惯用方式,即以0位起始,以[start, end)的方式查询,支持负数表示倒叙; 按日期查询同样遵循[start, end)惯例。
kType: 为K线数据类型(日线、分钟线、周线等):
- Query.DAY 日线
- Query.WEEK 周线
- Query.MONTH 月线
- Query.QUARTER 季线
- Query.HALFYEAR 半年线
- Query.YEAR 年线
- Query.MIN 1分钟线
- Query.MIN5 5分钟线
- Query.MIN15 15分钟线
- Query.MIN30 30分钟线
- Query.MIN60 60分钟线
recoverType:为复权类型(不复权、前向复权、后向复权、等比前向复权、等比后向复权),仅支持日线复权:
- Query.NO_RECOVER 不复权
- Query.FORWARD 前向复权
- Query.BACKWARD 后向复权
- Query.EQUAL_FORWARD 等比前向复权
- Query.EQUAL_BACKWARD 等比后向复权
1 按索引方式查询K线数据
#查询股票前100个交易日的K线数据
k = s.get_kdata(Query(0, 100))
#查询股票最后100个交易日K线数据
k = s.get_kdata(Query(-100))
#查询股票第199个交易日到第209个交易日的K线数据
k = s.get_kdata(Query(200, 210))
#查询股票倒数第100个交易日至倒数第10个交易日的K线数据
k = s.get_kdata(Query(-100, -10))
2 按日期方式查询K线数据
按日期查询同样遵循 [start, end) 惯例。
日期类型为Hikyuu库中定义的 Datetime,其记录的是“年月日时分”。可使用Python的datetime类型、日期字符串或数字表示法进行构建:
- Datetime(datetime.date(2017,1,1)) - 从Python的datetime构建
- Datetime('2017-1-1 9:35') - 通过日期字符串构建
- Datetime(201701010935) - 通过数字进行构建,数字格式须如“yyyymmddhhmm”(4位年份2位月份2位小时数2位分钟数)
3 查询复权日线
s = sm['sz000603'] #查询股票最后100个交易日K线数据,不复权 k = s.get_kdata(Query(-100)) k.plot()
#查询股票最后100个交易日K线数据,后向复权
k = s.get_kdata(Query(-100, recover_type=Query.BACKWARD))
k.plot()
**************计算并绘制技术指标***************
%matplotlib inline %time from hikyuu.interactive import *
1 绘制指标
s = sm['sz000001']
k = s.get_kdata(Query(-200))
#抽取K线收盘价指标,一般指标计算参数只能是指标类型,所以必须先将K线数据生成指标类型
c = CLOSE(k)
#计算收盘价的EMA指标
a = EMA(c)
#绘制指标
c.plot(legend_on=True)
a.plot(new=False, legend_on=True)
#绘制柱状图
a.bar()
#修正下柱状图,使其更美观
PRICELIST([x-9 for x in a]).bar()
2 指标(Indicator)
在 Hikyuu 中,Indicator 的实例是用于计算的主要数据结构,一般 ind(如无说明,ind代表Indicator的实例)计算的参数为另一个ind,如EMA(x),x应是一个Indicator的实例。可以简单的理解为类似 numpy.array。
2.1 特殊的Indicator
其中存在一类特殊的Indicator,用于将K线数据或普通数组转换为ind,才能供其他ind进行计算,如 KDATA 将 KData 转化为一个ind。其他包括: OPEN,HIGH,LOW,CLOSE,AMO(成交金额),VOL(成交量),KDATA_PART。
print("k is a instance of KData:\n", k)
print("--------------------------\n")
kind = KDATA(k)
print("kind is a instance of Indicator:\n", kind)
#获取 ind 的结果集数量,如MACD通常返回3个结果集 r = kind.get_result_num() print("result_num: ", r) #获取第一个结果集 x = kind.get_result(0) print(x)
#以下效果相同
c1 = CLOSE(k)
c2 = KDATA_PART(k, 'close')
另外一个常用的特殊指标 PRICELIST将 Python 中的类 list 对象包装成ind。
x = PRICELIST([i for i in range(100)])
print(len(x), x)
2.2 Indicator的特性与参数
每一个指标函数,如EMA、HHV,调用后生成一个ind对象,该对象本身可以再次调用生成新的ind。无论指标函数还是 ind 对象调用生成 ind,都是立刻进行计算。
e1 = EMA(CLOSE(k), n=5)
e2 = e1(CLOSE(k))
e3 = e2
print(e1 == e2)
除在指标函数中指定参数外,可以通过 getParam、setParam 方法来获取和修改 ind 对象的参数。修改参数后,ind 本身并不会发生变化,需要调用生成新的 ind,新的 ind 才是使用新参数计算的结果。
e = EMA(c)
print(e)
print(e.get_param('n'))
e.plot(legend_on=True)
e.set_param('n', 30)
e = e(c)
e.plot(new=False, legend_on=True)
查看 ind 参数。ind 参数支持:
- i : int
- s : str
- b : bool
- d : float
#EMA指标有参数 "n",类型"i"代表整数
print(EMA())
2.3 TA-Lib包装指标
在交互工具里对TA-Lib进行了包装,命名方式统一为 TA_FUNC名称。其中,ta-lib指标的lookback属性,用discard属性代替。
x = TA_SMA(CLOSE(k))
print(x)
x.plot()
print(x.discard)
个别的Ta-Lib函数需要两个数组参数,比如BETA、CORREL。此时需要利用特殊的 Indicator WEAVE 将两个数组包装到一个 ind 对象中。
query = Query(-200) k1 = sm['sh000001'].get_kdata(query) k2 = sm['sz000001'].get_kdata(query) w = WEAVE(CLOSE(k1), CLOSE(k2)) print(w.get_result_num()) cr = TA_CORREL(w) cr.plot()
***************绘制组合图形***********
%matplotlib inline
%time from hikyuu.interactive import *
绘制组合窗口
使用 create_figure 函数快速创建查看证券K线信息的常见组合窗口
help(create_figure)
s = sm['sh000001']
k = s.get_kdata(Query(-200))
#创建两个显示坐标轴的窗口
ax1,ax2 = create_figure(2)
#在第一个坐标轴中绘制K线和EMA
k.plot(axes=ax1)
ma = EMA(CLOSE(k))
ma.plot(axes=ax1, legend_on=True)
#在第二个坐标轴中绘制艾尔德力度指标
v = VIGOR(k)
v.plot(axes=ax2, legend_on=True)
绘制MACD
绘制MACD:
- ax_draw_macd
- ax_draw_macd2
ax1,ax2, ax3 = create_figure(3)
k.plot(axes=ax1)
ma.plot(axes=ax1, legend_on=True)
ax_draw_macd(axes=ax2, kdata=k)
ax_draw_macd2(axes=ax3, ref=ma, kdata=k)
内建的三个较复杂示例
- el.draw 绘制亚历山大.艾尔德交易系统图形
- kf.draw 绘制佩里.J.考夫曼(Perry J.Kaufman) 自适应移动平均系统(AMA)
- kf.draw2 绘制佩里.J.考夫曼(Perry J.Kaufman) 自适应移动平均系统(AMA)
- vl.draw 绘制普通K线图 + 成交量(成交金额)
- vl.draw2 绘制普通K线图 + 成交量(成交金额)+ MACD
el.draw(s)
vl.draw(s)
vl.draw2(s)
kf.draw(s)
kf.draw2(blocka)
*************TradeManager应用*************
%matplotlib inline %time from hikyuu.interactive import *
1 利用 TM 实现简单的记账本
radeManager对象可以理解为一个模拟的交易账户,负责交易的买/卖操作、记录交易记录以及持仓情况,也可以通过修改其买/卖操作的接口实现实盘接入。创建一个模拟交易账户,通常使用快捷创建函数 crtTM。TM对象的基本操作:
- buy 买入
- sell 卖出
- checkin 存入现金
- checkout 取出现金
可以利用 TM 实现简单的记账本,手工记录自己的操作情况,例如:
#创建一个初始资金10万元,起始日期2017年1月1日的模拟账户
my_tm = crtTM(init_cash=100000, date=Datetime(201701010000))
#2017年1月3日以9.11的价格买入100股 td = my_tm.buy(Datetime(201701030000), sm['sz000001'], 9.11, 100) #查看当前资金及持仓情况 print(my_tm)
#转化为pandas的DataFrame显示当前持仓情况
position = my_tm.get_position_list()
position.to_df()
2 利用 Excel 查看交易详情
使用 tocsv 方法将 TM 的交易记录、当前持仓及已平仓详细情况分别保存为 csv 文件,以便用 Excel 查看详情。
tocsv方法参数为一个指定的目录,目录必须以存在。其输出会在指定目录中,生成三个文件,“TM名称_交易记录.csv”、“TM名称_未平仓记录.csv”、“TM名称_已平仓记录.csv”。TM名称可在crtTM创建TM对象时指定,默认为“SYS”,如下图所示。
#在 hikyuu_XXX.ini 文件中配置的临时路径中输出 my_tm.tocsv(sm.tmpdir())
3 使用序列化保存或重新载入已有TM对象
#保存至指定文件
from datetime import date
filename = "{}/my_trade/my_trade_record_{}.xml".format(sm.tmpdir(), date.today());
hku_save(my_tm, filename)
*************系统策略演示**********
%matplotlib inline
%time from hikyuu.interactive import *
from pylab import plot
示例:通道突破系统
当价格突破20日高点时买入,当价格低于10日低点时卖出。
#创建一个从2001年1月1日开始的账户,初始资金20万元
my_tm = crtTM(Datetime(200101010000), 200000)
my_sys = SYS_Simple(tm=my_tm)
def TurtleSG(self):
n1 = self.get_param("n1")
n2 = self.get_param("n2")
k = self.to
c = CLOSE(k)
h = REF(HHV(c, n1), 1) #前n日高点
L = REF(LLV(c, n2), 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)
my_sg = crtSG(TurtleSG, {'n1': 20, 'n2': 10}, 'TurtleSG') my_mm = MM_FixedCount(1000) s = sm['sz000001'] query = Query(Datetime(200101010000), Datetime(201705010000)) my_sys.mm = my_mm my_sys.sg = my_sg my_sys.run(s, query)
calendar = sm.get_trading_calendar(query, 'SZ')
calendar
x1 = my_tm.get_funds_curve(calendar, Query.DAY)
PRICELIST(x1).plot()
my_sys.mm = MM_FixedPercent(0.03)
my_sys.run(s, query)
x2 = my_tm.get_funds_curve(calendar, Query.DAY)
PRICELIST(x2).plot()
my_sys.mm = MM_FixedRisk(1000)
my_sys.run(s, query)
x3 = my_tm.get_funds_curve(calendar, Query.DAY)
PRICELIST(x3).plot()
my_sys.mm = MM_FixedCapital(1000)
my_sys.run(s, query)
x4 = my_tm.get_funds_curve(calendar, Query.DAY)
PRICELIST(x4).plot()
ax = create_figure(1)
def x_plot(x, name, ax):
px = PRICELIST(x)
px.name = name
px.plot(axes=ax, legend_on=True)
x_plot(x1, 'MM_FixedCount', ax)
x_plot(x2, 'MM_FixedPercent', ax)
x_plot(x3, 'MM_FixedRisk', ax)
x_plot(x3, 'MM_FixedCapital', ax)
************序列化说明**************
%matplotlib inline
%time from hikyuu.interactive import *
k = get_kdata('sh000001', -100)
import pickle
with open("temp", 'wb') as f:
pickle.dump(k, f)
hku_save(k, "temp")
k2 = KData()
hku_load(k2, "temp")
k2.plot()
**********获取实时日线数据*********
%matplotlib inline
%time from hikyuu.interactive import *
获取实时日线数据
目前仅支持获取实时日线数据,使用函数 realtimeUpdate(source, delta=60)。其中,source支持 'sina' | 'qq' | 'tushare',默认使用 tushare。
tushare 需安装 Python tushare 库,pip install tushare.
使用 sina 或 qq 时,应注意控制两次获取数据之间的间隔时长(使用参数delta,默认时长60s),以免 ip 被 sina 或 qq 列入黑名单。
%time realtime_update('sina')