Skip to main content

rustyqlib/core/
data_models.rs

1use serde::{Deserialize, Serialize};
2use crate::core::curves::CurveInput;
3use crate::core::vols::VolInput;
4
5#[derive(Clone, Debug, Deserialize, Serialize)]
6#[serde(tag = "product_type", rename_all = "snake_case")]
7pub enum ProductData {
8    Option(EquityOptionData),
9    Future(EquityFutureData),
10    Forward(EquityForwardData),
11    RainbowOption(crate::equity::rainbow::RainbowOptionData),
12    CliquetOption(crate::equity::cliquet::CliquetOptionData),
13    Accumulator(crate::equity::accumulator::AccumulatorData),
14    VarianceSwap(crate::equity::variance_swap::VarianceSwapData),
15}
16
17#[derive(Clone, Debug, Deserialize, Serialize)]
18pub struct EquityInstrumentBase {
19    pub symbol: String,
20    pub currency: Option<String>,
21    pub exchange: Option<String>,
22    pub name: Option<String>,
23    pub cusip: Option<String>,
24    pub isin: Option<String>,
25    pub underlying_price: f64,
26    pub long_short: Option<i32>,
27    pub risk_free_rate: Option<f64>,
28    /// Continuous stock borrow (repo) cost; enters the carry like an
29    /// additional dividend yield (hard-to-borrow lowers the forward).
30    pub borrow_cost: Option<f64>,
31    pub settlement_type: Option<String>,
32    /// Pricing as-of date (`YYYY-MM-DD`). Defaults to today, but setting
33    /// it makes the contract price reproducibly and allows re-marking a
34    /// book as of any date.
35    pub valuation_date: Option<String>,
36}
37
38/// Resolve an optional contract `valuation_date`: parse it when present,
39/// default to today's date otherwise.
40pub fn parse_valuation_date(
41    field: Option<&str>,
42) -> Result<chrono::NaiveDate, crate::core::errors::RustyQLibError> {
43    match field {
44        Some(s) => chrono::NaiveDate::parse_from_str(s.trim(), "%Y-%m-%d").map_err(|_| {
45            crate::core::errors::RustyQLibError::invalid_input(
46                "valuation_date",
47                format!("invalid date '{s}' (expected YYYY-MM-DD)"),
48            )
49        }),
50        None => Ok(chrono::Local::now().date_naive()),
51    }
52}
53
54/// A discrete cash dividend: ex-date and amount per share.
55#[derive(Clone, Debug, Deserialize, Serialize)]
56pub struct CashDividendData {
57    pub date: String,
58    pub amount: f64,
59}
60
61
62#[derive(Clone, Debug, Deserialize, Serialize)]
63pub struct EquityFutureData {
64    #[serde(flatten)]
65    pub base: EquityInstrumentBase,
66    pub current_price: Option<f64>,
67    pub multiplier:Option<f64>,
68    pub entry_price:Option<f64>,
69    pub maturity: String,
70    pub dividend: Option<f64>,
71
72}
73#[derive(Clone, Debug, Deserialize, Serialize)]
74pub struct EquityForwardData {
75    #[serde(flatten)]
76    pub base: EquityInstrumentBase,
77    pub current_price: Option<f64>,
78    pub notional: Option<f64>,
79    pub entry_price:Option<f64>,
80    pub maturity: String,
81    pub dividend: Option<f64>,
82
83}
84
85#[derive(Clone, Debug, Deserialize, Serialize)]
86pub struct EquityOptionData {
87    #[serde(flatten)]
88    pub base: EquityInstrumentBase,
89    pub put_or_call: String, // "Call"/"Put"
90    pub payoff_type: String, // Vanilla/Barrier/Binary
91    /// Binary settlement: "cash" (default) or "asset".
92    pub binary_type: Option<String>,
93    /// Amount paid by a cash-or-nothing binary (default 1.0).
94    pub cash_amount: Option<f64>,
95    /// Barrier variant: "up_in" | "up_out" | "down_in" | "down_out".
96    pub barrier_type: Option<String>,
97    pub barrier_level: Option<f64>,
98    /// Second barrier level (makes the option a double barrier).
99    pub barrier_level2: Option<f64>,
100    /// Barrier rebate amount.
101    pub rebate: Option<f64>,
102    /// Knock-out rebate paid at the touch (default: at expiry).
103    pub rebate_at_hit: Option<bool>,
104    /// Lookback flavor: "floating" (default) or "fixed".
105    pub lookback_type: Option<String>,
106    /// Asian averaging: "arithmetic" (default) | "geometric".
107    pub averaging_type: Option<String>,
108    /// Asian strike: "fixed" (default, average price) | "floating" (average strike).
109    pub asian_strike_type: Option<String>,
110    /// Forward-start: strike fixing date and strike as a fraction of the
111    /// fixing spot (default 1.0).
112    pub forward_start_date: Option<String>,
113    pub strike_fraction: Option<f64>,
114    /// Autocallable: early-redemption and knock-in protection levels
115    /// (absolute), per-period coupon (rebate), observation count, notional.
116    pub autocall_barrier: Option<f64>,
117    pub protection_barrier: Option<f64>,
118    pub autocall_coupon: Option<f64>,
119    pub autocall_observations: Option<usize>,
120    /// Binomial tree parameterization: `LeisenReimer` (default), `CRR`,
121    /// `JarrowRudd`, `Tian`, `Trigeorgis`, `EQP`.
122    pub tree_type: Option<String>,
123    /// Binomial tree steps (default 1000; Leisen-Reimer bumps even
124    /// counts to odd).
125    pub tree_steps: Option<usize>,
126    /// Price the tree with term structures of rates and volatility
127    /// applied per step (variance-equal time grid). `tree_type` is then
128    /// ignored.
129    pub tree_term_structure: Option<bool>,
130    /// Bermudan exercise dates (`YYYY-MM-DD`, strictly increasing,
131    /// after valuation and at or before maturity). Required when
132    /// `exercise_style` is `Bermudan`. Expiry is always exercisable
133    /// through the terminal payoff.
134    pub exercise_dates: Option<Vec<String>>,
135    /// Explicit autocall observation dates (`YYYY-MM-DD`, strictly
136    /// increasing, after valuation and at or before maturity). Overrides
137    /// `autocall_observations`; use business-day adjusted dates from a
138    /// holiday calendar so observations do not land on weekends.
139    pub autocall_observation_dates: Option<Vec<String>>,
140    /// Phoenix: conditional-coupon barrier (absolute level).
141    pub coupon_barrier: Option<f64>,
142    /// Phoenix: memory coupons (missed coupons recovered later).
143    pub coupon_memory: Option<bool>,
144    pub notional: Option<f64>,
145    /// Discrete cash dividends (ex-date + amount per share).
146    pub cash_dividends: Option<Vec<CashDividendData>>,
147    /// When set, the option is on a future (Black-76): "discounted"
148    /// (standard) or "margined" (futures-style). `underlying_price` is then
149    /// the futures price.
150    pub futures_settlement: Option<String>,
151    /// Strike; required for vanilla/binary/barrier/asian payoffs, unused
152    /// for forward-start and autocallable contracts.
153    pub strike_price: Option<f64>,
154    /// Constant volatility; the simple alternative to `vol_surface`.
155    pub volatility: Option<f64>,
156    pub maturity: String,
157    pub dividend: Option<f64>,
158    pub current_price: Option<f64>,
159    pub multiplier:Option<f64>,
160    pub entry_price:Option<f64>,
161    /// Monte Carlo path count (engine "MC" only).
162    pub simulation: Option<u64>,
163    /// MC time steps: 1 = terminal simulation; > 1 = path-wise stepping.
164    pub mc_time_steps: Option<usize>,
165    /// "exact" (default) | "euler" | "milstein"
166    pub mc_scheme: Option<String>,
167    /// "sobol" (default, low-discrepancy) | "pseudo" (seeded PCG64)
168    pub mc_sampler: Option<String>,
169    pub mc_seed: Option<u64>,
170    /// "gbm" (default, constant vol) | "local_vol" (Dupire from the
171    /// option's vol surface). Applies to the MonteCarlo and
172    /// FiniteDifference engines.
173    pub mc_model: Option<String>,
174    /// Finite difference grid nodes in spot (default 400).
175    pub fd_spot_steps: Option<usize>,
176    /// Finite difference time steps (default 400).
177    pub fd_time_steps: Option<usize>,
178    /// Heston parameters; required when `mc_model` is "heston".
179    pub heston: Option<crate::equity::heston::HestonParams>,
180    pub exercise_style: Option<String>, //European, American,
181    pub pricer:Option<String>,
182    /// Optional discount curve; when absent a flat curve is built from
183    /// `risk_free_rate` (which stays the simple way to specify a rate).
184    pub discount_curve: Option<CurveInput>,
185    /// Optional volatility surface; when absent a flat surface is built
186    /// from `volatility`. One of the two must be provided.
187    pub vol_surface: Option<VolInput>,
188}
189