在《RSRS择时(上):预测市场阻力与支撑的全新方法》和《RSRS择时(中):用加权回归和标准分改进RSRS指标》中,我们介绍了RSRS择时的思路,本文将以一个具体的例子说明如何用Python实现RSRS择时。
# 导入需要使用的库
import akshare as ak
import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
# 在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')

# 基础版的RSRS
# 最高价和最低价的窗口长度
window_N = 16
# 初始化斜率和决定系数R-squared序列
beta = np.full(price_df.shape[0], np.nan)
r_squared = np.full(price_df.shape[0], np.nan)
# 逐个滚动窗口计算
for i in range(window_N-1, len(price_df)):
# 获取窗口数据
y = price_df['high'].iloc[i-window_N+1:i+1].values
X = np.c_[np.ones(window_N), price_df['low'].iloc[i-window_N+1:i+1].values]
# 线性回归模型
model = LinearRegression()
model.fit(X, y)
# 保存斜率和R-squared
beta[i] = model.coef_[1]
r_squared[i] = model.score(X, y)
price_df['rsrs_beta'] = beta
price_df['r_squared'] = r_squared
标准分RSRS = (当日斜率值 − 斜率均值) / 斜率标准差
# 标准分版的RSRS
# 计算标准分的窗口长度
window_M = 300
# 计算滚动窗口的平均值和标准差
rolling_mean = price_df['rsrs_beta'].rolling(window=window_M).mean()
rolling_std = price_df['rsrs_beta'].rolling(window=window_M).std()
# 计算斜率的Z-score值 = (当日斜率值 − 斜率均值) / 斜率标准差
price_df['rsrs_zscore'] = (price_df['rsrs_beta'] - rolling_mean) / rolling_std
# 修正标准分版的RSRS = 标准分RSRS * 决定系数
price_df['rsrs_zscore_r2'] = price_df['rsrs_zscore'] * price_df['r_squared']
# 右偏标准分版的RSRS = 修正标准分RSRS * 斜率
price_df['rsrs_zscore_positive'] = price_df['rsrs_zscore_r2'] * price_df['rsrs_beta']
rsrs_list = ['rsrs_zscore', 'rsrs_zscore_r2', 'rsrs_zscore_positive']
rsrs_name = ['标准分RSRS', '修正标准分RSRS', '右偏标准分RSRS']
s = 0.7
timing_df = pd.DataFrame()
for i in range(len(rsrs_list)):
rsrs = rsrs_list[i]
timing_df[f'{rsrs_name[i]}择时'] = (price_df[rsrs]>=s) * 1. + (price_df[rsrs]<=-s) * -1.
timing_df = timing_df.replace(0, np.nan)
timing_df = timing_df.fillna(method='ffill')
timing_df[timing_df<0] = 0
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='RSRS择时')

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