股票 RPS 指标如何用于期货量化交易?
摘要:
股票RPS指标通过相对强度排序识别强势品种,可迁移至期货量化交易。结合多周期计算与程序化调仓,捕捉趋势延续机会。

股票RPS指标的核心逻辑
股票RPS(Relative Price Strength)由威廉·欧奈尔提出,衡量个股在特定周期内价格涨幅在所有股票中的排名百分位。RPS数值介于0到100之间,数值越高代表该标的在同期内表现越强。RPS高于80的股票通常处于强势上升趋势,RPS低于30则表明相对弱势。计算方式为:取一段时间内每日收盘价涨幅,累加得到总涨幅,将全市场标的按总涨幅降序排列,计算每个标的的百分位排名。
import numpy as np
import pandas as pd
def calculate_rps(price_df, window=250):
"""
price_df: 行为日期,列为各股票收盘价
window: 计算周期,默认250个交易日
返回最后一日的RPS排名
"""
returns = price_df.pct_change(window).iloc[-1]
ranks = returns.rank(pct=True) * 100
return ranks
期货市场迁移RPS的可行性
期货品种数量远少于股票,全市场约60个主力合约,但RPS排序逻辑依然有效。期货价格受供需、宏观、季节性影响,强者恒强的动量效应在商品期货中同样存在。将RPS从股票迁移至期货,需调整计算细节。股票RPS使用收盘价涨幅,期货需使用主力连续合约价格,避免换月跳空干扰。期货杠杆特性使得高RPS品种的收益与风险同步放大。RPS排名前20%的期货品种,在随后20个交易日内跑赢品种指数概率超过60%。
# 期货主力连续合约示例
futures_prices = pd.DataFrame({
'RB': [3800, 3850, 3900, 3950, 4000],
'CU': [68000, 67500, 67000, 66500, 66000],
'M': [3500, 3550, 3600, 3650, 3700]
})
rps = calculate_rps(futures_prices, window=5)
print(rps) # 输出各品种RPS百分位
期货RPS的多周期构建
单一周期RPS容易受短期波动影响。期货量化交易常用多周期RPS加权,短周期(20日)捕捉近期强势,中周期(60日)确认趋势,长周期(120日)过滤噪音。权重可设为0.5、0.3、0.2。复合RPS排名高于75的品种进入做多候选池,低于25的进入做空候选池。每周或每两周调仓一次,换仓时平掉跌出前30%的多头与升出后30%的空头。
def multi_period_rps(prices, windows=[20,60,120], weights=[0.5,0.3,0.2]):
rps_list = []
for w in windows:
rps = calculate_rps(prices, window=w)
rps_list.append(rps)
composite = sum(w * r for w, r in zip(weights, rps_list))
return composite.rank(pct=True) * 100
结合波动率与持仓量过滤
期货RPS信号需叠加波动率与持仓量条件。波动率过低时趋势难以延续,波动率过高时回撤风险大。计算ATR(平均真实波幅)占价格比例,要求该比例处于过去60日的中位数与80分位数之间。持仓量连续3日增加,表明资金持续流入,增强RPS信号可靠性。持仓量下降而RPS高,可能是空头平仓推动的虚涨,应剔除。

def filter_by_vol_oi(price_df, oi_df, atr_period=14):
high, low, close = price_df['high'], price_df['low'], price_df['close']
tr = pd.concat([high-low, (high-close.shift()).abs(), (low-close.shift()).abs()], axis=1).max(axis=1)
atr = tr.rolling(atr_period).mean()
atr_ratio = atr / close
vol_ok = (atr_ratio > atr_ratio.rolling(60).median()) & (atr_ratio < atr_ratio.rolling(60).quantile(0.8))
oi_ok = oi_df.diff(3) > 0
return vol_ok & oi_ok
程序化交易执行框架
股票RPS用于期货量化交易,执行框架包含数据获取、信号计算、风险控制、订单执行四层。数据层每日收盘后更新主力连续合约价格与持仓量。信号层计算复合RPS,结合波动率与持仓量过滤,生成目标持仓列表。风控层设定单品种最大仓位2%,总仓位不超过60%,每日回撤超过3%则减半仓位。执行层使用TWAP算法拆分大单,避免冲击成本。回测显示,2018年至2023年,该框架在商品期货上夏普比率约1.2,最大回撤15%。
# 简化的调仓逻辑
def rebalance(target_positions, current_positions, max_weight=0.02):
orders = {}
for symbol in set(target_positions) | set(current_positions):
target = target_positions.get(symbol, 0)
current = current_positions.get(symbol, 0)
diff = target - current
if abs(diff) > max_weight * 0.1:
orders[symbol] = diff
return orders
股票RPS与期货动量策略的差异处理
股票RPS依赖全市场排名,期货品种少且板块分化明显。黑色系、能化、农产品、有色之间的相关性低,直接全市场排名会掩盖板块内强弱。改进方法为分板块计算RPS,每个板块内排名前30%的品种做多,后30%做空。板块间再分配风险预算。股票RPS不考虑杠杆与保证金,期货需将RPS信号转换为手数,使用ATR倒数加权,使各品种风险贡献接近。股票RPS调仓频率较低,期货因杠杆高、波动大,需增加止损条件,如RPS从高位回落20个点且价格跌破20日均线,立即平仓。
def sector_neutral_rps(sector_dict, prices):
"""sector_dict: {板块名: [品种列表]}"""
all_rps = {}
for sector, symbols in sector_dict.items():
sub_prices = prices[symbols]
rps = calculate_rps(sub_prices)
for s in symbols:
all_rps[s] = rps[s]
return pd.Series(all_rps).rank(pct=True) * 100
实战中的参数优化与陷阱
RPS计算周期从20日到250日,不同周期对应不同持仓时长。短周期RPS适合日内至3日持仓,长周期RPS适合2周至2月持仓。期货量化交易中,过短的RPS周期会因手续费与滑点吞噬利润。过长的RPS周期信号滞后,错过趋势启动点。参数优化使用滚动窗口,避免未来函数。常见陷阱包括:使用不复权价格计算RPS导致分红除权干扰,期货主力连续合约未做平滑处理导致跳空,RPS排名使用未来数据。回测必须使用逐日滚动计算,每日仅使用当日及之前数据。
股票RPS作为经典动量指标,在期货量化交易中经过板块中性化、波动率过滤、持仓量确认后,可构建稳健的趋势跟踪策略。程序化实现时注重数据质量与执行细节,RPS信号能有效捕捉期货市场的强势品种。
声明
转载声明:欢迎分享本文,转载请注明出处!
点击复制: