Diffusal
Math

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 when positions are underwater:

Adverse PnL Buffer=max(0,unrealizedPnL)×1.05\text{Adverse PnL Buffer} = \max(0, -\text{unrealizedPnL}) \times 1.05
  1. Notional Buffer - Percentage of total notional exposure:
Notional Buffer=Total Notional×0.15\text{Notional Buffer} = \text{Total Notional} \times 0.15

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 exposure of the portfolio:

Notional=i=1nsizei×Si\text{Notional} = \sum_{i=1}^{n} |\text{size}_i| \times S_i

Where:

  • size = position size
  • S = current spot price of the underlying

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}

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_MULTIPLIER1.05 (105%)Buffer on unrealized losses

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