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')


posted @ 2021-02-04 14:08  KnowledgePorter  阅读(425)  评论(0)    收藏  举报