设为首页加入收藏

微信关注
官方微信号:qingfeng7777777a
加关注获取每日精选资讯
股票入门欢迎您加入
广告服务联系我们网站地图

如何利用Python开发一套股票分析软件

2019-06-24 20:34:57 看盘

股票数据分析对象为沪深300,通过对数据的爬取以及分析,使数据可视化,这些为该分析软件要满足的功能。

确定目标,然后 JUST DO IT !

第一步:获取数据

沪深300历史交易数据的 URL 地址如下:

  • http://quotes.money.163.com/trade/lsjysj_zhishu_399300.html?year=2018&season=3

【1】分析网址获得 HTML

在查询历史记录时,我们可以观察出网址中 ‘399300’ 、‘2018’与‘3’的数字含义,分别代表‘股票代码’、 ‘年份’ 和 ‘季度’,由此我们就可以写一个函数,把 股票代码 以及 年份 、 季度 作为参数,进入到不同股票的历史交易记录中 

(下面代码我们默认股票代码为 399300,代码中year和season为参数,返回页面的 HTML,存放在 list 中。要获得多年的数据,可写一个 for 循环来循环爬取网页内容,这里就不做过多展示了。)

    def __init__(self, year, season):

        self.year = year

        self.season  = season

        self.soup = None

    def SpiderData(self):

        url = 'http://quotes.money.163.com/trade/lsjysj_zhishu_399300.html?year='

        list = []

        headers = {'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/2010010 Firefox/62.0'}

        temp = url + str(self.year) + '&season=' + str(self.season)

        req = ur.Request(url=temp, headers=headers)

        html = ur.urlopen(req).read()

        self.soup = BeautifulSoup(html, 'lxml')

        self.Spider(list)

        return list

沪深300历史交易记录网页如下:

【2】 从HTML中拿到我们需要的数据

通过审查元素,我们可以使用 BeautifulSoup 来 find_all 我们所需要的内容。

BeautifulSoup 中文官网如下:

  • https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/

代码如下:

    def Spider(self,list):

        tag = self.soup.find('table', {'class': "table_bg001 border_box limit_sale"})

        data = tag.find_all('td')

        for i in data:

            list.append(i.text)

注:此处连接上文代码,在一个class中。我们爬取的内容包括 日期收盘价格开盘价格 以及 交易数额等,包括网页上列表所展示的所有列名下的数据。

至此,我们就完成了数据的爬取,我们需要把数据存在数据库中(作者使用的 MySql 数据库,关于数据库的操作就不再啰嗦,篇幅有限,大家见谅,如有疑问,请通过留言等方式联系作者。)

第二步:分析处理数据

【1】数据分析包括两块:

  • 第一是计算沪深300交易数据的分位数;
  • 第二是数据的读取与更新

分位数 -- 有序 (由小到大) list 中某一数值所在位置的百分比,具体求解方法参见维基百科相应部分:

  • https://zh.wikipedia.org/wiki/Percentile

【2】有了算法,我们就开始处理数据。我们要从数据库中获得我们需要的数据,而我们在计算分位数时面对的是平均数(收盘价、开盘价以及最高价、最低价的平均数),故应该先计算出平均数,然后算出分位数。

注:股票周期为两年,我们计算某天的分位数要看这天的平均数所占之前两年每天平均数这一 list 的位置(有点拗口,不过就是这个意思,见谅)。

代码如下:

    def GetFra(self):

       for i in self.date:

           sql = "SELECT Average_One FROM stock WHERE Date BETWEEN DATE_SUB('" + str(

               i[0]) + "' ,INTERVAL " + str(self.period) + " YEAR) AND '" + str(i[0]) + "'ORDER BY Average_One ASC;"

           days = self.cursor.execute(sql)

           list = self.cursor.fetchall()

           sql1 = "SELECT Average_one FROM stock WHERE Date = '"+str(i[0])+"';"

           self.cursor.execute(sql1)

           temp = self.cursor.fetchone()

           sql2 = "UPDATE stock SET Fractile_Now=" + str(

               (list.index(temp)) * 100 // days) + " WHERE Date='" + str(i[0]) + "';"

           self.cursor.execute(sql2)

           self.db.commit()

           self.listone.append(numpy.percentile(list, 25))

    def Average(self):

        sql = "UPDATE stock SET Average_One=(Open_price+Top_price+Floor_price+Close_price)*0.25;"

        sql1 = "UPDATE stock SET Average_Two=Trade_amount/Trade_vol;"

        self.cursor.execute(sql)

        self.cursor.execute(sql1)

        self.db.commit()

Python 给我们提供了计算分位数的简便方法,一个是 list 的各种操作,通过它的index方法可以计算当前分为数;另一个就是numpy ,numpy.percentile可以迅速对 list 或者元组排序,然后得到分位数,是不是很方便。

通过代码大家可以看到我们把数据直接插入到 MySql 数据库中,为我们后续数据的可视化作准备。

具体结果如图:

作者使用的 navicat 来展示数据库内容,navicat 是针对 mysql 的一个很好的可视化工具,推荐英文版给大家,下载链接如下:

  • https://www.navicat.com/en/products

【3】在数据的可视化之前,我们还要解决数据的读取与更新问题,数据的读取很好弄,cursor.fetall会返回一个元组,我们通过 sql 语句就可以解决数据的读取问题;而更新操作就没有那么容易,网页上股票数据除了节假日都会更新,我们需要每天定时爬取数据以及处理数据,作者通过使用的 ubuntu 的crontab 定时运行 python 脚本文件,具体实施大家可以找度娘,因为不同电脑环境配置不同,出现的问题也比较复杂,作者能力有限,就不提供具体方法了。

第三步:数据的可视化

【1】数据的可视化还是比较容易的,因为我们的数据库中已经处理好了数据,无论是每天的平均价格还是分位数都在数据库中,我们只需要提取数据,然后作图就好了。

【2】在作图上,作者使用的是pyecharts,不过要pyecharts做出来的图需要在浏览器上打开,当然,还有pyecharts不会这么水,在搭建了Nodejs后,使用pyecharts-snapshot插件就可以在指定位置生成图片了。具体pyecharts教程参考链接:

  • http://pyecharts.org/#/zh-cn/prepare

注:在安装snapshot时可能遇到npm安装错误的问题,可以使用cnpm来解决问题,百度时记得把cnpm加上,可以轻松一些。

【3】可视化就介绍这些,下面看代码:

    def Trade(self):

        db = pymysql.connect('localhost', 'root', '******', '****')

        cursor = db.cursor()

        sql_75 = "SELECT Fractile_75 FROM stock WHERE Date BETWEEN  DATE_SUB('" +str(self.time) + "' ,INTERVAL 2 YEAR)  AND '" + str(self.time) + "' ORDER BY DATE ASC;"

        sql_40 = "SELECT Fractile_40 FROM stock WHERE Date BETWEEN  DATE_SUB('" +str(self.time) + "' ,INTERVAL 2 YEAR)  AND '" + str(self.time) + "' ORDER BY DATE ASC;"

        sql_average = "SELECT Average_one FROM stock WHERE Date BETWEEN  DATE_SUB('" +str(self.time) + "' ,INTERVAL 2 YEAR)  AND '" + str(self.time) + "' ORDER BY DATE ASC;"

        sql1 = "SELECT Date FROM stock WHERE Date BETWEEN  DATE_SUB('" +str(self.time) + "' ,INTERVAL 2 YEAR)  AND '" + str(self.time) + "' ORDER BY DATE ASC;"

        cursor.execute(sql_75)

        data_75 = cursor.fetchall()  

        cursor.execute(sql_40)

        data_40 = cursor.fetchall()

        cursor.execute(sql_average)

        data_average = cursor.fetchall()

        top = max(data_average)[0]- 300

        floor = min(data_average)[0]- 300

        cursor.execute(sql1)

        date = cursor.fetchall()

        temp = []

        for i in date:

            temp.append(i[0])

        line1 = Line("沪深300历史交易曲线", self.text ,title_text_size=12 ,subtitle_text_size=10 )

        line1.use_theme("dark")   #设置背景

        line1.add("平均价", temp, data_average, ys_aximin=math.floor(floor/100)*100, ys_aximax=math.ceil(top/100)*100)

        line1.add("分位数40", temp, data_40 ,yaxis_min=math.floor(floor/100)*100, ys_aximax=math.ceil(top/100)*100)

        line1.add("分位数75", temp, data_75,yaxis_min=math.floor(floor/100)*100 ,ys_aximax=math.ceil(top/100)*100)

        line1.render(path='Trade.png')   #此处可以指定文件位置   

作者在获取不同分位数的 SQL 语言看起来比较蠢,但是pyecharts作图中需要元组或者 list,而文中代码可以满足需要,并且简单(可以理解为作者没有好方法,只能这么做)。

下面上图:

关于股票分析到此基本上就结束了,大家在看此文章时会觉得描述不充分,的确,在写这篇文章时,作者省略了很多,不过都是一些比较简单操作,大家在看文中提供的代码时,基本可以想到省略的内容。

[!--temp.sitename--]声明:资讯来源于互联网,属作者个人观点,仅供投资者参考,并不构成投资建议。投资者据此操作,风险自担。