量化交易——python数据分析及可视化

news2024/11/25 7:36:17

该项目分为两个部分:一是数据计算,二是可视化,三是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,dea
    date,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
    #计算dea
    def dea(num,data):#传入数组numpy.array
        dea = [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_26
    dea=dea(9,dif)
    macd=(dif-dea)*2
    #转化为pd
    df1={'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 1
        else:
            return 0
    
    x=(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 = 0
    tag = 0
    vols = 0
    for i in range(len(data["times"])):
        if data["datas"][i][5] != 0 and tag == 0:
            idx = i
            vols = data["datas"][i][4]
            tag = 1
        if 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 = i
            vols = data["datas"][i][4]
            tag = 2
        if 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 = i
            vols = data["datas"][i][4]
    return mark_line_data


def calculate_ma(day_count: int):
    result: List[Union[float, str]] = []

    for i in range(len(data["times"])):
        if i < day_count:
            result.append("-")
            continue
        sum_total = 0.0
        for j in range(day_count):
            sum_total += float(data["datas"][i - j][1])
        result.append(abs(float("%.2f" % (sum_total / day_count))))
    return result


def 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 + Line
    overlap_kline_line = kline.overlap(kline_line)

    # Bar-1
    bar_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)

    # 最后的 Grid
    grid_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 DEAS
    grid_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()

文章持续更新中。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/794754.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

11.python设计模式【责任链模式】

内容&#xff1a;使多个对象都有机会处理请求&#xff0c;从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链&#xff0c;并沿着这条链传递该请求&#xff0c;直到有一个对象处理它为止。角色&#xff1a; 抽象处理者&#xff08;Handler&#xff09;具体处理…

Unity实现camera数据注入RMP推送或轻量级RTSP服务模块

技术背景 随着技术的不断进步和应用的不断深化&#xff0c;Unity3D VR应用的前景非常广阔&#xff0c;它广泛应用于教育、医疗、军事、工业设计、虚拟数字人等多个领域。 教育领域&#xff1a;Unity3D VR技术可以用来创建虚拟现实教室&#xff0c;让学生能够身临其境地体验课…

微信小程序 事件和语法

属性列表 target&#xff1a;触发事件的对象currentTarget&#xff1a;绑定事件的对象&#xff0c;可能不是由此对象触发而是触发对象冒泡导致触发此事件 微信小程序 事件绑定 <button type"primary" bindtap"btnTapHandler">按钮</button> …

pytorch学习-线性神经网络——softmax回归+损失函数+图片分类数据集

1.softmax回归 Softmax回归&#xff08;Softmax Regression&#xff09;是一种常见的多分类模型&#xff0c;可以用于将输入变量映射到多个类别的概率分布中。softmax回归是机器学习中非常重要并且经典的模型&#xff0c;虽然叫回归&#xff0c;实际上是一个分类问题 1.1分类与…

ORCA优化器浅析——Exploration and Implementation Apply CXform Phase

GPORCA通过规则对表达式做转换&#xff0c;规则分为两类&#xff1a;Exploration&#xff0c;是对逻辑表达式做等价变换的&#xff1b;Implementation&#xff0c;是把逻辑操作符转换为物理操作符。Except the types of operator generated during Exploration (Logical > L…

手机python怎么用海龟画图,python怎么在手机上编程

大家好&#xff0c;给大家分享一下手机python怎么用海龟画图&#xff0c;很多人还不知道这一点。下面详细解释一下。现在让我们来看看&#xff01; 1、如何python手机版创造Al&#xff1f; 如果您想在手机上使用Python来创建AI&#xff08;人工智能&#xff09;程序&#xff0…

服务器推送、在线游戏和电子邮件背后的网络协议

之前也聊了不少网络协议这块内容&#xff0c;现在我们将深入探讨关键的网络协议及其在不同应用中的作用。重点在于理解这些协议如何塑造我们在互联网上的通信和互动方式。我们将深入研究以下领域&#xff1a; WebSocket 在之前的讨论中&#xff0c;我们研究了HTTP及其在客户端和…

帮助中心客户服务中的作用与应用

随着互联网的快速发展&#xff0c;越来越多的企业开始寻求更加高效、便捷的客户服务方式&#xff0c;帮助中心的自助服务作为一种新型的客户服务模式&#xff0c;受到了广泛关注。本文将针对帮助中心的自助服务在客户服务中的作用与应用进行深入探讨。 帮助中心在客户服务中的…

scrcpy2.0+实时将手机画面显示在屏幕上并用鼠标模拟点击2023.7.26

想要用AI代打手游&#xff0c;除了模拟器登录&#xff0c;也可以直接使用第三方工具Scrcpy&#xff0c;来自github&#xff0c;它是一个开源的屏幕镜像工具&#xff0c;可以在电脑上显示Android设备的画面&#xff0c;并支持使用鼠标进行交互。 目录 1. 下载安装2. scrcpy的高级…

文本预处理——文本数据分析

目录 文本数据分析中文酒店评价语料获得训练集和验证集的标签数量分布获取训练集和验证集的句子长度分布获取训练集和验证集的正负样本长度散点分布获得训练集和验证集不同词汇总数统计获得训练集上正负的样本的高频形容词词云获得验证集上正负的样本的形容词词云 文本数据分析…

Golang指针详解

要搞明白Go语言中的指针需要先知道3个概念&#xff1a;指针地址、指针类型和指针取值。 指针介绍 我们知道变量是用来存储数据的&#xff0c;变量的本质是给存储数据的内存地址起了一个好记的别名。比如我们定义了一个变量 a : 10 ,这个时候可以直接通过 a 这个变量来读取内存…

IPv6 over IPv4

IPv6 over IPv4隧道简介 IPv6 over IPv4隧道可实现IPv6网络孤岛之间通过IPv4网络互连。由于IPv4地址的枯竭和IPv6的先进性&#xff0c;IPv4过渡为IPv6势在必行。因为IPv6与IPv4的不兼容性&#xff0c;所以需要对原有的IPv4设备进行替换。但是如果贸然将IPv4设备大量替换所需成…

明晚直播:可重构计算芯片的AI创新应用分享!

大模型技术的不断升级及应用落地&#xff0c;正在推动人工智能技术发展进入新的阶段&#xff0c;而智能化快速增长和发展的市场对芯片提出了更高的要求&#xff1a;高算力、高性能、灵活性、安全性。可重构计算区别于传统CPU、GPU&#xff0c;以指令驱动的串行执行方式&#xf…

SpringBoot 集成 Elasticsearch

一、版本 spring-boot版本&#xff1a;2.3.7.RELEASEElasticsearch7.8.0版本说明详见 二、Elasticsearch 下载和安装 Elasticsearch 下载 kibana下载 ik分词器下载 配置IK分词器 2.1 解压&#xff0c;在elasticsearch-7.8.0\plugins 路径下新建ik目录 2.2 将ik分词器解压放…

【VB6|第21期】检查SqlServer数据库置疑损坏的小工具(含源码)

日期&#xff1a;2023年7月25日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xf…

Java反射类private私有变量Map并赋值

Java反射类private私有变量Map并赋值 import java.util.LinkedHashMap; import java.util.Map;public class MyObj {private String KEY "NAME";//目标是通过反射在外部访问cacheprivate Map<String, String> cache new LinkedHashMap<>();public MyOb…

mac 删除自带的ABC输入法保留一个搜狗输入法,搜狗配置一下可以减少很多的敲击键盘和鼠标点击次数

0. 背景 对于开发者来说&#xff0c;经常被中英文切换输入法所困扰&#xff0c;我这边有一个方法&#xff0c;删除mac默认的ABC输入法 仅仅保留搜狗一个输入法&#xff0c;配置一下搜狗输入&#xff1a;哪些指定为英文输入&#xff0c;哪些指定为中文输入&#xff08;符号也可…

七、Kafka源码分析之网络通信

1、生产者网络设计 架构设计图 2、生产者消息缓存机制 1、RecordAccumulator 将消息缓存到RecordAccumulator收集器中, 最后判断是否要发送。这个加入消息收集器&#xff0c;首先得从 Deque 里找到自己的目标分区&#xff0c;如果没有就新建一个批量消息 Deque 加进入 2、消…

限幅器(信捷PLC C语言FC功能函数)

关于限幅器的算法介绍,请参考下面博客文章,这里不再赘述,受水平和能力所限文中难免出现错误和不足之处,欢迎大家批评指正。 限幅器算法介绍 PLC信号处理系列之限幅器(Saturation)_RXXW_Dor的博客-CSDN博客TITLE=限幅器VAR_INPUTrX:REAL;// 输出值// 上限到达 FALSE: Up…

RT thread 之 Nand flash 读写过程分析

文章目录 前言&#xff1a;什么是Nand Flash&#xff1f;1、Nand Flash 读取步骤2、从主存读到Cache2.1 在标准spi接口下读取过程2.2 测试时序&#xff08;SPI频率30MHz&#xff09; 3.从Cache读取数据3.1在标准spi接口读取过程测试时序 前言&#xff1a;什么是Nand Flash&…