borsa
The unified, intelligent, and resilient financial data toolkit for Rust.
Overview
borsa provides a high-level, asynchronous API for fetching market and financial data from multiple sources. Instead of juggling different client libraries and data formats, borsa offers a single, consistent interface that intelligently routes requests across multiple data providers.
Features
- Pluggable Architecture: Add multiple data connectors and let
borsaautomatically choose the best one - Intelligent Fallback: If one provider fails, automatically try the next one
- Smart Data Merging: Combine data from multiple sources for more complete datasets
- High Performance: Async/await with efficient concurrent requests
- Asset-Specific Routing: Configure different providers for different asset types
- Rich Data Types: Quotes, historical data, fundamentals, options, news, and more
Installation
Add borsa and a connector to your Cargo.toml:
[]
= "0.1.2"
= "0.1.2"
= { = "1", = ["full"] }
Usage
Fetch your first quote
use Borsa;
use ;
use YfConnector;
use Arc;
async
Concepts
Observability (optional)
Enable the tracing feature to emit structured spans from router entry points and core orchestration helpers:
[]
= { = "0.1", = ["tracing"] }
Initialize a subscriber in your application:
fmt
.with_env_filter
.init;
See the top-level examples/examples/00_tracing.rs for a working end-to-end sample.
Connectors
Connectors are plugins that fetch data from specific providers. borsa comes with:
borsa-yfinance: Yahoo Finance connector (free, no API key required)
Instruments
An Instrument represents a financial asset:
use ;
// Stocks
let aapl = from_symbol
.expect;
let tsla = from_symbol
.expect;
// Cryptocurrencies
let btc = from_symbol
.expect;
// ETFs
let spy = from_symbol
.expect;
Priority Configuration
Configure which connectors to use for different assets:
let borsa = builder
.with_connector
.with_connector
// Prefer Alpha Vantage for crypto (type-safe, ergonomic API)
.prefer_for_kind
// Use specific connector for TSLA
.prefer_symbol
.build?;
Data Types
Quotes & Market Data
// Get live quote
let quote = borsa.quote.await?;
if let Some = "e.price
// Get comprehensive info (snapshot + warnings)
let report = borsa.info.await?;
if let Some = report.info
Historical Data
use ;
// Get 6 months of daily data
let req = try_from_range?;
let history = borsa.history.await?;
println!;
if let Some = history.candles.last
// Get data with attribution (see which connector provided each piece)
let = borsa.history_with_attribution.await?;
for in attribution.spans
Fundamentals
// Income Statement
let income = borsa.income_statement.await?; // quarterly
if let Some = income.first
// Balance Sheet
let balance = borsa.balance_sheet.await?;
if let Some = balance.first
// Cash Flow
let cashflow = borsa.cashflow.await?;
if let Some = cashflow.first
Options Data
// Get available expiration dates
let expirations = borsa.options_expirations.await?;
println!;
// Get option chain for nearest expiration
if let Some = expirations.first
Analysis & Recommendations
// Analyst recommendations
let recs = borsa.recommendations.await?;
let summary = borsa.recommendations_summary.await?;
println!;
// Price targets
let target = borsa.analyst_price_target.await?;
let mean = target.mean.as_ref.map.unwrap_or_else;
let low = target.low.as_ref.map.unwrap_or_else;
let high = target.high.as_ref.map.unwrap_or_else;
println!;
News & Events
use NewsRequest;
// Get recent news
let news_req = default;
let news = borsa.news.await?;
for article in news.iter.take
// Get upcoming events
let calendar = borsa.calendar.await?;
for ts in calendar.earnings_dates.iter.take
DataFrames (PAFT integration)
borsa builds on paft. Enabling the dataframe feature on borsa activates paft's Polars integration, allowing you to call .to_dataframe() on returned types.
Enable it in your Cargo.toml:
[]
= { = "0.1", = ["dataframe"] }
Example:
use ToDataFrame; // bring the extension trait into scope
let quote = borsa.quote.await?;
let df = quote.to_dataframe?; // -> polars::DataFrame
Advanced Features
Bulk Operations
Download data for multiple instruments efficiently:
let instruments = ;
let summary = borsa.download
.instruments?
.range
.interval
.run
.await?;
if let Some = summary.response
Automatic Resampling
Configure automatic data resampling:
use Resampling;
let borsa = builder
.with_connector
// Always convert to daily bars
.resampling
// Or convert to weekly bars
// .resampling(Resampling::Weekly)
.build?;
History Merge Strategy
Control how historical data is fetched from multiple providers:
use MergeStrategy;
let borsa = builder
.with_connector
.with_connector
// Deep merge: fetch from all providers and merge data (default)
.merge_history_strategy
// Or fallback: stop at first provider with data (more economical)
// .merge_history_strategy(MergeStrategy::Fallback)
.build?;
Merge Strategies:
Deep(default): Fetches from all eligible providers concurrently and merges their data. This produces the most complete dataset by backfilling gaps from lower-priority providers, but uses more API calls.Fallback: Iterates through providers sequentially and stops as soon as one returns a non-empty dataset. This is more economical for API rate limits but may miss data from lower-priority providers.
Multi-Quote Fetching
Get quotes for multiple instruments efficiently:
let instruments = ;
let = borsa.quotes.await?;
for q in quotes
if !failures.is_empty
Architecture
The Borsa Ecosystem
borsa: High-level client library (this crate)borsa-core: Core traits and types for building connectorsborsa-yfinance: Yahoo Finance connector
Building Custom Connectors
Create your own connector by implementing role traits and advertising them via the BorsaConnector capability accessors. A minimal, current skeleton:
use async_trait;
use ;
;
Examples
Check out the examples package for comprehensive usage examples:
01_simple_quote.rs- Basic quote fetching02_history_merge.rs- Historical data with multiple sources03_search.rs- Symbol search04_price_target.rs- Analyst price target05_options_chain.rs- Options data06_fundamentals_deep_dive.rs- Financial statements07_financial_snapshot.rs- Aggregated info snapshot08_history_resampling.rs- Resampling and cadence control09_stock_comparison.rs- Multi-symbol comparison10_analyst_recommendations.rs- Analyst data11_upcoming_events.rs- Calendar/events12_per_symbol_priority.rs- Per-symbol provider priority
Contributing
We welcome contributions! Please see our Contributing Guide and our Code of Conduct.
Building from Source
Running Tests
Running Examples
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Yahoo Finance for providing free market data
- The Rust community for building amazing async tools
Ready to build something amazing with financial data? Start with borsa today!