# author:
# datetime:2020/12/7 15:56
"""
文件说明:"""
#数据包
import tushareas ts
# 数据处理包
import numpyas np
# dataframe表格数据处理
import pandasas pd
# 计算各种金融数据技术分析指标
import talibas ta
# 绘图包
from pyecharts.chartsimport Kline, Bar, Line, EffectScatter, Page, Grid
from pyechartsimport optionsas opts
from pyecharts.commons.utilsimport JsCode
# 内置主题类型可查看pyecharts.globals.ThemeType
from pyecharts.globalsimport ThemeType,SymbolType
# 接口秘钥
token= ''
# 对api接口进行验证
pro= ts.pro_api(token)
# 指数代码
index= {
'上证综指': '000001.SH',
'深证成指': '399001.SZ',
'沪深300': '000300.SH',
'创业板指': '399006.SZ',
'上证50': '000016.SH',
'中证500': '000905.SH',
'中小板指': '399005.SZ',
'上证180': '000010.SH'
}
# 定义信息函数
def get_stock_info():
stockInfos= pro.stock_basic(exchange='',list_status='L')
codes= stockInfos.ts_code.values
names= stockInfos.name.values
stock= dict(zip(names, codes))
return stock
# 获取原始日线行情数据
def get_daily(stock_name,startdate,enddate):
code= get_stock_info()[stock_name]
if codein index:
hisdata= pro.index_daily(ts_code=code,start_date=startdate,end_date=enddate)
else:
hisdata= pro.daily(ts_code=code,start_date=startdate,end_date=enddate)
# 对数据进行处理,设置日期为索引
hisdata.index= pd.to_datetime(hisdata.trade_date)
# 排序
hisdata= hisdata.sort_index()
return hisdata
# 对数据进行处理,N1个交易日的最高点,N2个交易日的最低点,一般N1>N2
def my_strategy(data,N1,N2):
# 获取前20日最高数据
data['up']= ta.MAX(data.high,timeperiod=N1).shift(1)
# 获取前20日最低数据
data['down']= ta.MIN(data.low,timeperiod=N2).shift(1)
# 当当天的【close】> 昨天的【最近N1个交易日的最高点】时,将【收盘发出的信号】设定为1
buy_index= data[data['close']> data['up'].shift(1)].index
data.loc[buy_index,'buy']= 1
# 当当天的【close】< 昨天的【最近N2个交易日的最低点】时,将【收盘发出的信号】设定为0
sell_index= data[data['close']< data['down'].shift(1)].index
data.loc[sell_index,'buy']= 0
# ==========计算每年指数的收益以及海龟交易法则的收益
data['turtle']= data['change']* data['CW']
# year_rtn = data.set_index('trade_date')[['change', 'turtle']].resample('A', how=lambda x: (x + 1.0).prod() - 1.0) * 100
return data
# 画K线图
def draw_k(Kname,X,Y):
kline= (
Kline()
.add_xaxis(X)
.add_yaxis(
Kname,# 标题名称
Y,
itemstyle_opts=opts.ItemStyleOpts(
color="#ec0000",
color0="#00da3c",
border_color="#FF0000",# 阳线颜色
border_color0="#32CD32",# 阴线颜色
),
)
.set_global_opts(
xaxis_opts=opts.AxisOpts(is_scale=True),
yaxis_opts=opts.AxisOpts(
is_scale=True,
splitarea_opts=opts.SplitAreaOpts(
is_show=True,areastyle_opts=opts.AreaStyleOpts(opacity=1)
),
),
# 数据缩放滑动,grid添加几个图,进行几条设置
datazoom_opts=[
opts.DataZoomOpts(
is_show=False,type_="inside",xaxis_index=[0,0],range_end=100
),
opts.DataZoomOpts(
is_show=True,xaxis_index=[0,1],pos_top="97%",range_end=100
),
# opts.DataZoomOpts(is_show=False, xaxis_index=[0, 2], range_end=100),
],
# datazoom_opts=[opts.DataZoomOpts(type_="slider")],
title_opts=opts.TitleOpts(title="左上角标题"),
)
)
return kline
# 画柱状图
def draw_bar(Bname,X,Y):
bar= (
Bar()
.add_xaxis(X)
.add_yaxis(Bname,Y,label_opts=opts.LabelOpts(is_show=False),yaxis_index=1,xaxis_index=1,
# 改进后在 grid 中 add_js_funcs 后变成如下
itemstyle_opts=opts.ItemStyleOpts(
color=JsCode(
"""
function(params) {
var colorList;
if (barData[params.dataIndex][1] > barData[params.dataIndex][0]) {
colorList = '#ef232a';
} else {
colorList = '#14b143';
}
return colorList;
}
"""
)
),
)
.set_global_opts(
datazoom_opts=[opts.DataZoomOpts(type_="slider")],
)
.set_global_opts(
xaxis_opts=opts.AxisOpts(
type_="category",
grid_index=1,
axislabel_opts=opts.LabelOpts(is_show=False),
),
legend_opts=opts.LegendOpts(is_show=False),
)
)
return bar
# 画折线图
def draw_line(lname,X,Y):
line= (
Line()
.set_global_opts(
tooltip_opts=opts.TooltipOpts(is_show=False),
xaxis_opts=opts.AxisOpts(type_="category"),
yaxis_opts=opts.AxisOpts(
type_="value",
axistick_opts=opts.AxisTickOpts(is_show=True),
splitline_opts=opts.SplitLineOpts(is_show=True),
),
)
.add_xaxis(xaxis_data=X)
.add_yaxis(
series_name=lname,
y_axis=Y,
symbol="emptyCircle",
is_symbol_show=True,
label_opts=opts.LabelOpts(is_show=False),
)
)
return line
if __name__== '__main__':
stock_name= '仁和药业'
N1= 20
N2= 10
original_data= get_daily(stock_name,'20180101','20201208')
final_data= my_strategy(original_data, N1, N2)
# 日期-横坐标字符串格式化
date= [str(t)for tin final_data.index.strftime('%Y%m%d')]
# K线图所需纵坐标
data_k= final_data.loc[:, ['open','close','low','high']].values.tolist()
kline= draw_k("K线图", date, data_k)
# 折线图
lup= final_data['up'].values.tolist()
ldown= final_data['down'].values.tolist()
lmoney= final_data['money'].values.tolist()
lincome= final_data['turtle'].values.tolist()
line_up= draw_line('20日均线', date, lup)
line_down= draw_line('10日均线', date, ldown)
line_money= draw_line('资金指数', date, lmoney)
line_income= draw_line('收益指数', date, lincome)
# k线图和折线图组合
kline_ll= kline.overlap(line_up).overlap(line_down).overlap(line_money).overlap(line_income)
# 柱状图
vol= final_data['vol'].values.tolist()
bar= draw_bar('成交量', date, vol)
grid_chart= Grid(init_opts=opts.InitOpts(width="1400px",height="800px"))
# 这个是为了把 data.datas 这个数据写入到 html 中,还没想到怎么跨 series 传值
# demo 中的代码也是用全局变量传的
grid_chart.add_js_funcs("var barData = {}".format(data_k))
# K线图和折线图
grid_chart.add(
kline_ll,
grid_opts=opts.GridOpts(pos_left="3%",pos_right="1%",height="60%"),
)
# 柱状图
grid_chart.add(
bar,
grid_opts=opts.GridOpts(
pos_left="3%",pos_right="1%",pos_top="51%",height="10%"
),
)
grid_chart.render('grid.html')