目录

  • 1 量化投资概论
    • 1.1 授课计划
    • 1.2 优秀结课论文分享
    • 1.3 量化鼻祖:西蒙斯
    • 1.4 量化投资的定义
    • 1.5 量化投资的特点
    • 1.6 量化投资的发展史
    • 1.7 量化投资的前景
    • 1.8 章节习题
  • 2 Python基础
    • 2.1 环境配置
    • 2.2 数据结构
    • 2.3 基本语句
    • 2.4 基本函数
    • 2.5 类与对象
    • 2.6 模块和包
    • 2.7 标准库
    • 2.8 Numpy库
    • 2.9 Pandas库
    • 2.10 Matplotlib库
    • 2.11 案例:金融数据分析之Pyhton实现
    • 2.12 章节习题
  • 3 统计学基础*
    • 3.1 统计函数库(自学)
    • 3.2 描述性统计
    • 3.3 随机变量
    • 3.4 统计推断
    • 3.5 方差分析
    • 3.6 回归分析
    • 3.7 章节习题
  • 4 金融学基础
    • 4.1 金融分析库(自学)
    • 4.2 资产收益率与风险
    • 4.3 投资组合理论
    • 4.4 资本资产定价模型
    • 4.5 Fama-French 因子模型
    • 4.6 章节习题
  • 5 金融时间序列分析*
    • 5.1 金融时间序列库(自学)
    • 5.2 基本概念
    • 5.3 基本性质
    • 5.4 金融时间序列预测
    • 5.5 波动率
    • 5.6 章节习题
  • 6 配对交易策略
    • 6.1 配对交易策略
    • 6.2 最小距离法之实战分析
    • 6.3 协整法之实战分析
    • 6.4 随机价差法之实战分析*
    • 6.5 章节习题
  • 7 技术指标策略
    • 7.1 技术指标库(自学)
    • 7.2 K线图
    • 7.3 KDJ 策略
    • 7.4 RSI 策略
    • 7.5 MACD 策略
    • 7.6 BOLL 策略
    • 7.7 DMI 策略
    • 7.8 CCI 策略
    • 7.9 MT 策略
    • 7.10 PTV 策略
    • 7.11 OBV 策略
    • 7.12 ROC 策略
    • 7.13 BIAS 策略
    • 7.14 其他技术指标策略
    • 7.15 章节习题
  • 8 机器学习在量化投资中的应用*
    • 8.1 机器学习库
    • 8.2 量化投资之逻辑回归算法模型
    • 8.3 量化投资之决策树算法模型
    • 8.4 量化投资之随机森林算法模型
    • 8.5 量化投资之支持向量机算法模型
    • 8.6 量化投资之集成算法模型
    • 8.7 量化投资之人工神经网络算法模型
    • 8.8 章节习题
  • 9 深度学习在量化投资中的应用**
    • 9.1 深度学习库
    • 9.2 量化投资之TensorFlow
    • 9.3 量化投资之PyTorch
    • 9.4 量化投资之MXNet
    • 9.5 章节习题
  • 10 附     录
    • 10.1 量化武器库大全
    • 10.2 2022年量化金融分析师全国统一考试考试大纲
BOLL 策略

1. 资源

百科:https://baike.baidu.com/item/RSI/6130115   

平台:http://www.cftsc.com/chaomaichaomaizhibiao/617.html 

(1)通道突破简介

 股票市场的行情是随机而起的,价格线的走势往往给人一种“横看成岭侧成峰,远近高低各不同”的感觉。一个震荡到底是隐含了趋势还是只是杂讯,那可真是言人人殊。通道模型适度解决了这一难题。它利用过去一定时间段内的价格信息,绘制出上下两条通道线(上、下轨),以此设定股价的相对高、低界限。通道线可以包容市场波动行情的部分信息,过滤震荡行情中均线系统“假”突破的信号。通道线除了涵盖市场价格高低的信息以外,两条通道线的距离也体现了股票价格震荡的幅度;当价格波动幅度较小时,通道的带宽较小,当价格震荡较大时,通道的带宽也相应变大。通道突破模型将价格高低与价格震荡的幅度融合在一起,成为判断市场中长期趋势的常用技术分析指标。对于价格通道的刻画,根据数据期数的不同和计算方式的迥异,模型的设定可以有诸多变化。唐奇安通道(Donchian Channel)和布林带通道(Bollinger Band)两种技术分析是常用的通道形式。

(2)唐奇安通道

       唐奇安通道流行于20世纪70年代,由著名的海龟交易员Richard Donchian发明,最早用于日内交易。其主要思想是寻找一定时间内(比如20日)出现的最高价和最低价,将最高价和最低价分布作为通道的上下轨道。当价格突破通道的上轨道时,说明股价运动较为强势,则释放出买入信号;当价格线向下突破通道的下轨道时,空头市场较为强势,市场下跌趋势较为明显,则释放出卖出信号。

      唐奇安通道由三条轨道线构成,上下轨道分别由20日的最高价和最低价来刻画,中轨道是上下轨道的平均线。即

通道上界 = 过去20日内最高价

通道下界 = 过去20日内最低价

中轨道 = (通道上界 +通道下界 )÷ 2

【1】唐奇安通道之Python刻画

# 导入包
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 读取中国联通的股票数据(600050)
ChinaUnicom=pd.read_csv('ChinaUnicom.csv')
ChinaUnicom.index=ChinaUnicom.iloc[:,1]
ChinaUnicom.index=pd.to_datetime(ChinaUnicom.index, format='%Y-%m-%d')
ChinaUnicom=ChinaUnicom.iloc[:,2:]

# 提取收盘价、最高价和最低价
Close = ChinaUnicom.Close
High = ChinaUnicom.High
Low = ChinaUnicom.Low

# 设置上、下、中通道线初始值
upboundDC = pd.Series(0.0,index=Close.index)
downboundDC = pd.Series(0.0,index=Close.index)
midboundDC = pd.Series(0.0,index=Close.index)

# 求唐奇安上、下、中通道
for i in range(20,len(Close)):
   upboundDC[i] = max(High[(i-20):i])
   downboundDC[i] = min(Low[(i-20):i])
   midboundDC[i] = 0.5 * (upboundDC[i] + downboundDC[i])
   
upboundDC = upboundDC[20:]
downboundDC = downboundDC[20:]
midboundDC = midboundDC[20:]

# 绘制2013年中国联通价格的唐奇安上中下通道
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.figure(figsize=(10,6))

plt.plot(Close['2013'],label="Close",color='k')
plt.plot(upboundDC['2013'],label="upboundDC",color='b',linestyle='dashed')
plt.plot(midboundDC['2013'],label="midboundDC",color='r',linestyle='-.')
plt.plot(downboundDC['2013'],label="downboundDC",color='b',linestyle='dashed')

plt.title("2013年中国联通股价唐奇安通道")
plt.ylim(2.9,3.9)
plt.legend()

plt.show()

# 绘制2013年上半年中国联通价格的K线图及唐奇安通道
upDownDC = pd.DataFrame({'upboundDC':upboundDC,'downboundDC':downboundDC})
ChinaUnicom13 = ChinaUnicom['2013-01-01':'2013-06-28']
upDownDC13 = upDownDC['2013-01-01':'2013-06-28']

import candle    # 实现把candle模块(附录下载)拷贝到工作路径下

plt.figure(figsize=(12,6))
title = '中国联通2013年上半年K线图及唐奇安通道'
candle.candleLinePlots(candleData=ChinaUnicom13,candleTitle=title,Data=upDownDC13)

【2】唐安奇通道突破之Python捕捉

# 定义向上突破函数
def upbreak(tsLine,tsRefLine):
   n = min(len(tsLine),len(tsRefLine))
   tsLine = tsLine[-n:]
   tsRefLin = tsRefLine[-n:]
   signal = pd.Series(0,index=tsLine.index)
   for i in range(1,len(tsLine)):
       if all([tsLine[i] > tsRefLine[i],tsLine[i-1] < tsRefLine[i-1]]):
           signal[i] = 1
   return(signal)

# 定义向下突破函数
def downbreak(tsLine,tsRefLine):
   n = min(len(tsLine),len(tsRefLine))
   tsLine = tsLine[-n:]
   tsRefLine = tsRefLine[-n:]
   signal = pd.Series(0,index=tsLine.index)
   for i in range(1,len(tsLine)):
       if all([tsLine[i] < tsRefLine[i],tsLine[i-1] > tsRefLine[i-1]]):
           signal[i] = 1
   return(signal)

# 唐安奇通道突破策略
# DC Strategy
UpBreak = upbreak(Close[upboundDC.index[0]:],upboundDC)
DownBreak = downbreak(Close[downboundDC.index[0]:],downboundDC)

# 制定交易策略
#上穿:singal为1
#下穿:singal为-1
BreakSig = UpBreak - DownBreak

# 计算20日通道交易策略的获胜率
tradeSig = BreakSig.shift(1)
ret = Close/Close.shift(1)-1
tradeRet = (ret*tradeSig).dropna()
tradeRet[tradeRet==0] = 0
winRate = len(tradeRet[tradeRet>0])/len(tradeRet[tradeRet!=0])

# 时间周期设定为40,并计算上中下三条轨道线
upboundDC2 = pd.Series(0.0,index=Close.index)
downboundDC2 = pd.Series(0.0,index=Close.index)
midboundDC2 = pd.Series(0.0,index=Close.index)

for i in range(40,len(Close)):
   upboundDC2[i] = max(High[(i-40):i])
   downboundDC2[i] = min(Low[(i-40):i])
   midboundDC2[i] = 0.5*(upboundDC2[i]+downboundDC2[i])

upboundDC2 = upboundDC2[40:]
downboundDC2 = downboundDC2[40:]
midboundDC2 = midboundDC2[40:]

# 绘制K线图及上下轨道线
upDownDC2 = pd.DataFrame({'upboundDC':upboundDC2,'downboundDC':downboundDC2})
ChinaUnicom13 = ChinaUnicom['2013-01-01':'2013-06-28']
upDownDC2 = upDownDC2['2013-01-01':'2013-06-28']

import candle

plt.figure(figsize=(12,6))
title = '中国联通2013年上半年K线图及40日唐奇安通道'
candle.candleLinePlots(candleData=ChinaUnicom13,candleTitle=title,Data=upDownDC2)



(3)布林通道策略(BOLL, Bollinger Bands)

   “布林通道”(布林带状、保力加通道),是通道形式之一;与唐奇安通道类似,布林带通道也有刻画股票价格变化情况和波动幅度大作用。布林带通道是美国投资者约翰·布林格(Joh B01H哪)在20世纪后期结合统计学理论发明的一种技术分析指标。在分析股价运动情况时,一股以股价平均线作为参照线,而布林带夜均线的基础上增添上下两条“股价通道”线。布林带的中轨线是股价的平均线,上通道为股价的均线加上一定倍数的标准差,而下通道则由均线减去一定倍数的标准差得到。

      布林带通道的趋势主要由中轨道平均线决定,当平均线呈现向上趋势时,布林带通道也会向上走,当平均线走低时,布林带通道也会有向下趋势。布林带通道的带宽由股价的标准差决定;而股价的标准差刻画了股价波动范围的大小,当股价波动较大时,标准差较大,进而布林带上下通道的带宽越大;反之,当股价波动幅度较小时,标准差越小,布林带带宽则会相应变窄。

【1】布林带通道的计算公式



一般而言,n 取值为20天,a 取值为2,则计算公式为

  • 中轨道


  • 上通道线



  • 下通道线


其中,

# 定义布林带通道函数
def bbands(tsPrice,period=20,times=2):
   upBBand = pd.Series(0.0,index=tsPrice.index)
   midBBand = pd.Series(0.0,index=tsPrice.index)
   downBBand = pd.Series(0.0,index=tsPrice.index)
   sigma = pd.Series(0.0,index=tsPrice.index)
   for i in range(period-1,len(tsPrice)):
       midBBand[i] = np.nanmean(tsPrice[i-(period-1):(i+1)])
       sigma[i] = np.nanstd(tsPrice[i-(period-1):(i+1)])
       upBBand[i] = midBBand[i]+times*sigma[i]
       downBBand[i] = midBBand[i]-times*sigma[i]
   BBands = pd.DataFrame({'upBBand':upBBand[(period-1):],\
                        'midBBand':midBBand[(period-1):],\
                        'downBBand':downBBand[(period-1):],\
                        'sigma':sigma[(period-1):]})
   return(BBands)
   
# 计算20日布林带通道线
UnicomBBands = bbands(Close,20,2)

# 绘制2013年布林带通道线
upDownBB = UnicomBBands[['downBBand','upBBand']]
upDownBB13 = upDownBB['2013-01-01':'2013-06-28']

import candle
plt.figure(figsize=(12,6))
title = '中国联通2013年上半年布林带通道线'
candle.candleLinePlots(candleData=ChinaUnicom13,candleTitle=title,Data=upDownBB13)


(4)布林带通道与市场风险

      布林带通道的设定蕴含着统计学原理,假设股票价格走势呈现正态分布1,正态分布是关于均值呈对称分布的,如图所示,均值加减两倍标准差范围内的数据大概占据了整个数据的95.44%。布林带通道以价格的平均值加减两个标准差来设定上下通道,从正态分布的角度来看,布林带通道刻画了股票价格的主要变化范围,即大部分情况下股票价格应该在布林带通道内部运动,股价只有大约5%的概率会突破布林带通道的上轨道或者下轨道。因此在正常情况下,当价格线超出布林带通道上下线时,可以认为价格线有偏离,未来价格很有可能回落到布林带通道的内部。

由于布林带通道的设定与标准差的倍数相关,有学者将布林带通道与股市风险联系在一起分析市场行情。在股价运动分布情况呈现出正态分布的前提下,布林带通道由平均线加减2倍标准差刻画,由图可推知,在正常情况下,股价有95.44%的概率在正负两倍标准差内部运动,当股价突破布林带上下界时,说明股价出现了异常波动,异常波动的概率为4.56%。将股价异常波动到布林带上下通道外部的情况定义成“布林带风险”(Bollinger Risk)。

     根据统计学原理,在置信水平为a的条件下,布林带风险BR。的计算公式为:


# 定义布林带风险函数
def CalBollRisk(tsPrice,multiplier):
    k = len(multiplier)
    overUp = []
    belowDown = []
    BollRisk = []
    for i in range(k):
        BBands = bbands(tsPrice,20,multiplier[i])
        a = 0
        b = 0
        for j in range(len(BBands)):
            tsPrice = tsPrice[-(len(BBands)):]
            if tsPrice[j] > BBands.upBBand[j]:
                a += 1
            elif tsPrice[j] < BBands.downBBand[j]:
                b += 1
        overUp.append(a)
        belowDown.append(b)
        BollRisk.append(100*(a+b) / len(tsPrice))
    return(BollRisk)
    
# 设定标准差的倍数向量
multiplier = [1,1.65,1.96,2,2.58]

# 计算不同年份的布林带风险:2010年
price2010 = Close['2010-01-04':'2010-12-31']
CalBollRisk(price2010,multiplier)

# 2011年
price2011=Close['2011-01-04':'2011-12-31']
CalBollRisk(price2011,multiplier)

# 2012年
price2012=Close['2012-01-04':'2012-12-31']
CalBollRisk(price2012,multiplier)

# 2013年
price2013=Close['2013-01-04':'2013-12-31']
CalBollRisk(price2013,multiplier)

(5)通道突破交易策略的制定

【1】一般策略

布林带通道最常见的策略就是根据价格线突破布林带通道上下界来制定交易策略。

  • 当股价向上突破布林带上通道时,股票可能产生了异常上涨,未来股价会跌落到到布林带通道内部,此时宜做空;

  • 当股价向下突破布林带下通道时,股票可能产生了异常跌势,未来股价会上升到布林带通道内部,此时宜做多。

############################ 向上突破上通道,做空;向下突破下通道,做多 ############################

BBands = bbands(Close,20,2)

upbreakBB1 = upbreak(Close,BBands.upBBand)
downbreakBB1 = downbreak(Close,BBands.downBBand)

# 信号出现2天后交易
upBBSig1 = -upbreakBB1.shift(2)
downBBSig1 = downbreakBB1.shift(2)

tradSignal1 = upBBSig1 + downBBSig1
tradSignal1[tradSignal1==0] = 0

# 定义交易评价函数
def perform(tsPrice,tsTradSig):
    ret = tsPrice / tsPrice.shift(1) - 1
    tradRet = (ret * tsTradSig).dropna()
    ret = ret[-len(tradRet):]
    winRate = [len(ret[ret>0]) / len(ret[ret!=0]),len(tradRet[tradRet>0]) / len(tradRet[tradRet!=0])]
    meanWin = [np.mean(ret[ret > 0]),np.mean(tradRet[tradRet > 0])]
    meanLoss = [np.mean(ret[ret < 0]),np.mean(tradRet[tradRet < 0])]
    Performance = pd.DataFrame({'winRate':winRate,'meanWin':meanWin,'meanLoss':meanLoss})
    Performance.index = ['Stock','Trade']
    return(Performance)
    
Performance1= perform(Close,tradSignal1)
Performance1


【2】特殊策略

布林带通道的上下轨道线的刻画,由选取的时间周期和标准差倍数两部分决定。不同的时间周期参数和标准差倍数可以刻画出不同的上下轨道线,进而股价穿破布林带上下轨道线的情形则会不同。如果布林带通道线设定不合理,股票价格向上穿过布林带上通道线以后,中短期内一直处于上升趋势,而不会回落到通道线内部,或者股价跌破布林带下通道线以后可能会比较晚回升到下通道线上方。为了降低“回落到通道内部”这个期望落空的风险,可以改变布林带通道突破交易策略。交易规则如下。

  • 当价格线由布林带上通道线的上方下穿到布林带通道内部时,说明股价从异常上升行期将要恢复到正常波动行期,股价短期有下跌趋势,此时做空;

  • 当价格线由布林带下通道线的下方上穿到布林带通道内部时,说明股价从异常下跌行期将要恢复到正常波动行期,股价短期有上升趋势,此时做多。

###################### 价格向上穿下通道,做多;价格向下穿上通道,做空 ##############################
upbreakBB2 = upbreak(Close,BBands.downBBand)
downbreakBB2 = downbreak(Close,BBands.upBBand)

# 交易执行
upBBSig2 = upbreakBB2.shift(2)
downBBSig2 = -downbreakBB2.shift(2)
tradSignal2 = upBBSig2 + downBBSig2
tradSignal2[tradSignal2==0] = 0

# 交易策略表现
Performance2 = perform(Close,tradSignal2)
Performance2


(6)作业

【1】获取标普500指数(Standard&Poor's 500 Index,股票名称为“^GSPC ")2020年1月1日到2020年12月31日的日度交易数据:

  1. 绘制标普500指数在2014年前两个月的K线图,并在K线图中绘制收盘价曲线;

  2. 利用布林带函数在K线图中添加布林带线,分析收盘价与布林带线之间的关系;

  3. 以10天为时间跨度,运用唐奇安通道策略,绘制标普500指数的上下两条通道线;

  4. 以10天为时间跨度计算简单移动平均数,作为布林带通道的中间线取值;再以前10日收盘价1.5倍标准差为依据,求出布林带上下通道值,最后绘制布林带通道的三条线。


【2】%b指标(Percent b,PB)是由布林带指标衍生出的一种指标,其主要刻画收盘价曲 线在布林带通道中的相对位置,计算公式为:


  • 当%b取值范围在(0,1)之间时,收盘价曲线在布林带内部波动;

  • 当%b取值为0.5时,收盘价曲线在布林带通道的中间位置;

  • 当%b取值大于1时,收盘价处于布林带上轨道上方;

  • 当%b取值小于0时,收盘价在布林带下轨道下方波动。


  1. 继续沿用第1题中的标普500指数数据,计算%b的值并绘制线图;

  2. 结合布林带线交易策略的思想与%b的取值情况,制定关于%b指标的交易策略,并用Python编写代码实现。


【3】带宽指标(Bandwidth, BW)是由布林带指标衍生出的另一种指标,其主要刻画出布林带通道的宽度情况,计算公式为:

布林带中轨道值由股价的移动平均值来刻画,其可以看作股价的平均成本;布林带上下轨道之间的宽度反映出股票价格的波动幅度,股价波动幅度越大,布林带上下轨道之间的跨度越大。带宽指标刻画了股价波动幅度相对于股票的平均成本的比率,带宽指标可以看作股价波动率的一种体现。

  1. 运用第1题中的标普500指数与2020年的交易数据,计算其带宽指标;

  2. 总结带宽指标取值的分布情况,并结合布林带线和股价线简要分析市场走势。


【4】多空布林线(BBI Boll)与布林线(Bollinger Band)类似,也是由上中下三条轨道构成。

  • 中轨道计算方式为:

  • 上轨道计算方式为:


  • 下轨道计算方式为:


其中,M一般取值为6,  N一般取值为11。

  1. 继续沿用标普500数据,运用Python编写代码计算BBI Boll上中下三条轨道取值,绘制出多空布林带线;

  2. 与布林带线进行比较分析。



 附件

【1】数据集:ChinaUnicom.csv


【2】模块:candle.py

请移步 10.2 附件中下载!