获取股票数据【实时更新股票数据、创建你的股票数据】、计算交易指标【买入、卖出信号、计算持仓收益、计算累计收益率】

article/2025/9/14 5:25:51

在上一次获取股票数据【使用JQData查询行情数据、财务指标、估值指标】学习了使用JQData来查询股票相关数据, 这次则开始一点点构建咱们的量化交易系统了。

量化交易平台功能模块了解:

对于一个量化交易平台,它主要包含如下功能模块:

而整个模块基本都是基于后端来开发的,只有图表可视化是用一个可视化库来打造,并未涉及到前端的功能,核心主要是来学习业务逻辑:

获取股票数据:

新建readme:

在咱们的工程中新建一个Readme文件用来进行功能的描述:

#DeltaTrader## 功能模块### 行情记录 (data)#### stock.py
- 获取所有A股股票列表
- 获取单个股票行情数据
- 导出股票行情数据
- 转换股票行情周期
- 获得单个股票财务指标
- 获取单个股票估值指标
### 策略开发### 自动交易

三大块,其中目前主要关注获取行情记录数据这块,所以咱们的包名是data:

而其它模块会随着学习的不断深入再慢慢填充,其实对于这些数据的获取在上一次咱们已经都试验过了,只是没有将其封装成一个通用的API,所以接下来则会基于咱们上次实现的代码进行一个抽取,来实现这里所列出的具体API。

获取所有A股股票列表:

这个在之前咱们实现的代码为:

咱们直接基于它来改一下:

获取单个股票行情数据:

先看一下咱们之前实现的:

定义一下:

导出股票相关数据:

原来咱们在获取股票财务指标时用过:

咱们来封装一下:

其中这里新建一个price目录,专门用来存储股票价格相关的文件:

如果要导出其它类别的数据,新建相关目录,在调用此函数时传相关的type名称既可。

转换股票行情周期:

先来看一下之前咱们使用的:

下面基于它来封装一下:

获取单个股票财务指标:

之前的代码:

封装一下:

获取单个股票估值指标:

封装为:

调用stock:

接下来咱们则来调用一下咱们重新封装的stock。

1、新建一个测试模块:

为了规范,这里将测试相关的代码都放到另一个模块中:

2、获取股票行情数据并导入csv:

控制台输出:

看一下表格文件有木有生成?

但是!!!你会发现表格中表头部分少了一个日期:

这个时候是需要咱们来处理一下的,如果不处理在未来的cvs的读取数据时是会有问题的,这个问题是啥呢?下面在stock中先增加一个cvs的读取函数,读出来自然就明白了:

咱们来调用读取一下:

接下来就来修复它,需要在导出函数那块进行处理了,如何处理呢,此时则需要对数据的索引进行重命名了,如下:

再重新导出,再获取:

计算交易指标:

接下来就来学习跟咱们炒股操作息息相关的一些东东啦~~

使用shift函数计算涨跌幅:

每日涨跌幅:

先来计算一下每日的涨跌幅,看是否准确,先来明确一下涨跌幅的计算公式:“(当期收盘价-前期收盘价)/ 前期收盘价” ,

其中的当期可以是当天、当分钟、当秒钟、当周、当月,具体实现如下:

其中shift(1)表示上一行的数据,而shift(2)表示上两行的数据,shift(-1)表示下一行的数据。

下面来调用验证一下是否准确,这里还是以平安银行的日K数据为例:

运行看一下:

/Users/xiongwei/opt/anaconda3/bin/python3.8 /Users/xiongwei/Documents/workspace/python/QuantitativeTrading/studycode/example/stock.py
auth success open  close   high    low       volume         money
2021-09-01  17.48  17.88  17.92  17.01  231689409.0  4.046284e+09
2021-09-02  18.00  18.40  18.78  17.80  242260354.0  4.454545e+09
2021-09-03  18.50  18.04  18.50  17.70  139481871.0  2.523273e+09
2021-09-06  17.93  18.45  18.60  17.78  151522556.0  2.780281e+09
2021-09-07  18.60  19.24  19.56  18.35  162234416.0  3.067366e+09open  close   high    low       volume         money  close_pct
2021-09-01  17.48  17.88  17.92  17.01  231689409.0  4.046284e+09        NaN
2021-09-02  18.00  18.40  18.78  17.80  242260354.0  4.454545e+09   0.029083
2021-09-03  18.50  18.04  18.50  17.70  139481871.0  2.523273e+09  -0.019565
2021-09-06  17.93  18.45  18.60  17.78  151522556.0  2.780281e+09   0.022727
2021-09-07  18.60  19.24  19.56  18.35  162234416.0  3.067366e+09   0.042818Process finished with exit code 0

接下来就要来验证咱们计算涨幅的正确性了,咱们这里来挑两天的验证一下既可,比如我们挑这两天的:

回到交易平台中咱们来看一下:

完成正确。

每周涨跌幅:

为了进一步验证准确性,这里再来看一下周K的涨跌幅,那首先咱们需要将日K的数据转换为周K的数据对吧,该功能我们已经封装好了,直接调用既可:

好,获取了三周的数据,回到同花顺软件里确认一下准确性:

为啥咱们打印的日期是显示的2021-09-05呢?

其实我们打印的是一周的最后一天:

而股票软件里是算到工作日的最后一天,关于这个细节就不过多较真的,总之涨幅结果对相同的,再来看一天的:

模拟股票交易:

买入、卖出信号:

对于股票操作最频繁的就是买入和卖出操作对吧,所以接下来会以一个简单的策略来对股票生成买卖信息,注意:由于这阶段还在打基础,还没有学习各种选股策略的应用这块,所以这里的策略是很呆板的,比如可能就是定就是周一卖,周四买之类的,重点是能让我们程序按预期来生成买卖信号。

1、新建Strategy模块:

由于未来会有很多的一些策略,所以这里新建一个包名:

2、创建周期选股策略:

好,接下来则来创建一个非常简单按周期选股的策略:周四买入、周一卖出【有过炒股经历的应该也能感受到这个规则,也有点用吧,因为基本上到了周四就开始阴了,而周一作为一周的开始往往势头比较旺~~】

"""
用来创建交易策略、生成交易信号
"""
import data.stock as st
import numpy as npdef week_peroid_strategy(code, time_freq, start_date, end_date):data = st.get_single_price(code, time_freq, start_date, end_date)# 新建周期字段,周一是从0开始data['weekday'] = data['date'].weekday# 周四买入,下面代码的意思是如果是周四,则是1表示买,0表示不买data['buy_signal'] = np.where((data['weekday'] == 3), 1, 0)# 周一卖出,下面代码的意思是如果是周一,则是-1表示卖,0表示不卖data['sell_signal'] = np.where((data['weekday'] == 0), -1, 0)return dataif __name__ == '__main__':data = week_peroid_strategy(code='000001.XSHE', time_freq='daily',start_date='2021-08-25',end_date='2021-09-08')print(data)

下面运行看一下,报错了:

原因是咱们的索引列木有给它重命名,没有date这一列,当时我们重命名只是在导出函数中加了:

好,那修改一下程序:

为了打印看得更加清楚,这里将字段过滤一下:

3、信号整合:

接下来想一个场景,就是有可能周四你买入,周五又有可能买入对吧,那连续两天买入,在实际做策略时会经常碰到这种重复的信号的,所以这里针对这样的场景模拟一下:

那针对这样的数据,咱们得想办法只让第一天买入为1,其它的买入都变为0,其实也很简单,如下:

此时又用到了shift()函数了对吧,不过这里还是会有些没覆盖的场景,这里将获取数据的时间改一下就能看到问题之所在了:

好,此时咱们把整合的那句代码又打开注释,再运行,你会发现:

这里需要改一下条件了,如下:

当然对于卖出信号也需要整合一下,因为也有可能出现重复卖出的情况,如下:

4、最终生成买卖信号:

目前buy_signal和sell_singal,在同一天只可能有一种signal,要么是买,要么是卖对么?所以这里再加一个字段,用来做买卖的直观判断,不然我看两个字段有点晕,如下:

计算持仓收益:

了解:

先来看一下股票软件中持仓收益一般包含的数据内容:

其中咱们需要了解的有如下几个计算公式:

1、总盈亏= (市价 - 成本价) * 股数;

也就是表格中这一列的值:

2、 浮动盈亏比 =  (市价 - 成本价) / 成本价;

也就是表格中的这一列的值,我们平常最关心的收益率:

比如7.377,通常也叫挣了7.3个点,其实还有一个更加简便的计算方法,比如盈利的情况下,直接拿市价/成本价,然后肉眼就可以看到收益率了,比如表格中的新城股份:

咱们来除一下:

然后用它再减去1,此时就可以看到百分收益率就是7.377啦,如果对于亏损的情况也类似,用价格高的除以价格低的就成。 

3、成本价 = 买入金额 / 持有股数

因为有可能在实际会分仓进行买入,所以成本价计算就是如上公式了。

4、股数 = 累计买入股数

这个就比较简单了,通常一手是100股。

以上数据不用太过关心,因为股票软件里持仓记录那块都能一眼看到,对于我们来说只要知道如何查询出这些数据就可以了, 其中重点是关注如何计算持仓收益率,这个是评价一个策略是否挣钱最直接的一个指标。

实现:

1、收益率计算:

接下来咱们基于上面的买卖信号数据来计算一下每次的收益率,先分析一下咱们的数据:

发现在买和卖之间的天数肯定是不一定的,短线的周期短,中长线的周期长,而对于计算收益率来说,只关心买入和卖出那两天的价格对吧?所以,我们可以为了方便计算的收益率,把买和卖中间持股的记录都给删掉,只保留买和卖那两天的数据,这样计算的话就比较方便了,所以基于这样的思路咱们来写一下逻辑:

接下来计算收益率为:

其中发现,对于买的情况很显然是不需要显示收益率的,所以这里再过滤一下:

2、获取上市以来所有数据:

目前咱们只获取了二个月的数据,那如果我想获取单支股票自上市以来的所有数据来进一步观察咱们策略的有效性呢?此时可以回到JQData的官网找一下如何获得上市以来的数据,其实就是在获取股票单个行情数据函数中的start_date传上市的时间既可:

那上官网查一下:

好,咱们来改一下:

此时咱们在调用时就可以传None了:

其中需要导一下datetime:

3、重构week_peroid_strategy函数:

目前对于week_peroid_strategy可以稍加优化一下代码,因为看着有点乱,就是把这俩逻辑抽离出去:

说不定未来还能在其它的功能上使用上,如下:

这样,整个逻辑就变得清爽了:

这个思想不管是用啥语言写程序都是应该我们来进行考虑的,因为可以大大增加代码的可读性。

另外目前咱们代码这有个报警:

是因为在main中也是用的data:

这里将它改一下名称既可:

4、打印一下数据的均值:describe()

对于平安银行自上市至今的数据太多了,可以用下面来查看一下均值,对整体数据有一个大概的了解:

关于各参数的函数可以参考:

3、将其可视化输出:plot()

接下来咱们也可以使用plot()函数来将整个的收益率情况可视化一下,如下:

是不是似曾相识,是的,在之前线性代数的学习https://www.cnblogs.com/webor2006/p/14271706.html中也使用到了该可视化库了,这也就是知识的关联系,学习的任何一个知识在未来的某一个时刻一定还能出现它的身影,并不是完全孤立的,好,运行,一个可视化的界面就出现了:

计算累计收益率:

概述:

现在我们已经能计算出一支股票的单次的收益率对吧?那如何根据单次收益率来计算出一个累计收益率呢?比如你支付宝中的基金【关于基金的学习,也是今年的一个计划,将来得实际行动起来】,通常在这个页面会展示累计收益率:

那你有没有搞清楚这个值是如何计算出来的呢?这里正好可以弥补一下这个知识,假如你买的一个基金,整体的收益情况如下:

那累计收益的计算,咱们口算一下,算完之后你就会发现公式出来了,公式有了那们咱们的程序就有戏了:

这个比较简单对吧,也就是原来100块钱,经过一天之后的收益利息,挣了3块钱,总金额变成了103了,好,接着算第二天的累计收益了:

接下来再把剩下的两天算出来,你就会发现公式了:

其中“(1 + 当天收益率)的累积乘积 ”,其实就是一个通用计算累计收益率的公式【一定要注意累计收益和累计收益率,累计收益是有本金在里面,而累计收益率是不包含本金的,就是一个比例嘛,这一点必须要搞清楚】,但是!!!它还是有问题的,为啥呢?那咱们以这个公式来算一下图中第一天的累积收益就知道了,很明显第一天的累计收益率就是3%,因为只有一天嘛,但是如果以"(1 + 3%)"来算,很明显它的收益率就为103%,需要将本金去掉,也就是累计收益率的公式为“(1 + 当天收益率)的累积乘积 - 1”,(1 + 3%) - 1 是不是收益率就是3%了?

实现:

接下来则回到python的世界,来计算一下平安银行的累计收益率:

接下来咱们来调用一下:

而看一下可视化的累积收益率的图:

从这个收益曲线图来看,貌似周四买入,周一卖出的简单策略,收益率还是蛮不错的嘛,当然啦,不可能按这么简单的规则来炒股的,纯学习。

最后在写python时有一个小的细节这里提一下,就是在计算累计收益率不是用到了这个函数嘛:

但是!!!你这个函数完全得要你手动敲全,不能智能的提示对吧?其实不提示的原因也很简单,原因是由于:

不知道它加出来的是DataFrame,所以当然也就不知道给你提示它里面的函数喽,要想解决这个提示问题,咱们可以显示的指定这数据是DataFrame既可,如下:

此时再输入时就可以看到提示了:

关注个人公众号,获得实时推送

 


http://chatgpt.dhexx.cn/article/cDRjvUqH.shtml

相关文章

使用Python获取股票实时数据和历史数据

决定新建一个专栏,专门研究股票数据的API接口。 由于不是混金融领域的人,百度调研了一会儿,没有找到合适的大公司维护的API接口。 yahoo-finance PyPI 这玩意架梯子都访问不到数据,不知道乍回事。许多大牛维护的pip包都是基于这…

Tushare免费获取股票数据:实时数据,历史数据,行情数据

一 操作手册 引导用户顺利开始使用Tushare Pro数据,以下步骤将带您开始Tushare数据之旅: 用户注册登录后可调用数据:https://tushare.pro/register?reg399205 二 如何获取TOKEN凭证 1、登录成功后,点击右上角->个人主页 2、…

如何用 Python 获取实时的股票数据?

这个我会!先上图 这篇回答中,我将向你展示两种不同的代码版本(加强版和一般版) 代码运行环境说明(非常重要) Python版本要求 Python 3 需要安装的库 efinance 库的安装方法是:打开 cmd&#x…

怎么用Python获取股票的实时数据?

学习目标: 应用industry实现行业股票列表的获取应用history_bars实现股票合约历史行情数据获取应用get_fundamentals实现股票基本面数据获取使用query的过滤条件完成股票数据的过滤应用scheduler定时器实现股票数据定期获取 1、 数据接口种类 获取指定行业、板块…

SAP UI5 Focus related

tap, keydown, keypresssap.ui.core.FocusHandlersap.ca.scfld.md.app.CommonHeaderFooterHelperevent new jQuery.Event(originalEvent);focusin, activate, blur, focusout, sapfocusleaveoElement._handleEvent(oEvent); 要获取更多Jerry的原创…

Consider defining a bean of type ‘com.qf.user.consumer.feign.api.UserFeignAPI‘ in your configuration

Consider defining a bean of type ‘com.qf.user.consumer.feign.api.UserFeignAPI’ in your configuration… 引导类加注解EnableFeignClients

Prime算法 C++实现

Prime算法 算法介绍: 课本实现方法: 先从最小堆说起(heap):任一结点的关键码均小于或等于它的左右子女的关键码,位于堆顶(即完全二叉树的根结点的位置)的结点的关键码是整个集合中最…

【数学】Prime-Factor Prime

Prime-Factor Prime 题目描述 A positive integer is called a "prime-factor prime" when the number of its prime factors is prime. For example, 12 is a prime-factor prime because the number of prime factors of 12223 is 3, which is prime. On the other…

Prime Factory (Training, Math)

Prime Factory (Training, Math) 题目描述 Your task is simple: Find the first two primes above 1 million, whose separate digit sums are also prime. As example take 23, which is a prime whose digit sum, 5, is also prime. The solution is the concatination of t…

Fiori Fundamentals和SAP UI5 Web Components

这周有位同事邀请我给团队讲一讲SAP技术的演进历史,所以我准备了下面几个主题来介绍。 其中SAP的技术回顾和演进,我的思路就是从前后台两方面分别介绍。 我画了一张非常简单的图: 去年5月我写过一篇文章:SAP UI和Salesforce UI开…

C++Prime Plus(3)

目录 51.抽象和类52.类的使用53.对象构造54.对象析构55.const与类56.this指针57.类作用域58.运算符重载59.运算符重载的实例60.友元61.运算符重载-成员或非成员62.类的类型转换63.拷贝构造函数与赋值运算符重载64.静态数据成员65.静态成员函数 51.抽象和类 类型的构成 1.数据占…

C++Prime Plus(6)

目录 92.STL(1)容器93.STL(2)迭代器94.STL(3)函数对象95.STL(4)算法 92.STL(1)容器 标准模板库 STL(Standard Template Library),是 C 标准库的一部分,不需要单独安装,只需要#include 头文件。STL提供了容器&#xff…

C++Prime Plus(5)

目录 85.异常(1)异常处理机制86.异常(2)exception类87.RTTI(1)88.RTTI(2)89.类型转换运算符90.string类91.智能指针 85.异常(1)异常处理机制 异常:运行错误(比如无法打开文件,动态内存申请失败),导致程序无法继续正常…

SAP Fiori学习笔记

资料链接:有些是需要自带梯子的哦~ Fiori Design Guidelines​experience.sap.com戴团长:SAP Fiori Design​zhuanlan.zhihu.com如何评价 SAP Fiori Design Guidelines?​www.zhihu.comhttps://mp.weixin.qq.com/s?__bizMzIyNjY…

C++Prime Plus(2)

目录 21.for循环(1)22.for循环(2)23.while循环24.do while循环25.二维数组与嵌套循环26.if语句27.逻辑表达式28.条件表达式29.switch语句30.文件概念31.文本文件的输入输出32.函数详解(1)回顾33.函数详解(2)参数传递34.函数详解(3)数组传递35.函数详解(4)C风格字符串36.递归概念…

C++Prime Plus(1)

目录 1.C简介2.程序生成(创建源码,编译和链接)3.进入C4.C语句5.函数入门6.整型7.char,bool(小整数)8.const与符号常量9.浮点数10.算术表达式11.数组12.C风格字符串13.C风格字符串14.结构15.指针16.动态内存…

C++Prime Plus(7)

目录 96.输入输出概述97.使用cout输出(1)ostream基本功能98.使用cout输出(2)格式化输出99.使用cin输入100.文件(1)简单的文件IO101.文件打开的进一步讨论102.二进制文件访问103.随机读写 96.输入输出概述 C的输入输出是由库iostream中提供的一组类实现的; 流 C把输…

E-Prime软件包及安装

E-Prime软件包及安装 1 版本问题2 安装过程3 注意事项4 唠唠叨叨 Hello, 这里是行上行下,我是喵君姐姐~ 众所周知,E-Prime是实验设计的执行者。 当我们提出一个想法,则需要一个具体的软件来实现它。 而E-Prime相对于Matlab和Py…

Prime Sample

又发现了个框架 但没有代码啊~~ 还是搬来了,重要样本关注机制,一种新颖的目标检测框架 上论文 论文地址: https://arxiv.org/pdf/1904.04821.pdf 在目标检测框架中,平等对待所有样本并以平均性能最大化目标是一种常见的范例。在…

Prime Factors

此题需要使用到质因子分解的算法,可以参考以下链接: https://blog.csdn.net/qq_42410605/article/details/100150140 题目描述: Given any positive integer N,you are supposed to find all of prime factors,and write them in the form…