1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
//! `QuantSupport` is a Rust library for financial calculations and analysis.
//!
//! This library provides tools for computing prices, sensitivities and other
//! metrics of financial products.
//!
//! # Quick-start example
//!
//! The snippet below prices a 5-year receive-fixed / pay-floating USD IRS,
//! retrieves its NPV, cashflow schedule and curve sensitivities.
//! A complete, runnable version lives in `examples/valuation/`.
//!
//! ## 1 — Imports
//!
//! Everything needed is re-exported through the [`prelude`] module.
//!
//! ```ignore
//! use std::{cell::RefCell, rc::Rc};
//! use quantsupport::prelude::*;
//! ```
//!
//! ## 2 — Build the swap trade
//!
//! Use [`MakeSwap`](crate::instruments::rates::makeswap::MakeSwap) to
//! configure the instrument, then wrap it in a
//! [`SwapTrade`](crate::instruments::rates::swap::SwapTrade) that carries
//! trade-level metadata (trade date, notional, side).
//!
//! ```ignore
//! # use std::{cell::RefCell, rc::Rc};
//! # use quantsupport::prelude::*;
//! let start_date = Date::new(2024, 1, 15);
//! let maturity_date = Date::new(2029, 1, 15);
//! let notional = 10_000_000.0;
//! let fixed_rate = 0.030; // 3.0%
//!
//! // Day-count / compounding convention for the fixed leg coupon rate.
//! let rate_definition = RateDefinition::new(
//! DayCounter::Actual360,
//! Compounding::Simple,
//! Frequency::Semiannual,
//! );
//!
//! let swap = MakeSwap::<DualFwd>::default()
//! .with_identifier("USD_IRS_5Y".to_string())
//! .with_start_date(start_date)
//! .with_maturity_date(maturity_date)
//! .with_fixed_rate(fixed_rate)
//! .with_notional(notional)
//! .with_rate_definition(rate_definition)
//! .with_currency(Currency::USD)
//! .with_market_index(MarketIndex::SOFR)
//! .with_side(Side::LongReceive) // receive fixed, pay floating
//! .with_fixed_leg_frequency(Frequency::Semiannual)
//! .with_floating_leg_frequency(Frequency::Semiannual)
//! .build()
//! .expect("Failed to build swap");
//!
//! let trade = SwapTrade::new(swap, start_date, notional, Side::LongReceive);
//! ```
//!
//! ## 3 — Set up the pricing context
//!
//! A `ContextManager` holds
//! market data (discount curves, quote / fixing stores) that pricers consult
//! during evaluation. Here we create a flat SOFR discount curve at 3.0%.
//!
//! ```ignore
//! # use std::{cell::RefCell, rc::Rc};
//! # use quantsupport::prelude::*;
//! let evaluation_date = Date::new(2024, 1, 15);
//! let discount_rate = 0.03; // 3.0% flat curve
//!
//! // Curve rate convention: continuous compounding, ACT/360.
//! let curve_definition = RateDefinition::new(
//! DayCounter::Actual360,
//! Compounding::Continuous,
//! Frequency::Annual,
//! );
//!
//! // Build the flat-forward term structure.
//! let discount_curve = FlatForwardTermStructure::new(
//! evaluation_date,
//! DualFwd::from(discount_rate),
//! curve_definition,
//! )
//! .with_pillar_label("SOFR_flat".to_string());
//!
//! // Register the curve as the SOFR discount curve.
//! let mut constructed_elements = ConstructedElementStore::default();
//! constructed_elements.discount_curves_mut().insert(
//! MarketIndex::SOFR,
//! DiscountCurveElement::new(
//! MarketIndex::SOFR,
//! Rc::new(RefCell::new(discount_curve)),
//! ),
//! );
//!
//! // Empty stores — no live quotes or historical fixings in this example.
//! let quote_store = QuoteStore::new(evaluation_date);
//! let fixing_store = FixingStore::default();
//!
//! let context = ContextManager::new(quote_store, fixing_store)
//! .with_base_currency(Currency::USD)
//! .with_constructed_elements(constructed_elements);
//! ```
//!
//! ## 4 — Price the swap and read results
//!
//! Create a [`DiscountedCashflowPricer`](crate::pricers::cashflows::discountedcashflowpricer::DiscountedCashflowPricer),
//! choose which outputs you need via [`Request`](crate::core::request::Request),
//! and call `evaluate`.
//!
//! ```ignore
//! # use std::{cell::RefCell, rc::Rc};
//! # use quantsupport::prelude::*;
//! # let start_date = Date::new(2024, 1, 15);
//! # let maturity_date = Date::new(2029, 1, 15);
//! # let notional = 10_000_000.0;
//! # let fixed_rate = 0.030;
//! # let rate_definition = RateDefinition::new(
//! # DayCounter::Actual360, Compounding::Simple, Frequency::Semiannual);
//! # let swap = MakeSwap::<DualFwd>::default()
//! # .with_identifier("USD_IRS_5Y".to_string())
//! # .with_start_date(start_date).with_maturity_date(maturity_date)
//! # .with_fixed_rate(fixed_rate).with_notional(notional)
//! # .with_rate_definition(rate_definition)
//! # .with_currency(Currency::USD).with_market_index(MarketIndex::SOFR)
//! # .with_side(Side::LongReceive)
//! # .with_fixed_leg_frequency(Frequency::Semiannual)
//! # .with_floating_leg_frequency(Frequency::Semiannual)
//! # .build().unwrap();
//! # let trade = SwapTrade::new(swap, start_date, notional, Side::LongReceive);
//! # let evaluation_date = Date::new(2024, 1, 15);
//! # let curve_definition = RateDefinition::new(
//! # DayCounter::Actual360, Compounding::Continuous, Frequency::Annual);
//! # let discount_curve = FlatForwardTermStructure::new(
//! # evaluation_date, DualFwd::from(0.03), curve_definition)
//! # .with_pillar_label("SOFR_flat".to_string());
//! # let mut constructed_elements = ConstructedElementStore::default();
//! # constructed_elements.discount_curves_mut().insert(
//! # MarketIndex::SOFR, DiscountCurveElement::new(
//! # MarketIndex::SOFR,
//! # Rc::new(RefCell::new(discount_curve))));
//! # let quote_store = QuoteStore::new(evaluation_date);
//! # let fixing_store = FixingStore::default();
//! # let context = ContextManager::new(quote_store, fixing_store)
//! # .with_base_currency(Currency::USD)
//! # .with_constructed_elements(constructed_elements);
//! let pricer = CashflowDiscountPricer::<Swap<DualFwd>, SwapTrade<DualFwd>>::new();
//! let requests = vec![Request::Value, Request::Cashflows, Request::Sensitivities];
//! let results = pricer.evaluate(&trade, &requests, &context).expect("pricing failed");
//!
//! // --- NPV ---
//! if let Some(price) = results.price() {
//! println!("Swap NPV = {price:.2}");
//! }
//!
//! // --- Sensitivities (dV/dQuote per curve pillar) ---
//! if let Some(sensitivities) = results.sensitivities() {
//! println!("\nSensitivities:");
//! for (key, exposure) in sensitivities.instrument_keys()
//! .iter()
//! .zip(sensitivities.exposure().iter())
//! {
//! println!(" {key}: {exposure:.4}");
//! }
//! }
//!
//! // --- Cashflow schedule ---
//! if let Some(cashflows) = results.cashflows() {
//! let dates = cashflows.payment_dates();
//! let types = cashflows.cashflow_types();
//! let amounts = cashflows.amounts();
//! let currencies = cashflows.currencies();
//!
//! println!("\nCashflows ({} rows):", dates.len());
//! for i in 0..dates.len() {
//! println!(
//! " {} | {:<20} | {:>14.2} {}",
//! dates[i], types[i], amounts[i], currencies[i]
//! );
//! }
//! }
//! ```
/// Pricing models (GBM, Hull-White, etc.).
/// Commonly used public exports for pricing and market-data workflows.
/// Payoff scripting language and model-backed evaluation runtime.