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