Quant Buffet放轻松,别过度思虑

股票的日内动量

登录后收藏

学术论文

Intraday Momentum: The First Half-Hour Return Predicts the Last Half-Hour Return

作者市场日内动量 [点击查看论文]

机构
  • George Mason University
  • University of North Carolina at Charlotte
  • ?University of North Carolina (UNC) at Charlotte - Finance
  • Rutgers, The State University of New Jersey
  • Washington University in St. Louis
  • ?Washington University in St. Louis - John M. Olin Business School
  • ?Rutgers, The State University of New Jersey - Rutgers Business School at Newark & New Brunswick

策略概要

投资者使用第一个和第十二个半小时的回报作为市场择时信号。如果两个信号都为正,则在最后一个半小时建立多头头寸;如果两个信号都为负,则建立空头头寸。如果信号不同,投资者保持中性。头寸在收盘时清算,确保没有隔夜风险。该策略可以使用ETF或期货执行,利用日内市场择时来利用短期趋势,同时保持纪律严明的系统性方法。

II. 策略合理性

学术研究对这种效应提供了两种解释。首先,日内交易者可能在第一个半小时回报强劲后做空,预期价格反转。当他们在收盘前平仓时,一些人会等到最后一个半小时,从而影响价格走势。其次,知情交易者会在高交易量时期策略性地择时交易。阿德马蒂和普费德勒(1988)以及霍拉(2006)的理论表明,最优策略包括在交易日的开始和结束时进行快速交易,在交易日中期进行较慢的交易,这与交易量和信息动态一致。这两种行为都导致了特定日内时段内可预测的价格模式。

回测表现

波动率4.49%
夏普比率0.98
索提诺比率-0.592
胜率48%

完整 Python 代码

from AlgorithmImports import *
class IntradayMomentumEquities(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2000, 1, 1)
self.SetCash(100000)
self.symbol = self.AddEquity("SPY", Resolution.Minute).Symbol
self.Schedule.On(self.DateRules.EveryDay(self.symbol), self.TimeRules.BeforeMarketClose(self.symbol, 30), self.Rebalance)
self.Schedule.On(self.DateRules.EveryDay(self.symbol), self.TimeRules.BeforeMarketClose(self.symbol, 1), self.MarketClose)

def Rebalance(self):
day_history = self.History([self.symbol], 12*30, Resolution.Minute)

if len(day_history) == 12*30 and 'close' in day_history:
    first_half_hour = day_history['close'][:30]
    first_half_hour_ret = self.Return(first_half_hour)
    
    twelfth_half_hour = day_history['close'][-30:]
    twelfth_half_hour_ret = self.Return(twelfth_half_hour)
    if first_half_hour_ret > 0 and twelfth_half_hour_ret > 0:
        self.SetHoldings(self.symbol, 1)
    elif first_half_hour_ret < 0 and twelfth_half_hour_ret < 0:
        self.SetHoldings(self.symbol, -1)

def MarketClose(self):
self.Liquidate()
def Return(self, history):
return (history[-1] - history[0]) / history[0]