# Strategy Documentation ## Overview Vault Dashboard currently documents and compares hedging approaches for a Lombard-style loan backed by gold exposure. The implementation focuses on paper analysis using option pricing, LTV protection metrics, and scenario analysis. The strategy subsystem currently includes: - protective puts - laddered puts - lease/LEAPS duration analysis This document focuses on the two primary hedge structures requested here: - protective put - laddered put --- ## Common portfolio assumptions The default research engine in `app/strategies/engine.py` uses: - portfolio value: `1,000,000` - loan amount: `600,000` - margin-call threshold: `0.75` - spot price: `460` - volatility: `0.16` - risk-free rate: `0.045` From these values, the portfolio is modeled as a `LombardPortfolio`: - gold ounces = `portfolio_value / spot_price` - initial LTV = `loan_amount / portfolio_value` - margin call price = `loan_amount / (margin_call_ltv * gold_ounces)` These assumptions create the common basis used to compare all strategies. --- ## Protective put ## What it is A protective put is the simplest downside hedge in the project. Structure: - long the underlying collateral exposure implicitly represented by the gold-backed portfolio - buy one put hedge sized to the portfolio's underlying units In this codebase, `ProtectivePutStrategy` creates a single long put whose strike is defined as a percentage of spot. Examples currently used by the engine: - ATM protective put: strike = `100%` of spot - 95% OTM protective put: strike = `95%` of spot - 90% OTM protective put: strike = `90%` of spot ## Why use it A protective put sets a floor on downside beyond the strike, helping reduce the chance that falling collateral value pushes the portfolio above the margin-call LTV. ## How it is implemented **File:** `app/strategies/protective_put.py` Main properties: - `hedge_units`: `portfolio.gold_value / spot_price` - `strike`: `spot_price * strike_pct` - `term_years`: `months / 12` A put contract is priced with Black-Scholes inputs: - current spot - strike - time to expiry - risk-free rate - volatility - option type = `put` The resulting `OptionContract` uses: - `quantity = 1.0` - `contract_size = hedge_units` That means one model contract covers the full portfolio exposure in underlying units. ## Protective put payoff intuition At expiry: - if spot is above strike, the put expires worthless - if spot is below strike, payoff rises linearly as `strike - spot` Total gross payoff is: ```text max(strike - spot, 0) * hedge_units ``` ## Protective put trade-offs Advantages: - simple to explain - clear downside floor - strongest protection when strike is high Costs: - premium can be expensive, especially at-the-money and for longer tenor - full notional protection may overspend relative to a client's risk budget - upside is preserved, but cost drags returns --- ## Laddered put ## What it is A laddered put splits the hedge across multiple put strikes instead of buying the full hedge at one strike. Structure: - multiple long put legs - each leg covers a weighted fraction of the total hedge - lower strikes usually reduce premium while preserving some tail protection Examples currently used by the engine: - `50/50` ATM + 95% OTM - `33/33/33` ATM + 95% OTM + 90% OTM ## Why use it A ladder can reduce hedge cost versus a full ATM protective put, while still providing meaningful protection as the underlying falls. This is useful when: - full-cost protection is too expensive - some drawdown can be tolerated before the hedge fully engages - the client wants a better cost/protection balance ## How it is implemented **File:** `app/strategies/laddered_put.py` A `LadderSpec` defines: - `weights` - `strike_pcts` - `months` Validation rules: - number of weights must equal number of strikes - weights must sum to `1.0` Each leg is implemented by internally creating a `ProtectivePutStrategy`, then weighting its premium and payoff. ## Ladder payoff intuition Each leg pays off independently: ```text max(leg_strike - spot, 0) * hedge_units * weight ``` Total ladder payoff is the sum across legs. Relative to a single-strike hedge: - protection turns on in stages - blended premium is lower when some legs are farther OTM - downside support is smoother but less absolute near the first loss zone than a full ATM hedge ## Ladder trade-offs Advantages: - lower blended hedge cost - more flexible cost/protection shaping - better fit for cost-sensitive clients Costs and limitations: - weaker immediate protection than a fully ATM hedge - more complex to explain to users - floor value depends on weight distribution across strikes --- ## Cost calculations ## Protective put cost calculation `ProtectivePutStrategy.calculate_cost()` returns: - `premium_per_share` - `total_cost` - `cost_pct_of_portfolio` - `term_months` - `annualized_cost` - `annualized_cost_pct` ### Formula summary Let: - `P` = option premium per underlying unit - `U` = hedge units - `T` = term in years - `V` = portfolio value Then: ```text total_cost = P * U cost_pct_of_portfolio = total_cost / V annualized_cost = total_cost / T annualized_cost_pct = annualized_cost / V ``` Because the model contract size equals the full hedge units, the total premium directly represents the whole-portfolio hedge cost. ## Laddered put cost calculation `LadderedPutStrategy.calculate_cost()` computes weighted leg costs. For each leg `i`: - `weight_i` - `premium_i` - `hedge_units` Leg cost: ```text leg_cost_i = premium_i * hedge_units * weight_i ``` Blended totals: ```text blended_cost = sum(leg_cost_i) blended_premium_per_share = sum(premium_i * weight_i) annualized_cost = blended_cost / term_years cost_pct_of_portfolio = blended_cost / portfolio_value annualized_cost_pct = annualized_cost / portfolio_value ``` ## Why annualized cost matters The engine compares strategies with different durations, especially in `LeaseStrategy`. Annualizing allows the system to compare short-dated and long-dated hedges on a common yearly basis. --- ## Protection calculations ## Margin-call threshold price The project defines the collateral price that would trigger a margin call as: ```text margin_call_price = loan_amount / (margin_call_ltv * gold_ounces) ``` This is a key reference point for all protection calculations. ## Protective put protection calculation At the threshold price: 1. compute the put payoff 2. add that payoff to the stressed collateral value 3. recompute LTV on the hedged collateral Formulas: ```text payoff_at_threshold = max(strike - threshold_price, 0) * hedge_units hedged_value_at_threshold = gold_value_at_threshold + payoff_at_threshold hedged_ltv_at_threshold = loan_amount / hedged_value_at_threshold ``` The strategy is flagged as maintaining a margin buffer when: ```text hedged_ltv_at_threshold < margin_call_ltv ``` ## Laddered put protection calculation For a ladder, threshold payoff is the weighted sum of all leg payoffs: ```text weighted_payoff_i = max(strike_i - threshold_price, 0) * hedge_units * weight_i payoff_at_threshold = sum(weighted_payoff_i) hedged_value_at_threshold = gold_value_at_threshold + payoff_at_threshold hedged_ltv_at_threshold = loan_amount / hedged_value_at_threshold ``` The ladder's implied floor value is approximated as the weighted strike coverage: ```text portfolio_floor_value = sum(strike_i * hedge_units * weight_i) ``` --- ## Scenario analysis methodology ## Scenario grid The current scenario engine in `ProtectivePutStrategy` uses a fixed price-change grid: ```text -60%, -50%, -40%, -30%, -20%, -10%, 0%, +10%, +20%, +30%, +40%, +50% ``` For each change: ```text scenario_price = spot_price * (1 + change) ``` Negative or zero prices are ignored. ## Metrics produced per scenario For each scenario, the strategy computes: - scenario spot price - unhedged gold value - option payoff - hedge cost - net portfolio value after hedge cost - unhedged LTV - hedged LTV - whether a margin call occurs without the hedge - whether a margin call occurs with the hedge ### Protective put scenario formulas Let `S` be scenario spot. ```text gold_value = gold_ounces * S option_payoff = max(strike - S, 0) * hedge_units hedged_collateral = gold_value + option_payoff net_portfolio_value = gold_value + option_payoff - hedge_cost unhedged_ltv = loan_amount / gold_value hedged_ltv = loan_amount / hedged_collateral ``` Margin-call flags: ```text margin_call_without_hedge = unhedged_ltv >= margin_call_ltv margin_call_with_hedge = hedged_ltv >= margin_call_ltv ``` ### Laddered put scenario formulas For ladders: ```text option_payoff = sum(max(strike_i - S, 0) * hedge_units * weight_i) hedged_collateral = gold_value + option_payoff net_portfolio_value = gold_value + option_payoff - blended_cost ``` All other LTV and margin-call logic is the same. ## Interpretation methodology Scenario analysis is used to answer four practical questions: 1. **Cost:** How much premium is paid upfront? 2. **Activation:** At what downside level does protection meaningfully start? 3. **Buffer:** Does the hedge keep LTV below the margin-call threshold under stress? 4. **Efficiency:** How much protection is obtained per dollar of annualized hedge cost? This is why each strategy exposes both: - a `calculate_protection()` summary around the threshold price - a full `get_scenarios()` table across broad upside/downside moves --- ## Comparing protective puts vs laddered puts | Dimension | Protective put | Laddered put | |---|---|---| | Structure | Single put strike | Multiple weighted put strikes | | Simplicity | Highest | Moderate | | Upfront cost | Usually higher | Usually lower | | Near-threshold protection | Stronger if ATM-heavy | Depends on ladder weights | | Tail downside protection | Strong | Strong, but blended | | Customization | Limited | High | | Best fit | conservative protection | balanced or cost-sensitive protection | --- ## Important limitations - The strategy engine is currently research-oriented, not an execution engine - Black-Scholes assumptions simplify real-world market behavior - Transaction costs, slippage, taxes, liquidity, and early exercise effects are not modeled here - The API payloads should be treated as analytical outputs, not trade recommendations - For non-`GLD` symbols, the engine currently still uses research-style assumptions rather than a complete live instrument-specific calibration ## Future strategy extensions Natural follow-ups for this subsystem: - collars and financed hedges - partial notional hedging - dynamic re-hedging rules - volatility surface-based pricing - broker-native contract sizing and expiries - user-configurable scenario grids