core.test_formatters

Tests for Response Formatting Functions

Tests the pure functions in f.domains.hedge.core.formatters that transform internal data structures into frontend-compatible API responses.

MATHEMATICAL BACKGROUND

These formatters handle the conversion of Decimal-based calculations to float-based API responses, ensuring numerical precision is preserved where needed while providing human-readable output.

KEY FORMULAS USED

  1. Impermanent Loss vs HODL:

    IL_hodl = V_LP / V_HODL - 1
    

    Where: V_LP = Current LP position value V_HODL = Value if tokens were held (not deposited)

    Example: V_LP = 89,857.74, V_HODL = 93,454.00 IL_hodl = 89857.74 / 93454.00 - 1 = -0.0385 (-3.85%)

  2. Impermanent Loss vs Deposit:

    IL_deposit = V_LP / I_initial - 1
    

    Where: V_LP = Current LP position value I_initial = Initial deposit value at entry

    Example: V_LP = 89,857.74, I_initial = 100,000.00 IL_deposit = 89857.74 / 100000.00 - 1 = -0.1014 (-10.14%)

  3. Relationship Between IL Metrics:

    • IL_hodl: Measures loss compared to passive holding
    • IL_deposit: Measures absolute loss from entry point
    • When price returns to entry: IL_hodl ≈ IL_deposit ≈ 0
    • IL_deposit includes price change effect; IL_hodl isolates IL only
  4. Put Option Payoff at Expiry:

    hedge_payoff = max(K - S_expiry, 0) × quantity
    

    Where: K = Strike price S_expiry = Spot price at expiration quantity = Number of put contracts

  5. ROI and APR:

    ROI = (capital / total_investment) - 1 APR = (1 + ROI)^(365/days) - 1

DERIBIT INSTRUMENT NAMING

Options on Deribit follow the format: {UNDERLYING}-{EXPIRY}-{STRIKE}-{TYPE}

Example: ETH-28MAR26-2600-P - UNDERLYING: ETH - EXPIRY: 28MAR26 (28 March 2026) - STRIKE: 2600 USD - TYPE: P (Put) or C (Call)

FUNCTIONS TESTED

  1. format_scenario_point_as_il_entry()

    • Converts ScenarioPoint to frontend IL table row
    • Keys: variation, spot_price, il_vs_hodl, il_vs_deposit
  2. format_il_table()

    • Batch conversion of multiple ScenarioPoints
    • Preserves ordering
  3. format_scenario_result_as_expiry_entry()

    • Converts ScenarioResult to expiry analysis row
    • Calculates hedge_payoff based on positions
  4. format_scenarios_at_expiry()

    • Batch conversion with payoff calculation
    • Aggregates across all positions
  5. format_deribit_order()

    • Converts HedgePosition to Deribit API format
    • Generates instrument name from strike + expiry
  6. format_deribit_orders()

    • Batch conversion with quantity filtering
    • Filters out positions below min_quantity

TYPE CONVERSION

All Decimal values are converted to float for JSON serialization: Decimal("0.0385") → 0.0385 (float)

This allows direct frontend consumption without Decimal handling.

@pytest.fixture
def sample_scenario_point():

Sample scenario point for testing.

@pytest.fixture
def sample_scenario_result():

Sample scenario result for testing.

@pytest.fixture
def sample_position():

Sample hedge position for testing.

@pytest.fixture
def expiry_date():

Sample expiry date.

def test_format_il_entry_negative_variation(sample_scenario_point):

Test: Format IL entry with negative variation.

NUMERICAL EXAMPLE

Input: variation = -0.20 price = 2440 il_vs_hodl = -0.0385

Expected: All Decimal values converted to float Keys match frontend interface

def test_format_il_entry_positive_variation():

Test IL entry with positive variation.

def test_format_il_entry_zero_variation():

Test IL entry with zero variation (base case).

def test_format_il_table_multiple_points():

Test: Format IL table with multiple scenario points.

NUMERICAL EXAMPLE

Input: 3 scenario points with variations -0.20, 0.00, 0.20

Expected: 3 entries in order, all properly formatted

def test_format_il_table_single_point(sample_scenario_point):

Test IL table with single point.

def test_format_il_table_empty():

Test IL table with empty list.

def test_format_expiry_entry_with_hedge_payoff(sample_scenario_result, sample_position):

Test: Format expiry entry with hedge payoff calculation.

NUMERICAL EXAMPLE

Input: scenario: price = 2440, variation = -0.20 position: Put 2600 × 5 fees = 500

Calculation: hedge_payoff = max(2600 - 2440, 0) × 5 = 160 × 5 = 800

Expected: hedge_payoff = 800

def test_format_expiry_entry_otm_no_payoff():

Test expiry entry when put is OTM (no payoff).

def test_format_expiry_entry_break_even():

Test expiry entry at break-even scenario.

def test_format_scenarios_at_expiry_multiple():

Test: Format multiple scenarios at expiry.

NUMERICAL EXAMPLE

Input: 2 scenarios: -20% and +20% variation

Expected: 2 entries with calculated payoffs

def test_format_scenarios_at_expiry_empty_scenarios():

Test scenarios at expiry with empty list.

def test_format_scenarios_at_expiry_no_positions():

Test scenarios at expiry with no hedge positions.

def test_format_deribit_order_buy(sample_position, expiry_date):

Test: Format buy order for Deribit.

NUMERICAL EXAMPLE

Input: position: Put 2600 × 5, direction = BUY expiry = 2026-03-28 p0 = 3050

Expected: instrument = "ETH-28MAR26-2600-P" side = "BUY" quantity = 5.0

def test_format_deribit_order_sell(expiry_date):

Test format sell order.

def test_format_deribit_order_large_quantity(expiry_date):

Test format order with large quantity.

def test_format_deribit_orders_multiple(expiry_date):

Test: Format multiple Deribit orders.

NUMERICAL EXAMPLE

Input: 2 positions: Put 2600 × 5, Put 2200 × 10

Expected: 2 orders formatted correctly

def test_format_deribit_orders_filter_small(expiry_date):

Test that small quantities are filtered out.

def test_format_deribit_orders_empty(expiry_date):

Test empty positions list.