core.test_lifetime
Tests for Lifetime Option Valuation
This module tests src/core/lifetime.py which provides option valuation and portfolio analysis during the lifetime of the hedge (before expiry), accounting for time value in addition to intrinsic value.
Key Concept: At Expiry vs During Lifetime
| Aspect | At Expiry | During Lifetime |
|---|---|---|
| Option Value | Intrinsic only: max(K-S, 0) | Black-Scholes with time val |
| Fees | Full period fees | Pro-rated based on elapsed |
| Time Value | Zero | Positive (decays over time) |
| APR Calculation | Based on total days | Based on days elapsed |
EXCEL VERIFICATION GUIDE
For a mathematician to verify these tests in Excel:
Option Valuation (Lifetime):
- Use the Black-Scholes Put formula (see
test_black_scholes.py). - Multiply the result (P/S ratio) by the Spot Price to get dollar value.
Value = BS_Put_Ratio(K, T_remaining, S, σ, r) * S
- Use the Black-Scholes Put formula (see
Fee Proration:
- Formula:
Fees = Total_Projected_Fees * (Days_Elapsed / Total_Duration) - Where
Total_Projected_Fees = Investment * Yield * (Total_Duration / 365)
- Formula:
Position Value:
PositionValue = OptionValue * Quantity
Test Categories
Option Valuation
- Tests for calc_option_value_during_lifetime()
- Verifies time value for OTM options, ITM > intrinsic, expiry = intrinsic
Position Value
- Tests for calc_position_value_during_lifetime()
- Verifies quantity scaling and directional behavior
Pro-Rated Fees
- Tests for calc_prorated_fees()
- Verifies linear proration based on days elapsed
Lifetime Analysis
- Tests for generate_lifetime_analysis()
- Verifies complete analysis generation with proper structure
Comparison Tests
- Tests for compare_expiry_vs_lifetime()
- Verifies time value difference between lifetime and expiry
Edge Cases
- Tests for boundary conditions (0 days, negative days, empty positions)
Standard Test Parameters
SPOT = 3050 (Current ETH price in USDT)
P_MIN = 2200 (Lower price bound for LP position)
P_MAX = 3650 (Upper price bound for LP position)
VOLATILITY = 0.70 (70% implied volatility)
INVESTMENT = 100000 (Initial investment in USDT)
FEE_YIELD = 0.63 (63% APR fee yield from LP)
Run with: uv run pytest tests/test_lifetime.py -v
Create sample HedgeInputs for testing.
Returns HedgeInputs with standard parameters:
- P0 = 3050 USDT/ETH
- Price range: [2200, 3650]
- Investment: $100,000
- Expiry: 106 days from now
- Volatility: 70%
- Fee yield: 63% APR
Create a sample hedge position.
Returns a long put position:
- Strike: 2500 (OTM by ~18%)
- Quantity: 10 contracts
- Premium: $1,525 total paid
Create sample scenario points.
Returns 3 scenarios:
- -20% price drop (2440 USDT/ETH)
- 0% change (3050 USDT/ETH)
- +20% price rise (3660 USDT/ETH)
Each scenario includes LP values and IL calculations.
OTM option should have time value when days remaining > 0.
EXCEL REPRODUCTION
1. Inputs (Cells A1:B5)
| Cell | Parameter | Value |
|---|---|---|
| B1 | Spot | 3050 |
| B2 | Strike | 2500 |
| B3 | Days | 50 |
| B4 | Vol | 0.70 |
| B5 | Rate | 0 |
2. Time in Years (Cell B6)
| Cell | Name | Formula | Value |
|---|---|---|---|
| B6 | T | =B3/365 |
~0.137 |
3. Black-Scholes Value (Cell B7)
Use the d1/d2 and Put Price formulas from test_black_scholes.py.
- Result should be > 0 even though Strike (2500) < Spot (3050).
- Intrinsic Value =
MAX(2500-3050, 0)= 0. - Option Value > Intrinsic Value.
ITM option should be worth more than intrinsic value.
At expiry (days=0), should return only intrinsic value.
More days remaining should mean more option value (all else equal).
Higher volatility should increase option value.
Position value should scale linearly with quantity.
Put position value should increase when price drops.
Full period should give full fees.
EXCEL REPRODUCTION
1. Inputs (Cells A1:B4)
| Cell | Parameter | Value |
|---|---|---|
| B1 | Invest | 100000 |
| B2 | Yield | 0.63 |
| B3 | DaysTot | 106 |
| B4 | DaysElap | 106 |
2. Calculation (Cell B5)
| Cell | Name | Formula | Expectation |
|---|---|---|---|
| B5 | Fees | =(B4/365) * B1 * B2 |
~18295.89 |
Note: The fee calculation assumes the yield is annualized (APR) and prorates it based on the number of days elapsed out of a 365-day year.
Half period should give approximately half fees.
Zero days elapsed should give zero fees.
Should return LifetimeAnalysis object.
days_remaining should match input.
Number of result scenarios should match input scenarios.
Fees should be pro-rated based on days elapsed.
Should return both expiry and lifetime analyses.
Expiry analysis should have days_remaining=0.
During lifetime, OTM options have time value. At expiry, OTM options are worthless. So lifetime capital should often be higher when options are OTM.
With 0 days remaining, options should be at intrinsic value.
NUMERICAL EXAMPLE
Position: Long 10 Put 3200 (ITM) spot = 3050, days = 0
Intrinsic = max(3200 - 3050, 0) = 150 per contract Position value = 10 × 150 = 1500 USDT
Negative days remaining should be treated as 0 (expiry).
Should handle empty positions list gracefully.