Diffusal

Margin Calculations

SPAN-like portfolio margin calculations and stress testing

Diffusal uses a SPAN-like portfolio margin system that calculates margin requirements by stress testing positions across multiple market scenarios. This approach captures the worst-case loss across plausible market movements.

For Black-Scholes pricing used in these calculations, see Black-Scholes Model.


Stress Testing

4 Corner Scenarios

The margin engine tests each portfolio against four extreme market scenarios combining ±30% spot moves with +50%/−30% IV changes. These scenarios capture the most adverse combinations of price and volatility movements for option portfolios.

See Margin System: Stress Scenarios for the complete scenario table and rationale.

Stressed Price Calculation

For each scenario, option prices are recalculated using Black-Scholes with stressed parameters:

Sstressed=S×spotMultiplierS_{\text{stressed}} = S \times \text{spotMultiplier} σstressed=σ×ivMultiplier\sigma_{\text{stressed}} = \sigma \times \text{ivMultiplier}

The stressed option price is then computed:

Pstressed=BlackScholes(Sstressed,K,r,σstressed,T)P_{\text{stressed}} = \text{BlackScholes}(S_{\text{stressed}}, K, r, \sigma_{\text{stressed}}, T)

Scenario Loss

For each scenario, the portfolio loss is calculated by comparing current mark prices to stressed prices:

Scenario Loss=i=1n(Pmark,iPstressed,i)×sizei\text{Scenario Loss} = \sum_{i=1}^{n} (P_{\text{mark},i} - P_{\text{stressed},i}) \times \text{size}_i

Where:

  • n = number of positions
  • P_mark = current Black-Scholes price
  • P_stressed = price under stress scenario
  • size = position size (positive for long, negative for short)

Maximum Stress Loss

The stress loss component of margin is the maximum loss across all four scenarios:

Stress Loss=maxs{1,2,3,4}Scenario Losss\text{Stress Loss} = \max_{s \in \{1,2,3,4\}} |\text{Scenario Loss}_s|

Margin Requirements

Initial Margin (IM)

Initial margin is the collateral required to open or maintain positions:

IM=Stress Loss+Adverse PnL Buffer+Notional Buffer\text{IM} = \text{Stress Loss} + \text{Adverse PnL Buffer} + \text{Notional Buffer}

Components:

  1. Stress Loss - Maximum loss across 4 corner scenarios

  2. Adverse PnL Buffer - Additional buffer on stress loss:

Adverse PnL Buffer=Stress Loss×0.05\text{Adverse PnL Buffer} = \text{Stress Loss} \times 0.05
  1. Notional Buffer - Percentage of total notional exposure:
Notional Buffer=Total Notional×0.15\text{Notional Buffer} = \text{Total Notional} \times 0.15

Note: Premium balance is NOT included in margin—it's already reflected in equity (reducing equity when negative). Since premium obligations are deterministic (fixed at trade time), they don't need stress buffering.

Maintenance Margin (MM)

Maintenance margin is the minimum collateral to avoid liquidation:

MM=IM×0.80\text{MM} = \text{IM} \times 0.80

A position becomes liquidatable when equity falls below maintenance margin.


Unrealized PnL

Unrealized profit/loss across all positions:

PnL=i=1n(Pmark,iPentry,i)×sizei\text{PnL} = \sum_{i=1}^{n} (P_{\text{mark},i} - P_{\text{entry},i}) \times \text{size}_i

Where:

  • P_mark = current Black-Scholes price
  • P_entry = price at which position was opened
  • size = signed position size

For long positions (size > 0): profit when mark > entry For short positions (size < 0): profit when mark < entry


Total Notional

Total notional value of the portfolio (current option value, not underlying exposure):

Notional=i=1noptionBalancei×Pmark,i\text{Notional} = \sum_{i=1}^{n} |\text{optionBalance}_i| \times P_{\text{mark},i}

Where:

  • optionBalance = signed position size (positive = long, negative = short)
  • P_mark = current Black-Scholes option price (mark price)

Equity and Health

Equity

Equity=Deposit+Unrealized PnL\text{Equity} = \text{Deposit} + \text{Unrealized PnL}

Health Check

A user is healthy when:

EquityMM\text{Equity} \geq \text{MM}

A user is liquidatable when:

Equity<MM\text{Equity} < \text{MM}

Note: Long-only portfolios cannot be liquidated if they hold sufficient cash to cover their premium obligations (deposit ≥ premium paid). This is because their position value can only go to zero (never negative). However, if a user's deposit is less than their premium paid, they can still be liquidated. See Margin System: Unliquidatable Long Position for details.

Maximum Withdrawal

Max Withdraw=max(0,EquityIM)\text{Max Withdraw} = \max(0, \text{Equity} - \text{IM})

Constants Reference

All margin constants are defined in Constants.sol:

ConstantValueDescription
STRESS_SPOT_DOWN0.70 (70%)Spot down scenario multiplier
STRESS_SPOT_UP1.30 (130%)Spot up scenario multiplier
STRESS_IV_DOWN0.70 (70%)IV down scenario multiplier
STRESS_IV_UP1.50 (150%)IV up scenario multiplier
MAINTENANCE_MARGIN_RATE0.80 (80%)MM as percentage of IM
INITIAL_MARGIN_RATE0.15 (15%)Notional buffer rate
ADVERSE_PNL_BUFFER0.05 (5%)Buffer rate on stress loss

Contract Interface

MarginEngine Functions

  • calculateInitialMargin(positions, quoterAddress) — Calculate IM for an array of positions (returns WAD)
  • calculateMargin(positions, quoterAddress) — Get complete margin metrics: unrealizedPnL (WAD, can be negative), stressLoss (WAD), initialMargin (WAD), maintenanceMargin (WAD)

CollateralVault Functions

  • getMarginInfo(user) — Returns complete MarginInfo struct containing: deposit (USDC), unrealizedPnL, equity (deposit + unrealizedPnL), initialMargin, maintenanceMargin, maxWithdraw, and isHealthy (whether equity >= MM)

Implementation

The margin calculations are implemented in Solidity:

Contract/LibraryPurpose
MarginEngineCore SPAN-like stress testing library
DiffusalCollateralVaultMargin enforcement on deposits/withdrawals
DiffusalLiquidationEngineLiquidation when MM is breached

On this page