Quant BuffetRelax, Not Over Thinking

Military Expenditures and Performance of the Stock Markets

Log in to collect

Academic paper

Military Expenditures and Performance of the Stock Markets

AuthorsMilitary Expenditures and Performance of the Stock Markets [Click to Open PDF]

Institute
  • ?Quantpedia
  • ?Quantpedia.com

Strategy in a nutshell

Universe: 22 country equity ETFs. Each year, go long the 3 countries with the highest military spending as % of GDP and short the 3 with the lowest, based on prior-year SIPRI data. Portfolios are equally weighted and rebalanced annually.

Economic rationale

Military spending relative to GDP often signals stronger market performance. By focusing on ratios rather than absolute values, the strategy isolates the effect of defense intensity on equity returns, offering an alternative data-driven perspective.

Backtest performance

Annualised return2.02%
Volatility2.91%
Beta0.081
Sharpe ratio0.69
Sortino ratio0.059
Maximum drawdown-4.8%
Win rate52%

Full Python code

from AlgorithmImports import *
import data_tools
from typing import Dict, List
# endregion

class MilitaryExpendituresandPerformanceoftheStockMarkets(QCAlgorithm):

def Initialize(self):
self.SetStartDate(2006, 1, 1)
self.SetCash(100000)

self.selection:int = 3
self.leverage:int = 3

self.symbols:Dict[str, str] = {
    'USA': 'SPY',
    'United Kingdom': 'EWU',
    'Germany': 'EWG',
    'France': 'EWQ',
    'Italy': 'EWI',
    'Sweden': 'EWD',
    'Netherlands': 'EWN',
    'Spain': 'EWP',
    'Belgium': 'EWK',
    'Switzerland': 'EWL',
    'Canada': 'EWC',
    'Japan': 'EWJ',
    'Mexico': 'EWW',
    'Malaysia': 'EWM',
    'Australia': 'EWA',
    'Singapore': 'EWS',
    'South Korea': 'EWY',
    'Taiwan': 'EWT',
    'Brazil': 'EWZ',
    'South Africa': 'EZA',
    'China': 'FXI',
    'India': 'INDY'
}

for country, ticker in self.symbols.items():
    data = self.AddEquity(ticker, Resolution.Daily)
    data.SetLeverage(self.leverage)

self.military_expenditures:Symbol = self.AddData(data_tools.MilitaryExpenditures, 'military_expenditures', Resolution.Daily).Symbol
self.Settings.MinimumOrderMarginPortfolioPercentage = 0.

def OnData(self, data: Slice):
military_expenditures_last_update_date:datetime.date = data_tools.MilitaryExpenditures._last_update_date
rebalance_flag:bool = False

# sort countries by military expenditures
if self.military_expenditures in data and data[self.military_expenditures]:
    current_military_expenditures:Dict[Symbol, float] = {self.Symbol(ticker) : data[self.military_expenditures][country] for country, ticker in self.symbols.items() \
                                                if self.Securities[self.Symbol(ticker)].GetLastData() and self.Time.date() < military_expenditures_last_update_date}

    if len(current_military_expenditures) >= self.selection * 2:
        sorted_military_expenditures:List[Symbol] = sorted(current_military_expenditures, key=current_military_expenditures.get, reverse=True)
        long:List[Symbol] = sorted_military_expenditures[:self.selection]
        short:List[Symbol] = sorted_military_expenditures[-self.selection:]
        rebalance_flag = True
    else:
        self.Liquidate()
        
if rebalance_flag:
    # trade execution
    invested:List[Symbol] = [x.Key for x in self.Portfolio if x.Value.Invested]
    for symbol in invested:
        if symbol not in long + short:
            self.Liquidate(symbol)

    for i, portfolio in enumerate([long, short]):
        for symbol in portfolio:
            if symbol in data and data[symbol]:
                self.SetHoldings(symbol, ((-1) ** i) / len(portfolio))