Quantitative finance library in Rust for derivatives pricing, curve bootstrapping, risk factor simulations, and XVA, all with AD support.
翻译准备中
正在加载完整 README。 以下为已保存的摘录。
QuantSupport is a quantitative-finance library written in Rust, with Python bindings provided in the same repository. It combines instrument construction, market-data bootstrapping, pricing, automatic differentiation, payoff scripting, Monte Carlo exposure simulation, and XVA in one toolkit.
A crate is available for usage in your project:
Quick start: price and risk a swap
This complete example values a five-year receive-fixed USD swap against a flat SOFR curve and asks for NPV, par rate, cashflows, and curve sensitivity.查看完整 README ↗QuantSupport (QS) is a quantitative finance library written in Rust, with Python and Excel bindings. It supports valuation across several asset classes, market sensitivities using automatic differentiation, interest-rate and credit curve construction, volatility markets, Monte Carlo simulation and XVA.
Observable quotes and fixings are stored separately from constructed market objects, such as bootstrapped curves and implied-volatility surfaces. Instruments define contractual terms, and trades add the position held. Pricers combine those trades with the market data needed for valuation.
Add the Rust crate to your project with:
cargo add quantsupport
| Reading purpose | Entry point |
|---|---|
| Financial concepts, architecture, conventions, and all three interfaces | QuantSupport Book |
| Exact native Rust signatures, errors, and numerical contracts | Rust API reference |
| Independently usable binding guides and declarations | Python documentation and Excel documentation |
| Executable quantitative-finance studies | Notebook collection |
Consider a five-year USD swap that receives a fixed coupon of 3% and pays
a floating coupon every six months on USD 10 million. We construct it with
MakeSwap, create a trade and supply a flat curve for projection and
discounting. The pricer returns NPV, par coupon, cashflows and sensitivities.
The fixed coupon uses simple ACT/360 accrual, while the 3% curve is continuously
compounded. The floating leg uses one SOFR-indexed observation per coupon
period. For daily compounded overnight coupons, use MakeOvernightIndexSwap.
use std::{cell::RefCell, rc::Rc};
use quantsupport::prelude::*;
fn main() -> Result<()> {
let valuation_date = Date::new(2024, 1, 15);
let maturity_date = Date::new(2029, 1, 15);
let notional = 10_000_000.0;
let swap = MakeSwap::<DualFwd>::default()
.with_identifier("USD_IRS_5Y".to_string())
.with_start_date(valuation_date)
.with_maturity_date(maturity_date)
.with_fixed_rate(0.03)
.with_notional(notional)
.with_rate_definition(RateDefinition::new(
DayCounter::Actual360,
Compounding::Simple,
Frequency::Semiannual,
))
.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()?;
let trade = SwapTrade::new(swap, valuation_date, notional, Side::LongReceive);
let curve = FlatForwardTermStructure::new(
valuation_date,
DualFwd::from(0.03),
RateDefinition::new(
DayCounter::Actual360,
Compounding::Continuous,
Frequency::Annual,
),
)
.with_pillar_label("SOFR_flat".to_string());
let mut elements = ConstructedElementStore::default();
elements.discount_curves_mut().insert(
MarketIndex::SOFR,
DiscountCurveElement::new(MarketIndex::SOFR, Rc::new(RefCell::new(curve))),
);
let context = PricingContext::new()
.with_quote_store(QuoteStore::new(valuation_date))
.with_fixing_store(FixingStore::default())
.with_base_currency(Currency::USD)
.with_constructed_elements(elements);
let pricer = DiscountedCashflowPricer::<Swap<DualFwd>, SwapTrade<DualFwd>>::new();
let requests = [
Request::Value,
Request::FairRate(0),
Request::Cashflows,
Request::Sensitivities,
];
let results = pricer.evaluate(&trade, &requests, &context)?;
let npv = results.price()
.ok_or_else(|| QSError::ValueNotSetErr("swap NPV".into()))?;
let par_rate = results.fair_rate()
.ok_or_else(|| QSError::ValueNotSetErr("swap par rate".into()))?;
println!("NPV (USD): {npv:.2}");
println!("Par coupon (decimal): {par_rate:.6}");
if let Some(risk) = results.sensitivities() {
for (pillar, exposure) in risk.instrument_keys().iter().zip(risk.exposure()) {
println!("dPV/dPillar {pillar}: {exposure:.4}");
println!("Approximate USD P&L for +1 bp: {:.2}", exposure * 1e-4);
}
}
if let Some(cashflows) = results.cashflows() {
println!("Cashflows: {}", cashflows.payment_dates().len());
}
Ok(())
}
A related program with a detailed cashflow report is available in
examples/valuation/swaps.
The NPV is approximately -10,723.59 USD and the flat-rate derivative is -47,405,484.05 USD per unit decimal rate, corresponding to about -4,740.55 USD for a one-basis-point increase. The continuous curve implies simple floating coupons slightly above the agreed fixed coupon, giving the receive-fixed position its small negative value. Sensitivity is measured against the flat rate supplied to the curve. The cashflow table contains unsigned, undiscounted amounts; apply direction and discounting to reconcile it to NPV.
QuantSupport separates market observables, calibrated market objects, product definitions, and valuation engines. This keeps the same market construction and risk machinery reusable across deterministic pricing, Monte Carlo, scripting, and XVA.
以上为 README 的开头部分。其余内容请阅读原文。 查看完整 README ↗