Skip to content

amr-coding1/execution-cost-model

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Execution Cost Model for Precious Metals

A comprehensive implementation of the Almgren-Chriss market impact model calibrated to GLD (gold) and SLV (silver) ETFs. This model simulates execution costs at various notional sizes to identify capacity constraints where strategy alpha decays.

Overview

This project answers the critical question: "At what AUM does the precious metals strategy stop being viable?"

The model quantifies:

  • Implementation shortfall at various order sizes
  • Optimal execution horizons
  • Strategy capacity constraints
  • Cost-risk trade-offs

Almgren-Chriss Model

The Almgren-Chriss framework models execution cost as:

Total Cost = Spread Cost + Temporary Impact + Permanent Impact

Mathematical Formulation

Spread Cost:

C_spread = (spread / 2) × X

Temporary Impact:

h(v) = η × σ × (v / V)^β

where:

  • v = execution rate (shares per period)
  • V = average volume per period
  • σ = volatility
  • η = temporary impact coefficient (0.142)
  • β = temporary impact exponent (0.6)

Permanent Impact:

g(v) = γ × σ × (v / V)^α

where:

  • γ = permanent impact coefficient (0.314)
  • α = permanent impact exponent (0.6)

Total Implementation Shortfall:

IS = C_spread + Σ[h(v_k) × x_k] + g(v_total) × X

Installation

cd execution_cost_model
pip install -r requirements.txt

Usage

Run Full Analysis

python main.py

This will:

  1. Fetch historical data for GLD and SLV
  2. Calculate market metrics (ADV, spread, volatility)
  3. Run execution cost simulations
  4. Perform capacity analysis
  5. Generate visualizations
  6. Output results to capacity_results.json

Programmatic Usage

from src.data_ingestion import DataIngestion
from src.impact_model import AlmgrenChrissModel, MarketConditions
from src.capacity_analysis import CapacityAnalyzer

# Fetch data
data = DataIngestion(tickers=["GLD", "SLV"], start_date="2015-01-01")
data.fetch_daily_data()
data.calculate_metrics()

# Set up model
model = AlmgrenChrissModel()
market = MarketConditions(
    price=180.0,
    volatility=0.15,
    adv_shares=5_000_000,
    adv_dollars=900_000_000,
    spread=0.0005,
)

# Calculate execution costs
costs = model.calculate_execution_cost(notional=5_000_000, market=market, execution_periods=60)
print(f"Total cost: {costs.total_cost_bps:.1f} bps")

# Capacity analysis
analyzer = CapacityAnalyzer(gross_sharpe=1.34, annual_turnover=24)
result = analyzer.analyze_capacity("GLD", market)
print(f"Capacity at Sharpe > 1.0: ${result.aum_at_sharpe_1/1e6:.0f}M")

Project Structure

execution_cost_model/
├── data/
│   ├── raw/                    # Raw price/volume data
│   ├── processed/              # Processed metrics (ADV, spread, vol)
│   └── calibration/            # Calibrated parameters
├── src/
│   ├── __init__.py
│   ├── data_ingestion.py       # Data retrieval and processing
│   ├── spread_estimation.py    # Bid-ask spread estimators
│   ├── impact_model.py         # Almgren-Chriss implementation
│   ├── execution_simulator.py  # Execution cost simulation
│   ├── optimal_execution.py    # Optimal trajectory calculation
│   ├── capacity_analysis.py    # Strategy capacity analysis
│   ├── visualisation.py        # Charts and figures
│   └── utils.py                # Helper functions
├── notebooks/
│   └── analysis.ipynb          # Exploratory analysis
├── tests/
│   └── test_*.py               # Unit tests
├── reports/
│   └── figures/                # Generated charts
├── config.yaml                 # Configuration parameters
├── requirements.txt
├── main.py                     # Entry point
├── capacity_results.json       # Results output
└── README.md

Configuration

Edit config.yaml to customize:

data:
  tickers: ["GLD", "SLV"]
  start_date: "2015-01-01"
  adv_window: 20
  volatility_window: 20

impact_model:
  eta: 0.035          # Temporary impact coefficient (calibrated for liquid ETFs)
  gamma: 0.08         # Permanent impact coefficient (calibrated for liquid ETFs)
  beta: 0.6           # Temporary impact exponent
  alpha: 0.6          # Permanent impact exponent

execution_simulation:
  notional_sizes: [100000, 500000, 1000000, 5000000, 10000000, 25000000, 50000000]

capacity_analysis:
  strategy_gross_sharpe: 1.34
  strategy_annual_turnover: 24

Key Outputs

1. Implementation Shortfall Table (GLD)

Notional Participation Rate Spread (bps) Temp Impact (bps) Perm Impact (bps) Total (bps)
$100K 0.001% 1.0 1.6 3.6 6.2
$1M 0.008% 1.0 6.3 14.3 21.6
$10M 0.08% 1.0 25.0 57.1 83.0
$50M 0.42% 1.0 65.6 149.9 216.5

2. Capacity Constraints

Metric GLD SLV
Average Daily Volume $1,530M $466M
Bid-Ask Spread (bps) 2.0 4.0
Annualized Volatility 13.9% 25.2%
Round-trip Cost @ $1M 43.2 bps 76.7 bps
Round-trip Cost @ $10M 166.1 bps 293.5 bps
Capacity (Sharpe > 1.0) $562K $182K
Capacity (Sharpe > 0.5) $2.81M $1.02M
Capacity (Breakeven) $6.26M $2.33M

3. Optimal Execution

For a $5M order:

  • Immediate execution: Higher cost, no timing risk
  • TWAP (1 hour): ~15% cost reduction
  • TWAP (1 day): ~30% cost reduction, increased timing risk

Execution Strategies Modeled

  1. Immediate Execution - Market order, single period
  2. TWAP 1 Hour - Time-weighted average over 60 minutes
  3. TWAP 1 Day - Time-weighted average over trading day
  4. TWAP 2 Days - Time-weighted average over 2 days
  5. VWAP 5% - Participate at 5% of volume
  6. VWAP 10% - Participate at 10% of volume

Spread Estimation Methods

Four estimators are implemented:

  1. Known Spreads (default, most accurate for liquid ETFs): Uses hardcoded bid-ask spreads based on market microstructure data:

    • GLD: 2 bps (highly liquid gold ETF)
    • SLV: 4 bps (slightly less liquid silver ETF)

    Note: High-low range methods dramatically overestimate spreads for liquid ETFs by including intraday volatility.

  2. High-Low Range (simple, overestimates):

    spread = (high - low) / close
    

    ⚠️ This captures daily price range (~85 bps for GLD), not actual bid-ask spread.

  3. Corwin-Schultz Estimator: Separates spread from volatility using two-day high-low ranges.

  4. Roll Estimator:

    spread = 2 × sqrt(-Cov(r_t, r_{t-1}))
    

Visualizations Generated

  • Implementation shortfall vs order size (log-log plot)
  • Cost breakdown stacked bar chart
  • Capacity curve: Sharpe ratio vs AUM
  • Optimal execution frontier (expected cost vs variance)
  • Strategy comparison charts
  • Spread and volatility time series
  • Parameter sensitivity tornado chart
  • Historical cost variation

Running Tests

pytest tests/ -v

Calibration Methodology

Default parameters are conservatively calibrated for precious metals ETFs:

  • η (temporary): 0.035
  • γ (permanent): 0.08
  • β (temporary exponent): 0.6
  • α (permanent exponent): 0.6

These are lower than Almgren et al. (2005) literature values (η=0.142, γ=0.314) to reflect the exceptional liquidity of GLD/SLV. The model can be recalibrated using the calibrate_from_data() method which performs regression analysis on historical price-volume relationships.

Limitations

  1. Daily Data: Uses daily OHLCV data; intraday data would improve accuracy
  2. Literature Parameters: Impact parameters from academic literature, not firm-specific calibration
  3. Linear Temporary Impact: May underestimate costs for very large orders
  4. No Information Leakage: Does not model alpha decay from information leakage
  5. Static Assumptions: Assumes constant volatility and liquidity conditions
  6. ETF Specific: Calibrated for highly liquid ETFs; less accurate for individual stocks

References

  • Almgren, R., & Chriss, N. (2001). Optimal execution of portfolio transactions. Journal of Risk, 3, 5-40.
  • Almgren, R., Thum, C., Hauptmann, E., & Li, H. (2005). Direct estimation of equity market impact. Risk, 18(7), 58-62.
  • Corwin, S. A., & Schultz, P. (2012). A simple way to estimate bid-ask spreads from daily high and low prices. Journal of Finance, 67(2), 719-760.
  • Roll, R. (1984). A simple implicit measure of the effective bid-ask spread in an efficient market. Journal of Finance, 39(4), 1127-1139.

License

MIT License

About

Almgren-Chriss market impact model for precious metals ETFs (GLD/SLV) with capacity analysis

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors