乐趣区

关于python:我用python实现了一个量化选股程序

背景

近期在学习数据分析,在课程最初老师讲了一下通过量化剖析抉择股票的案例,感觉挺有意思的,恰好四周也有人在炒股票,罗唆本人做一个软件来实际一下学到的常识。课程上次要用 python 相干库来解决比特币的数据,数据量也不大,然而了解原理之后咱们能够触类旁通。

首先来回顾一下次要的知识点,抉择股票的时候会用到两个重要的指标 RSV、KDJ。他们的定义见上面的课件截图,具体的内容我就不论述了,因为我是非金融业余的,对这些词汇解释起来有点吃力。咱们只有记住这两个指标如何计算,以及前面如何应用即可

KDJ 指标定义

计算 K 指标

计算 D 指标

计算 J 指标

试验原理

老师在课程中讲到 K 和 D 都是反映股票变化趋势的,K 要比 D 灵活,当 K 值上穿 D 值时(第一次呈现 K >D)时代表股票可能呈现向上反弹,此时是买入机会,当 K 下穿 D 值时(第一次呈现 K <D)时,代表股票有较大概率呈现上涨,此时是卖出机会。
通过利用这个办法,咱们能够在 4000 多支股票中筛选出若干可能呈现反弹的股票,而后再用人的教训和其余方面的信息选出心仪的股票了。
咱们的试验思路是:

  1. 先从网络上获取过来半年 4000 支股票的交易信息,包含日期(date)、最高价(high)、最低价(low)、开盘价(open)、收盘价(close),将这些信息存储到 stockbars 表中
  2. 用 python 程序读取 stockbars 表中的每条记录,计算出 rsv 指标存储到 stockrsvs 表中
  3. 最初用 python 程序读取 stockrsvs 表,计算出 k、d、j 三个指标
  4. 最初咱们用 SQL 语句查询数据库,每个人能够基于 RSV、k、d、j 这四个值自在定义查问形式

这里咱们用到了 kdj 金融常识、python 编程常识、SQL 语言以及数据库相干的内容,也算是一次综合性的演练了。还能够利用 Sugar 来在线绘制大屏小白学数据分析 – 工具篇(可视化 Sugar)

试验过程

试验环境筹备

咱们用到了 python 开发环境,这里咱们用 docker 间接获取一个镜像应用,省的装置一堆乌七八糟的依赖,当然你也能够依照本人的爱好来自行装置

Docker pull docker.io/python

数据库咱们应用了一个收费的云数据库 MemFireDB https://memfiredb.com,他提供了公网 IP 以及可视化的 SQL 编辑器不便咱们后续查问数据

试验步骤和代码

获取原始数据

计算 RSV 指标

   for stock in stocks:
        i += 1
        bars = session.query(StockBar).filter(StockBar.stock_id == stock.id).order_by(StockBar.date.asc()).all()

        if len(bars) < window:
            print("stock %s  bar less than window %s real %s cal next stock" % (stock.id, window, len(bars)))
            continue

        for bar in bars:
            rsv = session.query(StockRSV).filter(StockRSV.id == bar.stock_id + "_" + str(bar.date)
                ).first()


            if rsv is not None:
                print("rsv: id:%s stock_id:%s, date:%s,rsv value:%s cal next bar" % (rsv.id, rsv.stock_id, rsv.date, rsv.rsv))
                continue

            prevbars = session.query(StockBar).filter(
                    StockBar.stock_id == stock.id,
                    StockBar.date <= bar.date
                ).order_by(StockBar.date.desc()).limit(window).all()

            if len(prevbars) < window:
                print("stock %s date %s perv less than window %s cal next date" % (stock.id, bar.date, window))
                continue

            for prevbar in prevbars:
                print("prevbar: id %s , stock_id:%s, date:%s, open:%s, high:%s, low:%s, close:%s" % 
                        (prevbar.id, prevbar.stock_id, prevbar.date, prevbar.open, prevbar.high, prevbar.low, prevbar.close))

            low = prevbars[0].low
            high = prevbars[0].high
            lastopen = prevbars[0].open
            lastclose = prevbars[0].close

            for prevbar in prevbars:
                if prevbar.high >= high:
                    high = prevbar.high
                if prevbar.low <= low:
                    low = prevbar.low
            
            print("rsv: stock_id %s, date:%s lastopen:%s, lastclose:%s, high:%s, low:%s" % 
                    (bar.stock_id, bar.date, lastopen, lastclose, high, low))

            stockrsv = StockRSV(id = bar.stock_id + "_" + str(bar.date),
                stock_id = bar.stock_id,
                date = bar.date,
                rsv = 100 * (lastclose - low) / (high - low))
            session.add(stockrsv)
            session.commit()

计算结果

计算 KDJ 指标

 for stock in stocks:
        i += 1
        rsvs = session.query(StockRSV).filter(StockRSV.stock_id == stock.id).order_by(StockRSV.date.asc()).all()

        if len(rsvs) < 1:
            print("stock %s  rsv less than window %s real %s cal next stock" % (stock.id, 1, len(rsvs)))
            continue

        for stockrsv in rsvs:
            curkdj = session.query(StockKDJ).filter(StockKDJ.id == stockrsv.stock_id + "_" + str(stockrsv.date)
                ).first()
            if curkdj is not None:
                print("kdj id:%s, stock_id:%s,date:%s,k:%s, d:%s,j:%s exist cal next" % (curkdj.id, curkdj.stock_id, curkdj.date, curkdj.k, curkdj.d, curkdj.j))
                continue
            
            lastkdj = session.query(StockKDJ).filter(
                    StockKDJ.stock_id == stockrsv.stock_id,
                    StockKDJ.date < stockrsv.date
                ).order_by(StockKDJ.date.desc()).limit(1).first()


            lastkvalue = 0
            lastdvalue = 0

            if lastkdj is not None:
                lastkvalue = lastkdj.k
                lastdvalue = lastkdj.d

            stockkdj = StockKDJ(id = stockrsv.stock_id + "_" + str(stockrsv.date),
                stock_id = stockrsv.stock_id,
                date = stockrsv.date,
                k = curkvalue,
                d = curdvalue,
                j = 0)
            session.add(stockkdj)
            session.commit()

计算结果

应用 SQL 选股

咱们抉择最近 RSV 值较低,且 K >D 的十只股票

到股票软件上查看这几只股票的趋势图

试验总结

通过这次试验,咱们摸索了一种办法,应用 python 获取股票数据,因为记录数较多且计算过程无奈递归,只能通过循环的形式联合数据库循环计算指标。最初将计算的后果存储在数据库中,利用 SQL 语言的丰盛语义,能够灵便的验证各种选股的模型。尽管本次试验得进去的选股办法可能不如业余机构的精确,然而胜在灵便多变,你能够联合本人的教训调整。

退出移动版