
“该策略专注于西欧地区股息收益率高的股票,股价高于1.00欧元,市值超过5000万欧元,并在除息日前建立多头头寸。”
资产类别: 股票 | 地区: 欧洲 | 周期: 每日 | 市场: 股票 | 关键词: 除息日、欧洲
I. 策略概要
该投资范围包括在其本国交易的西欧上市公司,股价高于1.00欧元,市值高于5000万欧元。重点是高收益股票,特别是股息收益率排名前四分之一的股票。该策略涉及在除息日前五天对这些高股息股票建立多头头寸,并在除息日进行再平衡。这种效应在高收益股票中更为显著,使得这种方法对这些证券特别有效。
II. 策略合理性
行为因素显著影响股息支付等公司事件前后的股价。投资者通常会购买股票以获取股息,这吸引了试图平衡价格波动的套利者。如果套利失败,股价会在除息日前上涨。这导致异常回报在除息日后下降,从而产生“股息月溢价”。各种理论,如迎合理论和投资者注意力不集中,解释了这种现象。当股息支付稀少或被削减时,例如在新冠疫情期间,这种效应尤其强烈,因为支付股息的股票减少,需求增加,从而放大了价格压力,使这种异常现象更有利可图。
III. 来源论文
Chasing dividends during the COVID-19 pandemic [点击查看论文]
- Nicolas Eugstera, Romain Ducretb, Dušan Isakovc & Jean-Philippe Weisskopf。昆士兰大学商学院。弗里堡大学(瑞士)管理、经济与社会科学学院。弗里堡大学(瑞士)管理、经济与社会科学学院。洛桑酒店管理学院
<摘要>
本文研究了COVID-19大流行对欧洲投资者在除息日附近交易行为的影响。派发股息的公司数量骤减,减少了获取股息的机会。因此,在大流行期间维持股息支付的公司比以往吸引了更多的关注。这导致除息日附近通常观察到的股票回报模式幅度翻倍。我们的证据表明,寻求股息的投资者可能是除息日附近观察到的价格模式的主要驱动因素。


IV. 回测表现
| 年化回报 | 1.8% |
| 波动率 | N/A |
| β值 | 0.262 |
| 夏普比率 | N/A |
| 索提诺比率 | 0.506 |
| 最大回撤 | N/A |
| 胜率 | 58% |
V. 完整的 Python 代码
from AlgorithmImports import *
#endregion
class TheExDividendDateInTheEuropeanMarket(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2000, 1, 1)
self.SetCash(100000)
self.leverage:int = 5
tickers = []
self.symbols = []
self.dividends_data = {}
self.invested_data = {}
self.first_date = None
# Data source: https://www.nasdaq.com/market-activity/dividends
dividend_data:str = self.Download('data.quantpedia.com/backtesting_data/economic/dividend_dates.json')
dividend_data_json:Dict[str] = json.loads(dividend_data)
for obj in dividend_data_json:
date:datetime.date = datetime.strptime(obj['date'], "%Y-%m-%d").date()
self.dividends_data[date] = []
for stock_data in obj['stocks']:
if ' ' in stock_data['ticker']:
continue
ticker:str = stock_data['ticker']
if ticker not in tickers:
security = self.AddEquity(ticker, Resolution.Daily)
security.SetFeeModel(CustomFeeModel())
security.SetLeverage(self.leverage)
tickers.append(ticker)
self.symbols.append(security.Symbol)
self.dividends_data[date].append(ticker)
self.long = []
self.long_size = 80
def OnData(self, data):
current_date = self.Time.date()
date_to_lookup = (self.Time + timedelta(days=5)).date()
if current_date in self.invested_data:
self.LiquidateChosenSymbols(self.invested_data[current_date])
del self.invested_data[current_date]
# Open new trades.
if date_to_lookup in self.dividends_data:
for symbol in self.symbols:
if symbol.Value in self.dividends_data[date_to_lookup]:
if symbol in data and data[symbol]:
if self.Add(symbol):
if date_to_lookup not in self.invested_data:
self.invested_data[date_to_lookup] = []
self.invested_data[date_to_lookup].append(symbol)
def Add(self, symbol):
if len(self.long) < self.long_size:
if self.Securities[symbol].Price != 0 and self.Securities[symbol].IsTradable:
self.SetHoldings(symbol, 1 / self.long_size)
self.long.append(symbol)
return True # Stock successfully invested
else:
self.Log("There's not place for additional trade.")
return False # Unable to invest into stock
def LiquidateChosenSymbols(self, symbols):
for symbol in symbols:
if symbol in self.long:
self.long.remove(symbol)
self.Liquidate(symbol)
# Custom fee model
class CustomFeeModel(FeeModel):
def GetOrderFee(self, parameters):
fee = parameters.Security.Price * parameters.Order.AbsoluteQuantity * 0.00005
return OrderFee(CashAmount(fee, "USD"))