本次是完成一个股票的计算项目,其主要功能如下:

(1)输入股票代码、起止日期后下载股票的日期、股票代码、名称、收盘价、最高价、最低价、开盘价等一系列基本股票数据。

(2)计算异同移动平均线指标(MACD)、布林线(BOLL)的上轨线指标和下轨线指标、平均趋向指标(ADX)、相对强弱指标(RSI)、顺势指标(CCI)、30日和60日的移动平均线指标(MA)等并进行展示。

(3)设计交互界面。

(原项目比这个麻烦一点,但是不符合实用性,并且由于连接了mysql数据库无法普遍使用,我对此做了一点小小更改)

写在前面:

第一次写博客,做的不好多多包涵。本题目来源于个人的一个课程设计,进行了一定改编。

其实这是一个很简单的小项目,特别是做完去回看自己写的代码,会觉得其实也并没有什么太难的地方,但是在自己刚开始写的时候,包括学习爬虫、csv文件的处理、mysql的报错、stockstats的函数等也花费了大量时间,仅以此文记录一下学习生涯。

一、获得股票数据

首先关于股票数据,我选择某财经网站进行爬取,首先因为其有专门的历史数据页面,并且通过URL格式固定。

其次,相比于东方财富有反爬虫部分,该网站并未对爬虫有较多的限制,更加方便爬取。(由于版权问题,代码中的URL已被删除,若需要请自行加入)

关于爬虫部分,首先新建一个GetData模块来放置爬虫类,命名为Download_HistoryStock,在建立该类的self函数时,我们要传入code(股票代码),startDate(开始爬取的时间),endDate(截止时间)三个变量,而这三个变量我们会在交互页面通过用户输入传入,以此满足用户需求。而爬虫的headers只需要打开网页后按F12,选择网络,点击html的那个名称,并拉到最下面则可以查看自己的headers。

第二个函数即Download(数据下载)函数,为了避免在当前文件夹下数据杂乱,我首先新建了一个文件夹“数据”用于存放下载的股票历史数据。在调试过程中我发现,如果想要读取当前文件夹下的其他文件夹中的文件无法直接打开,open函数只能读取当前文件夹或绝对路径,故我先设置了一个basepath来存放当前文件夹的路径(其中调用了os模块的path.dirname,主要功能是返回当前文件夹的路径)再加上“\\数据”对存放数据的文件夹进行文件读取。接下来使用os.path.exists来先判断一下“数据”文件夹是否存在,如果不存在则使用os.makedirs来创建文件夹。

接下来就是对于网页的爬取部分,通过网页代码中找到网易财经历史数据的URL,通过观察发现网易财经的URL中包含了起止时间和股票代码一共三个会发生改变的变量,故我们将self的三个变量进行替换,即可完成对任意股票URL的爬取,随后我们使用request.get获得网页的内容,并通过循环将其读取到数据文件夹 的“code.csv”文件中。open函数可以在不存在该文件时创建文件,若存在则直接打开,并进行覆盖写入。

源代码如下:

#By ZUEL_Ronin
# 该模块用于爬取网站
import os
import requests
from fake_useragent import UserAgentclass Download_HistoryStock:  # 爬取股票历史数据def __init__(self, code, startDate, endDate):  # URL 和 headers设置self.code = codeself.startDate = startDateself.endDate = endDateself.downloadURL = print(self.downloadURL)self.headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36 Edg/100.0.1185.44"}def Download(self):  # 爬取股票历史数据path = "数据"basepath = os.path.dirname(__file__)if not os.path.exists(path):  # 在当前文件夹下新建“数据”文件夹,用于存放爬取下的数据os.makedirs(path)DownloadURL = data = requests.get(DownloadURL)  # 获得数据网页的主要内容fileHistoryStock = open(basepath + "\\" + '数据' + '\\' + self.code + '.csv', 'wb')for chunk in data.iter_content(chunk_size=10000):  # 将数据读写到文件中if chunk:fileHistoryStock.write(chunk)print('股票', self.code, '历史数据爬取成功,已存到数据文件夹中的' + self.code + ".csv")fileHistoryStock.close()

来看一下执行的结果,以晨光股份(603899)为例:

有一点美中不足的是在股票代码中,第一个字符会出现 ‘ ,应该是页面源代码的问题,在后续数据处理中可以用strip()函数将这个删除。

二、数据处理并生成图像

该部分在第一次看到我觉得非常难算,直到发现了一些金融类的python库也可帮忙解决,本次使用的是stockstats库,其安装方式很简单,只需要

pip install stockstats

该库的具体介绍比较少,很多用法还需摸索,其源码可以在csdn上找到,共一千多行代码左右,感兴趣的可以看看(顺便学习一下金融知识)。

首先该库可以直接读取csv文件,但是我导入时会报错如下

utf-8编码类型不对,然后我去查看了那个stockstats的源码发现(对,就是那个一千多行,看到我头疼的源码),它对csv文件的处理非常死板,标题必须是英文,而我的标题是中文,其次,列名必须严格按照date,open,close,high,low,volume来编写,因此我们需要对csv文件做一个预处理。

这部分主要就是删除多余的列,并将第一行替换为英文内容,多余的列可以直接用drop()来删除,但是根据网上删除行时一直发生错误,也无法直接在最前面加入标题行(注:网上很多对于csv文件的操作似乎都会产生一点问题,也没有太多资料进行查找)。于是,我选择新建一个csv文件,输入标题行后再循环输入该文件的除标题行以外的正文内容,最终完成对csv文件的预处理。

预处理源码如下

#By ZUEL_Ronin
# 该模块用于对爬取的数据进行预处理
import csv
import pandas as pd
import osdef CsvChangeToStockStats(code):  # 将股票第一次爬取的数据进行预处理,方便下面进行股票指标计算basepath = os.path.dirname(__file__)data = pd.read_csv(basepath + '\\' + '数据' + '\\' + code + '.csv', encoding="gb2312")data = data.sort_values(axis=0, by="日期", ascending=True)# 按日期进行排序data = data.drop(['股票代码', '名称', '前收盘', '涨跌额', '涨跌幅', '换手率', '成交金额', '总市值', '流通市值'], axis=1)data['收盘价'], data['最高价'], data['最低价'], data['开盘价'] = data['开盘价'], data['收盘价'], data['最高价'], data['最低价']data.to_csv(basepath + '\\' + '数据' + '\\' + code + "_backup.csv", index=False, encoding="gb2312")num = 1headline = ['date', 'open', 'close', 'high', 'low', 'volume']with open(basepath + '\\' + '数据' + '\\' + code + '_ForStockStats.csv', 'w', newline='') as csvOutFile:# 将修改后的文件保存在 code_ForStockStats.csv中with open(basepath + '\\' + '数据' + '\\' + code + '_backup.csv', 'r', newline='') as csvInput:# 中间计算过渡文件,使用后在最后进行删除reader = csv.reader(csvInput)for a in reader:if num == 1:num = num + 1csvWrite = csv.writer(csvOutFile)csvWrite.writerow(headline)else:csvWrite = csv.writer(csvOutFile)csvWrite.writerow(a)csvInput.close()csvOutFile.close()os.remove(basepath + '\\' + '数据' + '\\' + code + "_backup.csv")  # 删除冗余文件

处理完之后则可直接调用stockstats库进行计算相关指标,stockstats库功能非常强大,调用csv文件的代码如下:

stockStat = stockstats.StockDataFrame.retype(pd.read_csv('000001.csv'))

调用计算代码如下:

 stockStat[['macd']]

但是如今网络上似乎找不到输出具体值的方法,如果直接print()由于输出无法通过索引获得,会导致无法将数据导出计算。于是,我又去读了一下那个长达一千两百行的源码(所以强烈建议大家多读读,能治疗头发过多),最终发现可以通过

 stockStat[['macd']].get("macd")

前后都需要说明是哪一个函数,第一次调用get时,又由于前面没有加上macd,导致报错。该函数后面可以加上索引进行导出。

注:macd外面有两个[ ]。

剩下的就是调用stockstats进行数据处理,并通过matplotlib.pyplot库来进行展示。代码如下:

# By ZUEL_Ronin
# 该模块用于计算和展示相关股票指数
import matplotlib.pyplot as plt
import stockstats  # 该库在show模块用到,因主要影响该模块,故放在该模块中def MACD(stockStat): #计算MACD并展示stockStat[['macd']].plot(subplots=True, figsize=(15, 10), grid=True)plt.show()def BOLL(stockStat): #计算BOLL以及其上轨线指标和下轨线指标并展示stockStat[['boll', 'boll_ub', 'boll_lb']].plot(subplots=True, figsize=(15, 10), grid=True)plt.show()def ADX(stockStat): #计算ADX并展示stockStat[['adx']].plot(subplots=True, figsize=(15, 10), grid=True)plt.show()def RSI(stockStat): #计算RSI并展示stockStat[['rsi_6', 'rsi_12']].plot(subplots=True, figsize=(15, 10), grid=True)plt.show()def CCI(stockStat): #计算CCI并展示stockStat[['cci', 'cci_20']].plot(subplots=True, figsize=(15, 10), grid=True)plt.show()def MA(stockStat): #计算MA30和MA60并展示stockStat[['close_30_sma', 'close_60_sma']].plot(subplots=True, figsize=(15, 10), grid=True)plt.show()

三、交互页面制作

该部分主要是利用tkinter库进行页面的设置,并读取用户输入的股票代码和起止日期来传导给前面几个部分进行爬取和计算,主要是要进行差错检测,避免用户其不合规的操作导致程序产生错误。(后附页面截图)

# by ZUEL_Ronin
# 该模块用于展示界面
import os
import CalculateStock
import tkinter.messagebox
import pandas as pd
from tkinter import *
import GetData
import CsvChangeForStockStatsclass showStockStats:  # 执行展示def __init__(self):self.win = Tk()  # 建立窗口self.win.title("股票相应趋势图分析")  # 设置窗口名称self.txtSeekStock = StringVar()  # 定义文本组件self.txtStartDate = StringVar()self.txtEndDate = StringVar()self.basepath = os.path.dirname(__file__)  # 获得当前文件位置def createLabel(self):labelSeekStock = Label(self.win, text="请输入查询股票代码", font='楷体 -24 bold')  # 定义窗口label组件,并显示相关文字labelSeekStock.grid(row=0, column=0)  # 按相关顺序显示labellabelStartDate = Label(self.win, text="开始时间", font='楷体 -24 bold')  # 定义窗口label组件,并显示相关文字labelStartDate.grid(row=1, column=0)labelEndDate = Label(self.win, text="结束时间", font='楷体 -24 bold')  # 定义labelEndDate.grid(row=1, column=2)labelPs = Label(self.win, text='注1:时间格式如下 20220421 需严格按照本格式输入,且若是修改日期需要重新下载\n''注2:输入股票代码,起止时间后,需先进行数据下载,才能展现股票指标,\n ''若使用结束后不需要该数据,可点击删除,\n否则将保留于当前文件夹下的数据文件夹中。', font='楷体 -24 bold')  # 定义labelPs.grid(row=5,columnspan=5)def createTxt(self):EntrySeekStock = Entry(self.win, textvariable=self.txtSeekStock, width=24, font='楷体 -24')  # 设置文本组件基本信息EntrySeekStock.grid(row=0, column=1)  # 布局文本组件EntryStartDate = Entry(self.win, textvariable=self.txtStartDate, width=24, font='楷体 -24')  # 设置文本组件基本信息EntryStartDate.grid(row=1, column=1)  # 布局文本组件EntryEndDate = Entry(self.win, textvariable=self.txtEndDate, width=24, font='楷体 -24')  # 设置文本组件基本信息EntryEndDate.grid(row=1, column=3)  # 布局文本组件def getCode(self):return str(self.txtSeekStock.get())def getStartDate(self):return str(self.txtStartDate.get())def getEndDate(self):return str(self.txtEndDate.get())def MACD_Show(self):try:code = self.txtSeekStock.get()stockStat = CalculateStock.stockstats.StockDataFrame.retype(pd.read_csv(self.basepath + '/' + '数据' + '/' + str(code) + '_ForStockStats.csv'))CalculateStock.MACD(stockStat)except:tkinter.messagebox.showerror('错误', "数据未下载")def BOLL_Show(self):try:code = self.txtSeekStock.get()stockStat = CalculateStock.stockstats.StockDataFrame.retype(pd.read_csv(self.basepath + '\\' + '数据' + '\\' + str(code) + '_ForStockStats.csv'))CalculateStock.BOLL(stockStat)except:tkinter.messagebox.showerror('错误', "数据未下载")def ADX_Show(self):try:code = self.txtSeekStock.get()stockStat = CalculateStock.stockstats.StockDataFrame.retype(pd.read_csv(self.basepath + '\\' + '数据' + '\\' + str(code) + '_ForStockStats.csv'))CalculateStock.ADX(stockStat)except:tkinter.messagebox.showerror('错误', "数据未下载")def RSI_Show(self):try:code = self.txtSeekStock.get()stockStat = CalculateStock.stockstats.StockDataFrame.retype(pd.read_csv(self.basepath + '\\' + '数据' + '\\' + str(code) + '_ForStockStats.csv'))CalculateStock.RSI(stockStat)except:tkinter.messagebox.showerror('错误', "数据未下载")def CCI_Show(self):try:code = self.txtSeekStock.get()stockStat = CalculateStock.stockstats.StockDataFrame.retype(pd.read_csv(self.basepath + '\\' + '数据' + '\\' + str(code) + '_ForStockStats.csv'))CalculateStock.CCI(stockStat)except:tkinter.messagebox.showerror('错误', "数据未下载")def MA_Show(self):try:code = self.txtSeekStock.get()stockStat = CalculateStock.stockstats.StockDataFrame.retype(pd.read_csv(self.basepath + '\\' + '数据' + '\\' + str(code) + '_ForStockStats.csv'))CalculateStock.MA(stockStat)except:tkinter.messagebox.showerror('错误', "数据未下载")def DownloadData(self):try:if str(self.getCode()) == "":tkinter.messagebox.showerror('错误', '股票代码不能为空')elif str(self.getStartDate()) == "":tkinter.messagebox.showerror('错误', '开始时间不能为空')elif str(self.getEndDate()) == '':tkinter.messagebox.showerror('错误', '结束时间不能为空')else:Download = GetData.Download_HistoryStock(str(self.getCode()), self.getStartDate(), self.getEndDate())Download.Download()tkinter.messagebox.showinfo("成功", '下载完成,保存在当前文件夹中的数据文件夹中')CsvChangeForStockStats.CsvChangeToStockStats(str(self.getCode()))except:tkinter.messagebox.showerror('错误', "股票代码输入错误,或未按要求输入时间(若确认正常,可能是由于网站维护造成爬取失败)")def DeleteData(self):try:os.remove(self.basepath + "\\" + "数据" + "\\" + str(self.getCode()) + ".csv")os.remove(self.basepath + "\\" + "数据" + "\\" + str(self.getCode()) + "_ForStockStats.csv")tkinter.messagebox.showinfo("成功", '删除成功')except:tkinter.messagebox.showerror('错误', '文件已删除或不存在')def createButtom(self):btnMACD = Button(self.win, text='显示MACD线', command=self.MACD_Show, font='楷体 -24',width=12) btnMACD.grid(row=3, column=0, sticky=W)btnBOLL = Button(self.win, text='显示BOLL线', command=self.BOLL_Show, font='楷体 -24',width=12)  btnBOLL.grid(row=3, column=2, sticky=W)btnADX = Button(self.win, text='显示ADX线', command=self.ADX_Show, font='楷体 -24',width=12)   btnADX.grid(row=3, column=4, sticky=W)btnRSI = Button(self.win, text='显示RSI线', command=self.RSI_Show, font='楷体 -24',width=12)   btnRSI.grid(row=4, column=0, sticky=W)btnCCI = Button(self.win, text='显示CCI线', command=self.CCI_Show, font='楷体 -24',width=12)   btnCCI.grid(row=4, column=2, sticky=W)btnMA = Button(self.win, text='显示MA线', command=self.MA_Show, font='楷体 -24',width=12)   btnMA.grid(row=4, column=4, sticky=W)btnClose = Button(self.win, text='关闭窗口', command=self.win.quit, font='楷体 -24', width=12)   btnClose.grid(row=2, column=4, sticky=W)btnDownload = Button(self.win, text='下载数据', command=self.DownloadData, font='楷体 -24',width=12)   btnDownload.grid(row=2, column=0, sticky=W)btnDownload = Button(self.win, text='删除数据', command=self.DeleteData, font='楷体 -24',width=12)   btnDownload.grid(row=2, column=2, sticky=W)def run(self):self.createLabel()self.createTxt()self.createButtom()self.win.mainloop()

四、结果展示

import Show
if __name__ == '__main__':  # 主函数show = Show.showStockStats()  show.run()  # 窗口显示

本次以晨光股份(603899)为例

交互页面如下:

输入603899,时间为2017年4月16日-2022年4月16日,首先点击下载数据

显示各个函数线:

MACD

BOLL

ADX

RSI

CCI

MA

五、最后

本文只是记录一下最近学python的过程,虽然最后呈现出来的比较简单,有很多写的不好的地方,欢迎各位大佬指点。

利用python计算股票相关指数相关推荐

  1. 在python中股票的收盘价如何表示_利用python计算股票涨跌幅

    作为一个python新手,在学习中遇到很多问题,要善于运用各种方法.今天,在学习中,碰到了如何通过收盘价计算股票的涨跌幅. 第一种: 读取数据并建立函数: import numpy as np imp ...

  2. 利用Python进行股票交易分析(三):A股量化交易策略的验证及数据分析。

    鉴于近期空闲时间比较少,本篇文章采用不定时更新的方式来写,如大家有更好的思路也可以评论区一起讨论.... 目前进度: 2021-07-13 梳理.修改思路 2021-07-14 步骤1代码完成 背景 ...

  3. 利用python进行股票技术分析--以茅台为例

    """ 利用python进行股票技术分析–以茅台为例 通过下述策略对利用python进行股票技术分析,可以举一反三,并且能够实现复杂的技术分析策略,同时可以同python ...

  4. python ks值计算_利用Python计算KS的实例详解

    在金融领域中,我们的y值和预测得到的违约概率刚好是两个分布未知的两个分布.好的信用风控模型一般从准确性.稳定性和可解释性来评估模型.sOf免费资源网 一般来说.好人样本的分布同坏人样本的分布应该是有很 ...

  5. 利用Python计算UDP校验和

    UDP 检验和提供了差错检测的功能.这是基于端到端原则实现的.但是 UDP 的检验和并不提供差错回复的能力. 一.UDP结构 二.UDP校验和计算方法  计算校验和的过程很关键,主要分为以下几个步骤: ...

  6. 【python】利用python计算A类不确定度

    利用python计算A类不确定度 前言 在上学期大学物理实验课的时候发现经常要计算A类不确定度,而且这个不确定度计算又非常复杂,凑巧当时正在学习python,于是利用python实现了这一小小功能. ...

  7. 异动分析(四)利用Python计算指标贡献度

    异动分析(四)利用Python计算指标贡献度 小P:有些异动的原因是多方面的,我看网上说可以通过计算贡献度进行量化. 小H:是的,容我想想- 虽然不是必要的,但有时候异动的原因多个,通过计算每个原因的 ...

  8. 如何利用python对股票的走势进行一个判断?

    如何利用python对股票的走势进行一个判断? 一.问题 当我们拿到沪深股票的所有股票的数据的时候,如何对所有股票的走势,做一个模糊的判断? 当然可以通过画出一个股票的走势图来进行判断.但是问题是,我 ...

  9. 利用 Python 计算资产 beta 值和市场 beta 值

    作者:chen_h 微信号 & QQ:862251340 微信公众号:coderpai 在这篇文章中,我们将强调理解股票市场中 beta 的重要性,以及我们如何来使用 beta 来对冲市场风险 ...

  10. 用python进行股票数据分析_利用python进行股票数据分析

    个人觉得这问题问的不太对,说句不好的话,你是来搞编程的还是做股票的. 当然,如果题主只是用来搜集资料,看数据的话那还是可以操作一波的,至于python要怎么入门,个人下面会推荐一些入门级的书籍,通过这 ...

最新文章

  1. 在家远程办公,如何才能让员工高效工作?
  2. linux redis 配置详解
  3. 以效率为根本,网易慢跑要做“另类”的TO B业务
  4. Angular NgReflectProperty的设置位置 - 只有在调试模式下才设置该属性
  5. ui unity 图片高亮_程序化生成UI模型与顶点动画
  6. python多线程多进程
  7. 【前端工程师手册】说清楚JavaScript中的相等性判断
  8. css 绘制三角形_解释CSS形状:如何使用纯CSS绘制圆,三角形等
  9. linux Swap交换分区概念
  10. python邮件发送_Python实现邮件发送
  11. 图片从预处理到分类的过程
  12. (转)ASP.NET程序中常用代码汇总
  13. 实际运用中DataSet、DataTable、DataRow点滴
  14. 成功解决3dmax三维建模过程中,视口中不显示贴图但渲染时显示
  15. GMT5SAR--由*.grd文件生成*.ps
  16. 头条视频消重软件 安卓修改视频md5
  17. 机械硬盘启动失败,总是转一下挺停一下
  18. 深入浅出讲解 Python 元类(Metaclass)的使用
  19. 软件推荐:强力卸载软件HIBIT
  20. 再记公式弱爆了!用 ChatGPT 将 Excel 工作效率提高 10 倍

热门文章

  1. 系统状态空间模型c语言,【单选题】能完全描述系统动态行为的数学模型是() A. 传递函数 B. 微分方程 C. 状态 空间表...
  2. 在线影音页面的制作方法
  3. chromium之WebUI
  4. 优质的APP推广渠道那么多,怎么选才好?
  5. Spring Boot做国际化
  6. mysql聚簇索引和非聚簇索引的区别_聚簇索引与非聚簇索引的区别
  7. python图片裁剪
  8. html个人空间制作,html+css+js制作简单网站首页
  9. 用python定时发送邮件
  10. 白蛋白纳米-超声微泡载组织型纤溶酶原激活物基因靶向制备研究