| Crates.io | borsa-core |
| lib.rs | borsa-core |
| version | 0.2.0 |
| created_at | 2025-10-18 19:00:24.312156+00 |
| updated_at | 2025-10-23 14:29:32.880292+00 |
| description | Core types, connector traits, and time-series utilities for the borsa financial data ecosystem. |
| homepage | https://github.com/borsaorg/borsa |
| repository | https://github.com/borsaorg/borsa |
| max_upload_size | |
| id | 1889539 |
| size | 222,477 |
Core types, traits, and utilities shared across the borsa financial data ecosystem.
borsa-core provides the foundational building blocks for the borsa ecosystem, a unified interface for accessing financial market data from multiple providers. It defines common data structures, the connector trait for implementing data providers, and utilities for working with time series data.
BorsaConnector trait: The main interface that all data providers must implementas_*_provider) expose granular capability traitsThe library supports multiple asset classes:
Add this to your Cargo.toml:
[dependencies]
borsa-core = "0.2.0"
After adding borsa-core to your Cargo.toml, you can start with the following examples.
use borsa_core::{AssetKind, BorsaConnector, BorsaError, Instrument};
// Create an instrument (validated and canonicalized)
let instrument = Instrument::from_symbol("AAPL", AssetKind::Equity)?;
// Use with any connector that implements BorsaConnector
async fn get_quote(connector: &impl BorsaConnector, instrument: &Instrument) -> Result<(), BorsaError> {
let provider = connector
.as_quote_provider()
.ok_or_else(|| BorsaError::unsupported("quote"))?;
let quote = provider.quote(instrument).await?;
if let Some(price) = "e.price {
println!("{}: {}", quote.symbol.as_str(), price.format());
}
Ok(())
}
use borsa_core::BorsaConnector;
fn check_support(connector: &impl BorsaConnector) {
if connector.as_quote_provider().is_some() {
println!("This connector supports real-time quotes");
}
if connector.as_history_provider().is_some() {
println!("This connector supports historical data");
}
if connector.as_earnings_provider().is_some() {
println!("This connector supports earnings");
}
}
use borsa_core::timeseries::{merge::merge_history, resample::resample_to_daily};
// Merge multiple HistoryResponse values in priority order
let merged = merge_history(vec![resp_a, resp_b, resp_c]);
// Resample arbitrary candles to daily bars
let daily_candles = resample_to_daily(candles)?;
BorsaConnector is a capability hub: providers implement granular role traits and advertise them via as_*_provider accessors on the connector. This keeps the core stable and enables mix-and-match features. Use supports_kind(&AssetKind) to declare which asset classes the connector can serve.
use borsa_core::connector::{BorsaConnector, QuoteProvider, HistoryProvider};
pub struct MyConnector;
#[async_trait]
impl QuoteProvider for MyConnector {
async fn quote(&self, instrument: &Instrument) -> Result<Quote, BorsaError> {
// ...
}
}
#[async_trait]
impl HistoryProvider for MyConnector {
async fn history(&self, instrument: &Instrument, req: HistoryRequest) -> Result<HistoryResponse, BorsaError> {
// ...
}
fn supported_history_intervals(&self, _kind: AssetKind) -> &'static [Interval] { &[] }
}
impl BorsaConnector for MyConnector {
fn name(&self) -> &'static str { "my-connector" }
fn supports_kind(&self, kind: AssetKind) -> bool { matches!(kind, AssetKind::Equity) }
fn as_quote_provider(&self) -> Option<&dyn QuoteProvider> { Some(self) }
fn as_history_provider(&self) -> Option<&dyn HistoryProvider> { Some(self) }
}
examples/ packageborsa: High-level router/orchestratorborsa-yfinance: Yahoo Finance connectorContributions are welcome! Please see our Contributing Guide and our Code of Conduct. For major changes, please open an issue first to discuss what you would like to change.
This project is licensed under the MIT License - see the LICENSE file for details.