过滤后的短期反转
登录后收藏学术论文
Filtered Market Statistics and Technical Trading Rules
过滤后的市场统计数据和技术交易规则 [点击查看论文]
- MUFlex (Mauritius)
- ?Flexible Plan Investments, Ltd
策略概要
该策略基于连续的每日收益或损失(“运行”)交易标准普尔500指数工具(交易所交易基金(ETF)、差价合约(CFD)或期货)。在连续两天下跌(包括当天)后,投资者在收盘时做多,在连续两天上涨后,投资者转为空头。动态过滤器通过排除绝对回报低于标准普尔500指数(SPX)每日回报的60天滚动标准差的20%的交易日来消除噪音。此过滤器每日更新,以优化信号计算并提高交易准确性。头寸根据过滤后的“运行”动态调整,有效捕捉短期市场趋势。
II. 策略合理性
回测表现
波动率18.6%
夏普比率0.31
索提诺比率-0.03
胜率49%
完整 Python 代码
import numpy as np
from AlgorithmImports import *
class FilteredShortTermReversal(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2000, 1, 1)
self.SetCash(100000)
self.symbol: Symbol = self.AddEquity("SPY", Resolution.Minute).Symbol
# Setup consolidator.
self.spy_onsolidator = TradeBarConsolidator(timedelta(days=1))
self.spy_onsolidator.DataConsolidated += self.DailyData
self.SubscriptionManager.AddConsolidator(self.symbol, self.spy_onsolidator)
# SPY closes.
self.period: int = 61
self.data: RollingWindow = RollingWindow[float](self.period)
# Warmup.
history: DataFrame = self.History(self.symbol, self.period, Resolution.Daily)
if not history.empty:
closes = history.loc[self.symbol].close
for time, close in closes.items():
self.data.Add(close)
self.run_days: RollingWindow = RollingWindow[float](2)
# On daily data.
def DailyData(self, sender, consolidated) -> None:
self.data.Add(consolidated.Close)
if self.data.IsReady:
closes: np.ndarray = np.array([x for x in self.data])
return_data: np.ndarray = closes[:-1] / closes[1:] - 1
ret: float = return_data[0]
if ret >= 0:
self.run_days.Add(1)
else:
self.run_days.Add(0)
if len(return_data) == self.period - 1:
if self.run_days.IsReady:
mean: float = np.mean(return_data)
ret_std: float = np.std(return_data)
run_days: List[float] = [x for x in self.run_days]
# Positive run
if sum(run_days) == 2:
if ret >= mean + ret_std:
if self.Portfolio[self.symbol].IsLong:
self.Liquidate()
self.SetHoldings(self.symbol, -1)
else:
self.Liquidate()
# Negative run
elif sum(run_days) == 0:
if ret <= mean - ret_std:
if self.Portfolio[self.symbol].IsShort:
self.Liquidate()
self.SetHoldings(self.symbol, 1)
else:
self.Liquidate()
else:
self.Liquidate()