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
//! Borsa orchestrates requests across multiple market data providers.
//!
//! Overview
//! - Routes requests to connectors that implement the `borsa_core` contracts.
//! - Applies per-symbol and per-kind priorities to influence provider order.
//! - Supports configurable fetch and merge strategies with resampling options.
//! - Normalizes error handling and exposes uniform domain types from `borsa_core`.
//!
//! Key behaviors and trade-offs
//! - Fetch strategy:
//! - `PriorityWithFallback`: deterministic order, per-provider timeout, aggregates
//! errors; fewer concurrent requests but potentially higher latency.
//! - `Latency`: races eligible providers; lowest tail latency but higher request fanout.
//! - History merge:
//! - `Deep`: fetch all eligible providers and backfill gaps; most complete series,
//! more requests and provider load.
//! - `Fallback`: first non-empty dataset wins; economical but can miss data present
//! on lower-priority providers.
//! - Resampling: daily/weekly (or auto-subdaily→daily) simplifies downstream analysis
//! but drops native cadence and clears per-candle `close_unadj` to avoid ambiguity.
//! - Adjusted preference: favors adjusted series to smooth corporate actions at the
//! cost of diverging from unadjusted close values.
//! - Streaming: selects the first provider per asset kind that connects; supervised
//! backoff with jitter reduces synchronized reconnect storms.
//!
//! Examples
//! Building an orchestrator with preferences and strategies:
//! ```rust,ignore
//! use std::sync::Arc;
//! use borsa::{Borsa, MergeStrategy, FetchStrategy, Resampling};
//! use borsa_core::AssetKind;
//!
//! let yf = Arc::new(YfConnector::new_default());
//! let av = Arc::new(AvConnector::new_with_key("..."));
//!
//! let routing = borsa_core::RoutingPolicyBuilder::new()
//! .providers_for_kind(
//! AssetKind::Equity,
//! &[av.key(), yf.key()],
//! )
//! .build();
//!
//! let borsa = Borsa::builder()
//! .with_connector(yf.clone())
//! .with_connector(av.clone())
//! // Type-safe, ergonomic API via typed connector keys
//! .routing_policy(routing)
//! .merge_history_strategy(MergeStrategy::Deep)
//! .fetch_strategy(FetchStrategy::PriorityWithFallback)
//! .resampling(Resampling::Daily)
//! .build()?;
//! ```
//!
//! Fetching a quote and a merged history series:
//! ```rust,ignore
//! use borsa_core::{Instrument, Interval, Range};
//!
//! let aapl = Instrument::stock("AAPL");
//! let quote = borsa.quote(&aapl).await?;
//! let hist = borsa.history(
//! &aapl,
//! borsa_core::HistoryRequest{
//! range: Some(Range::Y1),
//! interval: Interval::D1,
//! ..Default::default()
//! }
//! ).await?;
//! ```
//!
//! Streaming with supervised failover:
//! ```rust,ignore
//! use borsa_core::Instrument;
//! let (handle, mut rx) = borsa.stream_quotes(&[Instrument::stock("AAPL")]).await?;
//! // ... consume updates ...
//! handle.stop().await;
//! ```
//!
//! Bulk download helper (multi-symbol history):
//! ```rust,ignore
//! use borsa_core::{Instrument, Interval, Range};
//! let report = borsa
//! .download()
//! .instruments(&[Instrument::stock("AAPL"), Instrument::stock("MSFT")])?
//! .range(borsa_core::Range::M6)
//! .interval(Interval::D1)
//! .run()
//! .await?;
//! if let Some(resp) = report.response.as_ref() {
//! if let Some(aapl_history) = resp.series.get("AAPL") {
//! // inspect candles returned for AAPL
//! }
//! }
//! ```
//!
//! See the `examples/` package for runnable end-to-end demonstrations.
pub
pub use ;
pub use ;
pub use DownloadBuilder;