This paper documents evidence of reversals in the long-term returns of international equity markets. We use recent short-term performance to better select contrarian securities that appear ready to reverse. Our late-stage contrarian strategy consistently provides stronger evidence of long-term return reversal than does the traditional pure contrarian strategy when applied to developed and emerging market indices. Despite an absence of cross-sectional contrarian profits for developed markets in our post-1989 subsample, longitudinal analysis provides strong evidence of reversals during this period. Overall, our results suggest that the reversal of long-term returns may be stronger and more pervasive than is generally understood.
Keywords: contrarian effect, international financial integration, developed markets, emerging markets
- Investment universe: 26 countries from emerging markets.
- Evaluate and rank on a monthly basis using previous five-year returns.
- Top quartile: Late-stage outperformers (LW).
- Last quartile: Late-stage underperformers (LL).
- Within each subgroup, classify nations by their half-year (6-month) momentum.
- Long positions: Top 50% of best 6-month momentum in LL group.
- Short positions: Bottom 50% of worst 6-month momentum in LW group.
- Equal weighting for each country.
- Hold positions for 6 months.
- Monthly portfolio rebalance (1/6th of the portfolio each month).
import backtrader as bt class EmergingMarketStrategy(bt.Strategy): def __init__(self): self.month_counter = 0 self.rebalance_period = 6 def next(self): # Check if it's time to rebalance the portfolio self.month_counter += 1 if self.month_counter % self.rebalance_period != 0: return # Calculate 60-month performance past_60_month_perf = [d.close / d.close[-60] for d in self.datas] # Calculate 6-month momentum six_month_momentum = [d.close / d.close[-6] for d in self.datas] # Sort countries by 60-month performance and create late-stage groups sorted_indices = sorted(range(len(past_60_month_perf)), key=lambda k: past_60_month_perf[k]) lw_group = sorted_indices[:len(self.datas) // 4] ll_group = sorted_indices[-len(self.datas) // 4:] # Rank countries in each subgroup by 6-month momentum lw_ranked = sorted(lw_group, key=lambda k: six_month_momentum[k], reverse=True) ll_ranked = sorted(ll_group, key=lambda k: six_month_momentum[k], reverse=True) # Set target positions for i, data in enumerate(self.datas): target_weight = 0 # Set long positions for top 50% of best 6-month momentum in LL group if i in ll_ranked[:len(ll_group) // 2]: target_weight = 1 / (len(ll_group) // 2) # Set short positions for bottom 50% of worst 6-month momentum in LW group if i in lw_ranked[-len(lw_group) // 2:]: target_weight = -1 / (len(lw_group) // 2) # Rebalance the portfolio self.order_target_percent(data, target_weight)
Remember to add your data feeds and set up a Cerebro instance to execute this strategy in Backtrader. The code provided above assumes that you have already prepared the data feeds for the 26 emerging market countries.