1use async_trait::async_trait;
2
3use crate::BorsaError;
4use paft::domain::{AssetKind, Instrument, Isin};
5use paft::fundamentals::analysis::{
6 Earnings, PriceTarget, RecommendationRow, RecommendationSummary, UpgradeDowngradeRow,
7};
8use paft::fundamentals::esg::EsgScores;
9use paft::fundamentals::holders::{
10 InsiderRosterHolder, InsiderTransaction, InstitutionalHolder, MajorHolder,
11 NetSharePurchaseActivity,
12};
13use paft::fundamentals::profile::Profile;
14use paft::fundamentals::statements::{BalanceSheetRow, Calendar, CashflowRow, IncomeStatementRow};
15use paft::market::news::NewsArticle;
16use paft::market::options::OptionChain;
17use paft::market::quote::{Quote, QuoteUpdate};
18use paft::market::requests::history::{HistoryRequest, Interval};
19use paft::market::requests::news::NewsRequest;
20use paft::market::requests::search::SearchRequest;
21use paft::market::responses::history::HistoryResponse;
22use paft::market::responses::search::SearchResponse;
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
26pub struct ConnectorKey(pub &'static str);
27
28impl ConnectorKey {
29 #[must_use]
33 pub const fn new(name: &'static str) -> Self {
34 Self(name)
35 }
36
37 #[must_use]
39 pub const fn as_str(self) -> &'static str {
40 self.0
41 }
42}
43
44impl From<ConnectorKey> for &'static str {
45 fn from(k: ConnectorKey) -> Self {
46 k.0
47 }
48}
49
50#[async_trait]
52pub trait HistoryProvider: Send + Sync {
53 async fn history(
55 &self,
56 instrument: &Instrument,
57 req: HistoryRequest,
58 ) -> Result<HistoryResponse, BorsaError>;
59
60 fn supported_history_intervals(&self, kind: AssetKind) -> &'static [Interval];
67}
68
69#[async_trait]
71pub trait QuoteProvider: Send + Sync {
72 async fn quote(&self, instrument: &Instrument) -> Result<Quote, BorsaError>;
74}
75
76#[async_trait]
79pub trait EarningsProvider: Send + Sync {
80 async fn earnings(&self, instrument: &Instrument) -> Result<Earnings, BorsaError>;
82}
83
84#[async_trait]
86pub trait IncomeStatementProvider: Send + Sync {
87 async fn income_statement(
89 &self,
90 instrument: &Instrument,
91 quarterly: bool,
92 ) -> Result<Vec<IncomeStatementRow>, BorsaError>;
93}
94
95#[async_trait]
97pub trait BalanceSheetProvider: Send + Sync {
98 async fn balance_sheet(
100 &self,
101 instrument: &Instrument,
102 quarterly: bool,
103 ) -> Result<Vec<BalanceSheetRow>, BorsaError>;
104}
105
106#[async_trait]
108pub trait CashflowProvider: Send + Sync {
109 async fn cashflow(
111 &self,
112 instrument: &Instrument,
113 quarterly: bool,
114 ) -> Result<Vec<CashflowRow>, BorsaError>;
115}
116
117#[async_trait]
119pub trait CalendarProvider: Send + Sync {
120 async fn calendar(&self, instrument: &Instrument) -> Result<Calendar, BorsaError>;
122}
123
124#[async_trait]
126pub trait RecommendationsProvider: Send + Sync {
127 async fn recommendations(
129 &self,
130 instrument: &Instrument,
131 ) -> Result<Vec<RecommendationRow>, BorsaError>;
132}
133
134#[async_trait]
136pub trait RecommendationsSummaryProvider: Send + Sync {
137 async fn recommendations_summary(
139 &self,
140 instrument: &Instrument,
141 ) -> Result<RecommendationSummary, BorsaError>;
142}
143
144#[async_trait]
146pub trait UpgradesDowngradesProvider: Send + Sync {
147 async fn upgrades_downgrades(
149 &self,
150 instrument: &Instrument,
151 ) -> Result<Vec<UpgradeDowngradeRow>, BorsaError>;
152}
153
154#[async_trait]
156pub trait AnalystPriceTargetProvider: Send + Sync {
157 async fn analyst_price_target(
159 &self,
160 instrument: &Instrument,
161 ) -> Result<PriceTarget, BorsaError>;
162}
163
164#[async_trait]
166pub trait MajorHoldersProvider: Send + Sync {
167 async fn major_holders(&self, instrument: &Instrument) -> Result<Vec<MajorHolder>, BorsaError>;
169}
170
171#[async_trait]
173pub trait InstitutionalHoldersProvider: Send + Sync {
174 async fn institutional_holders(
176 &self,
177 instrument: &Instrument,
178 ) -> Result<Vec<InstitutionalHolder>, BorsaError>;
179}
180
181#[async_trait]
183pub trait MutualFundHoldersProvider: Send + Sync {
184 async fn mutual_fund_holders(
186 &self,
187 instrument: &Instrument,
188 ) -> Result<Vec<InstitutionalHolder>, BorsaError>;
189}
190
191#[async_trait]
193pub trait InsiderTransactionsProvider: Send + Sync {
194 async fn insider_transactions(
196 &self,
197 instrument: &Instrument,
198 ) -> Result<Vec<InsiderTransaction>, BorsaError>;
199}
200
201#[async_trait]
203pub trait InsiderRosterHoldersProvider: Send + Sync {
204 async fn insider_roster_holders(
206 &self,
207 instrument: &Instrument,
208 ) -> Result<Vec<InsiderRosterHolder>, BorsaError>;
209}
210
211#[async_trait]
213pub trait NetSharePurchaseActivityProvider: Send + Sync {
214 async fn net_share_purchase_activity(
216 &self,
217 instrument: &Instrument,
218 ) -> Result<Option<NetSharePurchaseActivity>, BorsaError>;
219}
220
221#[async_trait]
223pub trait ProfileProvider: Send + Sync {
224 async fn profile(&self, instrument: &Instrument) -> Result<Profile, BorsaError>;
226}
227
228#[async_trait]
230pub trait IsinProvider: Send + Sync {
231 async fn isin(&self, instrument: &Instrument) -> Result<Option<Isin>, BorsaError>;
233}
234
235#[async_trait]
237pub trait SearchProvider: Send + Sync {
238 async fn search(&self, req: SearchRequest) -> Result<SearchResponse, BorsaError>;
240}
241
242#[async_trait]
244pub trait EsgProvider: Send + Sync {
245 async fn sustainability(&self, instrument: &Instrument) -> Result<EsgScores, BorsaError>;
247}
248
249#[async_trait]
251pub trait NewsProvider: Send + Sync {
252 async fn news(
254 &self,
255 instrument: &Instrument,
256 req: NewsRequest,
257 ) -> Result<Vec<NewsArticle>, BorsaError>;
258}
259
260#[async_trait]
262pub trait StreamProvider: Send + Sync {
263 async fn stream_quotes(
265 &self,
266 instruments: &[Instrument],
267 ) -> Result<
268 (
269 crate::stream::StreamHandle,
270 tokio::sync::mpsc::Receiver<QuoteUpdate>,
271 ),
272 BorsaError,
273 >;
274}
275
276#[async_trait]
278pub trait OptionsExpirationsProvider: Send + Sync {
279 async fn options_expirations(&self, instrument: &Instrument) -> Result<Vec<i64>, BorsaError>;
281}
282
283#[async_trait]
285pub trait OptionChainProvider: Send + Sync {
286 async fn option_chain(
288 &self,
289 instrument: &Instrument,
290 date: Option<i64>,
291 ) -> Result<OptionChain, BorsaError>;
292}
293
294#[async_trait]
296pub trait BorsaConnector: Send + Sync {
297 fn name(&self) -> &'static str;
299
300 fn vendor(&self) -> &'static str {
302 "unknown"
303 }
304
305 fn supports_kind(&self, kind: AssetKind) -> bool {
310 let _ = kind;
311 false
312 }
313
314 fn as_history_provider(&self) -> Option<&dyn HistoryProvider> {
316 None
317 }
318
319 fn as_quote_provider(&self) -> Option<&dyn QuoteProvider> {
321 None
322 }
323
324 fn as_earnings_provider(&self) -> Option<&dyn EarningsProvider> {
326 None
327 }
328 fn as_income_statement_provider(&self) -> Option<&dyn IncomeStatementProvider> {
330 None
331 }
332 fn as_balance_sheet_provider(&self) -> Option<&dyn BalanceSheetProvider> {
334 None
335 }
336 fn as_cashflow_provider(&self) -> Option<&dyn CashflowProvider> {
338 None
339 }
340 fn as_calendar_provider(&self) -> Option<&dyn CalendarProvider> {
342 None
343 }
344
345 fn as_recommendations_provider(&self) -> Option<&dyn RecommendationsProvider> {
347 None
348 }
349 fn as_recommendations_summary_provider(&self) -> Option<&dyn RecommendationsSummaryProvider> {
351 None
352 }
353 fn as_upgrades_downgrades_provider(&self) -> Option<&dyn UpgradesDowngradesProvider> {
355 None
356 }
357 fn as_analyst_price_target_provider(&self) -> Option<&dyn AnalystPriceTargetProvider> {
359 None
360 }
361
362 fn as_major_holders_provider(&self) -> Option<&dyn MajorHoldersProvider> {
364 None
365 }
366 fn as_institutional_holders_provider(&self) -> Option<&dyn InstitutionalHoldersProvider> {
368 None
369 }
370 fn as_mutual_fund_holders_provider(&self) -> Option<&dyn MutualFundHoldersProvider> {
372 None
373 }
374 fn as_insider_transactions_provider(&self) -> Option<&dyn InsiderTransactionsProvider> {
376 None
377 }
378 fn as_insider_roster_holders_provider(&self) -> Option<&dyn InsiderRosterHoldersProvider> {
380 None
381 }
382 fn as_net_share_purchase_activity_provider(
384 &self,
385 ) -> Option<&dyn NetSharePurchaseActivityProvider> {
386 None
387 }
388
389 fn as_profile_provider(&self) -> Option<&dyn ProfileProvider> {
391 None
392 }
393 fn as_isin_provider(&self) -> Option<&dyn IsinProvider> {
395 None
396 }
397 fn as_search_provider(&self) -> Option<&dyn SearchProvider> {
399 None
400 }
401 fn as_esg_provider(&self) -> Option<&dyn EsgProvider> {
403 None
404 }
405 fn as_news_provider(&self) -> Option<&dyn NewsProvider> {
407 None
408 }
409
410 fn as_options_expirations_provider(&self) -> Option<&dyn OptionsExpirationsProvider> {
412 None
413 }
414 fn as_option_chain_provider(&self) -> Option<&dyn OptionChainProvider> {
416 None
417 }
418
419 fn as_stream_provider(&self) -> Option<&dyn StreamProvider> {
421 None
422 }
423}