前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用baoStock+talib画一个股票筹码图

使用baoStock+talib画一个股票筹码图

作者头像
写一点笔记
发布2022-08-11 17:45:27
1.1K1
发布2022-08-11 17:45:27
举报
文章被收录于专栏:程序员备忘录程序员备忘录

在股市中,筹码就是交易最真实的刻画,我们摸索了一年,最后还是决定罢黜百家,独尊筹码。就是说炒股首先是趋势,其次才是战术。时代创造英雄,但很少有英雄创造时代。股市应该服从趋势第一的原则。在正向趋势内的波涛才是水手展现才华的地方。所以这块作者借此机会再用python画一个筹码图。稍微写个笔记,当做打发周末的美好时光了。

  1. 筹码类
代码语言:javascript
复制
class Chip:

    index=0

    open=0

    close=0

    max=0

    min=0

    avc_price=0

    chouMa=0

    def __init__(self,index,open,close,max,min,avc_price,chouMa):
        self.index=index
        self.open=open
        self.close=close
        self.max=max
        self.min=min
        self.avc_price=avc_price
        self.chouMa=chouMa

    def getChouMa(self):
        return self.chouMa


    def getOpen(self):
        return self.open

    def getClose(self):
        return self.close

    def getAvcPrice(self):
        return self.avc_price

    def getMax(self):
        return self.max

    def getMin(self):
        return self.min

    def getIndex(self):
        return self.index

    def print(self):
        print("日期:"+str(self.getIndex())+"    筹码:"+str(self.getChouMa())+"    最高:"+str(self.getMax())+"    最低:"+str(self.getMin())+"    平均:"+str(self.getAvcPrice()))

2、筹码计算

代码语言:javascript
复制
# 筹码量的计算
from src.NewTun.Chip import Chip


class ChipCalculate:

    isProd=False
    shuanJian = 1

    # 1.价格和筹码量的分布
    price_vol = {}

    # 2.每个交易日的筹码量
    DayChouMaList = []


    # 倒叙计算每日的筹码量
    # 传入的数据id,open,high,low,close,volume,typePrice,trun
    #          0,   1,   2,  3,   4,    5,    6,       7
    def getDataByShowLine(self, data,prod):
        self.isProd=True
        result = []
        dataLength = len(data)
        csdnAvcPrice = []
        TtodayChouma = []
        TTprice = 0
        TTmax = 0
        shuanjian = 0
        # 保障显示120天的筹码线
        # 倒叙计算每日的筹码量,当日的筹码分布和最近的120天有关系
        for k in range(len(data) - 120):
            self.DayChouMaList.clear()
            # 倒数第k日的基本数据
            Baseline = data[dataLength - 1 - k]
            if Baseline[8] < 1:
                continue
            # 拿到id
            baseIndex = int(Baseline[0])
            currentPrice = float(Baseline[4])
            for i in range(120):
                if i < 1:
                    continue
                line = data[dataLength - k - i]
                if line[8] < 1:
                    continue
                if line[0] == '':
                    index = 0
                else:
                    index = int(line[0])
                open = float(line[1])
                close = float(line[4])
                max = float(line[2])
                min = float(line[3])
                vol = 0
                if line[5] == '':
                    vol = 0
                else:
                    vol = float(line[5])
                avc_price = float(line[6])
                if line[7] == '':
                    line[7] = 0
                if data[dataLength - i][8] == '' or data[dataLength - i][8] == None or float(
                        data[dataLength - i][8]) < 1:
                    continue
                if i == 1:
                    currentChouMa = vol
                    chip = Chip(index, open, close, max, min, avc_price, currentChouMa)
                    shuanjian = (1 - float(data[dataLength - i][7]) / 100)
                    self.DayChouMaList.append(chip)
                else:
                    value = 0
                    if data[dataLength - i][5] != '':
                        value = float(data[dataLength - i][5])
                    chouma = shuanjian * value
                    shuanjian = shuanjian * (1 - float(data[dataLength - i][7]) / 100)
                    chip = Chip(index, open, close, max, min, avc_price, chouma)
                    self.DayChouMaList.append(chip)
            # 倒序计算完每日的筹码量,然后将筹码平均分布到当日的价格上
            todayChouma, tmax, csdn ,maxVolprice,myUp= self.adviseChouMa2Price()
            if k == 0:
                TtodayChouma = todayChouma
                TTmax = tmax
            csdnTemp = []
            csdnTemp.append(baseIndex)
            csdnTemp.append(csdn)
            csdnTemp.append(TtodayChouma)
            csdnTemp.append("")
            csdnTemp.append(TTmax)
            t = 0
            if currentPrice * 100 > maxVolprice:
                # 当前的价格大于筹码的平均价格
                t = 1
            else:
                t = 0
            csdnTemp.append(t)
            csdnTemp.append(myUp)

            if csdn * 100 >= maxVolprice and t == 1:
                csdnTemp.append(1)
            else:
                csdnTemp.append(0)
            result.append(csdnTemp)
        return result

    # 将每日的筹码分布到价格上

    def adviseChouMa2Price(self):
        length = len(self.DayChouMaList)
        self.price_vol.clear()
        for i in range(length):
            # 当日的筹码
            chouma = self.DayChouMaList[i].getChouMa()
            index = self.DayChouMaList[i].getIndex()
            open = self.DayChouMaList[i].getOpen()
            close = self.DayChouMaList[i].getClose()
            max = self.DayChouMaList[i].getMax()
            min = self.DayChouMaList[i].getMin()
            avcPrice = self.DayChouMaList[i].getAvcPrice()
            # 移入地时候,矩形和三角形的面积比为3比7,其中矩形的筹码分布占0.3,三角形占0.7
            # 1.先算矩形部分的筹码迁移,将每股价格精确到分。
            maoshu = round((max - min), 2) * 100
            if maoshu <= 0:
                continue
            # 得到矩形部分筹码量
            everyMao = chouma * 0.3 / maoshu
            for j in range(int(maoshu)):
                # 从最小价格向最大价格进行逐个筹码分布
                key = j + round(min * 100)
                # 如果已经包含了当前价格,那么就进行累加
                if self.price_vol.__contains__(key):
                    volTemp = self.price_vol.get(key)
                    volTemp = volTemp + everyMao
                    self.price_vol[key] = volTemp
                else:
                    # 当前价格上的筹码量
                    self.price_vol[key] = everyMao
            # 三角形一半的筹码量
            totalChouma = chouma * 0.35
            # 将三角形的筹码分布到价格上
            for j in range(int(maoshu / 2)):
                # 从下往上
                if min * 100 + j < avcPrice * 100:
                    key = int(j + min * 100)
                    # --   max
                    # -----
                    # -----------  avrageprice
                    # -------
                    # ------   min
                    # 看是递增还是递减的,k大于零表示递增,k小于零表示递减
                    k = (avcPrice - min) / ((max - min) / 2)
                    # 当前价格上应该分配的筹码在三角形半上所占据的比列多少
                    ditVol = (j * k) / (((avcPrice - min) * (max - min) / 2) / 2)
                    ditChouma = totalChouma * ditVol
                    # 下三角筹码分配
                    if self.price_vol.__contains__(key):
                        volTemp = self.price_vol[key]
                        volTemp = volTemp + ditChouma
                        self.price_vol[key] = volTemp
                    else:
                        self.price_vol[key] = ditChouma
                    # 上三角筹码分布
                    if self.price_vol.__contains__(int(max * 100 - j)):
                        volTemp = self.price_vol[int(max * 100 - j)]
                        volTemp = volTemp + ditChouma
                        self.price_vol[int(max * 100 - j)] = volTemp
                    else:
                        self.price_vol[int(max * 100 - j)] = ditChouma
        choumaList = []
        isFirst = 1
        totalVol = 0
        totalPrice = 0
        tmax = 0
        #筹码峰价格
        maxVolprice=0
        #weight价格
        weightPrice=0
        for i in sorted(self.price_vol):
            # 这里的i就表示价格
            if isFirst == 1:
                isFirst = 0
            cm = []
            # 寻找最大的筹码量
            if self.price_vol[i] > tmax:
                tmax = self.price_vol[i]
                maxVolprice = i
            # 计算当日的各个价格上的筹码量之和
            totalVol = totalVol + self.price_vol[i]
            # 计算当前价格上筹码的累计大小
            totalPrice = totalPrice + i * self.price_vol[i]
            # 封装当前价格和价格上的筹码量
            cm.append(i)
            cm.append(self.price_vol[i])
            choumaList.append(cm)
        if totalVol == 0:
            csdn = 0
            return choumaList, 0, tmax, csdn,0,0
        else:
            csdn = round((totalPrice / totalVol) / 100, 2)
            myUp=1
            if self.isProd==True:
                close = self.DayChouMaList[0].getClose()
                downPower=0
                upPower=0
                for i in sorted(self.price_vol):
                    # 这里的i就表示价格
                    #战斗力对比
                    tP=close-round(i/100,2)
                    if tP<0:
                        downPower=downPower+(tP*self.price_vol[i])
                    if tP>0:
                        upPower=upPower+(tP*self.price_vol[i])
                result=upPower+downPower
                if result>=0:
                    myUp=1
                else:
                    myUp=0
            return choumaList, tmax, csdn,maxVolprice,myUp

3、筹码作图

代码语言:javascript
复制
# 筹码计算
import time

import numpy as np
import pandas as pd
import talib
from matplotlib import pyplot as plt

from src.NewTun.ChipCalculate import ChipCalculate
import baostock as bs

class ParseChouMa:
    #画160的窗口期筹码
    window = 160

    def doParseByCode(self,code):
        endTime = time.strftime('%Y-%m-%d', time.localtime(time.time()))
        lg = bs.login()
        rs = bs.query_history_k_data_plus(code,
                                          "date,code,open,high,low,close,preclose,volume,amount,adjustflag,turn,tradestatus,pctChg,isST",
                                          start_date="2018-01-01", end_date=endTime,
                                          frequency="d", adjustflag="2")
        data_list = []
        while (rs.error_code == '0') & rs.next():
            data_list.append(rs.get_row_data())
        result = pd.DataFrame(data_list, columns=rs.fields)
        start = len(result) - self.window
        result = result.loc[:, ['date', 'open', 'high', 'low', 'close', 'volume', 'turn']]
        if code == 'sh.000001':
            result['temp'] = 100
            result['open'] = talib.DIV(result['open'], result['temp'])
            result['high'] = talib.DIV(result['high'], result['temp'])
            result['low'] = talib.DIV(result['low'], result['temp'])
            result['close'] = talib.DIV(result['close'], result['temp'])
        result = result[-self.window:]
        chipCalculateList = []
        for index, row in result.iterrows():
            if index>=start:
                temp = []
                temp.append(index-start)
                print(index-start)
                temp.append(row['open'])
                temp.append(row['high'])
                temp.append(row['low'])
                temp.append(row['close'])
                temp.append(row['volume'])
                temp.append(row['close'])
                temp.append(row['turn'])
                temp.append(1)
                chipCalculateList.append(temp)
        index=[]
        closePrice=[]
        for i in range(len(chipCalculateList)):
            index.append(chipCalculateList[i][0])
            close=chipCalculateList[i][4]
            close=round(float(close), 2)
            closePrice.append(close)
        return chipCalculateList,index,closePrice

    # K线的展示
    def show(self,choumaList,TavcPrice,tmax,index,closePrice):
        fig=plt.figure()
        ax=fig.add_axes([0.1,0.35,0.6,0.6])
        # 画平均成本
        ax.plot(index, closePrice, color="green")
        cmx=fig.add_axes([0.7,0.35,0.2,0.6])
        chouMalit=np.array(choumaList)
        for item in chouMalit:
            item[0]=item[0]*1.0/100
        cmx.barh(chouMalit[:,0],chouMalit[:,1],color="Turquoise",align="center",height=0.01)
        cmx.barh(TavcPrice,tmax,color="red",height=0.02)
        fig.show()
        pass

4、demo演示

代码语言:javascript
复制
parseFile=ParseChouMa()
chipCalculateList,index,closePrice=parseFile.doParseByCode("sh.000001")
calcualate = ChipCalculate()
resultEnd = calcualate.getDataByShowLine(chipCalculateList, True)
parseFile.show(resultEnd[0][2],resultEnd[0][1],resultEnd[0][4],index,closePrice)

5、与通达信、腾讯自选股筹码图的对比

上证指数的筹码分布:

通达信

对比发现跟通达信的筹码差距还挺大。我们按真实的价格去重新算一下。发现还是那样,所以到底哪个比较靠谱呐?我们再看看其他的股票。

金证股份

看看通达信的筹码

手机app

发现差别还挺大的,我们再对比双汇发展。

手机app

我们再对比一下冀中能源

通达信

手机app

西麦食品

通达信

手机app

6、总结:

如开题所说,股票的筹码决定趋势,这是我们研究筹码的动机。经过以上实验,作者凭个人经验,本算法将筹码计算周期设置为120的时候所绘制的筹码图跟软件上差异最小。当然因为每种软件的算法都不一样,因此所绘制的筹码图也并非相同。从现实来说,我们通过算法假设去演绎现实往往有理想的成分在里边。因此算法也只能给出一个大概的方向,作者觉得这应该就已经够了。当然假设以后能发现更好的算法,作者也会第一时间分享出来,本次文章就到这里了,周么愉快。

春天来了,大家出去走走~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-04-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 写点笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档