首页 > 其他分享 >pyecharts绘制K线的记录

pyecharts绘制K线的记录

时间:2023-09-20 22:59:39浏览次数:38  
标签:index pyecharts 记录 data price strategy print 绘制 opts

import tushare as ts
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pyecharts.charts import *
from pyecharts import options as opts
from pyecharts.globals import ThemeType

pd.set_option('expand_frame_repr', False)
pd.set_option('display.max_rows',None)

token = 'd6e7a61d3655208dd2cf86180344ae804df9661be085a7c3233f957c'
pro = ts.pro_api(token)
df_price = pro.daily(ts_code='600519.SH', start_date='20110101', end_date='20211008',
                     fields='ts_code,trade_date,close,open,high,low')
df_price.index = pd.to_datetime(df_price.trade_date)
df_price['year'] = df_price.index.year
df_price = df_price.sort_index()

# print(df_price.iloc[0:5,:])
# print(df_price)
# exit()

# 列名flag 索引为10
# 列名position 索引为9
# 列名close 索引为5
def Strategy(data_price, window_short=5, window_long=10, loss_ratio=0.20):
    # df_price:价格数据;
    # window_short:短均线周期,默认为5;
    # window_long:长均线周期,默认为10;
    # lossratio:止损率,默认为1%,即开仓后下跌超过1%止损。

    ##2.1绘制K线和均线
    data_price = data_price.copy()
    data_price.index = data_price.index.strftime('%Y%m%d')

    data_price['sma'] = data_price.close.rolling(window_short).mean()
    data_price['lma'] = data_price.close.rolling(window_long).mean()
    data_price['position'] = 0  # 记录仓位
    data_price['flag'] = 0  # 记录买卖


    kline = Kline(init_opts=opts.InitOpts(width='1200px', height='600px', theme=ThemeType.DARK))
    kline.add_xaxis(data_price.index.tolist())
    y = list(data_price.loc[:, ['open', 'close', 'low', 'high']].round(2).values)  # 现在里面的单个元素是数组
    y = [i.tolist() for i in y]  # 里面的单个数组也必须转换成list
    kline.add_yaxis('K线', y)
    # kline.extend_axis(yaxis=opts.AxisOpts( axislabel_opts=opts.LabelOpts(formatter="{value}") ))
    kline.set_series_opts(label_opts=opts.LabelOpts(is_show=False))  # 是否显示数据标签
    kline.set_global_opts(
        xaxis_opts=opts.AxisOpts(is_scale=True, axislabel_opts=opts.LabelOpts(rotate=60)),
        yaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(formatter="{value}")),
        datazoom_opts=[opts.DataZoomOpts(type_='inside')],  # 内部滑动
        title_opts=opts.TitleOpts(title="贵州茅台(600519.SH)K线及均线", pos_left='45%'),  # 题目位置
        legend_opts=opts.LegendOpts(pos_right="35%", pos_top="5%"),  # 图例位置
        tooltip_opts=opts.TooltipOpts(trigger="axis", axis_pointer_type="cross")  # 添加趋势线
    )

    line = Line()
    line.add_xaxis(data_price.index.tolist())
    line.add_yaxis('MA5', data_price.sma.round(2).tolist(), is_smooth=True)
    line.add_yaxis('MA10', data_price.lma.round(2).tolist(), is_smooth=True)
    line.set_series_opts(label_opts=opts.LabelOpts(is_show=False))  # 是否显示数据标签
    line.set_global_opts(
        datazoom_opts=[opts.DataZoomOpts(type_='inside')],  # 内部滑动
        legend_opts=opts.LegendOpts(pos_right="20%", pos_top="5%"),  # 图例位置
        tooltip_opts=opts.TooltipOpts(trigger="axis", axis_pointer_type="cross")  # 添加趋势线
    )

    kline.overlap(line)
    kline.render("16.1 贵州茅台(600519.SH)K线及均线.html")

    ##2.2均线策略的交易记录
    Buy = []  # 保存买入记录
    Sell = []  # 保存卖出记录
    price_in = 1  # 初始买入价设置为1

    for i in range(max(1, window_long), data_price.shape[0] - 1):
        # 情形一:当前无仓位且短均线上穿长均线(金叉),则买入股票
        if (data_price['position'][i] == 0) and (data_price['sma'][i - 1] < data_price['lma'][i - 1]) and (
                data_price['sma'][i] > data_price['lma'][i]):
            data_price.iloc[i, 10] = 1
            data_price.iloc[i + 1, 9] = 1

            date_in = data_price.index[i]
            price_in = data_price.iloc[i, 5]
            Buy.append([date_in, price_in, '金叉买入'])

        # 情形二:当前持仓且下跌超过止损率,则平仓止损
        elif (data_price['position'][i] == 1) & (1 - data_price['close'][i] / price_in > loss_ratio):
            data_price.iloc[i, 10] = -1
            data_price.iloc[i + 1, 9] = 0

            date_out = data_price.index[i]
            price_out = data_price.iloc[i, 5]
            Sell.append([date_out, price_out, '止损平仓'])

        # 情形三:当前持仓且短均线下穿长均线(死叉),则卖出股票
        elif (data_price['position'][i] == 1) & (data_price['sma'][i - 1] > data_price['lma'][i - 1]) & (
                data_price['sma'][i] < data_price['lma'][i]):
            data_price.iloc[i, 10] = -1
            data_price.iloc[i + 1, 9] = 0

            date_out = data_price.index[i]
            price_out = data_price.iloc[i, 5]
            Sell.append([date_out, price_out, '死叉卖出'])

        # 其他情形:保持之前的仓位不变
        else:
            data_price.iloc[i + 1, 9] = data_price.iloc[i, 9]

    p1 = pd.DataFrame(Buy, columns=['买入日期', '买入价格', '备注'])
    p2 = pd.DataFrame(Sell, columns=['卖出日期', '卖出价格', '备注'])
    transactions = pd.concat([p1, p2], axis=1)  # 交易记录

    data_price = data_price.iloc[window_long:, :]
    data_price['ret'] = data_price.close.pct_change(1).fillna(0)
    data_price['nav'] = (1 + data_price.ret * data_price.position).cumprod()
    data_price['benchmark'] = data_price.close / data_price.close[0]

    ##2.3返回交易记录和全过程数据
    return transactions, data_price


trans, data = Strategy(df_price, window_short=25, window_long=50, loss_ratio=0.10)
print('交易记录:\n', trans)
print('结果展示:\n', data)


def performance(transactions, strategy):
    ##3.1策略评价指标
    # 年化收益率
    N = 250
    rety = strategy.nav[strategy.shape[0] - 1] ** (N / strategy.shape[0]) - 1

    # 夏普比
    Sharp = (strategy.ret * strategy.position).mean() / (strategy.ret * strategy.position).std() * np.sqrt(N)

    # 胜率
    VictoryRatio = ((transactions['卖出价格'] - transactions['买入价格']) > 0).mean()

    # 最大回撤率
    DD = 1 - strategy.nav / strategy.nav.cummax()
    MDD = max(DD)

    # 单次最大亏损
    maxloss = min(transactions['卖出价格'] / transactions['买入价格'] - 1)

    # 月均交易次数
    trade_count = strategy.flag.abs().sum() / strategy.shape[0] * 20

    print('------------------------------')
    print('夏普比率为:', round(Sharp, 2))
    print('年化收益率为:{}%'.format(round(rety * 100, 2)))
    print('胜率为:{}%'.format(round(VictoryRatio * 100, 2)))
    print('最大回撤率为:{}%'.format(round(MDD * 100, 2)))
    print('单次最大亏损为:{}%'.format(round(-maxloss * 100, 2)))
    print('月均交易次数为:{}(买卖合计)'.format(round(trade_count, 2)))
    print('------------------------------')

    result = {'Sharp': Sharp,
              'RetYearly': rety,
              'WinRate': VictoryRatio,
              'MDD': MDD,
              'maxlossOnce': -maxloss,
              'num': round(strategy.flag.abs().sum() / strategy.shape[0], 1)}

    result = pd.DataFrame.from_dict(result, orient='index').T
    print(result)

    ##3.2策略逐年表现
    nav_peryear = strategy.nav.groupby(strategy.year).last() / strategy.nav.groupby(strategy.year).first() - 1
    benchmark_peryear = strategy.benchmark.groupby(strategy.year).last() / strategy.benchmark.groupby(
        strategy.year).first() - 1

    excess_ret = nav_peryear - benchmark_peryear
    result_peryear = pd.concat([nav_peryear, benchmark_peryear, excess_ret], axis=1)
    result_peryear.columns = ['strategy_ret', 'bench_ret', 'excess_ret']
    result_peryear = result_peryear.T
    print('------------------------------')
    print(result_peryear)
    print('------------------------------')

    ##3.3策略净值可视化
    line1 = Line(init_opts=opts.InitOpts(width='1200px', height='600px', theme=ThemeType.DARK))
    line1.add_xaxis(strategy.index.tolist())
    line1.add_yaxis('策略净值', strategy.nav.round(2).to_list(), yaxis_index=0, is_smooth=True)
    line1.add_yaxis('基准净值', strategy.benchmark.round(2).to_list(), yaxis_index=0, is_smooth=True)
    line1.extend_axis(yaxis=opts.AxisOpts(min_=0.8, axislabel_opts=opts.LabelOpts(formatter="{value}")))
    line1.set_series_opts(label_opts=opts.LabelOpts(is_show=True))  # 是否显示数据标签
    line1.set_global_opts(
        xaxis_opts=opts.AxisOpts(is_scale=True, axislabel_opts=opts.LabelOpts(rotate=60)),
        yaxis_opts=opts.AxisOpts(min_=0.75, axislabel_opts=opts.LabelOpts(formatter="{value}")),
        datazoom_opts=[opts.DataZoomOpts(type_='inside')],  # 内部滑动
        title_opts=opts.TitleOpts(title="双均线择时策略回测", pos_left='45%'),  # 题目位置
        legend_opts=opts.LegendOpts(pos_right="35%", pos_top="5%"),  # 图例位置
        tooltip_opts=opts.TooltipOpts(trigger="axis", axis_pointer_type="cross")  # 添加趋势线
    )

    line2 = Line()
    line2.add_xaxis(strategy.index.tolist())
    line2.add_yaxis('净值之比', (strategy.nav / strategy.benchmark).round(2).tolist(), yaxis_index=1, is_smooth=True)
    line2.set_global_opts(
        datazoom_opts=[opts.DataZoomOpts(type_='inside')],  # 内部滑动
        legend_opts=opts.LegendOpts(pos_right="20%", pos_top="5%"),  # 图例位置
        tooltip_opts=opts.TooltipOpts(trigger="axis", axis_pointer_type="cross")  # 添加趋势线
    )

    line1.overlap(line2)
    line1.render("16.2 双均线择时策略回测.html")

    return result, result_peryear


performance(trans, data)

 

标签:index,pyecharts,记录,data,price,strategy,print,绘制,opts
From: https://www.cnblogs.com/yuyanc/p/17718708.html

相关文章

  • pyecharts 画K线记录 精细版
    importpandasaspdfrompyechartsimportoptionsasoptsfrompyecharts.chartsimportKline,Line,Bar,Grid,EffectScatterfrompyecharts.globalsimportSymbolTypefrompyecharts.commons.utilsimportJsCodedefdrawKline(df):#klinex=df.in......
  • 日常记录--day7--2023-9月20日--周三
    日程:今天只有上午有节英语课,8点30起床,吃了个早饭去上课。中午小睡一个小时,下午没课,起来学习了一会Javaweb,今天主要学了HTML,自己写了个简单的,晚上7-9点继续javaweb,今天没有力扣。学了什么:Javaweb让人头疼,复习了之前的力扣题,继续学习Javaweb。PS:不想学习,想要成为充电线;......
  • Netfilter日志记录
    iptables-traw-IPREROUTING-ptcp--dport80-jLOG#iptables-traw-IPREROUTING-ptcp--dport80-jLOG--log-level3--log-prefix"ipt-err:" 可以指定log级别日志级别可通过syslog定义进行查看。另外LOG目标还可指定参数:–log-tcp-sequence,–log-tcp-option......
  • Learn Git in 30 days——第 21 天:修正 commit 过的版本历史记录 Part 3
    写的非常好的一个Git系列文章,强烈推荐原文链接:https://github.com/doggy8088/Learn-Git-in-30-days/tree/master/zh-cn在版本控制过程中,还有个常见的状況,那就是当你在一个分支中开发了一段时间,但后来决定整个分支都不要了,不过当中却有几个版本还想留下,这时要删除分支也不是,把......
  • 行车记录仪方案 联发科Mini安卓主板超低功耗
    现代行车记录仪常常存在分辨率不清、死机、卡顿和高功耗等问题,同时价格较高。为了解决这些问题,提出了行车记录仪的新解决方案。新解决方案采用高性能处理器,确保行车记录仪的流畅运行,告别死机问题。新一代高性能运动图像处理器搭配大内存,能够顺畅记录行车过程中的美好瞬......
  • 记录--不要再滥用可选链运算符(?.)啦!
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前言可选链运算符(?.),大家都很熟悉了,直接看个例子:constresult=obj?.a?.b?.c?.d很简单例子,上面代码?前面的属性如果是空值(null或undefined),则result值是undefined,反之如果都不是空值,则会返回最后一个d属性......
  • vuejs+antv-g6绘制图表
    该内容包括antv-g6官网地址、antv-g6的基本使用(包括自定义节点、常用插件(右键菜单等)、基本事件、目前我所遇到的一些需求)。1、antv-g6的官网地址:https://g6.antv.antgroup.com/examples2、安装antv-g6组件npminstall@antv/g6 3、创建antvView.vue文件使用antv/g6......
  • 230920 创记录的亏损 泉阳泉
    今天-2.5,出了泉阳泉,亏损12%左右.模式外的交易,以及凭借主观感觉做交易,导致出现了如此大的亏损.1.模式外你磨刀霍霍,准备低吸,但是,从常山到一众,你选择了看起来跌的很快的泉阳泉.一个主要的观点,就是你前几天认为,它股性好,可能是大跌洗盘,你认为它会复制另外一个个股的走......
  • 记录 小程序调用前置摄像头的数据获取及简单配置
    业务是需要调取前置摄像头之后获取图片上代码wx.chooseMedia({count:1,//只允许上传一张照片 mediaType:['image'],//文件类型sizeType:['original','compressed'],//是否压缩所选文件,original原始compressed压缩......
  • thinkphp上传文件失败的一次记录
    问题出现有用户反映上传图片报网络错误,问题转到开发之后怀疑可能是用户上传的图片比较大导致的错误,后面测试发现在上传8m左右大小的图片的时候就会报错,但是报的错误不是代码里面图片大小验证规则的错误,而是异常捕获的错误,让我很纳闷后来决定先让前端在页面提......