Python使用pyecharts库构建股票交易 可交互可视化展示——基于Tushare大数据开放社区
Python使用pyecharts库构建股票交易 可交互可视化展示——基于Tushare大数据社区
1、前言
大家好!欢迎各位访问我的博客,今天给大家分享的是 python使用pyecharts库构建股票交易的可交互可视化展示,并简单设置股票买入卖出条件,统计股票收益率等操作。本次数据的来源是Tushare大数据开发社区(:D 感谢Tushare的数据支持,Tushare拥有丰富的数据内容,如股票、基金、期货、数字货币等行情数据,能够让我们解放双手,逃脱最痛苦的数据收集步骤),本次重点是利用pyecharts库绘制k线图,希望大家能够喜欢。
2、成品展示
图片1 可交互展示
图片2 pyecharts-300274-阳光电源.html
图片3 自选股统计收益率分析
图片4 个股分析导出
3、源码分享
python
import tushare as ts
import pandas as pd
import matplotlib.pyplot as plt
import json
import numpy as np
from matplotlib.pylab import date2num
import datetime
import mpl_finance as mpf
import pyecharts
from pyecharts import options as opts
from pyecharts.commons.utils import JsCode
from pyecharts.charts import *
import numpy as np
from openpyxl import Workbook
from openpyxl.styles import PatternFill
from openpyxl import load_workbook
# 设置Token
ts.set_token('******************') #请填入自己的Token
# 初始化接口
ts_api = ts.pro_api()
print("Tushare 接口调用正常,版本号:" + ts.__version__ +"\n")
print("pyecharts数据交互 接口调用正常,版本号:{}".format(pyecharts.__version__)+"\n")
class RobotTrade():
id = None
buyTime = None
buyPrice = None
sellTime = None
sellPrice = None
profit = None
def setId(self,id):
self.id = id
def buy(self,time,price):
self.buyTime = time
self.buyPrice = price
def sell(self,time,price):
self.sellTime = time
self.sellPrice = price
self.profit = round((self.sellPrice - self.buyPrice)/self.buyPrice,4)
def Out(self):
a = self.buyTime
b = self.sellTime
c = self.buyPrice
d = self.sellPrice
e = self.profit
f = self.id
return [a,b,c,d,e,f]
class Stock:
global returnList
isTodayBuy = ""
df = pd.DataFrame([0, 0])
code = ""
start = ""
end = ""
name = ""
list_BuyorSell = []
# 设置股票代码
def set_code(self,code):
stock_list = ts_api.stock_basic(exchange='', list_status='L',
fields='ts_code,symbol,name,area,industry,market,list_date')
a = stock_list["ts_code"].tolist()
for i in range(len(a)):
if a[i][0:6] == code:
self.code=a[i]
self.name=stock_list.loc[i,"name"]
# 请求股票列表
# 获取日线交易数据
def get_daily_trade(self): # 股票代码,开始日期20120101,结束日期20180101
# print("正在获取交易数据:\n --Start Download")
if self.start == "":
self.start = input("请输入交易开始日期:")
self.end = input("请输入交易结束日期:")
# 请求日线数据
# print(self.start)
df = ts_api.daily(ts_code = self.code, start_date = self.start, end_date = self.end)
# 按交易日升序排序
df.sort_values(by=["trade_date"], inplace=True)
df.reset_index(drop=True, inplace=True)
self.df = df
# print("已获取{} {},交易数据,共计{}条交易数据\n".format(self.code,self.name, len(self.df)))
# 指数移动均线工具
def get_MA_EMA(self, n):
df = self.df
newname = "EMA" + str(n)
df[newname] = 0 # 初始化n天指数移动均线
for i in range(n - 1, len(df)): # 循环第n个数据开始,为之后的每个数据计算EMA
list_temp = []
list_ema = []
for d in range(n): # 添加数据
list_temp.append(df.loc[i - (n - d) + 1, "close"])
list_ema.append(0)
for d in range(n): # 进行计算
if d == 0:
list_ema[d] = list_temp[d]
else:
list_ema[d] = (2 * list_temp[d] + (n - 1) * list_ema[d - 1]) / (n + 1)
df.loc[i, newname] = list_ema[n - 1]
# print(" --已计算指数移动均线EMA{}".format(n))
self.df = df
# 移动均线计算
def get_MA(self, n):
df = self.df
newname = "MA" + str(n)
df[newname] = None # 初始化n天指数移动均线
for i in range(n-1,len(df)):
list_temp = []
sum = 0
avg = 0
for d in range(n):
sum = sum + df.loc[ i-(n-d)+1 ,"close"]
avg = round(sum/n,2)
df.loc[i, newname] = avg
# print(" --已计算移动均线MA{}".format(n))
# 移动均线计算
def get_Vol_MA(self, n):
df = self.df
newname = "VolMA" + str(n)
df[newname] = None # 初始化n天指数移动均线
for i in range(n-1,len(df)):
list_temp = []
sum = 0
avg = 0
for d in range(n):
sum = sum + df.loc[ i-(n-d)+1 ,"vol"]
avg = round(sum/n,2)
df.loc[i, newname] = avg
# print(" --已计算成交量移动均线MA{}".format(n))
# Macd的快速线DIF计算
def get_Macd_DIF(self, n1, n2):
df = self.df
newname = "Macd_DIF"
df[newname] = 0 # 初始化n天指数移动均线
for i in range(n2,len(df)):
df.loc[i, "Macd_DIF"] = df.loc[i, "EMA" + str(n1)] - df.loc[i, "EMA" + str(n2)]
# print(" --已计算MACD 快速线DIF")
self.df = df
# Macd的慢速线DEA计算
def get_Macd_DEA(self, n):
df = self.df
newname = "Macd_DEA"
df[newname] = 0 # 初始化n天指数移动均线
for i in range(n - 1, len(df)): # 循环第n个数据开始,为之后的每个数据计算EMA
list_temp = []
list_dif = []
for d in range(n): # 添加数据
list_temp.append(df.loc[i - (n - d) + 1, "Macd_DIF"])
list_dif.append(0)
for d in range(n): # 进行计算
if d == 0:
list_dif[d] = list_temp[d]
else:
list_dif[d] = (2 * list_temp[d] + (n - 1) * list_dif[d - 1]) / (n + 1)
df.loc[i, newname] = list_dif[n - 1]
# print(" --已计算MACD 慢速线DEA")
self.df = df
# 计算MACD柱状线
def get_Macd_Bar(self,n):
df = self.df
for i in range(n,len(df)):
df.loc[i,"MACD_Bar"] = 2 * ( df.loc[i, "Macd_DIF"] - df.loc[i, "Macd_DEA"])
# print(" --已计算MACD 柱状线Bar")
self.df = df
# Macd计算
def get_Macd(self, a=12, b=26, c=9):
# print("正在计算MACD指标:")
# 计算EMA12、EMA26 数据
self.get_MA_EMA(a)
self.get_MA_EMA(b)
# 计算三条曲线
self.get_Macd_DIF(a,b)
self.get_Macd_DEA(c)
self.get_Macd_Bar(b)
# print(" --已完成MACD指标的计算")
# 交易策略
def set_Trading_Strategy(self):
df = self.df
list_BuyorSell = []
count = 0
temp = 0 # 买入后的世界线进行
for i in range(10,len(df)): # 偷懒从第十个交易日开始
i = i + temp
if i >=len(df):
break
lowThanma5 = 0 # 收盘价低于5日均线的天数
Is_skip = False # 是否条件不满足
Is_selled = False
# 条件0:买点的前2天收盘价均小于5日均线
for day in range(1,2):
if df.loc[i-day,"MA5"] < df.loc[i-day,"close"]:
Is_skip = True
if Is_skip==True:
continue
# 条件1:当天收盘价大于5日线
if df.loc[i,"close"] < df.loc[i,"MA5"]:
Is_skip = True
if Is_skip==True:
continue
# # 条件2:当天开盘价低于5日线
# if df.loc[i, "open"] > df.loc[i, "MA5"]:
# Is_skip = True
# if Is_skip == True:
# continue
# 条件3: 当日增幅超过3%
if ((df.loc[i,"close"]-df.loc[i,"open"]) / df.loc[i,"open"] ) <= 0.03:
Is_skip = True
if Is_skip==True:
continue
# 条件3:...
if Is_skip==True:
continue
# 买入条件均满足后买入
r = RobotTrade() # 设置交易机器人id
r.setId(count)
if i+1 == len(df): # 是否今天买入
self.isTodayBuy = "下个交易日开盘立刻买入"
break
r.buy(i+1,df.loc[i+1,"open"]) # 机器人后一天买入
have_price = df.loc[i+1,"open"] # 第二天开盘立刻买入
# 一但卖出条件成熟,机器人执行卖出
for day in range(1,31): # 最大持股时间30日
if i+1+day >= len(df) - 1: # 检查数组是否越界
r.sell(len(df) - 1, r.buyPrice)
list_BuyorSell.append(r.Out())
break
# 单次操作亏损达到-0.0666时卖出
if (df.loc[i+1+day,"close"]-r.buyPrice)/r.buyPrice <= -0.0666:
r.sell(i + 1 + day, r.buyPrice*0.9334)
list_BuyorSell.append(r.Out())
Is_selled = True
break
# 单次操作盈利达到+0.2888时卖出
if (df.loc[i + 1 + day, "high"] - r.buyPrice) / r.buyPrice >= 0.1888:
r.sell(i + 1 + day, r.buyPrice * 1.1888)
list_BuyorSell.append(r.Out())
Is_selled = True
break
# 5日均线小于10日均线的0.98 卖出
if df.loc[i+1+day,"MA10"]*0.98 > df.loc[i+1+day,"MA5"]:
r.sell(i+1+day,df.loc[i+1+day,"close"])
list_BuyorSell.append(r.Out())
Is_selled = True
break
# 连续3天收盘价小于5日均线 且 5日线小于10日线 卖出
if df.loc[i + 1 + day, "MA5"] > df.loc[i + 1 + day, "close"] and df.loc[i + 1 + day, "MA5"] < \
df.loc[i + 1 + day, "MA10"]:
lowThanma5 = lowThanma5 + 1
if lowThanma5 >= 3:
r.sell(i + 1 + day, df.loc[i + 1 + day, "close"])
list_BuyorSell.append(r.Out())
Is_selled = True
break
# 若卖出条件未出现,则持仓等候
a = 1+1 # 摸鱼
temp = temp + 1
if Is_selled == True:
continue
if i+31 >= len(df)-1: # 检查数组越界
r.sell(len(df)-1,r.buyPrice)
list_BuyorSell.append(r.Out())
break
# 如果最大持股时间达到时 还持有仓位,则强制卖出
if Is_selled != True:
r.sell(i + 31,df.loc[i + 31, "close"])
list_BuyorSell.append(r.Out())
Is_selled = True
# 结束一个周期
count = count +1
self.list_BuyorSell = list_BuyorSell
# print(list_BuyorSell)
# 绘制MA指标图,返回line_ma
def get_Pyecharts_MA(self,n,index,itheme="light"):
df = self.df
colorlist = ["rgb(47,79,79)","rgb(255,140,0)","rgb(0,191,255)","rgb(187, 102, 255)"]
icolor = colorlist[index-2]
line = (
Line(init_opts=opts.InitOpts(theme=itheme,animation_opts=opts.AnimationOpts(animation=False),))
# 添加x轴交易日期数据
.add_xaxis(df["trade_date"].tolist())
.add_yaxis("MA{}".format(n),df["MA{}".format(n)].tolist(),xaxis_index=index,yaxis_index=index,
label_opts=opts.LabelOpts(is_show=False),
is_symbol_show=False, # 是否显示小圆点
itemstyle_opts=opts.ItemStyleOpts(color=icolor)) # 更改颜色
.set_global_opts(
xaxis_opts=opts.AxisOpts(is_show=False,grid_index=index),
yaxis_opts=opts.AxisOpts(is_show=False,grid_index=index),
legend_opts=opts.LegendOpts(is_show=True), # 图例是否显示
)
)
return line
# 绘制成交量均值线
def get_Pyecharts_VolMA(self,n,index,itheme="light"):
df = self.df
colorlist = ["rgb(47,79,79)","rgb(255,140,0)"]
icolor = colorlist[index-6]
line = (
Line(init_opts=opts.InitOpts(theme=itheme,animation_opts=opts.AnimationOpts(animation=False),))
# 添加x轴交易日期数据
.add_xaxis(df["trade_date"].tolist())
.add_yaxis("VolMA{}".format(n),df["VolMA{}".format(n)].tolist(),xaxis_index=index,yaxis_index=index,
label_opts=opts.LabelOpts(is_show=False),
is_symbol_show=False, # 是否显示小圆点
tooltip_opts=opts.TooltipOpts(is_show=False),
itemstyle_opts=opts.ItemStyleOpts(color=icolor)) # 更改颜色
.set_global_opts(
xaxis_opts=opts.AxisOpts(is_show=False,grid_index=index),
yaxis_opts=opts.AxisOpts(is_show=False,grid_index=index),
# 图例是否显示
)
)
return line
# 绘制K线图,
def get_Pyecharts_Kline(self,itheme="light"):
tradeAction = [] # 交易输出记录
df = self.df
valueList = []
temp_data = [] # 用于标记区域
temp_data2 = [] # 用于标记线
totalProfit = 100
# 构建日交易金额数据list
for i in range(len(self.list_BuyorSell)):
profit = self.list_BuyorSell[i][4] # 0.05
temp_data.append(opts.MarkAreaItem(name="", x=(df.loc[self.list_BuyorSell[i][0],"trade_date"], df.loc[self.list_BuyorSell[i][1],"trade_date"])))
temp_data2.append([ { "xAxis": df.loc[self.list_BuyorSell[i][0],"trade_date"],
"yAxis": df.loc[self.list_BuyorSell[i][0],"open"],
"value": "盈利:{:.2f}%".format(profit*100)
},
{
"xAxis": df.loc[self.list_BuyorSell[i][1], "trade_date"],
"yAxis": self.list_BuyorSell[i][3],
}])
totalProfit = totalProfit*(1+profit)
# 输出Excel交易操作信息
tradeAction.append([ df.loc[self.list_BuyorSell[i][0],"trade_date"], df.loc[self.list_BuyorSell[i][1], "trade_date"], round(df.loc[self.list_BuyorSell[i][0],"open"],2),round(self.list_BuyorSell[i][3],2), "{:.2f}%".format(self.list_BuyorSell[i][4]*100)])
self.totalProfit = totalProfit
# name="交易{:0>2d}\n{:.2f}%".format(i+1,profit)
returnList.append([self.name, self.code, tradeAction, round((self.totalProfit-100)/100*100,2)])
for i in range(len(df)):
valueList.append([df.loc[i, "open"], df.loc[i, "close"], df.loc[i, "high"], df.loc[i, "low"],(df.loc[i,"close"]-df.loc[i,"open"])/df.loc[i,"open"] ])
x = df["trade_date"].tolist()
y = valueList
# 绘制K线图
kline = (
Kline(init_opts=opts.InitOpts(theme=itheme,animation_opts=opts.AnimationOpts(animation=True,animation_easing_update="backOut"))) # chalk
# 添加x轴交易日期数据
.add_xaxis(x)
# 添加y轴成交价格数据
.add_yaxis(series_name="Daily Trade Data", y_axis=y, itemstyle_opts=opts.ItemStyleOpts( # 风格设置
color="red",color0="green",
border_color="#ef232a",border_color0="#14b143", # 边框色彩
),
markline_opts=opts.MarkLineOpts(
label_opts=opts.LabelOpts(
position="middle", color="blue"
),
data=temp_data2,
symbol=["none", "arrow"],
symbol_size=10,
linestyle_opts=opts.LineStyleOpts(color="blue",width=3)
),
)
# 设计标记区 x = 开始,结束
.set_series_opts(markarea_opts=opts.MarkAreaOpts(data=temp_data,
itemstyle_opts=opts.ItemStyleOpts(opacity=0.6, # 透明度
color={
"type":'linear',
"x":1,"y":1,"x2":0,"y2":0,
"colorStops": [{"offset": 0, "color": '#F55555'}, {"offset": 1, "color": '#FCCF31'}]
}
)
)
)
# 设置x、y轴显示信息
.set_global_opts(xaxis_opts=opts.AxisOpts(name='交易时间'))
# .set_global_opts(yaxis_opts=opts.AxisOpts(name='交易价格/元'))
# 固定y轴的范围
# .set_global_opts(yaxis_opts=opts.AxisOpts(min_=5, max_=10))
.set_global_opts(title_opts=opts.TitleOpts(title="{} {} 总盈利{:.2f}% {}".format(self.code,self.name,(self.totalProfit-100)/100*100,self.isTodayBuy), subtitle='日K线图 交易价格/元'), # 标题选项
legend_opts=opts.LegendOpts(is_show=True), # 图例选项
datazoom_opts=[ # 缩放选项
opts.DataZoomOpts(
is_show=False,
type_="inside",
xaxis_index=[0,1],
# 初始的框选范围
range_start=80,
range_end=100,
),
opts.DataZoomOpts(
is_show=True,
xaxis_index=[0,1],
type_="slider",
pos_top="95%",
range_start=80,
range_end=100,
)
],
yaxis_opts=opts.AxisOpts( # 坐标轴配置项
is_scale=True, # 是否显示y轴
splitarea_opts=opts.SplitAreaOpts( # 分割区域配置项
is_show=True, areastyle_opts=opts.AreaStyleOpts(opacity=1))
),
# 控制x轴label
xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(formatter=JsCode(
"""
function (x) {
a = x.substring(0,4);
b = x.substring(4,6);
c = x.substring(6,8);
return a+'年'+b+'月'+c+'日';
}
""")
)),
tooltip_opts=opts.TooltipOpts( # 提示框配置项
trigger="axis", # 触发类型默认
axis_pointer_type="cross", # 鼠标指针指示器
background_color="rgba(245, 245, 245, 0.8)", # 提示框漂浮层背景色
border_width=1, # 提示框漂浮层边框
border_color="#ccc",
textstyle_opts=opts.TextStyleOpts(color="#000"), # 提示框文字选项
formatter=JsCode(
"""
function (x) {
date = x[0].axisValue.substring(0,4)+ '年' + x[0].axisValue.substring(4,6)+ '月' +x[0].axisValue.substring(6,8)+ '日';
open = x[0].data[1];
close = x[0].data[2];
return date + '<br>' + '开盘价:' + open + '<br>' +'收盘价:' + close + '<br>' +'涨跌幅:' + Math.round((close-open)/close*100*100)/100 + '%<br>'+ x[1].seriesName +' :'+ x[1].data[1] + '<br>' + x[2].seriesName +':'+ x[2].data[1] + '<br>'+ x[3].seriesName +':'+ x[3].data[1] + '<br>'+ x[4].seriesName +':'+ x[4].data[1] + '<br>';
}
""")
),
axispointer_opts=opts.AxisPointerOpts( # 坐标轴指示器配置项
is_show=True,
label=opts.LabelOpts(background_color="#777"),
),
brush_opts=opts.BrushOpts( # 区域选择组建配置项
x_axis_index="all", # 指定哪些 xAxisIndex 可以被刷选
brush_link="all", # 不同系列间,选中的项可以联动。
out_of_brush={"colorAlpha": 0.1},
brush_type="lineX",
),
)
)
return kline
# 绘制成交量图形
def get_Pyecharts_Bar(self,itheme="light"):
df = self.df
valueList = []
# 构建日交易金额数据list
for i in range(len(df)):
valueList.append([df.loc[i, "open"], df.loc[i, "close"], df.loc[i, "high"], df.loc[i, "low"]])
# 绘制成交量柱状图
bar = (
Bar()
.add_xaxis(xaxis_data=df["trade_date"].tolist())
.add_yaxis(series_name="Volume",y_axis=df["vol"].tolist(),label_opts=opts.LabelOpts(is_show=False),
# 设置多图联动
xaxis_index=1,
yaxis_index=1,
tooltip_opts=opts.TooltipOpts(is_show=False),)
.set_global_opts(
xaxis_opts=opts.AxisOpts(
# 控制x轴label
axislabel_opts=opts.LabelOpts(formatter=JsCode(
"""
function (x) {
a = x.substring(0,4);
b = x.substring(4,6);
c = x.substring(6,8);
return a+'年'+b+'月'+c+'日';
}
""")
),
type_="category",
is_scale=True,
grid_index=1,
axisline_opts=opts.AxisLineOpts(is_on_zero=True),
axistick_opts=opts.AxisTickOpts(is_show=True),
splitline_opts=opts.SplitLineOpts(is_show=False),
split_number=20,
min_="dataMin",
max_="dataMax",),
yaxis_opts=opts.AxisOpts(
grid_index=1,
is_scale=True,
split_number=2,
axislabel_opts=opts.LabelOpts(is_show=True),
axisline_opts=opts.AxisLineOpts(is_show=True),
axistick_opts=opts.AxisTickOpts(is_show=True),
splitline_opts=opts.SplitLineOpts(is_show=False),),
legend_opts=opts.LegendOpts(is_show=False),
)
)
return bar
# 绘制主图并输出页面
def Print_Main_index(self,kline,bar_volumn,line_ma=None,line_ma2=None,line_ma3=None,line_ma4 = None,itheme="light"):
bar = bar_volumn
kline.overlap(line_ma)
kline.overlap(line_ma2)
kline.overlap(line_ma3)
kline.overlap(line_ma4)
grid_chart = Grid(
init_opts=opts.InitOpts(
width="1200px", height="580px",
animation_opts=opts.AnimationOpts(animation=True,animation_easing="linear"),
theme=itheme, page_title="Pyecharts_Demo",
)
)
# 添加上图
grid_chart.add(
kline,
grid_opts=opts.GridOpts(pos_left="10%", pos_right="10%", height="60%"),
)
# 添加下图
grid_chart.add(
bar,
grid_opts=opts.GridOpts(pos_left="10%", pos_right="10%", pos_top="75%", height="16%"),
)
grid_chart.render(path = "C:/Users/***/Desktop/StockAnalysis/pyecharts-{}-{}.html".format(self.code[0:6],self.name))
import os
print("已保存文件至{}".format("C:/Users/***/Desktop/StockAnalysis/pyecharts-{}-{}.html".format(self.code[0:6],self.name)))
# os.system("start C:/Users/***/Desktop/pyecharts-{}-{}.html".format(self.code[0:6],self.name))
def begin(self):
self.get_daily_trade()
# self.get_Macd()
self.get_MA(5)
self.get_MA(10)
self.get_MA(20)
self.get_MA(150)
self.get_Vol_MA(5)
self.get_Vol_MA(10)
self.set_Trading_Strategy()
self.line_ma5 = self.get_Pyecharts_MA(5,2) # index由2开始
self.line_ma10 = self.get_Pyecharts_MA(10,3)
self.line_ma20 = self.get_Pyecharts_MA(20,4)
self.line_ma50 = self.get_Pyecharts_MA(150,5)
self.line_volma5 = self.get_Pyecharts_VolMA(5, 6)
self.line_volma10 = self.get_Pyecharts_VolMA(10, 7)
self.kline = self.get_Pyecharts_Kline()
self.bar_volumn = self.get_Pyecharts_Bar().overlap(self.line_volma5).overlap(self.line_volma10)
self.Print_Main_index(self.kline, self.bar_volumn, self.line_ma5, self.line_ma10, self.line_ma20, self.line_ma50)
class ExcelWriter:
path = None
wb = None
ws = None
def setLocation(self,Path):
self.path = Path
def newFile(self):
wb = Workbook()
ws = wb.active
self.wb = wb
self.ws = ws
def outList(self):
list = []
a = -100
size = 5
for i in range(70):
a = a
b = a + size
list.append([[a, b], "{}%->{}%".format(a, b), 0])
a = a + size
return list
def inList(self,n,list):
n = int(n)
for i in list:
# print(type(n), type(i[0][0]))
if int(i[0][0]) <= n and n < int(i[0][1]):
i[2] = i[2] + 1
return list
def writeData(self,Lists): # List 单个元素内容 [stockName,stockCode,[操作1,操作2,...],总盈利]
dictProfit = self.outList() # 收益率计数列表
countColumn = 1 # 控制列的输出
countRow = 1 # 控制行的输出
Avprofit = 0
for stock in Lists:
countRow = 1
# 输出股票名称及代码
self.ws.cell(row=countRow,column=countColumn).value = stock[0] + stock[1]
countRow = countRow+1
# 输出操作信息
for action in stock[2]:
self.ws.cell(row=countRow, column=countColumn).value = "{} {} {} {} {}".format(action[0],action[1],action[2],action[3],action[4])
countRow = countRow+1
self.ws.cell(row=25, column=countColumn).value = "个股收益:"
self.ws.cell(row=26, column=countColumn).value = str(stock[3]) + "%"
dictProfit = self.inList(stock[3],dictProfit)
Avprofit = Avprofit + stock[3]
countColumn = countColumn + 1
# print(profit)
self.ws.cell(row=27, column=1).value = "平均收益:"
self.ws.cell(row=28, column=1).value = str(round(Avprofit/len(Lists),2)) + "%"
self.ws.cell(row=30, column=1).value = "收益分布分析:"
countColumn2 = 1
for i in dictProfit:
self.ws.cell(row=31, column=countColumn2).value = i[2]
self.ws.cell(row=32, column=countColumn2).value = i[1]
countColumn2 = countColumn2 + 1
def saveExcel(self):
print("保存文件至 -> {}".format(self.path))
self.wb.save(self.path)
import os
os.system("start C:/Users/***/Desktop/StockAnalysis/totalAnalysis.xlsx")
if __name__ == '__main__':
returnList = []
codeList = []
with open("C:/Users/***/Desktop/StockAnalysis/code.txt", 'r') as file:
data = file.readlines()
for i in data:
codeList.append(i.replace("\n",""))
print(codeList)
# for i in range(10):
# code = input("请输入证券代码:")
# codeList.append(code)
for i in codeList:
stock1 = Stock()
stock1.set_code(i)
stock1.start = "20210101"
stock1.end = "20211201"
stock1.begin()
ew = ExcelWriter()
ew.setLocation("C:/Users/***/Desktop/StockAnalysis/totalAnalysis.xlsx")
ew.newFile()
ew.writeData(returnList)
ew.saveExcel()
4、开发日志
交易系统开发日志
10月19日:构思完成,寻求股票交易数据。
10月21日:计划使用Tushare平台获取交易数据。
10月23日:申请Tushare高校学生权限。
10月24日:获取Tushare 1000积分,构建股票信息DataFrame。
10月26日:学习matplotlib绘制K线图。
10月27日:绘制第一张K线图。
10月31日:学习技术指标公式,尝试构建Macd指标(MACD计算结果错误,原因未核查)。
11月5日:开始接触pyecharts绘图库。
11月9日:理清pyecharts库的多图交互逻辑Grid、Overlap、Page。
11月12日:做出第一张基于Pyecharts库的可交互K线图。
11月14日:完成成交量与K线图的页面叠加。
11月18日:完成代码系统化构建。
11月25日:完成MA均线的计算与绘制。
11月26日:
完成交互的动画效果优化、
完成x轴日期格式化输出、
新增RobotTrade类:
新增自动交易机器人模型
新增set_Trading_Strategy函数:
现已支持设置自定义买入卖出条件
新增MarkArea标记域的父类继承设置:
能够自动标出买入卖出区域、自动计算当前收益率
11月28日:
重构Tooltip提示框:
删除不必要的信息
新增标记线:
现已支持显示机器人操作的收益率
新增区域标识透明度设置
12月3日:
新增ExcelWriter类,支持将结果输出到Excel:
已实现统计自选股收益信息,并将其保存。
新增对下一个交易日的行动安排
新增TxtRead方法:
现已支持导入外部自选股列表批量分析。
12月4日:
优化程序输出、
新增inList 和outList 方法:
现已支持收益率的数频统计
好啦本次的分享就到这,欢迎大家留言哟!
Python使用pyecharts库构建股票交易 可交互可视化展示——基于Tushare大数据开放社区的更多相关文章
- Python关于PIL库的学习总结与成果展示
一.关于PIL库的学习总结 PIL(Python Image Library)库是Python语言的第三方库,需要通过pip工具安装.安装PIL库的方法如下,需要注意,安装库的名字是pillow. : ...
- R、Python、Scala和Java,到底该使用哪一种大数据编程语言?
有一个大数据项目,你知道问题领域(problem domain),也知道使用什么基础设施,甚至可能已决定使用哪种框架来处理所有这些数据,但是有一个决定迟迟未能做出:我该选择哪种语言?(或者可能更有针对 ...
- 【拖拽可视化大屏】全流程讲解用python的pyecharts库实现拖拽可视化大屏的背后原理,简单粗暴!
"整篇文章较长,干货很多!建议收藏后,分章节阅读." 一.设计方案 整体设计方案思维导图: 整篇文章,也将按照这个结构来讲解. 若有重点关注部分,可点击章节目录直接跳转! 二.项目 ...
- Python基础——matplotlib库的使用与绘图可视化
1.matplotlib库简介: Matplotlib 是一个 Python 的 2D绘图库,开发者可以便捷地生成绘图,直方图,功率谱,条形图,散点图等. 2.Matplotlib 库使用: 注:由于 ...
- python的ws库功能,实时获取服务器ws协议返回的数据
# -*- coding:utf-8 -*- ''' 模块下载,帮助地址:https://github.com/liris/websocket-client#readme 模块:websocket-c ...
- python网络编程-socket上传下载文件(包括md5验证,大数据发送,粘包处理)
ftp server 1) 读取文件名 2)检查文件是否存在 3)打开文件 4)检查文件大小 5)发送文件大小给客户端 6)等客户端确认 7)开始边读边(md5计算)发数据 8)给客户端发md5 ft ...
- 数据科学速查手册(包括机器学习,概率,微积分,线性代数,python,pandas,numpy,数据可视化,SQL,大数据等方向)
介绍:https://redstonewill.com/2372/ 项目网址:https://github.com/FavioVazquez/ds-cheatsheets
- python 三方面库整理
测试开发 Web UI测试自动化 splinter - web UI测试工具,基于selnium封装. selenium - web UI自动化测试. –推荐 mechanize- Python中有状 ...
- Python常用的库简单介绍一下
Python常用的库简单介绍一下fuzzywuzzy ,字符串模糊匹配. esmre ,正则表达式的加速器. colorama 主要用来给文本添加各种颜色,并且非常简单易用. Prettytable ...
- Storm 实战:构建大数据实时计算
Storm 实战:构建大数据实时计算(阿里巴巴集团技术丛书,大数据丛书.大型互联网公司大数据实时处理干货分享!来自淘宝一线技术团队的丰富实践,快速掌握Storm技术精髓!) 阿里巴巴集团数据平台事业部 ...
随机推荐
- 微服务保护-Sentinel
1.初识Sentinel 1.1.雪崩问题及解决方案 1.1.1.雪崩问题 微服务中,服务间调用关系错综复杂,一个微服务往往依赖于多个其它微服务. 如图,如果服务提供者I发生了故障,当前的应用的部分业 ...
- 如何控制Tomcat的catalina.out的大小
catalina.out文件,数据主要来源为:System.out 和 System.err 在控制台上直接输出的信息. 编码时应避免使用System.out.println()和e.printSta ...
- C#中DataTable数据导出为HTML格式文件
/// <summary> /// DataTable导出为HTML的Table并保存到本地 /// </summary> /// <param name="d ...
- 使用easyexcel导入62个字段,十万加行数的excel
使用easyexcel导入62个字段,十万加行数的excel 1️⃣ 准备工作 1. 版本对应 在easyexcel官网的常见问题栏中往下滑找到 2. 下载jar包 maven项目不想多说,在pom. ...
- NC207751 牛牛的旅游纪念品
题目链接 题目 题目描述 牛牛在牛市的旅游纪念商店里面挑花了眼,于是简单粗暴的牛牛决定--买最受欢迎的就好了. 但是牛牛的背包有限,他只能在商店的n个物品里面带m个回去,不然就装不下了. 并且牛牛希望 ...
- NC16664 [NOIP2004]合唱队形
题目链接 题目 题目描述 N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形. 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2-,K,他们的身高分 ...
- gitlab+jenkins+docker持续集成环境搭建实战
介绍 什么是持续集成? 持续集成(CI)是在源代码变更后自动检测.拉取.构建和(在大多数情况下)进行单元测试的过程.持续集成是启动管道的环节(尽管某些预验证 -- 通常称为 上线前检查(pre-fli ...
- Vue+SpringBoot+ElementUI实战学生管理系统-10.学生管理模块
1.章节介绍 前一篇介绍了教师管理模块,这一篇编写学生管理模块,需要的朋友可以拿去自己定制.:) 2.获取源码 源码是捐赠方式获取,详细请QQ联系我 :)! 3.实现效果 学生列表 修改学生 4.模块 ...
- 解决:EXP-00003: 未找到段 (0,0) 的存储定义报错
问题说明 DB服务器oracle版本:11.2.0.4.0 最近在客户端用exp命令导出部分表时报错,如题.搜索了一下,找到以下解决方案: 问题原因 Oracle 11g 有一个参数deferred_ ...
- 【Android 逆向】【ARM汇编】 函数的栈帧
1. 函数的调用约定 ARM32 参数1-4 放入r0-r3 剩下的入栈,函数返回值放入r0 ARM64 参数1-8 放入X0-X7 剩下的入栈,函数返回值放入X0 (浮点数是放入 Dn 或 Sn) ...