当前位置: 首页 > news >正文

【数据分析】Python+Tushare实现均线金叉死叉交易策略回测

【数据分析】Python+Tushare实现均线金叉死叉交易策略回测

简介

在本文中,我们将利用 Python 和 Tushare 数据接口,对贵州茅台(600519.SH)进行数据分析,并实现基于“双均线”策略的量化回测,完整评估该策略的收益效果。

项目目标

  • 使用tushare包获取贵州茅台的历史行情数据。
  • 计算该股票历史数据的5日均线和30日均线。
  • 分析输出所有金叉日期和死叉日期。
  • 模拟实际买卖交易流程。

1.数据获取和处理

导入所需要的库
import tushare as ts
import pandas as pd
from pandas import DataFrame,Series
import numpy as np
初始化Pro接口,填入自己在tushare注册后的Token
pro = ts.pro_api('f573ee6f0129fd70b86b2b3a7858210bf008fe47b0233ce71d98986b')
df = pro.daily(ts_code='600519.SH', start_date='20100101')
print(df)
数据展示

在这里插入图片描述

将数据存储在本地

调用to_csv方法将获取到的数据写入到本地进行存储,并进行读取。

df.to_csv('./maotai.csv')
df = pd.read_csv('./maotai.csv')
print(df.head())
运行结果

在这里插入图片描述

删除多余的列并查看数据类型

对于多余的Unnamed:0,需要删去

df.drop(labels='Unnamed: 0', axis=1, inplace=True)

查看每一列的数据类型

print(df.info())
运行结果

可以看到并没有缺失值
在这里插入图片描述

转化时间序列类型和作为行索引

将date列转为时间序列类型

df['trade_date'] = pd.to_datetime(df['trade_date'], format='%Y%m%d')

将date列作为源数据的行索引

df.set_index('trade_date', inplace=True)
print(df.head())
运行结果

在这里插入图片描述

2.计算双均线

  • 计算该股票历史数据的5日均线和30日均线
    - 什么是均线?
    - 对于每一个交易日,都可以计算出前N天的移动平均值,然后把这些移动平均值连起来,成为一条线,就叫做N日移动平均线。移动平均线常用线有5天、10天、30天、60天、120天和240天的指标。
    - 5天和10天的是短线操作的参照指标,称做日均线指标;
    - 30天和60天的是中期均线指标,称做季均线指标;
    - 120天和240天的是长期均线指标,称做年均线指标。
    - 均线计算方法:MA=(C1+C2+C3+…+Cn)/N C:某日收盘价 N:移动平均周期(天数)
计算5日和30日均线
ma5 = df['close'].rolling(5).mean()
ma30 = df['close'].rolling(30).mean()
画出5日均线和30日均线
# 画出5日均线
import matplotlib.pyplot as plt
plt.plot(MA5[50:180])
plt.plot(MA30[50:180])
plt.show()
运行结果

在这里插入图片描述

计算金叉和死叉

  • 分析输出所有金叉日期和死叉日期
    - 股票分析技术中的金叉和死叉,可以简单解释为:
    - 分析指标中的两根线,一根为短时间内的指标线,另一根为较长时间的指标线。
    - 如果短时间的指标线方向拐头向上,并且穿过了较长时间的指标线,这种状态叫“金叉”;
    - 如果短时间的指标线方向拐头向下,并且穿过了较长时间的指标线,这种状态叫“死叉”;
    - 一般情况下,出现金叉后,操作趋向买入;死叉则趋向卖出。当然,金叉和死叉只是分析指标之一,要和其他很多指标配合使用,才能增加操作的准确性。
设置条件
df = df[30:]
MA5 = MA5[30:]
MA30 = MA30[30:]
s1 = MA5 < MA30
s2 = MA5 > MA30

s1 = MA5 < MA30:金叉(5日均线上穿30日均线)
s2 = MA5 > MA30:死叉(5日均线下穿30日均线)

计算金叉和死叉对应的时间
golden_ex = -(s1|s2.shift(1)) # 判度金叉的条件
golden_date = df.loc[golden_ex].index # 金叉的索引(也就是时间)
death_ex = s1 & s2.shift(1) # 判断死叉的条件
death_date = df.loc[death_ex[df.index]].index # 死叉对应的索引(也就是时间)
print(golden_date,death_date)
运行结果

在这里插入图片描述
在这里插入图片描述

4.模拟买卖交易

  • 如果从2010年1月1日开始,初始资金为1000000元,金叉尽量买入,死叉全部卖出,则到今天为止,炒股收益率如何?
  • 分析:
    - 买卖股票的单价使用开盘价
    - 买卖股票的时机
    - 最终手里会有剩余的股票没有卖出去
    - 会有。如果最后一天为金叉,则买入股票。估量剩余股票的价值计算到总收益。
    - 剩余股票的单价就是用最后一天的收盘价。
计算金叉和死叉对应的时间
# 金叉的标识(1)
s1 = Series(data=1,index=golden_date)
# 死叉的标识(0)
s2 = Series(data=0,index=death_date)
s = pd.concat([s1,s2])
s = s.sort_index() # 排序,存储金叉和死叉对应的时间
print(s)
运行结果

在这里插入图片描述

计算总收益
# 设置本金1000000(不变的)
first_money = 1000000
# 设置可变的变量(买股票和卖股票的钱都从该变量进行操作)
money = first_money
# 设置持有的股票的数量(100股=一手)
hold = 0
for i in range(0,len(s)):if s.iloc[i] == 1:# 获取股票的单价time = s.index[i]# 金叉的时间p = df.loc[time]['open']# 金叉股票单价hand_hold = money // (p*100)# 使用1000000最多买入多少手股票hold = hand_hold * 100money -= (hold*p)# 买股票的钱从可变的本金中扣除else:death_time = s.index[i]# 死叉时间p = df.loc[death_time]['open']# 死叉股票单价money += (hold*p)# 卖出的股票收入加入到可变的本金中hold = 0# 持有的股票变为0
last_money = hold * df['close'].iloc[-1]# 剩余股票的价值
# 总收益
print(money+last_money-first_money)
运行结果

-993528.9999999991

相关文章:

  • 黑马JVM解析笔记(六):深入理解JVM类加载机制与运行时优化
  • 【JS-6.2-模板字符串】ES6 模板字符串:现代JavaScript的字符串处理利器
  • 可达性分析算法Test
  • 如何将Excel表的内容转化为json格式呢?
  • 深入理解Mysql索引底层数据结构和算法
  • InnoDB的redo日志涉及文件及结构
  • 嵌入式硬件中电容的基本原理与详解
  • WPF学习笔记(13)列表框控件ListBox与数据模板
  • Spring Boot项目开发实战销售管理系统——数据库设计!
  • 大模型在恶性心律失常预测及治疗方案制定中的应用研究
  • 计算机网络基础知识详解
  • 筑牢网络安全屏障
  • RabbitMQ 集群与高可用配置
  • 【安全有效新方案】WSL 默认路径迁移实战:通过 PowerShell 符号链接实现自动重定向
  • 【大语言模型入门】—— 浅析LLM基座—Transformer原理
  • 面试八股---HTML
  • 【51单片机节日彩灯控制器设计】2022-6-11
  • Linux的基础IO
  • Segment Anything in High Quality之SAM-HQ论文阅读
  • 浮油 - 3 相分层和自由表面流 CFX 模拟