研究背景与策略探索
量化研究员通常会考虑不同交易时段对股票超额收益的影响。具体来说,研究人员通常将策略的收益分解为两个部分:隔夜Overnight收益和盘中收益。
基于隔夜收益排序并在隔夜交易:经济上和统计上显著的正超额收益。 基于盘中收益排序并在盘中交易:同样产生显著的正超额收益。 基于盘中收益排序并在隔夜交易:产生负收益,且在统计上显著。 基于隔夜收益排序并在盘中交易:也产生显著的负收益。
相同的排序和交易周期导致了经济上和统计上显著的正超额收益。相反,不同的排序和交易周期(例如,基于盘中收益排序而在隔夜交易)则产生了相当大的负收益(统计上也显著)。通过我们对这四种策略的回测,发现所有策略的回报均高于基本动量Momentum策略,其中隔夜动量策略的月度超额收益最高,为3.47%(年化夏普比率为4.39),因此我们将进一步描述这一策略,供大家学习交流。策略的代码放到了文末。
背景知识
什么是Overnight Position(隔夜持仓)?
Overnight Position(隔夜持仓)是指在正常交易日结束后,投资者持有的未平仓的交易头寸。这些头寸将在下一个交易时段继续被持有。
隔夜持仓的风险包括:
• 市场风险: 市场在休市期间的重大新闻或全球经济事件可能导致市场的剧烈波动,投资者无法及时做出反应。
• 利息与费用: 在一些市场(例如外汇市场),隔夜持仓会产生额外的费用或利息。
什么是Momentum策略(动量策略)?
Momentum策略是金融市场中的一种常用量化交易策略,基于"强者恒强,弱者恒弱"的理念。该策略通过买入近期表现优异的股票并卖空表现不佳的股票,寻求在短期内获得超额收益。一般来说,投资者在证券价格上涨时买入,并在其看起来达到峰值时卖出。目标是通过在短期上升趋势中寻找买入机会,然后在证券开始失去动量时卖出,来利用波动性。之后,投资者将现金取出,寻找下一个短期上升趋势或买入机会,并重复这一过程。熟练的交易者知道何时进入市场、持有多长时间以及何时退出,他们还可以对短期的、受消息驱动的波动或下跌做出反应。根据动量交易的风险包括过早进入市场、过晚退出市场、分心以及错过关键趋势和技术偏离。
基本原理
通常情况下,股票中的动量效应源于投资者的非理性行为,导致对新闻的反应不足。作者认为,动量效应在夜间表现得更为明显,其原因在于机构交易活动。根据他们的实证研究,机构投资者大多进行日内交易,而个人投资者则相反,平均而言,他们会与动量趋势相反交易。
策略介绍
数据初始化:
设定策略开始日期为2010年1月1日,并设置初始资金为100,000美元。
投资标的选取:
该策略主要投资于在美国三大证券交易所(纽约证券交易所 NYSE、美国证券交易所 AMEX 和纳斯达克 NASDAQ)上市的股票。选择市值最大、流动性最高的100只美股,且股价需高于5美元。我们的策略通过CoarseSelectionFunction
筛选流动性最高的100只股票,并按隔夜收益率排序。
数据来源:
股票的收益数据依赖于两大数据库:CRSP 提供的每日收盘价和 TAQ 提供的成交量加权平均价格(VWAP)。VWAP 被定义为交易日前半小时的成交量加权平均价格,避免了因少量交易或拍卖导致的价格波动。
隔夜收益计算:
通过UpdateOvernightReturns
函数计算每天的隔夜收益,并存储在 RollingWindow 数据结构中。
选股排序:
在每个月底,投资者根据前一个月的隔夜收益率对股票进行排序,将其分为十分位(decile),并根据结果构建投资组合。赢家组合(隔夜收益率最高的前10%)进行做多,输家组合(隔夜收益率最低的后10%)进行做空。
市值加权:
股票的权重根据其市值决定,确保组合中的权重分配合理,每月进行再平衡。
交易流程:
开盘时平仓:市场开盘时,通过市场订单将隔夜持仓卖出。 收盘时开仓:市场收盘前,重新建立隔夜头寸,买入赢家组股票并卖空输家组股票。
5. 策略优势与风险
策略优势
• 捕捉隔夜波动:策略通过分离盘中和隔夜收益,抓住市场在休市期间的价格变化,如未公开信息或全球性事件的影响。
• 动态调整:策略会根据每月末的隔夜收益排序对持仓进行动态再平衡,最大化收益潜力。
策略风险
• 隔夜事件风险:市场闭市期间的重大新闻、公告或全球事件可能引发开盘时的大幅波动,增加策略的风险。
• 流动性风险:部分流动性较低的股票可能在开盘时存在较大的买卖价差,增加交易成本。
总结:该策略通过每月隔夜收益率的排序,结合市值加权进行隔夜交易,旨在捕捉市场在收盘与开盘之间的价格波动。其优点在于能够有效利用市场非交易时段的信息波动,但同时也存在一定的隔夜风险。
策略公式与解释:
策略的核心在于精确区分日内市场行为与隔夜市场行为。隔夜收益的计算至关重要,为了进一步解释这些操作,接下来的公式部分将详细展示策略中的一些公式,投资者能够理解如何将每日的收益分解为隔夜与盘中的两个部分,并准确评估它们各自对投资组合回报的贡献。
第i支股票在第s天的盘中收益率定义为:
其中:
• :第(i)支股票在第(s)天的收盘价。
• :第(i)支股票在第(s)天的开盘价。
这个公式表示的是从当天市场开盘到市场收盘的价格百分比变化。
第i支股票在第s天的隔夜收益率由盘中收益率和收盘到收盘的收益率计算得出:
其中:
• 收盘到收盘收益率 :第(i)支股票从前一天(s-1)的收盘价到当天(s)的收盘价的价格百分比变化。
• 盘中收益率 :这是单个交易日内,从市场开盘到市场收盘的价格变化所产生的收益率。
• 隔夜收益率 :这是市场收盘时到第二天市场开盘时,价格变化所产生的收益率。
该公式计算隔夜收益率,将其视为总的收盘到收盘收益率中扣除盘中收益率后剩余的部分。
该方法依赖于使用**成交量加权平均价格(VWAP)**计算交易开始前半小时的开盘价,以避免因小额订单或竞拍造成的价格扭曲,确保开盘价的测量更加稳健。
累积盘中收益率:
• :股票 在月份 内的累积盘中收益率。
• :股票 在天 的盘中收益率。
• :表示对月份 内的每一天 进行乘积运算。
累积隔夜收益率:
• :股票 在月份 内的累积隔夜收益率。
• :股票 在天 的隔夜收益率。
• :表示对月份 内的每一天 进行乘积运算。
总收益率:
• :股票 在月份 的总收益率(包括盘中和隔夜收益)。
• :股票 在月份 的累积盘中收益率。
• :股票 在月份 的累积隔夜收益率。
组合收益率:
• :在月份 内组合的总收益率。
• :股票 在月份 的权重。
• :股票 在月份 的总收益率。
组合盘中收益率:
• :在月份 内组合的盘中收益率。
• :股票 在月份 的权重。
• :股票 在月份 内的累积盘中收益率。
组合隔夜收益率:
• :在月份 内组合的隔夜收益率。
• :股票 在月份 的权重。
• :股票 在月份 内的累积隔夜收益率。
策略实现代码基于QuantConnect平台,详细完整代码和策略原文请见知识星球
# The investment universe consists of stocks listed at NYSE, AMEX, and NASDAQ, whose daily close-to-close price data are available at the
# CRSP database, and volume-weighted average price data are available at TAQ database. The open price is obtained as the volume-weighted
# average price in the first half-hour of trading. The formula used to calculate overnight returns is on pages number 6 and 7 of the paper.
# At the end of each month, the investor sorts stocks into deciles based on their month-1 one-month overnight returns. Then the investor goes
# long on the top decile (winner stocks) and short on the bottom decile (loser stocks). Stocks are held only during overnight session
# (positions are initiated each day at close and are closed during open) Stocks in the portfolios are value-weighted.
#
# QC Implementation:
# - The investment univese consists of 100 most liquid US stocks listed at NYSE, AMEX, and NASDAQ with price > 5$.
import numpy as np
from AlgorithmImports import *
class OvernightMomentumStrategy(QCAlgorithm):
def Initialize(self):
# set start date and start cash
self.SetStartDate(...)
self.SetCash(...)
self.period = 21 # need n of ovenight returns
# TODO 1: add SPY equities symbols with a minute resolution
def OnSecuritiesChanged(self, changes):
def CoarseSelectionFunction(self, coarse):
# warm up overnight returns
# get overnight returns from RollingWindow object and reverse it's list for simplier calculation of returns accumulation
# calculate accumulated returns
# TODO 3:
return [x for x in selected if self.data[x].is_ready()]
def FineSelectionFunction(self, fine):
for stock in fine:
symbol = stock.Symbol
return list(self.traded_quantity.keys())
def MarketClose(self):
# send market on open and on close orders before market closes
def UpdateOvernightReturns(self, symbol, history):
# TODO 5: calculate overnight return.
def Selection(self):
self.selection_flag = True
self.traded_quantity.clear()
class SymbolData():
def __init__(self, period):
def is_ready(self):
def is_overnight_returns_ready(self):
"""
关于LLMQuant
📰 每日资讯:人工智能与量化金融的前沿动态,附中英文原文,助你紧跟行业发展。
💻 策略详解:获取量化策略的完整代码,支持多平台回测,提升你的实战能力。
❓ 免费答疑:每日解答社区成员问题,高效提升你的知识水平。
🌐 线上交流:与国内外量化从业者互动,参与深度知识分享,拓展你的专业网络。
欢迎加入我们的知识星球,和全球精英一起探索人工智能与量化金融的无限可能!🚀✨
搜索 LLMQuant
关注我们