量化交易——python数据分析及可视化
该项目分为两个部分:一是数据计算,二是可视化,三是MACD策略
一、计算MACD
1、数据部分
数据来源:tushare
数据字段包含:日期,开盘价,收盘价,最低价,最高价,涨跌
需要计算的数据:macd,diff,dea
2、MACD的计算
(1)计算指数移动平均值(EMA)
12日EMA的算式为
EMA(12)=前一日EMA(12)×11/13+今日收盘价×2/13
26日EMA的算式为
EMA(26)=前一日EMA(26)×25/27+今日收盘价×2/27
(2)计算离差值(DIF)
DIF=今日EMA(12)-今日EMA(26)
(3)计算DIF的9日EMA
根据离差值计算其9日的EMA,即离差平均值,是所求的MACD值。为了不与指标原名相混淆,此值又名
DEA或DEM。
今日DEA(MACD)=前一日DEA×8/10+今日DIF×2/10。
计算出的DIF和DEA的数值均为正值或负值。
用(DIF-DEA)×2即为MACD柱状图。
二、可视化
1、可视化工具:pyecharts
pyecharts官网
三、MACD策略
代码实现如下:
from typing import List, Sequence, Union
from pyecharts import options as opts
from pyecharts.commons.utils import JsCode
from pyecharts.charts import Kline, Line, Bar, Grid# 数据
#时间,
#ema重构版
import pandas as pd
import numpy as np
import tushare as ts
def macd(code,start_date,end_date):'''获取数据预处理计算股票的ema、dif、dea、macd主要有9日,12日,26日'''#获取数据pro=ts.pro_api()#获取日k线数据df=pro.daily(ts_code=code,start_date=start_date,end_date=end_date)#删除不需要的数据df=df.drop('ts_code',axis=1)df=df.drop('pre_close',axis=1)df=df.drop('change',axis=1)df=df.drop('pct_chg',axis=1)df=df.drop('amount',axis=1)df=df.sort_values(by='trade_date')#将成交量缩小一万倍df.loc[:,['vol']]=df.loc[:,['vol']].apply(lambda x:x/10000)df.loc[:,['vol']]=df.loc[:,['vol']].round(2)'''需要输出哪些数据?return: 日期,开盘价,收盘价,最低价,最高价,涨跌,macd,dif,deadate,open,close,low,high,vol,涨跌,macd,diff,dea'''#ema计算函数def ema(num,data=df):ema = [data['close'][0]] * len(data)for i in range(1, len(data)):ema[i] = ema[i-1] * (num-1)/(num+1) + data['close'][i] * 2/(num+1)return ema#计算deadef dea(num,data):#传入数组numpy.arraydea = [data[0]] * len(data)for i in range(1, len(data)):dea[i] = dea[i-1] * (num-1)/(num+1) + data[i] * 2/(num+1)return np.array(dea)ema_12=np.array(ema(12))ema_26=np.array(ema(26))dif=ema_12-ema_26dea=dea(9,dif)macd=(dif-dea)*2#转化为pddf1={'macd':macd,'dif':dif,'dea':dea}df1=pd.DataFrame(df1)#连接数据df=df.join(df1)df=df.round(2)print(df)#判断涨跌,1为涨,0为跌def f(x):if x>=0:return 1else:return 0x=(df['close']-df['open']).apply(f)#调整列顺序df=df.loc[:,['trade_date','open','close','low','high','vol','macd','dif','dea']]#插入涨跌数据df.insert(loc=6,column='x',value=x)return df.values#转化为列表macd=macd(code='000001.SZ',start_date='20230101',end_date='20230320')
echarts_data =macd.tolist()
print(type(echarts_data))
print(echarts_data)
'''
echarts_data = [["2015-10-16", 18.4, 18.58, 18.33, 18.79, 67.00, 1, 0.04, 0.11, 0.09],["2015-10-19", 18.56, 18.25, 18.19, 18.56, 55.00, 0, -0.00, 0.08, 0.09],["2016-12-30", 17.53, 17.6, 17.47, 17.61, 22.00, 0, -0.05, -0.03, -0.01],["2017-01-03", 17.6, 17.92, 17.57, 17.98, 28.00, 1, 0.00, 0.00, 0.00],
]
'''
def split_data(origin_data) -> dict:datas = []times = []vols = []macds = []difs = []deas = []for i in range(len(origin_data)):datas.append(origin_data[i][1:])times.append(origin_data[i][0:1][0])vols.append(origin_data[i][5])macds.append(origin_data[i][7])difs.append(origin_data[i][8])deas.append(origin_data[i][9])vols = [int(v) for v in vols]return {"datas": datas,"times": times,"vols": vols,"macds": macds,"difs": difs,"deas": deas,}def split_data_part() -> Sequence:mark_line_data = []idx = 0tag = 0vols = 0for i in range(len(data["times"])):if data["datas"][i][5] != 0 and tag == 0:idx = ivols = data["datas"][i][4]tag = 1if tag == 1:vols += data["datas"][i][4]if data["datas"][i][5] != 0 or tag == 1:mark_line_data.append([{"xAxis": idx,"yAxis": float("%.2f" % data["datas"][idx][3])if data["datas"][idx][1] > data["datas"][idx][0]else float("%.2f" % data["datas"][idx][2]),"value": vols,},{"xAxis": i,"yAxis": float("%.2f" % data["datas"][i][3])if data["datas"][i][1] > data["datas"][i][0]else float("%.2f" % data["datas"][i][2]),},])idx = ivols = data["datas"][i][4]tag = 2if tag == 2:vols += data["datas"][i][4]if data["datas"][i][5] != 0 and tag == 2:mark_line_data.append([{"xAxis": idx,"yAxis": float("%.2f" % data["datas"][idx][3])if data["datas"][i][1] > data["datas"][i][0]else float("%.2f" % data["datas"][i][2]),"value": str(float("%.2f" % (vols / (i - idx + 1)))) + " M",},{"xAxis": i,"yAxis": float("%.2f" % data["datas"][i][3])if data["datas"][i][1] > data["datas"][i][0]else float("%.2f" % data["datas"][i][2]),},])idx = ivols = data["datas"][i][4]return mark_line_datadef calculate_ma(day_count: int):result: List[Union[float, str]] = []for i in range(len(data["times"])):if i < day_count:result.append("-")continuesum_total = 0.0for j in range(day_count):sum_total += float(data["datas"][i - j][1])result.append(abs(float("%.2f" % (sum_total / day_count))))return resultdef draw_chart():kline = (Kline().add_xaxis(xaxis_data=data["times"]).add_yaxis(series_name="",y_axis=data["datas"],itemstyle_opts=opts.ItemStyleOpts(color="#ef232a",color0="#14b143",border_color="#ef232a",border_color0="#14b143",),markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="max", name="最大值"),opts.MarkPointItem(type_="min", name="最小值"),]),markline_opts=opts.MarkLineOpts(label_opts=opts.LabelOpts(position="middle", color="blue", font_size=15),data=split_data_part(),symbol=["circle", "none"],),).set_series_opts(markarea_opts=opts.MarkAreaOpts(is_silent=True, data=split_data_part())).set_global_opts(title_opts=opts.TitleOpts(title="K线周期图表", pos_left="0"),xaxis_opts=opts.AxisOpts(type_="category",is_scale=True,boundary_gap=False,axisline_opts=opts.AxisLineOpts(is_on_zero=False),splitline_opts=opts.SplitLineOpts(is_show=False),split_number=20,min_="dataMin",max_="dataMax",),yaxis_opts=opts.AxisOpts(is_scale=True, splitline_opts=opts.SplitLineOpts(is_show=True)),tooltip_opts=opts.TooltipOpts(trigger="axis", axis_pointer_type="line"),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),],# 三个图的 axis 连在一块# axispointer_opts=opts.AxisPointerOpts(# is_show=True,# link=[{"xAxisIndex": "all"}],# label=opts.LabelOpts(background_color="#777"),# ),))kline_line = (Line().add_xaxis(xaxis_data=data["times"]).add_yaxis(series_name="MA5",y_axis=calculate_ma(day_count=5),is_smooth=True,linestyle_opts=opts.LineStyleOpts(opacity=0.5),label_opts=opts.LabelOpts(is_show=False),).set_global_opts(xaxis_opts=opts.AxisOpts(type_="category",grid_index=1,axislabel_opts=opts.LabelOpts(is_show=False),),yaxis_opts=opts.AxisOpts(grid_index=1,split_number=3,axisline_opts=opts.AxisLineOpts(is_on_zero=False),axistick_opts=opts.AxisTickOpts(is_show=False),splitline_opts=opts.SplitLineOpts(is_show=False),axislabel_opts=opts.LabelOpts(is_show=True),),))# Overlap Kline + Lineoverlap_kline_line = kline.overlap(kline_line)# Bar-1bar_1 = (Bar().add_xaxis(xaxis_data=data["times"]).add_yaxis(series_name="Volumn",y_axis=data["vols"],xaxis_index=1,yaxis_index=1,label_opts=opts.LabelOpts(is_show=False),# 根据 echarts demo 的原版是这么写的# itemstyle_opts=opts.ItemStyleOpts(# color=JsCode("""# function(params) {# var colorList;# if (data.datas[params.dataIndex][1]>data.datas[params.dataIndex][0]) {# colorList = '#ef232a';# } else {# colorList = '#14b143';# }# return colorList;# }# """)# )# 改进后在 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(xaxis_opts=opts.AxisOpts(type_="category",grid_index=1,axislabel_opts=opts.LabelOpts(is_show=False),),legend_opts=opts.LegendOpts(is_show=False),))# Bar-2 (Overlap Bar + Line)bar_2 = (Bar().add_xaxis(xaxis_data=data["times"]).add_yaxis(series_name="MACD",y_axis=data["macds"],xaxis_index=2,yaxis_index=2,label_opts=opts.LabelOpts(is_show=False),itemstyle_opts=opts.ItemStyleOpts(color=JsCode("""function(params) {var colorList;if (params.data >= 0) {colorList = '#ef232a';} else {colorList = '#14b143';}return colorList;}""")),).set_global_opts(xaxis_opts=opts.AxisOpts(type_="category",grid_index=2,axislabel_opts=opts.LabelOpts(is_show=False),),yaxis_opts=opts.AxisOpts(grid_index=2,split_number=4,axisline_opts=opts.AxisLineOpts(is_on_zero=False),axistick_opts=opts.AxisTickOpts(is_show=False),splitline_opts=opts.SplitLineOpts(is_show=False),axislabel_opts=opts.LabelOpts(is_show=True),),legend_opts=opts.LegendOpts(is_show=False),))line_2 = (Line().add_xaxis(xaxis_data=data["times"]).add_yaxis(series_name="DIF",y_axis=data["difs"],xaxis_index=2,yaxis_index=2,label_opts=opts.LabelOpts(is_show=False),).add_yaxis(series_name="DIF",y_axis=data["deas"],xaxis_index=2,yaxis_index=2,label_opts=opts.LabelOpts(is_show=False),).set_global_opts(legend_opts=opts.LegendOpts(is_show=False)))# 最下面的柱状图和折线图overlap_bar_line = bar_2.overlap(line_2)# 最后的 Gridgrid_chart = Grid()# 这个是为了把 data.datas 这个数据写入到 html 中,还没想到怎么跨 series 传值# demo 中的代码也是用全局变量传的grid_chart.add_js_funcs("var barData = {}".format(data["datas"]))# K线图和 MA5 的折线图grid_chart.add(overlap_kline_line,grid_opts=opts.GridOpts(pos_left="3%", pos_right="1%", height="60%"),)# Volumn 柱状图grid_chart.add(bar_1,grid_opts=opts.GridOpts(pos_left="3%", pos_right="1%", pos_top="71%", height="10%"),)# MACD DIFS DEASgrid_chart.add(overlap_bar_line,grid_opts=opts.GridOpts(pos_left="3%", pos_right="1%", pos_top="82%", height="14%"),)grid_chart.render("professional_kline_chart.html")if __name__ == "__main__":data = split_data(origin_data=echarts_data)draw_chart()
文章持续更新中。。。
相关文章:

量化交易——python数据分析及可视化
该项目分为两个部分:一是数据计算,二是可视化,三是MACD策略 一、计算MACD 1、数据部分 数据来源:tushare 数据字段包含:日期,开盘价,收盘价,最低价,最高价,…...
微服务网关
1.网关是如何演化来的,在微服务中有什么作用? 随着单体架构转化为微服务架构的时候,由一个后台服务由一个单一的服务变成了多个微服务,前端应用需要调用多个服务的接口,为了解决这个问题,网关就产生了。网…...

【打卡】Datawhale暑期实训ML赛事
文章目录 赛题描述任务要求数据集介绍评估指标 赛题分析基于LightGBM模型Baseline详解改进baseline早停法添加特征 赛题描述 赛事地址:科大讯飞锂离子电池生产参数调控及生产温度预测挑战赛 任务要求 初赛任务:初赛提供了电炉17个温区的实际生产数据&…...
【python脚本】python实现:目标检测裁剪图片样本,根据类标签文件进行裁剪保存
python实现:目标检测裁剪图片样本,根据类标签文件进行裁剪保存 我在进行目标检测时候,比如红绿灯检测,目标区域很小,样本杂乱。 想要筛选错误样本的话,很困难。可以把目标区域裁剪出来。人大脑处理对于这…...
Mac 终端美化显示
Linux 也可安装 Zsh 后使用此套配置。 1. 安装 Oh My Zsh sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"2. 更换主题,修改文件:~/.zshrc,原内容: ZSH_THEME&quo…...

信息安全:密码学基本理论.
信息安全:密码学基本理论. 密码学是研究编制密码和破译密码的技术科学。研究密码变化的客观规律,应用于编制密码以保守通信秘密的,称为编码学;应用于破译密码以获取通信情报的,称为破译学,总称密码学. 目录…...
【linux升级ssh】 利用rpmbuild工具对ssh打包为rpm包进场安装升级
制作rpm包 rpmbuild命令用于创建软件的二进制包和源代码包。 官方文档:rpm.org - RPM Reference Manual rpmbuild 中文手册:rpmbuild 中文手册 [金步国] 使用rpmbuild将tar包打成rpm包 RPM打包使用的是rpmbuild命令,这个命令来自rpm-buil…...

UCloud上线可商用LLaMA2镜像,助力AGI应用发展
随着人工智能技术的快速发展,大模型应用在自然语言处理、图像识别、智能交互等领域展现出了巨大的潜力,为企业带来了更多创新和商机。众多企业纷纷将大模型应用于产品开发和业务优化中,希望通过提升智能化水平和用户体验来赢得竞争优势。近日…...

Linux推出Debian 12.1,并进行多方面系统修复
据了解,Debian是最古老的 GNU / Linux 发行版之一,也是许多其他基于 Linux 的操作系统的基础,包括 Ubuntu、Kali、MX 和树莓派 OS 等。 此外,该操作系统以稳定性为重,不追求花哨的新功能,因此新版本的发布…...

Spring 事务的使用、隔离级别、@Transactional的使用
Spring事务是Spring框架提供的一种机制,用于管理应用程序中的数据库事务。 事务是一组数据库操作的执行单元,要么全部成功提交,要么全部失败回滚,保证数据的一致性和完整性。 Spring事务提供了声明式事务和编程式事务两种方式&am…...

Top命令
Top top - 12:46:01 up 2 days, 11:10, 3 users, load average: 0.56, 0.59, 0.45系统基本信息:显示了系统运行时间、登录用户数和平均负载(load average)情况。平均负载是系统在特定时间范围内的平均活跃进程数,可以用来衡量系…...

(三)RabbitMQ七种模式介绍与代码演示
Lison <dreamlison163.com>, v1.0.0, 2023.06.22 七种模式介绍与代码演示 文章目录 七种模式介绍与代码演示四大交换机四种交换机介绍 工作模式简单模式(Hello World)工作队列模式(Work queues)订阅模式(Publis…...

ElasticSearch Java API 操作
1.idea创建Maven项目 2.添加依赖 修改 pom.xml 文件 <dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.8.0</version></dependency><!-- elasticsearch 的客户端 --…...

【Qt】QML-01:使用QtCreator10创建QML工程,并讲解第一个程序:Hello World
1、创建QML工程 1)新建工程 打开QtCreator10,依次点击“Create Project” --> “Application(Qt)” --> “Qt Quick Application(compat)” 注意:本人打算使用Qt5.15.2创建工程,而非Qt6,因此选择兼容低于Qt6版本的“Qt Quick Applicat…...

Docker的安装与部署
Docker 基本概念介绍 通俗理解:镜像是类,容器是对象实例 仓库 应用商店、镜像 下载的应用安装程序、容器 应用程序 镜像(Image) 这里面保存了应用和需要的依赖环境 为什么需要多个镜像?当开发、构建和运行容器化应用程序时,我们…...

【数据结构】实验四:循环链表
实验四 循环链表 一、实验目的与要求 1)熟悉循环链表的类型定义和基本操作; 2)灵活应用循环链表解决具体应用问题。 二、实验内容 题目一:有n个小孩围成一圈,给他们从1开始依次编号,从编号为1的小孩开…...
【FPGA/D7】
2023年7月26日 串口传图到RAM并TFT显示 视频25note要求:接收两个字节数据合并为一个16位数据并写入ram: FIFO模型与应用场景 视频26 串口传图到RAM并TFT显示 视频25 note 存储器的使用,在开始读写或者结束读写的位置非常容易出现数据错误或…...

Vue的下载以及MVVM分析
😀前言本片文章是vue系列第一篇整理了vue的基础和发展史 🏠个人主页:尘觉主页 🧑个人简介:大家好,我是尘觉,希望我的文章可以帮助到大家,您的满意是我的动力😉Ƕ…...

ElasticSearch学习--自动补全
目录 自定义分词器 介绍 配置自定义分词器 拼音分词器的问题编辑 总结 DSL自动补全查询 RestAPI实现自动补全 自定义分词器 介绍 自定义分词器只在当前库中有效 配置自定义分词器 拼音分词器的问题 总结 DSL自动补全查询 RestAPI实现自动补全...

【C++】多态,虚函数表相关问题解决
文章目录 多态概念及其触发条件重写和协变(考点1)(考点2) 虚函数表及其位置(考点3) 多继承中的虚函数表 多态概念及其触发条件 多态的概念:通俗来说,就是多种形态。具体点就是去完成…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

群晖NAS如何在虚拟机创建飞牛NAS
套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...