Why Do US Stocks Outperform EM and EAFE Regions?
Log in to collectAcademic paper
Why Do US Stocks Outperform EM and EAFE Regions?
Cyril Dujava; Radovan Vojtko
- ?Quantpedia
- ?Quantpedia.com
Strategy in a nutshell
This strategy applies a simple trend-following rule on the spread between U.S. equities (SPY) and emerging markets (EEM). If the spread shows positive performance over the past 12 months, go long SPY and short EEM; otherwise, reverse the position. Positions are rebalanced yearly.
Economic rationale
The strategy leverages long-term outperformance of U.S. equities versus global markets, combined with momentum effects and U.S. dollar trends that influence commodities and emerging market stocks, reinforcing spread-based trading opportunities.
Backtest performance
Annualised return7.14%
Volatility19.5%
Beta0.132
Sharpe ratio0.37
Sortino ratio0.308
Maximum drawdown-62.28%
Win rate67%
Full Python code
from AlgorithmImports import *
import data_tools
from pandas.core.frame import DataFrame
# endregion
class WhyDoUSStocksOutperformEMandEAFERegions(QCAlgorithm):
def Initialize(self) -> None:
self.SetStartDate(2000, 1, 1)
self.SetCash(100000)
self.period: int = 365
self.leverage: int = 3
self.spread_assets: List[Symbol] = [
self.AddEquity('SPY', Resolution.Daily).Symbol,
self.AddEquity('EEM', Resolution.Daily).Symbol
]
for symbol in self.spread_assets:
self.Securities[symbol].SetLeverage(self.leverage)
self.Settings.MinimumOrderMarginPortfolioPercentage = 0.
self.current_month: int = -1
def OnData(self, data: Slice) -> None:
# monthly rebalance
if self.Time.month == self.current_month:
return
self.current_month = self.Time.month
trade_direction: int = 0
returns_df: DataFrame = self.History(self.spread_assets, timedelta(days=self.period), Resolution.Daily)['close'].unstack(level=0).pct_change().iloc[1:].dropna(axis=1)
if returns_df.shape[1] == 2:
spread: pd.Series = returns_df[self.spread_assets[0]] - returns_df[self.spread_assets[1]]
spread_equity: float = (1 + spread).cumprod()
trade_direction: int = 1 if spread_equity[-1] > spread_equity[0] else -1
# order execution
portfolio: List[PortfolioTarget] = [PortfolioTarget(symbol, ((-1)**i) * trade_direction) for i, symbol in enumerate(self.spread_assets) if symbol in data and data[symbol]]
self.SetHoldings(portfolio, True)