在上一篇文章《量在价先(上):如何利用成交量预测市场走势》中,我们参考光大证券的研究报告《放量恰是入市时,成交量择时初探》,介绍了用成交量进行择时的一个思路:对成交量进行时序排名,然后根据排名的大小择时交易。本文以沪深300指数为例,介绍如何用Python实现成交量时序排名择时策略,并观察策略的择时效果。
# 导入需要使用的库
import pandas as pd
import numpy as np
import akshare as ak
# 在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 = 'sh000300'
start_date = pd.to_datetime('2005-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'])
price_df = price_df[(price_df['date']>=start_date) & (price_df['date']<=end_date)]
price_df = price_df.sort_values('date').set_index('date')

从小到大排序,计算当日成交量的排名,然后将排名标准化到 [-1, 1] 的范围内。
# 计算成交量时序排名
# 设置滚动窗口的大小
N = 40
# 计算排名
price_df['ranked'] = price_df['volume'].rolling(window=N).apply(lambda x: x.rank().iloc[-1], raw=False)
# 标准化排名到[-1, 1]范围
price_df['normalized_rank'] = (price_df['ranked'] * 2 - (N + 1)) / (N - 1)
# 成交量时序排名择时信号:成交量时序排名高于阈值s时开仓,低于阈值s时清仓
s = 0.5 # 择时阈值
timing_df = pd.DataFrame()
timing_df['成交量时序排名'] = (price_df['normalized_rank'] > s) * 1.
timing_df['不择时'] = 1.
# 计算指数每日的收益率
price_df['returns'] = price_df['close'].pct_change().shift(-1).fillna(0)
# 计算择时后的每日收益率
timing_ret = timing_df.mul(price_df['returns'], axis=0).dropna()
# 计算择时后的累计收益率
cumul_ret = (1 + timing_ret.fillna(0)).cumprod() - 1.
# 可视化输出
cumul_ret.plot(figsize=(10, 6), title='成交量时序排名择时')

# 根据不同行情设置不同的交易阈值择时
Sf = 0.6 # 熊市阈值
Sc = 0.3 # 震荡市阈值
Sr = 0 # 牛市阈值
days = 10 # 涨跌幅天数
c = 0.05 # 涨幅阈值
# 计算指数涨幅
price_df[f'ret_{days}'] = price_df['close'].pct_change(days)
# 指数涨幅大于c为牛市,择时阈值设为Sr;指数涨幅小于-c为熊市,择时阈值设为Sf;其余为震荡市,择时阈值设为Sc
price_df['thre'] = Sc
price_df['thre'].loc[price_df[price_df[f'ret_{days}']>c].index] = Sr
price_df['thre'].loc[price_df[(price_df[f'ret_{days}']<-c)].index] = Sf
# 计算不同行情下的择时信号
timing_df['成交量时序排名_分行情'] = (price_df['normalized_rank'] > price_df['thre']) * 1.
# 计算择时后的每日收益率
timing_ret = timing_df.mul(price_df['returns'], axis=0).dropna()
# 计算择时后的累计收益率
cumul_ret = (1 + timing_ret.fillna(0)).cumprod() - 1.
# 可视化输出
cumul_ret.plot(figsize=(10, 6), title='成交量时序排名择时')

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