High-Performance Fixed Income Analytics Library in Rust
Live Demo | WASM Demo - Try the interactive bond analytics calculator
Convex is a production-grade fixed income analytics library providing comprehensive bond pricing, yield curve construction, and risk analytics with industry-standard methodologies.
- Bond Pricing: All major bond types (government, corporate, callable, putable, sinking fund)
- Yield Calculations: YTM, YTC, YTW with industry-standard methodology
- Yield Curves: Bootstrap from market data with multiple interpolation methods
- Spread Analytics: Z-spread, G-spread, I-spread, Asset Swap spreads, OAS
- Risk Metrics: Duration (Macaulay, Modified, Effective, Key Rate), Convexity, DV01
- Day Count Conventions: ACT/360, ACT/365, 30/360, ACT/ACT (ICMA, ISDA)
- Holiday Calendars: SIFMA, TARGET2, UK, Japan with O(1) lookups + dynamic calendars
- High Performance: Microsecond-level pricing
- Type Safety: Leverage Rust's type system to prevent errors
- WebAssembly: Full browser support via wasm-pack (Live Demo | WASM Demo)
- Language Bindings: C FFI bindings available; Python, Java, C# (coming soon)
Add this to your Cargo.toml:
[dependencies]
convex = "0.1"use convex::prelude::*;
use rust_decimal_macros::dec;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create a US Treasury bond
let bond = Bond::builder()
.isin("US912828Z229")
.coupon_rate(dec!(2.5))
.maturity(Date::from_ymd(2030, 5, 15))
.frequency(Frequency::SemiAnnual)
.day_count(DayCount::ActAct)
.build()?;
// Build a yield curve from market data
let curve = YieldCurve::bootstrap()
.add_deposit(dec!(0.015), Period::Months(3))
.add_deposit(dec!(0.018), Period::Months(6))
.add_bond(dec!(98.50), Date::from_ymd(2027, 5, 15))
.add_bond(dec!(97.25), Date::from_ymd(2032, 5, 15))
.interpolation(Interpolation::CubicSpline)
.build()?;
// Price the bond
let settlement = Date::today();
let price = bond.price(&curve, settlement)?;
println!("Clean Price: {:.4}", price.clean());
println!("Dirty Price: {:.4}", price.dirty());
println!("Accrued Interest: {:.4}", price.accrued());
// Calculate yield
let ytm = bond.yield_to_maturity(price.clean(), settlement)?;
println!("Yield to Maturity: {:.4}%", ytm.as_percentage());
// Calculate risk metrics
let duration = bond.modified_duration(&curve, settlement)?;
let convexity = bond.convexity(&curve, settlement)?;
let dv01 = bond.dv01(&curve, settlement)?;
println!("Modified Duration: {:.4}", duration);
println!("Convexity: {:.4}", convexity);
println!("DV01: ${:.2}", dv01);
Ok(())
}use convex::prelude::*;
use rust_decimal_macros::dec;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let bond = Bond::builder()
.isin("US459200KJ18") // IBM Corporate Bond
.coupon_rate(dec!(3.75))
.maturity(Date::from_ymd(2028, 11, 15))
.frequency(Frequency::SemiAnnual)
.day_count(DayCount::Thirty360)
.build()?;
// Government curve for discounting
let gov_curve = YieldCurve::from_market_data(/* ... */)?;
// Market price
let market_price = Price::new(dec!(102.50), Currency::USD);
// Calculate Z-spread
let z_spread = bond.z_spread(market_price, &gov_curve, Date::today())?;
println!("Z-Spread: {:.2} bps", z_spread.as_basis_points());
Ok(())
}Convex is organized into several crates for modularity:
convex/
├── convex-core # Core types (Date, Price, Yield, etc.)
├── convex-math # Mathematical utilities and solvers
├── convex-curves # Yield curve construction and interpolation
├── convex-bonds # Bond instruments and definitions
├── convex-analytics # Unified analytics (yields, spreads, risk)
├── convex-wasm # WebAssembly bindings
└── convex-ffi # Foreign Function Interface for language bindings
Convex is designed for production trading systems with strict performance requirements:
| Operation | Time | Notes |
|---|---|---|
| Bond Price | < 1 μs | Single fixed-rate bond |
| YTM Calculation | < 10 μs | Newton-Raphson convergence |
| Bootstrap 50-point curve | < 100 μs | Parallel processing |
| Z-Spread | < 50 μs | Iterative solver |
| Holiday Lookup | < 10 ns | O(1) bitmap lookup |
| Portfolio (1000 bonds) | < 10 ms | Parallel pricing |
Benchmarked on AMD Ryzen 9 5950X @ 3.4GHz
Convex implements all major day count conventions with industry-standard compliance:
- ACT/360: Actual days / 360 (Money market)
- ACT/365: Actual days / 365 (UK Gilts)
- 30/360 US: 30-day months, 360-day year (US Corporate bonds)
- 30E/360: European 30/360 convention
- ACT/ACT ICMA: Actual/Actual per period (Government bonds)
- ACT/ACT ISDA: Actual/Actual with year convention (Swaps)
Convex provides comprehensive holiday calendar support with O(1) bitmap-based lookups:
| Calendar | Description | Usage |
|---|---|---|
SIFMACalendar |
US fixed income (bond market) | Corporate bonds, Munis |
USGovernmentCalendar |
US Treasury securities | Treasuries |
Target2Calendar |
Eurozone payments | EUR swaps, Bunds |
UKCalendar |
UK bank holidays | Gilts |
JapanCalendar |
Japan holidays | JGBs |
Load calendars from JSON or create custom calendars at runtime:
use convex_core::calendars::{DynamicCalendar, CustomCalendarBuilder, WeekendType, Calendar};
// Load from JSON
let cal = DynamicCalendar::from_json(r#"{
"name": "My Calendar",
"weekend": "SaturdaySunday",
"holidays": ["2025-01-01", "2025-12-25"]
}"#)?;
// Build custom calendar
let cal = CustomCalendarBuilder::new("Trading Calendar")
.weekend(WeekendType::SaturdaySunday)
.add_fixed_holiday(1, 1) // New Year's Day
.add_nth_weekday(1, Weekday::Mon, 3) // MLK Day
.add_good_friday()
.add_custom(|year| fetch_holidays_from_db(year))
.build();
// Dynamic modification
let mut cal = DynamicCalendar::new("Custom", WeekendType::SaturdaySunday);
cal.add_holiday(date);
cal.merge_from(&SIFMACalendar::new());Convex uses industry-standard methodology for all yield calculations:
- Sequential Roll-Forward: Starting from settlement date, roll forward through each period
- Exact Day Counts: Use actual calendar days with appropriate day count convention
- Newton-Raphson Solver: Converge to 1e-10 tolerance within 100 iterations
- Compounding Frequency: Support annual, semi-annual, quarterly, monthly
This ensures accurate results matching professional trading systems.
from convex import Bond, YieldCurve, Date
from decimal import Decimal
bond = Bond(
isin="US912828Z229",
coupon_rate=Decimal("2.5"),
maturity=Date(2030, 5, 15),
frequency="semi-annual"
)
curve = YieldCurve.from_market_data(...)
price = bond.price(curve, Date.today())
print(f"Clean Price: {price.clean():.4f}")
print(f"YTM: {bond.ytm(price.clean()):.4f}%")import com.convex.Bond;
import com.convex.YieldCurve;
import java.math.BigDecimal;
Bond bond = new Bond.Builder()
.isin("US912828Z229")
.couponRate(new BigDecimal("2.5"))
.maturity(LocalDate.of(2030, 5, 15))
.build();
YieldCurve curve = YieldCurve.fromMarketData(...);
Price price = bond.price(curve, LocalDate.now());
System.out.printf("Clean Price: %.4f%n", price.clean());=CONVEX.BOND.PRICE("US912828Z229", TODAY(), "CURVE_USD")
=CONVEX.BOND.YTM("US912828Z229", 98.50, TODAY())
=CONVEX.BOND.DURATION("US912828Z229", "CURVE_USD", TODAY())
- ✅ Fixed-rate bonds (government, corporate)
- ✅ Zero-coupon bonds (T-Bills, discount bonds)
- ✅ Floating-rate notes (SOFR, SONIA, EURIBOR with caps/floors)
- ✅ Callable bonds (American, Bermudan, European, Make-Whole)
- ✅ Putable bonds
- ✅ Sinking fund bonds (with average life calculations)
- 🔜 Convertible bonds
- 🔜 Inflation-linked bonds (TIPS, Linkers)
- 🔜 Asset-backed securities
- 🔜 Mortgage-backed securities
# Clone the repository
git clone https://github.com/sujitn/convex.git
cd convex
# Build all crates
cargo build --release
# Run tests
cargo test --all
# Run benchmarks
cargo bench
# Generate documentation
cargo doc --open- Rust 1.75 or later
- Cargo
# All tests
cargo test
# Specific crate
cargo test -p convex-core
# With output
cargo test -- --nocapture
# Integration tests
cargo test --test '*'# Linting
cargo clippy -- -D warnings
# Formatting
cargo fmt --check
# Check for common mistakes
cargo auditContributions are welcome! Please open an issue or submit a pull request on GitHub.
- Additional bond types (inflation-linked, convertibles)
- Additional language bindings
- Performance improvements
- Documentation and examples
- Bug fixes and testing
- Core infrastructure (Date, Price, Yield types)
- Day count conventions (all major conventions)
- Yield curve construction and bootstrapping
- Fixed-rate bond pricing with industry-standard methodology
- Spread calculations (G-spread, Z-spread, I-spread, OAS, ASW)
- Holiday calendars (SIFMA, TARGET2, UK, Japan)
- Dynamic calendar system (JSON loading, custom builders)
- Floating rate notes (SOFR, SONIA, EURIBOR)
- Callable/putable bonds with OAS
- Sinking fund bonds
- Risk metrics (Duration, Convexity, DV01, VaR)
- Multi-curve framework (OIS discounting)
- WebAssembly support with interactive demo
- Advanced interpolation (Nelson-Siegel, Svensson, Monotone Convex)
- Python bindings (PyO3)
- Comprehensive documentation
- Performance optimizations
- Java and C# bindings
- Excel plugin
- Convertible bonds
- Inflation-linked bonds (TIPS, Linkers)
- REST API service
Convex is validated against:
- Industry-standard reference implementations
- Known academic test cases
- Historical market data
All pricing and risk calculations are tested to match professional systems within 1e-6 tolerance.
Run benchmarks with:
cargo benchThis project is licensed under the MIT License - see the LICENSE file for details.
- Inspired by QuantLib design patterns
- Industry-standard fixed income methodologies
- Rust Financial community
If you use Convex in academic work, please cite:
@software{convex2025,
title = {Convex: High-Performance Fixed Income Analytics Library},
author = {Sujit Nair},
year = {2025},
url = {https://github.com/sujitn/convex}
}- GitHub Issues: Bug reports and feature requests
Built with ❤️ in Rust 🦀