Backtest Period
1968-2009
Markets Traded
Equities
Maximum Drawdown
Period of Rebalancing
Monthly
Return (Annual)
17.7%
Sharpe Ratio
Standard Deviation (Annual)
Original paper
SSRN-id273569.pdf187.2KB
Trading rules
- Investment universe: Country-specific equity index ETFs
- Selection criterion: Top 5 countries with highest X-month momentum (X typically between 10-12 months)
- Portfolio rebalancing: Monthly
Python code
Backtrader
import backtrader as btclass CountryMomentum(bt.Strategy):
params = (
('lookback_period', 11), # X-month momentum (11 months for 12-month lookback, including the current month)
('top_n', 5), # Top 5 countries
)
def __init__(self):
self.inds = {}
for d in self.datas:
self.inds[d] = {}
self.inds[d]['momentum'] = bt.indicators.Momentum(d.close, period=self.params.lookback_period)
def next(self):
country_momentums = []
for d in self.datas:
country_momentums.append((d, self.inds[d]['momentum'][0]))
# Sort countries by momentum and select top N countries
top_countries = sorted(country_momentums, key=lambda x: x[1], reverse=True)[:self.params.top_n]
# Calculate equal weights for the selected countries
weight = 1 / len(top_countries)
# Rebalance the portfolio
for d in self.datas:
if d in [country_data for country_data, _ in top_countries]:
self.order_target_percent(d, target=weight)
else:
self.order_target_percent(d, target=0)
# Create a Cerebro engine
cerebro = bt.Cerebro()
# Add the data feeds to Cerebro
# Add each country-specific ETF as a data feed here
# Add the strategy to Cerebro
cerebro.addstrategy(CountryMomentum)
# Run Cerebro engine
results = cerebro.run()
# Plot the results
cerebro.plot()
Please note that you will need to add the data feeds for the country-specific equity index ETFs before running the Cerebro engine.