布林带(Bollinger Bands)也称为布林通道、保力加通道,是由约翰·布林格(John Bollinger)发明的技术分析指标。布林通道通常被用来确认资产价格波动范围。

布林通道是由三条平滑的曲线组成的趋势线图表,中线为均线,上/下线为中线±2个标准差。

在上一个章节没有自己造轮子,直接使用 Pandas 函数计算 MACD,非常方便的实现了计算和绘图。

本次使用更快捷的方式,直接上飞机:使用 AI 来写代码。

我在上篇文章《利用AI快速跨过新手区:用DevChat编写Python程序》 介绍了如何使用 DevChat 编写程序。

这次直接借助 DevChat 来编写布林带并绘图。

目录

  • AI 编程
  • 程序优化
  • 进阶
  • 题外话
  • 福利

AI 编程

因为数据源来源不一致,对程序进行修改,直接套用之前的代码。

import pandas as pdimport matplotlibimport matplotlib.pyplot as pltimport requestsimport jsonfrom requests.auth import HTTPBasicAuthimport datetimeimport numpy as npimport fun## def global variablesglobal dbname global stbname global usernameglobal passwordglobal tdurlglobal logfiledbname = 'trade_data_a'stbname = 'tdata'username = 'root'password = 'taosdata'## 如果是本地数据库将地址修改为localhosttdurl = 'http://10.7.7.14:6041/rest/sql/trade_data_a" />= 'error.log'##SQLst = '2022-06-01'et = '2022-10-01'sql = 'select tdate,close from trade_data_c.tdata where fcode="000001" and tdate>="'+st+'" and tdate<="'+et+'"'## Get data to DataFramedef request_get_d(resInfo):load_data = json.loads(resInfo)data = load_data.get("data")df = pd.DataFrame(data)df.rename(columns={0:'tdate',1:'close'},inplace=True)return dfif __name__ == '__main__':# 指定默认字体matplotlib.rcParams['font.sans-serif'] = ['SimHei']matplotlib.rcParams['font.family']='sans-serif'# 解决保存图像是负号'-'显示为方块的问题matplotlib.rcParams['axes.unicode_minus'] = Falsert = fun.request_post(tdurl,sql,username,password)scode = fun.check_return(rt)if scode != 'error':df = request_get_d(rt)# 计算20日移动平均线、标准差、布林上线和布林下线df['20日MA'] = df['close'].rolling(window=20).mean()df['20日STD'] = df['close'].rolling(window=20).std()df['布林上线'] = df['20日MA'] + (df['20日STD'] * 2)df['布林下线'] = df['20日MA'] - (df['20日STD'] * 2)# 绘制布林带df[['close','20日MA','布林上线','布林下线']].plot(figsize=(12,6))plt.title('平安银行布林带')plt.ylabel('价格 (人民币)')plt.show()

运行脚本,图形可以正常绘制,但是中文显示有问题。不过不急,直接问AI。


修改后图形就显示正常了。

程序优化

利用 DevChat 对程序进行进一步优化:

import pandas as pdimport matplotlib.pyplot as pltimport requestsimport jsonfrom matplotlib import font_manager# Global variablesDB_NAME = 'trade_data_a'STB_NAME = 'tdata'USERNAME = 'root'PASSWORD = 'taosdata'TD_URL = 'http://10.7.7.14:6041/rest/sql/trade_data_a" />= 'error.log'# ConstantsSTART_DATE = '2022-06-01'END_DATE = '2022-10-01'SQL = f'select tdate,close from trade_data_c.tdata where fcode="000001" and tdate>="{START_DATE}" and tdate<="{END_DATE}"'# Specify default fontplt.rcParams['font.sans-serif'] = ['SimHei']plt.rcParams['font.family'] = 'sans-serif'# Resolve issue with negative numbers being displayed as a squareplt.rcParams['axes.unicode_minus'] = Falsedef request_get_d(resInfo):load_data = json.loads(resInfo)data = load_data.get("data")df = pd.DataFrame(data)df.rename(columns={0: 'tdate', 1: 'close'}, inplace=True)return dfif __name__ == '__main__':rt = fun.request_post(TD_URL, SQL, USERNAME, PASSWORD)scode = fun.check_return(rt)if scode != 'error':df = request_get_d(rt)# Calculate 20-Day Moving Average, Standard Deviation, Upper Band and Lower Banddf['20 Day MA'] = df['close'].rolling(window=20).mean()df['20 Day STD'] = df['close'].rolling(window=20).std()df['Upper Band'] = df['20 Day MA'] + (df['20 Day STD'] * 2)df['Lower Band'] = df['20 Day MA'] - (df['20 Day STD'] * 2)# Draw Bollinger Bandsdf[['close', '20 Day MA', 'Upper Band', 'Lower Band']].plot(figsize=(12, 6))plt.title('Ping An Bank Bollinger Bands')plt.ylabel('Price')plt.show()

别的不说,起码看上去挺漂亮的。不过有两个小问题:

  1. import fun 被删除了,这是我的一个存储函数的文件,不引用这个,很多自定义函数会报错。
  2. 中文名称变英文了。

进阶

直接让 DevChat 编写完整的程序。

import taosimport pandas as pdimport numpy as npfrom matplotlib import pyplot as plt# 连接到 TDengine 数据库conn = taos.connect(host='10.7.7.14', user='root', password='taosdata', database='trade_data_c')# 查询一段时间内的收盘价query = "select tdate,close from trade_data_c.tdata where fcode='000001' and tdate>= '2022-03-01' AND tdate <= '2023-02-28'"result = conn.query(query)df = pd.DataFrame(result.fetch_all(), columns=['Timestamp', 'Close'])df['Timestamp'] = pd.to_datetime(df['Timestamp'])df.set_index('Timestamp', inplace=True)# 计算20日均线和标准差df['20 Day MA'] = df['Close'].rolling(window=20).mean()df['20 Day STD'] = df['Close'].rolling(window=20).std()# 计算布林带上线和下线df['Upper Band'] = df['20 Day MA'] + (df['20 Day STD'] * 2)df['Lower Band'] = df['20 Day MA'] - (df['20 Day STD'] * 2)# 绘制布林带图形plt.figure(figsize=(12, 6))plt.plot(df.index, df['Close'], label='Close')plt.plot(df.index, df['Upper Band'], label='Upper Band')plt.plot(df.index, df['Lower Band'], label='Lower Band')plt.title('Bollinger Bands')plt.xlabel('Timestamp')plt.ylabel('Price')plt.legend()plt.show()# 提示买卖信号last_close = df['Close'].iloc[-1]last_upper_band = df['Upper Band'].iloc[-1]last_lower_band = df['Lower Band'].iloc[-1]if last_close > last_upper_band:print('做空')elif last_close < last_lower_band:print('做多')else:print('继续观察')


有一种要失业的预感!!

题外话

布林带或者叫布林通道,顾名思义,绘制了一条以均线为中心,4倍标准差宽度的通道。

和 MACD 一样,布林带依然是对价格趋势的描述,只是相较于 MACD 描述趋势的变化程度,布林带更关注于价格的异常波动。

要搞懂布林带,就需要从定义入手,除了之前提到的均线,另一个重要的概念就是标准差。

标准差是反映一组数据离散程度最常用的一种量化形式,是表示精确度的重要指标。标准差的计算步骤如下:

  1. 求平均:计算数据集中数值的平均值。
  2. 计算每个数值与平均值的差:从每个数值中减去平均值,然后求差的平方。
  3. 求结果的平均:将所有差的平方相加,然后除以数据集中的数值个数,再取平方根。

由此看出,布林带绘制了一条价格变化的通道,在绝大多数情况下,价格会处于通道内,并围绕中线上下波动。

对于单边趋势(如上涨),价格如果突破布林带,说明开始了加速行情。
对于震荡趋势,价格如果突破了布林带,说明要开始回调或突破。

世界上并不存在圣杯和银弹,像盲人摸象一样,任何指标都只能反应市场的一部分,而且计算的过程越复杂,离真是可能越远。

福利

扫码免费试用DevChat