Skip to content

Conversation

@joaquinbejar
Copy link
Owner

Summary

This PR implements Chooser option pricing (also called as-you-like-it options), where the holder can choose at a specified date whether the option becomes a call or a put.

What Was Implemented

Simple Chooser (Rubinstein 1991)

At the choice date t, the holder chooses max(Call value, Put value).

Formula:

V = S*e^(-qT)*N(d1) - K*e^(-rT)*N(d2) + K*e^(-rt)*N(-y2) - S*e^(-qt)*N(-y1)

Where:

  • T = time to final expiration
  • t = time to choice date (t < T)
  • d1, d2 = standard Black-Scholes d-values for T
  • y1 = [ln(S/K) + (b + σ²/2)*t] / (σ√t)
  • y2 = y1 - σ√t

Edge Cases

  • Choice at expiry (t ≥ T): Returns straddle value (call + put)
  • Zero time: Returns max(call intrinsic, put intrinsic)

Integration

  • New module: src/pricing/chooser.rs
  • Exported via src/pricing/mod.rs
  • Routed OptionType::Chooser in black_scholes_model.rs

Why It Was Implemented

Chooser options are important because they:

  1. Provide flexibility to decide call/put based on market movement
  2. Are valuable in uncertain/volatile markets
  3. Are more expensive than vanilla options (due to choice flexibility)
  4. Have unique payoff structure: always max(call, put)

Technical Decisions

  1. Rubinstein Formula: Closed-form solution for efficiency
  2. Choice Date in Days: Stored as days, converted to years for calculations
  3. Decimal Arithmetic: Used .to_dec() to avoid Positive type panics on negative intrinsic
  4. Straddle at Expiry: When choice_date ≥ expiration, returns call + put

Testing

Added 11 comprehensive unit tests:

  • test_simple_chooser: Basic pricing
  • test_chooser_more_valuable_than_call / test_chooser_more_valuable_than_put: Fundamental properties
  • test_early_choice_date / test_late_choice_date: Edge timing
  • test_choice_at_expiry: Straddle case
  • test_short_chooser_option: Position negation
  • test_zero_time_to_expiry: ATM at expiry = 0
  • test_itm_call_at_expiry / test_itm_put_at_expiry: Intrinsic values
  • test_higher_vol_means_higher_chooser_value: Volatility property

Verification

  • All 3753+ existing tests pass
  • make lint-fix pre-push completes successfully
  • No Clippy warnings

Closes #242

Implements Chooser option (as-you-like-it) pricing using:
- Rubinstein (1991) simple chooser formula
- Choice between call and put at specified date

Formula:
V = S*e^(-qT)*N(d1) - K*e^(-rT)*N(d2) + K*e^(-rt)*N(-y2) - S*e^(-qt)*N(-y1)

Where:
- T = time to final expiration
- t = time to choice date
- d1, d2 = standard BS d-values for T
- y1, y2 = choice date d-values

Changes:
- New file src/pricing/chooser.rs with pricing functions
- Integrated into pricing module exports
- Routed OptionType::Chooser in black_scholes_model.rs

Tests:
- 11 comprehensive unit tests covering:
  - Simple chooser pricing
  - Chooser >= call and >= put (fundamental property)
  - Early/late choice dates
  - Choice at expiry (straddle)
  - Short option negation
  - Zero time / ITM call/put at expiry
  - Higher vol = higher value

Closes #242
@joaquinbejar joaquinbejar merged commit 769b37c into main Jan 13, 2026
11 checks passed
@codecov
Copy link

codecov bot commented Jan 13, 2026

Codecov Report

❌ Patch coverage is 87.05882% with 11 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/pricing/chooser.rs 88.09% 10 Missing ⚠️
src/pricing/black_scholes_model.rs 0.00% 1 Missing ⚠️
Files with missing lines Coverage Δ
src/pricing/black_scholes_model.rs 54.41% <0.00%> (+1.55%) ⬆️
src/pricing/chooser.rs 88.09% <88.09%> (ø)

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Implement Chooser option pricing model

2 participants