本文是量化策略解析系列的第6篇,本系列的内容为各种量化策略的思路和实现代码,系列连载见:
# 导入需要使用的库
import akshare as ak
import pandas as pd
import numpy as np
import pandas_ta as ta
# 在matplotlib绘图中显示中文和负号
import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.rcParams['font.family'] = 'STKAITI' # 中文字体'STKAITI'
plt.rcParams['axes.unicode_minus'] = False # 解决坐标轴负数的负号显示问题
# 关闭警告信息
import warnings
warnings.filterwarnings('ignore')
# 获取上证指数数据
index_code = 'sh000001'
start_date = pd.to_datetime('2014-01-01')
end_date = pd.to_datetime('2023-12-31')
price_df = ak.stock_zh_index_daily(symbol=index_code)
price_df['date'] = pd.to_datetime(price_df['date']).dt.date
price_df = price_df[(price_df['date']>=start_date) & (price_df['date']<=end_date)]
price_df = price_df.sort_values('date').set_index('date')
计算每日的收益率
price_df['returns'] = price_df['close'].pct_change().shift(-1).fillna(0)
# 计算布林带(Bollinger Bands)
length = 20 # 均线的周期
std = 2.0 # 通道的宽度设定为几倍标准差
mamode = 'sma' # 均线的计算方式
channel = ta.bbands(price_df['close'], length=length, std=std, mamode=mamode)
均线解密:如何有效利用移动平均线》。

# 计算肯特纳通道(Keltner Channels)
length = 20 # 均线的周期
scalar = 2 # 通道的宽度设定为几倍ATR
mamode = 'ema' # 均线的计算方式
channel = ta.kc(price_df['high'], price_df['low'], price_df['close'], length=length, scalar=scalar, mamode=mamode)

# 计算唐奇安通道(Donchian Channels)
length = 20 # 最高价、最低价的周期
channel = ta.donchian(price_df['high'], price_df['low'], lower_length=length, upper_length=length)

# 计算霍尔特-温特通道(Holt-Winter Channel)
channel = ta.hwc(price_df['close'])

# 计算加速带(Acceleration Bands)
length = 20 # 均线的周期
mamode = 'sma' # 均线的计算方式
channel = ta.accbands(price_df['high'], price_df['low'], price_df['close'], length=length, mamode=mamode)

# 可视化输出通道
# 通道上轨、下轨、中轨的名称
up = 'BBU_20_2.0'
down = 'BBL_20_2.0'
middle = 'BBM_20_2.0'
channel[[up, down, middle]].plot(figsize=(10, 6))

# 计算择时信号:价格突破通道上轨时开仓,价格跌破通道下轨时清仓,价格在通道内时维持先前的仓位
timing_df = pd.DataFrame()
timing_df['择时'] = (price_df['close']>=channel[up]) * 1. + (price_df['close']<=channel[down]) * -1.
timing_df = timing_df.replace(0, np.nan) # 先将0替换为NA
timing_df = timing_df.fillna(method='ffill').fillna(0) # 使用前值填充NA
timing_df[timing_df<0] = 0
timing_df['不择时'] = 1.
# 计算择时和不择时的每日收益率
timing_ret = timing_df.mul(price_df['returns'], axis=0)
timing_ret['超额收益'] = (1+timing_ret['择时']).div(1+timing_ret['不择时'], axis=0) - 1.
# 计算累计收益率
cumul_ret = (1 + timing_ret.fillna(0)).cumprod() - 1.
# 可视化输出
cumul_ret.plot(figsize=(10, 6), title='通道择时')

发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/106000
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!