【Python量化】布林带策略

article/2025/9/19 10:29:38

文章目录

  • 一、计算布林带
  • 三、构建策略,计算持仓头寸序列和买卖信号序列
  • 四、计算策略收益
  • 五、绘制交易信号

此文章首发于公众号:Python for Finance

链接:https://mp.weixin.qq.com/s/CJR2gwXkkzFRavZ8I98qdw

布林带(BOLL)指标是美国股市分析家约翰·布林根据统计学中的标准差原理设计出来的一种非常简单实用的技术分析指标。一般而言,股价的运动总是围绕某一价值中枢(如均线、成本线等)在一定的范围内变动,布林线指标正是在上述条件的基础上,引进了“股价通道”的概念,其认为股价通道的宽窄随着股价波动幅度的大小而变化,而且股价通道又具有变异性,它会随着股价的变化而自动调整。

一、计算布林带

首先我们导入相关库。

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

接下来编写一个函数来计算我们的布林带。

  • 中轨:股价的平均成本,N时间段的简单移动平均
  • 上轨:压力线,上轨 = 中轨 + K × N时间段的标准差
  • 下轨:支撑线,下轨 = 中轨 − K × N时间段的标准差
def calculate_bollinger_bands(df, window = 20, no_of_std = 2, column_name = ''):'''Parameters----------df : 股价数据集window : 计算的周期,默认20天no_of_std : 标准偏差的倍数,默认2column_name : 股价数据集选择的列名,默认为第一列'''if column_name == '':     column_name = df.columns[0]  df['Observation']=df[column_name]df['RollingMean'] = df[column_name].rolling(window).mean()std = df[column_name].rolling(window).std(ddof=0)  df['UpperBound'] = df['RollingMean'] + no_of_std * stddf['LowerBound'] = df['RollingMean'] - no_of_std * stdbb = df[['Observation','RollingMean','UpperBound','LowerBound']]bb.plot(title='Observation with Bollinger Bands') #绘制布林带return df

我们以SPY数据为例,csv文件地址如下:链接:https://pan.baidu.com/s/1uqX_F07q28SaYMtosque3w ,提取码:vwi2。

我们读取SPY价格数据。

df = pd.read_csv(r'C:\Users\mi\Desktop\SPY.csv') 
df = df.set_index('Date')

数据如下:

>>>dfOpen        High  ...   Adj Close    Volume
Date                                ...                      
2021-08-10  442.609985  443.440002  ...  436.474243  43339300
2021-08-11  443.820007  443.880005  ...  437.558807  44034300
2021-08-12  443.619995  445.260010  ...  438.870117  38909400
2021-08-13  445.589996  445.940002  ...  439.668823  39470300
2021-08-16  444.529999  447.109985  ...  440.704102  73740000...         ...  ...         ...       ...
2022-08-04  414.369995  415.089996  ...  414.170013  45656600
2022-08-05  409.660004  414.149994  ...  413.470001  56755600
2022-08-08  415.250000  417.619995  ...  412.989990  53886100
2022-08-09  412.220001  412.750000  ...  411.350006  44840500
2022-08-10  418.779999  420.040009  ...  419.276886  30838744[253 rows x 6 columns]

我们以SPY数据为例,计算其布林带。

df = calculate_bollinger_bands(df, 10, 2, 'Adj Close') #计算布林带

数据如下:

>>>dfOpen        High  ...  UpperBound  LowerBound
Date                                ...                        
2021-08-10  442.609985  443.440002  ...         NaN         NaN
2021-08-11  443.820007  443.880005  ...         NaN         NaN
2021-08-12  443.619995  445.260010  ...         NaN         NaN
2021-08-13  445.589996  445.940002  ...         NaN         NaN
2021-08-16  444.529999  447.109985  ...         NaN         NaN...         ...  ...         ...         ...
2022-08-04  414.369995  415.089996  ...  421.151341  388.468666
2022-08-05  409.660004  414.149994  ...  422.323881  390.972127
2022-08-08  415.250000  417.619995  ...  422.553138  394.226867
2022-08-09  412.220001  412.750000  ...  418.489248  402.382755
2022-08-10  418.779999  420.040009  ...  419.151863  405.367516[253 rows x 10 columns]

绘制的布林带图形如下:

三、构建策略,计算持仓头寸序列和买卖信号序列

策略的关键是得到持仓头寸序列和买卖信号序列。

布林带策略有多种。

(1)均值回归策略

布林线均值回归策略认为,标的价格在上轨线和下轨线围成的范围内浮动,即使短期内突破上下轨,但长期内仍然会回归到布林带之中。因此,一旦突破上下轨,即形成买卖信号。

我们可构建策略1:

当股价由下向上穿过上轨的时候,做空;然后由上向下穿过中轨的时候,平仓。

当股价由上向下穿过下轨的时候,做多;然后由下向上穿过中轨的时候,平仓。

def calculate_strategy1_position(df): '''策略1:均值回归策略当收盘价由下向上穿过上轨的时候,做空;然后由上向下穿过中轨的时候,平仓。当收盘价由上向下穿过下轨的时候,做多;然后由下向上穿过中轨的时候,平仓。'''   xs = (df.Observation - df.RollingMean) / (df.Observation.shift(1) - df.RollingMean.shift(1))df['position'] = np.nan  df['position'] = np.where(df.Observation<df.LowerBound, 1,df['position'])    df['position'] = np.where(df.Observation>df.UpperBound ,-1,df['position'])   df['position'] = np.where(xs<0, 0, df['position'])df['position'] = df['position'].ffill().fillna(0)  #买入开仓long_entry_condition = (df['position']==1) & (df['position'].shift(1)!=1)df.loc[long_entry_condition,'signal_long'] = 1#卖出平仓long_exit_condition = (df['position']!=1) &(df['position'].shift(1)==1)df.loc[long_exit_condition,'signal_long'] = 0#卖出开仓short_entry_condition = (df['position']==-1) & (df['position'].shift(1)!=-1)df.loc[short_entry_condition,'signal_short'] = -1#买入平仓short_exit_condition = (df['position']!=-1) & (df['position'].shift(1)==-1)df.loc[short_exit_condition,'signal_short'] = 0return df

(2)趋势性交易策略

布林线趋势性交易策略略认为,标的价格在上轨线和下轨线围成的范围内浮动,如果突破上轨,通常认为产生上涨趋势,做多;如果突破下轨,通常认为产生下跌趋势,做空。因此,一旦突破上下轨,即形成买卖信号。

我们可构建策略2:

当股价由下向上穿过上轨的时候,做多;然后由上向下穿过上轨的时候,平仓。

当股价由上向下穿过下轨的时候,做空;然后由下向上穿过下轨的时候,平仓。

策略3:

当股价由下向上穿过上轨的时候,做多;然后由上向下穿过中轨的时候,平仓。

当股价由上向下穿过下轨的时候,做空;然后由下向上穿过中轨的时候,平仓。

def calculate_strategy2_position(df):   '''-------策略2:当收盘价由下向上穿过上轨的时候,做多;然后由上向下穿过上轨的时候,平仓。当收盘价由上向下穿过下轨的时候,做空;然后由下向上穿过下轨的时候,平仓。'''#position : 持仓头寸,多仓为1,不持仓为0,空仓为-1#siganal : 交易信号,做多为1,平仓为0,做空为-1df['position'] = np.where(df.Observation > df.UpperBound, 1, 0) df['position'] = np.where(df.Observation < df.LowerBound, -1, df['position'])   #买入开仓long_entry_condition = (df['position']==1) & (df['position'].shift(1)!=1)df.loc[long_entry_condition,'signal_long'] = 1#卖出平仓long_exit_condition = (df['position']!=1) &(df['position'].shift(1)==1)df.loc[long_exit_condition,'signal_long'] = 0#卖出开仓short_entry_condition = (df['position']==-1) & (df['position'].shift(1)!=-1)df.loc[short_entry_condition,'signal_short'] = -1#买入平仓short_exit_condition = (df['position']!=-1) & (df['position'].shift(1)==-1)df.loc[short_exit_condition,'signal_short'] = 0return dfdef calculate_strategy3_position(df): '''策略3:当收盘价由下向上穿过上轨的时候,做多;然后由上向下穿过中轨的时候,平仓。当收盘价由上向下穿过下轨的时候,做空;然后由下向上穿过中轨的时候,平仓。'''   xs = (df.Observation - df.RollingMean) / (df.Observation.shift(1) - df.RollingMean.shift(1))df['position'] = np.nan  df['position'] = np.where(df.Observation>df.UpperBound, 1,df['position']) #做多 df['position'] = np.where(df.Observation<df.LowerBound ,-1,df['position']) #做空    df['position'] = np.where(xs<0, 0, df['position']) #平仓df['position'] = df['position'].ffill().fillna(0)  #买入开仓long_entry_condition = (df['position']==1) & (df['position'].shift(1)!=1)df.loc[long_entry_condition,'signal_long'] = 1#卖出平仓long_exit_condition = (df['position']!=1) &(df['position'].shift(1)==1)df.loc[long_exit_condition,'signal_long'] = 0#卖出开仓short_entry_condition = (df['position']==-1) & (df['position'].shift(1)!=-1)df.loc[short_entry_condition,'signal_short'] = -1#买入平仓short_exit_condition = (df['position']!=-1) & (df['position'].shift(1)==-1)df.loc[short_exit_condition,'signal_short'] = 0return df

四、计算策略收益

我们可编制函数,计算市场收益率、策略收益率及策略超常收益率。注意我们的买卖信号出现后,第二天才能进行交易。

def calculate_returns(df):# 计算市场对数收益率、策略对数收益率、策略超常收益率df['market_log_returns'] = np.log(df['Observation']/df['Observation'].shift(1))df['strat_log_returns'] = df['position'].shift(1)* df['market_log_returns'] #交易信号出现后第二天交易df['abnormal_returns'] = df['strat_log_returns'] - df['market_log_returns']# 计算市场累积收益率、策略累积收益率、策略累积超常收益率df['market_cum_returns'] = np.exp(df['market_log_returns'].cumsum()) - 1df['strat_cum_returns'] = np.exp(df['strat_log_returns'].cumsum()) - 1df['abnormal_cum_returns'] = df['strat_cum_returns'] - df['market_cum_returns']# 绘图ret = df[['market_log_returns','strat_log_returns','abnormal_returns']]ret.plot(title='Market,Strategy,and Abnormal Returns')cum_returns = df[['market_cum_returns','strat_cum_returns','abnormal_cum_returns']]cum_returns.plot(title='Cumulative Returns')return df

五、绘制交易信号

我们可编制函数,将买卖信号标注在布林带中。

def plot_bands_with_signal(df):# 绘制交易图表#买入开仓long_entry = df.loc[df['signal_long']==1]['Observation']#卖出平仓long_exit = df.loc[df['signal_long']==0]['Observation']#卖出开仓short_entry = df.loc[df['signal_short']==-1]['Observation']#卖出平仓short_exit = df.loc[df['signal_short']==0]['Observation']fig, ax = plt.subplots(1, figsize=(15, 10), sharex=True)   ax.plot(df['Observation'], label='Observation')ax.plot(df['RollingMean'], label='RollingMean')ax.plot(df['UpperBound'])ax.plot(df['LowerBound'])ax.fill_between(df.index, df['UpperBound'], df['LowerBound'],alpha=0.3, label='Bollinger Band')ax.scatter(long_entry.index, long_entry, color='r', s=100, marker='^', label='Long Entry',zorder=10)ax.scatter(long_exit.index, long_exit, color='r',s=100, marker='x', label='Long Exit',zorder=10)ax.scatter(short_entry.index, short_entry, color='b', s=100, marker='^', label='Short Entry',zorder=10)ax.scatter(short_exit.index, short_exit, color='b',s=100, marker='x', label='Short Exit',zorder=10)ax.set_title('Bollinger Band Strategy Trading Signals')ax.legend()plt.show()

我们以SPY数据为例,调用上述函数。

df = pd.read_csv(r'C:\Users\mi\Desktop\SPY.csv') 
df = df.set_index('Date')
df = calculate_bollinger_bands(df, 10, 2, 'Adj Close') #计算布林带
# 策略1
df1 = calculate_strategy1_position(df.copy()) 
df1 = calculate_returns(df1)
plot_bands_with_signal(df1)
# 策略2
df2 = calculate_strategy2_position(df.copy()) 
df2 = calculate_returns(df2)
plot_bands_with_signal(df2)
# 策略3
df3 = calculate_strategy3_position(df.copy()) 
df3 = calculate_returns(df3)
plot_bands_with_signal(df3)

可得到策略1的收益率、累积收益率、交易信号如下图所示:

可得到策略2的收益率、累积收益率、交易信号如下图所示:

可得到策略3的收益率、累积收益率、交易信号如下图所示:


欢迎关注:
Python for Finance微信公众号


http://chatgpt.dhexx.cn/article/vl1ys2Um.shtml

相关文章

Lyndon的量化修炼之路——布林通道优化策略(一)

//期市妖风大&#xff0c;小心被刮飞。本文不构成任何实质性建议&#xff0c;也不对任何依此进行的交易结果负责经过某位大佬的提醒&#xff0c;原来大白有另外的含义&#xff0c;侵权了侵权了&#xff08;原谅我孤陋寡闻&#xff09;&#xff0c;所以还是简单点好。 我也不知…

现货黄金指标精讲(布林通道)

现货黄金的特点在于可以多空双向交易&#xff0c;如果投资者能精通一到两种的技术分析手段&#xff0c;必定能大幅提高交易的成功率。布林通道指标不仅能揭示金价运行的趋势&#xff0c;还能提供清晰的买卖信号&#xff0c;帮助长、中、短线的投资者提高交易决策的质量。 一、布…

布林通道 Bollinger Bands——非炒股向个人学习笔记

有一组数据&#xff0c;大多数是以时间序列的数据&#xff0c;如年、月、日为度量的某指标变化。&#xff08;上图的绿线不用管&#xff09; 布林通道的作用是描述数值的近期波动程度&#xff0c;具体表现就表现在轨道的收窄与拓宽上。 一、基本概念 作图需设定的变量&#x…

eclipse安装教程与使用教程

第一首先在电脑的浏览器中输入“eclipse官网”。 然后在网页中点击进入eclipse的官方下载网站。 2 第二然后再点击页面右边的“download”。 在弹出的页面下面点击“download packages”。 3 第三然后在下面找到“eclipse IDE for java developers”的选项。 在选项右边有…

eclipse基础实用教程

一、打开eclipse&#xff0c;创建java文件 1.点击eclipse.exe文件 Workspace&#xff1a;&#xff08;这个是你写的代码存放位置&#xff0c;可以自己选择创建一个文件夹&#xff09; 2.新装的eclipse中在new里面未找到java project&#xff0c; 点击Open Perspective&#…

eclipse使用教程(图文)

很多人都知道要用eclipse来做java开发&#xff0c;但很多的新手朋友却不知道怎么下载和安装eclipse。下面给你介绍一下怎么下载和安装eclipse来用于自己的学习或者项目开发&#xff0c; 很多人都知道要用eclipse来做java开发&#xff0c;但很多的新手朋友却不知道怎么下载和安装…

Eclipse详细安装教程

Eclipse安装教程 前言一、Eclipse是什么&#xff1f;二、安装步骤1. Eclipse下载下载网址 2. Eclipse安装 前言 Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。 一、Eclipse是什么&#xff1f; Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言…

Eclipse最新最简最详细安装教程

Eclipse最新最简最详细安装教程 1、首先打开官方地址&#xff08;见下面&#xff09; Eclipse官方下载地址&#xff1a;点击打开官方链接 2、点击红箭头指向的红框中的“Download Packages”。 3、出现新的页面之后往下翻找到并点击红箭头指向的红色矩形的部分Eclipse IDE f…

Eclipse安装教程 ——史上最详细安装Java Python教程说明

Eclipse安装教程 ——史上最详细安装Java&Python教程说明 (Win7_64位 Eclipse 64位 JDK_8u131_64位 python2.7.8 PyDev5.7.0插件) 适用操作系统&#xff1a;Win7 64位 所需要的软件以及插件&#xff1a;Eclipse 64位、JDK_8u131_64位、python2.7.8、PyDev5.7.0插件 …

Eclipse 教程

Eclipse的使用 前言一、Eclipse的介绍二、下载与安装1.下载2.安装 三、基本使用步骤1.启动2.创建项目3. 创建包及class文件 四、一些使用技巧1. 快速生成构造方法2.自动补全3. 快速生成get-set方法4. 查找某变量所在位置,或者替换某变量的变量名5. 快速导入包6.合理利用eclipse…

视频消重处理,视频原创怎么做,视频处理软件

现在的新传媒行业&#xff0c;有很多小伙伴搬过来的视频都不太清楚怎么把它变成自己的视频&#xff0c;也就是消重&#xff0c;现在有一款工具可以达到这种消重原创&#xff0c;像某头条通过率在96%以上了 这是一个视频消重处理软件&#xff0c;现在给大家说说功能和页面 1&…

视频合成-moviepy

最近发现&#xff0c;公司在进行视频合成的时候&#xff0c;部分业务不是在客户端进行合成&#xff0c;而是在后端进行合成&#xff0c;让我有点惊讶&#xff0c;立马问开发要了代码&#xff0c;想要看看到底在后端如何处理的。 学习文档&#xff1a;https://blog.csdn.net/uc…

计算机图像视频处理

计算机图像视频处理 计算机视觉概论 计算机视觉概念 计算机图像处理&#xff0c;也即数字图像处理(Digital Image Processing)&#xff0c; 是指将图像信号转换成数字信号并利用计算机对其进行处理的过程&#xff0c;是通过计算机对图像进行去除噪声、增强、复原、分割、提取…

视频处理

1.视频处理 在视频压缩前后&#xff0c;对视频图像质量增强的操作视频编解码系统输出的图像主观质量不仅与压缩算法的性能有关&#xff0c;还受视频处理的影响压缩之前对视频的处理称作预处理&#xff08;Pre-processing&#xff09;压缩之后对视频的处理称作后处理&#xff0…

基于PythonOpenCv的视频图像处理

博主简介 博主是一名大二学生&#xff0c;主攻人工智能研究。感谢让我们在CSDN相遇&#xff0c;博主致力于在这里分享关于人工智能&#xff0c;c&#xff0c;Python&#xff0c;爬虫等方面知识的分享。 如果有需要的小伙伴可以关注博主&#xff0c;博主会继续更新的&#xff0c…

openpose如何处理视频

openpose提供了官方的bin文件&#xff0c;可以通过shell直接处理视频&#xff0c; 此外还提供了一系列的demo文件&#xff0c;用于处理图片文件。 那如何修改官方的demo用来处理视频呢&#xff1f; 找了不少别人的教程都是通过 cv2.dnn.readNetFromCaffe(protoFile, weight…

使用python的视频处理

本文探讨的是使用python对视频进行如下操作&#xff1a; 将待处理的视频分割成帧对每一帧进行处理对处理后的帧合并得到最终的视频 为了方便接下去的实验过程&#xff0c;读者必须具备如下的工具&#xff1a; 1、依赖包python-opencv 2、借助工具ffmpeg import cv2 import …

VideoProc v4.4 多功能视频处理工具

前言 VideoProc是WinX/MacX HD Video Converter Deluxe的进阶版本&#xff0c;在功能上更上一层。VideoProc全方位整合了影片转档、影片压缩、&#xff08;YouTube&#xff09;影片下载、影片剪辑的功能&#xff0c;使你在Windows上管理不同的多轨道、SD、HD、4K影片的绝佳方案…

视频分类Video-Swin-Transformer

视频分类Video-Swin-Transformer 视频分类Video-Swin-Transformer 视频分类Video-Swin-Transformer前言一、Video-Swin-Transformer二、环境安装三、数据预测四、对源码进行更改五、总结六、参考资料 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 星光…

Python - MoviePy 处理音视频

文章目录 一、关于 MoviePy相关教程安装工作原理 二、音频获取音频信息切割拼接音频叠加音频循环播放格式转换视频提取音频 三、视频获取视频信息预览视频视频/Gif 提取图片图片生成视频 / gif图片 音乐合成视频视频提取 gif视频添加文字视频拼接 concatenate_videoclips堆叠 …