btgsolutions-dataservices-python-client 4.0.0__tar.gz → 4.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. {btgsolutions_dataservices_python_client-4.0.0/btgsolutions_dataservices_python_client.egg-info → btgsolutions_dataservices_python_client-4.1.1}/PKG-INFO +15 -7
  2. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/README.md +15 -7
  3. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/__init__.py +1 -1
  4. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/alternative_data_companies.py +73 -7
  5. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/alternative_data_funds.py +71 -19
  6. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/alternative_data_macro_markets.py +3 -3
  7. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/alternative_data_metadata.py +91 -7
  8. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/alternative_data_ownership.py +34 -3
  9. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/alternative_data_people.py +3 -3
  10. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/public_sources.py +11 -8
  11. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1/btgsolutions_dataservices_python_client.egg-info}/PKG-INFO +15 -7
  12. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/LICENSE +0 -0
  13. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/MANIFEST.in +0 -0
  14. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/config.py +0 -0
  15. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/exceptions.py +0 -0
  16. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/__init__.py +0 -0
  17. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/authenticator.py +0 -0
  18. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/book_scope.py +0 -0
  19. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/broker_analytics.py +0 -0
  20. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/broker_reference.py +0 -0
  21. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/bulk_data.py +0 -0
  22. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/company_data.py +0 -0
  23. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/corporate_events.py +0 -0
  24. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/hfn.py +0 -0
  25. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/historical_candles.py +0 -0
  26. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/historical_candles_crypto.py +0 -0
  27. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/intraday_candles.py +0 -0
  28. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/intraday_tick_data.py +0 -0
  29. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/quotes.py +0 -0
  30. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/reference_data.py +0 -0
  31. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/stock_loan.py +0 -0
  32. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/ticker_last_event.py +0 -0
  33. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/rest/ticker_last_event_polling.py +0 -0
  34. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/websocket/__init__.py +0 -0
  35. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/websocket/broker_analytics.py +0 -0
  36. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/websocket/hfn_websocket_client.py +0 -0
  37. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/websocket/market_data_feed.py +0 -0
  38. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/websocket/market_data_websocket_client.py +0 -0
  39. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices/websocket/websocket_default_functions.py +0 -0
  40. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices_python_client.egg-info/SOURCES.txt +0 -0
  41. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices_python_client.egg-info/dependency_links.txt +0 -0
  42. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices_python_client.egg-info/requires.txt +0 -0
  43. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/btgsolutions_dataservices_python_client.egg-info/top_level.txt +0 -0
  44. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/pyproject.toml +0 -0
  45. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/requirements.txt +0 -0
  46. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/setup.cfg +0 -0
  47. {btgsolutions_dataservices_python_client-4.0.0 → btgsolutions_dataservices_python_client-4.1.1}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: btgsolutions_dataservices_python_client
3
- Version: 4.0.0
3
+ Version: 4.1.1
4
4
  Summary: Python package containing several classes and data for extracting and manipulating market and trading data.
5
5
  Home-page: https://github.com/BTG-Pactual-Solutions/btgsolutions-dataservices-python-client
6
6
  Author: BTG Solutions Data Services powered by BTG Pactual Solutions
@@ -527,6 +527,8 @@ company_data.all_financial_tables(ticker='PETR4')
527
527
  import btgsolutions_dataservices as btg
528
528
  meta = btg.AlternativeDataMetadata(api_key='YOUR_API_KEY')
529
529
  meta.get_company_directory(query='PETROBRAS', jurisdiction='BR')
530
+ meta.list_companies(query='PETROBRAS', jurisdiction='BR')
531
+ meta.list_etfs(query='BOVA')
530
532
  meta.get_company_sector(identifier='PETR4')
531
533
  meta.get_taxonomy(system='b3')
532
534
  meta.get_cnae(code='6422100')
@@ -543,6 +545,7 @@ meta.get_available_indicators()
543
545
  ```python
544
546
  import btgsolutions_dataservices as btg
545
547
  companies = btg.AlternativeDataCompanies(api_key='YOUR_API_KEY')
548
+ companies.list_companies(query='PETROBRAS', jurisdiction='BR')
546
549
  companies.get_board(company_id='VALE3', body='board')
547
550
  companies.get_governance_summary(company_id='ITUB4')
548
551
  companies.get_governance_history(company_id='PETR4', start_date='2023-01-01', end_date='2024-12-31')
@@ -554,8 +557,9 @@ companies.get_corporate_registry(company_id='PETR4', direction='partners')
554
557
  companies.get_corporate_registry(company_id='PETR4', direction='investees')
555
558
  companies.get_insider_trades(company_id='AAPL', start_date='2024-01-01', end_date='2024-12-31')
556
559
  companies.get_board_changes(company_id='VALE3', event='appointed')
557
- companies.get_financial_statements(company_id='PETR4', statement='income_statement', quarter='Q42024')
558
- companies.get_financial_notes(company_id='VALE3', quarter='Q42024')
560
+ companies.get_assemblies(company_id='PINE4')
561
+ companies.get_financial_statements(company_id='PETR4', statement='income_statement', quarter='4T24')
562
+ companies.get_financial_notes(company_id='VALE3', quarter='4T24')
559
563
  companies.get_disclosures(company_id='PETR4', document_type='repurchase')
560
564
  companies.get_disclosures(company_id='PETR4', document_type='insider')
561
565
  ```
@@ -574,10 +578,11 @@ people.get_appointments(person_id='slug:Jean Paul Lemann', group_by='company')
574
578
  ```python
575
579
  import btgsolutions_dataservices as btg
576
580
  funds = btg.AlternativeDataFunds(api_key='YOUR_API_KEY')
577
- funds.get_holdings(fund_id='73.232.530/0001-46', reference_date='2024-12-31')
578
- funds.get_exposures(fund_id='73.232.530/0001-46', exposure_type='asset_class')
579
- funds.get_history(fund_id='73.232.530/0001-46', start_date='2024-01-01', end_date='2024-12-31')
580
- funds.get_lookthrough(fund_id='73.232.530/0001-46')
581
+ funds.list_etfs(query='BOVA')
582
+ funds.get_holdings(fund_id='BOVA11', reference_date='2024-12-31')
583
+ funds.get_exposures(fund_id='BOVA11', exposure_type='asset_class')
584
+ funds.get_history(fund_id='BOVA11', start_date='2024-01-01', end_date='2024-12-31')
585
+ funds.get_lookthrough(fund_id='BOVA11')
581
586
  funds.get_manager_aggregate_holdings(manager_id='ITAÚ ASSET MANAGEMENT')
582
587
  ```
583
588
 
@@ -591,6 +596,7 @@ ownership.get_ownership_current(company_id='ITUB4')
591
596
  ownership.get_ownership_history(company_id='PETR4', start_date='2023-01-01', end_date='2024-12-31')
592
597
  ownership.get_ownership_change_events(company_id='VALE3', start_date='2024-01-01', end_date='2024-12-31')
593
598
  ownership.get_ownership_official_notices(company_id='PETR4')
599
+ ownership.get_notice_summary(url='https://www.rad.cvm.gov.br/ENETWEB/frmGerenciaPastaDeArquivos.aspx?numProtocolo=1234567')
594
600
  ownership.get_ownership_control_group(company_id='VALE3')
595
601
  ownership.get_ownership_free_float(company_id='PETR4')
596
602
  ownership.get_shareholder_holdings(shareholder_id='00.000.000/0001-91')
@@ -613,6 +619,8 @@ macro.get_dpmfi(start_date='2024-01', end_date='2024-12', status='dados_oficiais
613
619
  macro.get_dpmfi_composition(bond_type='IPCA')
614
620
  ```
615
621
 
622
+ `AlternativeDataMacroMarkets` exposes the public-sources market-data endpoint for B3 maximum theoretical margin. The direct market-data `investor-categories` endpoint is intentionally not exposed in this package.
623
+
616
624
  ### Reference Data
617
625
 
618
626
  #### Corporate Events
@@ -504,6 +504,8 @@ company_data.all_financial_tables(ticker='PETR4')
504
504
  import btgsolutions_dataservices as btg
505
505
  meta = btg.AlternativeDataMetadata(api_key='YOUR_API_KEY')
506
506
  meta.get_company_directory(query='PETROBRAS', jurisdiction='BR')
507
+ meta.list_companies(query='PETROBRAS', jurisdiction='BR')
508
+ meta.list_etfs(query='BOVA')
507
509
  meta.get_company_sector(identifier='PETR4')
508
510
  meta.get_taxonomy(system='b3')
509
511
  meta.get_cnae(code='6422100')
@@ -520,6 +522,7 @@ meta.get_available_indicators()
520
522
  ```python
521
523
  import btgsolutions_dataservices as btg
522
524
  companies = btg.AlternativeDataCompanies(api_key='YOUR_API_KEY')
525
+ companies.list_companies(query='PETROBRAS', jurisdiction='BR')
523
526
  companies.get_board(company_id='VALE3', body='board')
524
527
  companies.get_governance_summary(company_id='ITUB4')
525
528
  companies.get_governance_history(company_id='PETR4', start_date='2023-01-01', end_date='2024-12-31')
@@ -531,8 +534,9 @@ companies.get_corporate_registry(company_id='PETR4', direction='partners')
531
534
  companies.get_corporate_registry(company_id='PETR4', direction='investees')
532
535
  companies.get_insider_trades(company_id='AAPL', start_date='2024-01-01', end_date='2024-12-31')
533
536
  companies.get_board_changes(company_id='VALE3', event='appointed')
534
- companies.get_financial_statements(company_id='PETR4', statement='income_statement', quarter='Q42024')
535
- companies.get_financial_notes(company_id='VALE3', quarter='Q42024')
537
+ companies.get_assemblies(company_id='PINE4')
538
+ companies.get_financial_statements(company_id='PETR4', statement='income_statement', quarter='4T24')
539
+ companies.get_financial_notes(company_id='VALE3', quarter='4T24')
536
540
  companies.get_disclosures(company_id='PETR4', document_type='repurchase')
537
541
  companies.get_disclosures(company_id='PETR4', document_type='insider')
538
542
  ```
@@ -550,11 +554,12 @@ people.get_appointments(person_id='slug:Jean Paul Lemann', group_by='company')
550
554
 
551
555
  ```python
552
556
  import btgsolutions_dataservices as btg
553
- funds = btg.AlternativeDataFunds(api_key='YOUR_API_KEY')
554
- funds.get_holdings(fund_id='73.232.530/0001-46', reference_date='2024-12-31')
555
- funds.get_exposures(fund_id='73.232.530/0001-46', exposure_type='asset_class')
556
- funds.get_history(fund_id='73.232.530/0001-46', start_date='2024-01-01', end_date='2024-12-31')
557
- funds.get_lookthrough(fund_id='73.232.530/0001-46')
557
+ funds = btg.AlternativeDataFunds(api_key='YOUR_API_KEY')
558
+ funds.list_etfs(query='BOVA')
559
+ funds.get_holdings(fund_id='BOVA11', reference_date='2024-12-31')
560
+ funds.get_exposures(fund_id='BOVA11', exposure_type='asset_class')
561
+ funds.get_history(fund_id='BOVA11', start_date='2024-01-01', end_date='2024-12-31')
562
+ funds.get_lookthrough(fund_id='BOVA11')
558
563
  funds.get_manager_aggregate_holdings(manager_id='ITAÚ ASSET MANAGEMENT')
559
564
  ```
560
565
 
@@ -568,6 +573,7 @@ ownership.get_ownership_current(company_id='ITUB4')
568
573
  ownership.get_ownership_history(company_id='PETR4', start_date='2023-01-01', end_date='2024-12-31')
569
574
  ownership.get_ownership_change_events(company_id='VALE3', start_date='2024-01-01', end_date='2024-12-31')
570
575
  ownership.get_ownership_official_notices(company_id='PETR4')
576
+ ownership.get_notice_summary(url='https://www.rad.cvm.gov.br/ENETWEB/frmGerenciaPastaDeArquivos.aspx?numProtocolo=1234567')
571
577
  ownership.get_ownership_control_group(company_id='VALE3')
572
578
  ownership.get_ownership_free_float(company_id='PETR4')
573
579
  ownership.get_shareholder_holdings(shareholder_id='00.000.000/0001-91')
@@ -590,6 +596,8 @@ macro.get_dpmfi(start_date='2024-01', end_date='2024-12', status='dados_oficiais
590
596
  macro.get_dpmfi_composition(bond_type='IPCA')
591
597
  ```
592
598
 
599
+ `AlternativeDataMacroMarkets` exposes the public-sources market-data endpoint for B3 maximum theoretical margin. The direct market-data `investor-categories` endpoint is intentionally not exposed in this package.
600
+
593
601
  ### Reference Data
594
602
 
595
603
  #### Corporate Events
@@ -1,4 +1,4 @@
1
- __version__ = "4.0.0"
1
+ __version__ = "4.1.1"
2
2
 
3
3
  from .websocket import *
4
4
  from .rest import *
@@ -14,6 +14,7 @@ class AlternativeDataCompanies:
14
14
 
15
15
  >>> from btgsolutions_dataservices import AlternativeDataCompanies
16
16
  >>> companies = AlternativeDataCompanies(api_key='YOUR_API_KEY')
17
+ >>> companies.list_companies(query='PETROBRAS', jurisdiction='BR')
17
18
  >>> companies.get_board(company_id='PETR4')
18
19
  >>> companies.get_governance_summary(company_id='VALE3')
19
20
  >>> companies.get_financial_statements(company_id='ITUB4')
@@ -28,13 +29,13 @@ class AlternativeDataCompanies:
28
29
 
29
30
  def __init__(self, api_key: str):
30
31
  self.api_key = api_key
31
- self.token = Authenticator(self.api_key).token
32
- self.headers = {"authorization": f"Bearer {self.token}"}
32
+ self.__authenticator = Authenticator(self.api_key)
33
33
 
34
34
  def _get(self, path: str, params: dict) -> dict:
35
35
  url = f"{url_api_v1}/public-sources/{path}"
36
36
  params = {k: v for k, v in params.items() if v is not None and v != ""}
37
- response = requests.get(url, params=params, headers=self.headers, timeout=30)
37
+ headers = {"authorization": f"Bearer {self.__authenticator.token}"}
38
+ response = requests.get(url, params=params, headers=headers, timeout=30)
38
39
  if response.status_code != 200:
39
40
  self._raise_error(response)
40
41
  return response.json()
@@ -48,6 +49,38 @@ class AlternativeDataCompanies:
48
49
  detail = response.text
49
50
  raise BadResponse(f"Error {response.status_code}: {detail}")
50
51
 
52
+ def list_companies(
53
+ self,
54
+ query: Optional[str] = None,
55
+ jurisdiction: Optional[str] = None,
56
+ limit: int = 50,
57
+ offset: int = 0,
58
+ ) -> dict:
59
+ """
60
+ List or search companies available in the public-sources company directory.
61
+
62
+ Parameters
63
+ ----------------
64
+ query: str
65
+ Free-text search over company name, ticker, CNPJ, or CIK.
66
+ Field is not required. Example: 'PETROBRAS'.
67
+ jurisdiction: str
68
+ Filter by jurisdiction: 'BR' or 'US'.
69
+ Field is not required.
70
+ limit: int
71
+ Maximum number of results to return.
72
+ Field is not required. Default: 50.
73
+ offset: int
74
+ Number of results to skip for pagination.
75
+ Field is not required. Default: 0.
76
+ """
77
+ return self._get("companies/list", {
78
+ "query": query,
79
+ "jurisdiction": jurisdiction,
80
+ "limit": limit,
81
+ "offset": offset,
82
+ })
83
+
51
84
  def get_board(
52
85
  self,
53
86
  company_id: str,
@@ -439,7 +472,7 @@ class AlternativeDataCompanies:
439
472
  Statement type (e.g. 'income_statement', 'balance_sheet', 'cash_flow').
440
473
  Field is not required. Default: 'income_statement'.
441
474
  quarter: str
442
- Quarter filter in QTyy format (e.g. 'Q12024').
475
+ Brazilian quarter code filter (e.g. '1T24' or '4T24').
443
476
  Field is not required.
444
477
  reference_date: str
445
478
  Reference date in YYYY-MM-DD format.
@@ -486,7 +519,7 @@ class AlternativeDataCompanies:
486
519
  Company identifier (CNPJ, CVM code, or B3 ticker).
487
520
  Field is required. Example: 'VALE3'.
488
521
  quarter: str
489
- Quarter filter in QTyy format (e.g. 'Q42024').
522
+ Brazilian quarter code filter (e.g. '1T24' or '4T24').
490
523
  Field is not required.
491
524
  limit: int
492
525
  Maximum number of results to return.
@@ -527,8 +560,9 @@ class AlternativeDataCompanies:
527
560
  Company identifier.
528
561
  Field is not required. Example: 'PETR4'.
529
562
  document_type: str
530
- Document type: 'repurchase' (buyback programs) or 'insider'
531
- (insider trading notifications).
563
+ Document type: 'repurchase' (buyback programs) or 'insiders'
564
+ (Brazilian insider trading notifications). The 'insider' alias is
565
+ also accepted upstream.
532
566
  Field is not required. Default: 'repurchase'.
533
567
  asset: str
534
568
  Ticker asset filter.
@@ -575,3 +609,35 @@ class AlternativeDataCompanies:
575
609
  "limit": limit,
576
610
  "offset": offset,
577
611
  })
612
+
613
+ def get_assemblies(
614
+ self,
615
+ company_id: str,
616
+ start_date: Optional[str] = None,
617
+ end_date: Optional[str] = None,
618
+ limit: int = 50,
619
+ ) -> dict:
620
+ """
621
+ Shareholder assembly index (AGO/AGE) for a Brazilian company.
622
+
623
+ Parameters
624
+ ----------------
625
+ company_id: str
626
+ Company identifier (ticker, CNPJ or company name).
627
+ Field is required. Example: 'PINE4'.
628
+ start_date: str
629
+ Start date in YYYY-MM-DD format.
630
+ Field is not required.
631
+ end_date: str
632
+ End date in YYYY-MM-DD format.
633
+ Field is not required.
634
+ limit: int
635
+ Maximum number of results to return.
636
+ Field is not required. Default: 50.
637
+ """
638
+ return self._get("companies/assemblies", {
639
+ "company_id": company_id,
640
+ "start_date": start_date,
641
+ "end_date": end_date,
642
+ "limit": limit,
643
+ })
@@ -14,9 +14,10 @@ class AlternativeDataFunds:
14
14
 
15
15
  >>> from btgsolutions_dataservices import AlternativeDataFunds
16
16
  >>> funds = AlternativeDataFunds(api_key='YOUR_API_KEY')
17
- >>> funds.get_holdings(fund_id='73.232.530/0001-46')
18
- >>> funds.get_exposures(fund_id='73.232.530/0001-46')
19
- >>> funds.get_history(fund_id='73.232.530/0001-46')
17
+ >>> funds.list_etfs()
18
+ >>> funds.get_holdings(fund_id='BOVA11')
19
+ >>> funds.get_exposures(fund_id='BOVA11')
20
+ >>> funds.get_history(fund_id='BOVA11')
20
21
 
21
22
  Parameters
22
23
  ----------------
@@ -27,13 +28,13 @@ class AlternativeDataFunds:
27
28
 
28
29
  def __init__(self, api_key: str):
29
30
  self.api_key = api_key
30
- self.token = Authenticator(self.api_key).token
31
- self.headers = {"authorization": f"Bearer {self.token}"}
31
+ self.__authenticator = Authenticator(self.api_key)
32
32
 
33
33
  def _get(self, path: str, params: dict) -> dict:
34
34
  url = f"{url_api_v1}/public-sources/{path}"
35
35
  params = {k: v for k, v in params.items() if v is not None and v != ""}
36
- response = requests.get(url, params=params, headers=self.headers, timeout=30)
36
+ headers = {"authorization": f"Bearer {self.__authenticator.token}"}
37
+ response = requests.get(url, params=params, headers=headers, timeout=30)
37
38
  if response.status_code != 200:
38
39
  self._raise_error(response)
39
40
  return response.json()
@@ -47,6 +48,55 @@ class AlternativeDataFunds:
47
48
  detail = response.text
48
49
  raise BadResponse(f"Error {response.status_code}: {detail}")
49
50
 
51
+ def list_etfs(
52
+ self,
53
+ query: Optional[str] = None,
54
+ issuer: Optional[str] = None,
55
+ source: str = "official",
56
+ sort_by: str = "name",
57
+ min_positions: int = 1,
58
+ limit: int = 100,
59
+ offset: int = 0,
60
+ ) -> dict:
61
+ """
62
+ List ETFs available in the public-sources ETF registry.
63
+
64
+ Parameters
65
+ ----------------
66
+ query: str
67
+ Free-text filter over ticker, fund name, CNPJ, or issuer.
68
+ Field is not required. Example: 'BOVA'.
69
+ issuer: str
70
+ Issuer key/name filter (e.g. 'blackrock', 'btg_pactual').
71
+ Field is not required.
72
+ source: str
73
+ Holdings source used to compute reference_date, positions_count and
74
+ total_value: 'official', 'approximate', or 'index'.
75
+ Field is not required. Default: 'official'.
76
+ sort_by: str
77
+ Sort mode: 'name', 'ticker', 'positions_count_desc',
78
+ 'total_value_desc', or 'total_value_asc'.
79
+ Field is not required. Default: 'name'.
80
+ min_positions: int
81
+ Minimum number of positions required for an ETF to be returned.
82
+ Field is not required. Default: 1.
83
+ limit: int
84
+ Maximum number of ETFs to return.
85
+ Field is not required. Default: 100.
86
+ offset: int
87
+ Number of results to skip for pagination.
88
+ Field is not required. Default: 0.
89
+ """
90
+ return self._get("funds/etfs", {
91
+ "query": query,
92
+ "issuer": issuer,
93
+ "source": source,
94
+ "sort_by": sort_by,
95
+ "min_positions": min_positions,
96
+ "limit": limit,
97
+ "offset": offset,
98
+ })
99
+
50
100
  def get_holdings(
51
101
  self,
52
102
  fund_id: str,
@@ -62,7 +112,8 @@ class AlternativeDataFunds:
62
112
  Parameters
63
113
  ----------------
64
114
  fund_id: str
65
- Fund identifier. Accepts CNPJ (BR funds/ETFs) or US fund identifier.
115
+ Fund identifier. Accepts a CNPJ, a BR ETF ticker such as 'BOVA11',
116
+ or a US fund identifier.
66
117
  Field is required. Example: '73.232.530/0001-46'.
67
118
  reference_date: str
68
119
  Reference date in YYYY-MM-DD format. Defaults to the most recent snapshot.
@@ -96,14 +147,14 @@ class AlternativeDataFunds:
96
147
  exposure_type: str = "all",
97
148
  ) -> dict:
98
149
  """
99
- Portfolio exposures for a Brazilian CVM fund (asset class, issuer,
100
- sector, indexer, maturity, country).
150
+ Portfolio exposures for a Brazilian CVM fund or ETF (asset class,
151
+ issuer, sector, indexer, maturity, country).
101
152
 
102
153
  Parameters
103
154
  ----------------
104
155
  fund_id: str
105
- Fund CNPJ.
106
- Field is required. Example: '73.232.530/0001-46'.
156
+ Fund CNPJ or BR ETF ticker.
157
+ Field is required. Example: 'BOVA11'.
107
158
  reference_date: str
108
159
  Reference date in YYYY-MM-DD format. Defaults to the most recent snapshot.
109
160
  Field is not required.
@@ -126,14 +177,15 @@ class AlternativeDataFunds:
126
177
  limit: int = 12,
127
178
  ) -> dict:
128
179
  """
129
- Holdings history time-series for a Brazilian CVM fund (snapshot metadata
130
- per reference date: positions count, total value, NAV).
180
+ History time-series for a Brazilian CVM fund or ETF. Mutual funds
181
+ return NAV/quota fields; ETFs return portfolio total_value and
182
+ positions_count.
131
183
 
132
184
  Parameters
133
185
  ----------------
134
186
  fund_id: str
135
- Fund CNPJ.
136
- Field is required. Example: '73.232.530/0001-46'.
187
+ Fund CNPJ or BR ETF ticker.
188
+ Field is required. Example: 'BOVA11'.
137
189
  start_date: str
138
190
  Start date in YYYY-MM-DD format.
139
191
  Field is not required.
@@ -158,14 +210,14 @@ class AlternativeDataFunds:
158
210
  limit: int = 100,
159
211
  ) -> dict:
160
212
  """
161
- Look-through resolution for a fund-of-funds (resolves nested fund
162
- positions to underlying assets).
213
+ Look-through resolution for a fund or ETF (resolves nested fund
214
+ positions to underlying assets when available).
163
215
 
164
216
  Parameters
165
217
  ----------------
166
218
  fund_id: str
167
- Fund CNPJ.
168
- Field is required.
219
+ Fund CNPJ or BR ETF ticker.
220
+ Field is required. Example: 'BOVA11'.
169
221
  reference_date: str
170
222
  Reference date in YYYY-MM-DD format. Defaults to the most recent snapshot.
171
223
  Field is not required.
@@ -28,13 +28,13 @@ class AlternativeDataMacroMarkets:
28
28
 
29
29
  def __init__(self, api_key: str):
30
30
  self.api_key = api_key
31
- self.token = Authenticator(self.api_key).token
32
- self.headers = {"authorization": f"Bearer {self.token}"}
31
+ self.__authenticator = Authenticator(self.api_key)
33
32
 
34
33
  def _get(self, path: str, params: dict) -> dict:
35
34
  url = f"{url_api_v1}/public-sources/{path}"
36
35
  params = {k: v for k, v in params.items() if v is not None and v != ""}
37
- response = requests.get(url, params=params, headers=self.headers, timeout=30)
36
+ headers = {"authorization": f"Bearer {self.__authenticator.token}"}
37
+ response = requests.get(url, params=params, headers=headers, timeout=30)
38
38
  if response.status_code != 200:
39
39
  self._raise_error(response)
40
40
  return response.json()
@@ -15,6 +15,8 @@ class AlternativeDataMetadata:
15
15
 
16
16
  >>> from btgsolutions_dataservices import AlternativeDataMetadata
17
17
  >>> meta = AlternativeDataMetadata(api_key='YOUR_API_KEY')
18
+ >>> meta.list_companies(query='PETROBRAS')
19
+ >>> meta.list_etfs(query='BOVA')
18
20
  >>> meta.get_company_directory(query='PETROBRAS')
19
21
  >>> meta.get_taxonomy(system='b3')
20
22
  >>> meta.get_company_sector(identifier='PETR4')
@@ -28,13 +30,13 @@ class AlternativeDataMetadata:
28
30
 
29
31
  def __init__(self, api_key: str):
30
32
  self.api_key = api_key
31
- self.token = Authenticator(self.api_key).token
32
- self.headers = {"authorization": f"Bearer {self.token}"}
33
+ self.__authenticator = Authenticator(self.api_key)
33
34
 
34
35
  def _get(self, path: str, params: dict) -> dict:
35
36
  url = f"{url_api_v1}/public-sources/{path}"
36
37
  params = {k: v for k, v in params.items() if v is not None and v != ""}
37
- response = requests.get(url, params=params, headers=self.headers, timeout=30)
38
+ headers = {"authorization": f"Bearer {self.__authenticator.token}"}
39
+ response = requests.get(url, params=params, headers=headers, timeout=30)
38
40
  if response.status_code != 200:
39
41
  self._raise_error(response)
40
42
  return response.json()
@@ -50,8 +52,8 @@ class AlternativeDataMetadata:
50
52
 
51
53
  def get_datasets(self) -> dict:
52
54
  """
53
- List the public-source market-data datasets available for discovery
54
- (maximum_theoretical_margin, investor_categories).
55
+ List public-source datasets available for discovery. The direct
56
+ market-data investor-categories endpoint is not exposed by this package.
55
57
  """
56
58
  return self._get("datasets", {})
57
59
 
@@ -71,8 +73,9 @@ class AlternativeDataMetadata:
71
73
  Reference date in YYYY-MM-DD format. Defaults to the latest available day.
72
74
  Field is not required.
73
75
  dataset: str
74
- Dataset to scope the listing: 'maximum_theoretical_margin',
75
- 'investor_categories', or 'all' (default).
76
+ Dataset to scope the listing: 'maximum_theoretical_margin' or
77
+ 'all' (default). The direct investor-categories endpoint is not
78
+ exposed by this package.
76
79
  Field is not required. Default: 'all'.
77
80
  prefix: str
78
81
  Ticker/code prefix filter (e.g. 'PETR' to list only PETR3, PETR4, ...).
@@ -127,6 +130,87 @@ class AlternativeDataMetadata:
127
130
  "offset": offset,
128
131
  })
129
132
 
133
+ def list_companies(
134
+ self,
135
+ query: Optional[str] = None,
136
+ jurisdiction: Optional[str] = None,
137
+ limit: int = 50,
138
+ offset: int = 0,
139
+ ) -> dict:
140
+ """
141
+ List or search companies available in the public-sources company directory.
142
+
143
+ Parameters
144
+ ----------------
145
+ query: str
146
+ Free-text search over company name, ticker, CNPJ, or CIK.
147
+ Field is not required. Example: 'PETROBRAS'.
148
+ jurisdiction: str
149
+ Filter by jurisdiction: 'BR' or 'US'.
150
+ Field is not required.
151
+ limit: int
152
+ Maximum number of results to return.
153
+ Field is not required. Default: 50.
154
+ offset: int
155
+ Number of results to skip for pagination.
156
+ Field is not required. Default: 0.
157
+ """
158
+ return self._get("companies/list", {
159
+ "query": query,
160
+ "jurisdiction": jurisdiction,
161
+ "limit": limit,
162
+ "offset": offset,
163
+ })
164
+
165
+ def list_etfs(
166
+ self,
167
+ query: Optional[str] = None,
168
+ issuer: Optional[str] = None,
169
+ source: str = "official",
170
+ sort_by: str = "name",
171
+ min_positions: int = 1,
172
+ limit: int = 100,
173
+ offset: int = 0,
174
+ ) -> dict:
175
+ """
176
+ List ETFs available in the public-sources ETF registry.
177
+
178
+ Parameters
179
+ ----------------
180
+ query: str
181
+ Free-text filter over ticker, fund name, CNPJ, or issuer.
182
+ Field is not required. Example: 'BOVA'.
183
+ issuer: str
184
+ Issuer key/name filter (e.g. 'blackrock', 'btg_pactual').
185
+ Field is not required.
186
+ source: str
187
+ Holdings source used to compute reference_date, positions_count and
188
+ total_value: 'official', 'approximate', or 'index'.
189
+ Field is not required. Default: 'official'.
190
+ sort_by: str
191
+ Sort mode: 'name', 'ticker', 'positions_count_desc',
192
+ 'total_value_desc', or 'total_value_asc'.
193
+ Field is not required. Default: 'name'.
194
+ min_positions: int
195
+ Minimum number of positions required for an ETF to be returned.
196
+ Field is not required. Default: 1.
197
+ limit: int
198
+ Maximum number of ETFs to return.
199
+ Field is not required. Default: 100.
200
+ offset: int
201
+ Number of results to skip for pagination.
202
+ Field is not required. Default: 0.
203
+ """
204
+ return self._get("funds/etfs", {
205
+ "query": query,
206
+ "issuer": issuer,
207
+ "source": source,
208
+ "sort_by": sort_by,
209
+ "min_positions": min_positions,
210
+ "limit": limit,
211
+ "offset": offset,
212
+ })
213
+
130
214
  def get_financial_statement_types(self) -> dict:
131
215
  """
132
216
  List the available financial statement types (e.g. income_statement,
@@ -28,13 +28,13 @@ class AlternativeDataOwnership:
28
28
 
29
29
  def __init__(self, api_key: str):
30
30
  self.api_key = api_key
31
- self.token = Authenticator(self.api_key).token
32
- self.headers = {"authorization": f"Bearer {self.token}"}
31
+ self.__authenticator = Authenticator(self.api_key)
33
32
 
34
33
  def _get(self, path: str, params: dict) -> dict:
35
34
  url = f"{url_api_v1}/public-sources/{path}"
36
35
  params = {k: v for k, v in params.items() if v is not None and v != ""}
37
- response = requests.get(url, params=params, headers=self.headers, timeout=30)
36
+ headers = {"authorization": f"Bearer {self.__authenticator.token}"}
37
+ response = requests.get(url, params=params, headers=headers, timeout=30)
38
38
  if response.status_code != 200:
39
39
  self._raise_error(response)
40
40
  return response.json()
@@ -203,6 +203,37 @@ class AlternativeDataOwnership:
203
203
  "limit": limit,
204
204
  })
205
205
 
206
+ def get_notice_summary(
207
+ self,
208
+ url: str,
209
+ lang: str = "pt",
210
+ timeout: int = 120,
211
+ ) -> dict:
212
+ """
213
+ AI-generated summary for a CVM RAD PDF document.
214
+
215
+ Parameters
216
+ ----------------
217
+ url: str
218
+ CVM RAD download URL for the PDF to summarize.
219
+ Field is required.
220
+ lang: str
221
+ Summary language: 'pt', 'en', or 'es'.
222
+ Field is not required. Default: 'pt'.
223
+ timeout: int
224
+ Request timeout in seconds. AI summaries can take longer than
225
+ standard data endpoints when a new summary is generated.
226
+ Field is not required. Default: 120.
227
+ """
228
+ endpoint = f"{url_api_v1}/public-sources/companies/notices/summary"
229
+ params = {"url": url, "lang": lang}
230
+ params = {k: v for k, v in params.items() if v is not None and v != ""}
231
+ headers = {"authorization": f"Bearer {self.__authenticator.token}"}
232
+ response = requests.get(endpoint, params=params, headers=headers, timeout=timeout)
233
+ if response.status_code != 200:
234
+ self._raise_error(response)
235
+ return response.json()
236
+
206
237
  def get_ownership_control_group(self, company_id: str) -> dict:
207
238
  """
208
239
  Control group composition for a Brazilian company (CVM FRE).
@@ -25,13 +25,13 @@ class AlternativeDataPeople:
25
25
 
26
26
  def __init__(self, api_key: str):
27
27
  self.api_key = api_key
28
- self.token = Authenticator(self.api_key).token
29
- self.headers = {"authorization": f"Bearer {self.token}"}
28
+ self.__authenticator = Authenticator(self.api_key)
30
29
 
31
30
  def _get(self, path: str, params: dict) -> dict:
32
31
  url = f"{url_api_v1}/public-sources/{path}"
33
32
  params = {k: v for k, v in params.items() if v is not None and v != ""}
34
- response = requests.get(url, params=params, headers=self.headers, timeout=30)
33
+ headers = {"authorization": f"Bearer {self.__authenticator.token}"}
34
+ response = requests.get(url, params=params, headers=headers, timeout=30)
35
35
  if response.status_code != 200:
36
36
  self._raise_error(response)
37
37
  return response.json()
@@ -32,10 +32,13 @@ class PublicSources:
32
32
  api_key:str
33
33
  ):
34
34
  self.api_key = api_key
35
- self.token = Authenticator(self.api_key).token
36
- self.headers = {"authorization": f"Bearer {self.token}"}
35
+ self.__authenticator = Authenticator(self.api_key)
37
36
 
38
- def get_opas(self, start_date:str, end_date:str, asset:Optional[str]=None, type:Optional[str]=None, raw_data:bool=False):
37
+ @property
38
+ def _headers(self) -> dict:
39
+ return {"authorization": f"Bearer {self.__authenticator.token}"}
40
+
41
+ def get_opas(self, start_date:str, end_date:str, asset:Optional[str]=None, type:Optional[str]=None, raw_data:bool=False):
39
42
 
40
43
  """
41
44
  This method uses OPAs filtered by a range of dates (registration_date), asset or type.
@@ -59,9 +62,9 @@ class PublicSources:
59
62
  Field is not required. Default: False.
60
63
  """
61
64
 
62
- url = f"{url_api_v1}/public-sources/opas?start_date={start_date}&end_date={end_date}" + (f"&asset={asset}" if asset else "") + (f"&type={type}" if type else "")
65
+ url = f"{url_api_v1}/public-sources/opas?start_date={start_date}&end_date={end_date}" + (f"&asset={asset}" if asset else "") + (f"&type={type}" if type else "")
63
66
 
64
- response = requests.request("GET", url, headers=self.headers)
67
+ response = requests.request("GET", url, headers=self._headers)
65
68
  if response.status_code == 200:
66
69
  if raw_data:
67
70
  return response.json()
@@ -71,7 +74,7 @@ class PublicSources:
71
74
  response = json.loads(response.text)
72
75
  raise BadResponse(f'Error: {response.get("error", "")}')
73
76
 
74
- def get_share_repurchase(self, start_date:str, end_date:str, asset:Optional[str]=None, raw_data:bool=False):
77
+ def get_share_repurchase(self, start_date:str, end_date:str, asset:Optional[str]=None, raw_data:bool=False):
75
78
 
76
79
  """
77
80
  This method returns a list of share repurchase transactions filtered by period (reference_date) and/or asset.
@@ -92,9 +95,9 @@ class PublicSources:
92
95
  Field is not required. Default: False.
93
96
  """
94
97
 
95
- url = f"{url_api_v1}/public-sources/share-repurchase?start_date={start_date}&end_date={end_date}" + (f"&asset={asset}" if asset else "")
98
+ url = f"{url_api_v1}/public-sources/share-repurchase?start_date={start_date}&end_date={end_date}" + (f"&asset={asset}" if asset else "")
96
99
 
97
- response = requests.request("GET", url, headers=self.headers)
100
+ response = requests.request("GET", url, headers=self._headers)
98
101
  if response.status_code == 200:
99
102
  if raw_data:
100
103
  return response.json()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: btgsolutions_dataservices_python_client
3
- Version: 4.0.0
3
+ Version: 4.1.1
4
4
  Summary: Python package containing several classes and data for extracting and manipulating market and trading data.
5
5
  Home-page: https://github.com/BTG-Pactual-Solutions/btgsolutions-dataservices-python-client
6
6
  Author: BTG Solutions Data Services powered by BTG Pactual Solutions
@@ -527,6 +527,8 @@ company_data.all_financial_tables(ticker='PETR4')
527
527
  import btgsolutions_dataservices as btg
528
528
  meta = btg.AlternativeDataMetadata(api_key='YOUR_API_KEY')
529
529
  meta.get_company_directory(query='PETROBRAS', jurisdiction='BR')
530
+ meta.list_companies(query='PETROBRAS', jurisdiction='BR')
531
+ meta.list_etfs(query='BOVA')
530
532
  meta.get_company_sector(identifier='PETR4')
531
533
  meta.get_taxonomy(system='b3')
532
534
  meta.get_cnae(code='6422100')
@@ -543,6 +545,7 @@ meta.get_available_indicators()
543
545
  ```python
544
546
  import btgsolutions_dataservices as btg
545
547
  companies = btg.AlternativeDataCompanies(api_key='YOUR_API_KEY')
548
+ companies.list_companies(query='PETROBRAS', jurisdiction='BR')
546
549
  companies.get_board(company_id='VALE3', body='board')
547
550
  companies.get_governance_summary(company_id='ITUB4')
548
551
  companies.get_governance_history(company_id='PETR4', start_date='2023-01-01', end_date='2024-12-31')
@@ -554,8 +557,9 @@ companies.get_corporate_registry(company_id='PETR4', direction='partners')
554
557
  companies.get_corporate_registry(company_id='PETR4', direction='investees')
555
558
  companies.get_insider_trades(company_id='AAPL', start_date='2024-01-01', end_date='2024-12-31')
556
559
  companies.get_board_changes(company_id='VALE3', event='appointed')
557
- companies.get_financial_statements(company_id='PETR4', statement='income_statement', quarter='Q42024')
558
- companies.get_financial_notes(company_id='VALE3', quarter='Q42024')
560
+ companies.get_assemblies(company_id='PINE4')
561
+ companies.get_financial_statements(company_id='PETR4', statement='income_statement', quarter='4T24')
562
+ companies.get_financial_notes(company_id='VALE3', quarter='4T24')
559
563
  companies.get_disclosures(company_id='PETR4', document_type='repurchase')
560
564
  companies.get_disclosures(company_id='PETR4', document_type='insider')
561
565
  ```
@@ -574,10 +578,11 @@ people.get_appointments(person_id='slug:Jean Paul Lemann', group_by='company')
574
578
  ```python
575
579
  import btgsolutions_dataservices as btg
576
580
  funds = btg.AlternativeDataFunds(api_key='YOUR_API_KEY')
577
- funds.get_holdings(fund_id='73.232.530/0001-46', reference_date='2024-12-31')
578
- funds.get_exposures(fund_id='73.232.530/0001-46', exposure_type='asset_class')
579
- funds.get_history(fund_id='73.232.530/0001-46', start_date='2024-01-01', end_date='2024-12-31')
580
- funds.get_lookthrough(fund_id='73.232.530/0001-46')
581
+ funds.list_etfs(query='BOVA')
582
+ funds.get_holdings(fund_id='BOVA11', reference_date='2024-12-31')
583
+ funds.get_exposures(fund_id='BOVA11', exposure_type='asset_class')
584
+ funds.get_history(fund_id='BOVA11', start_date='2024-01-01', end_date='2024-12-31')
585
+ funds.get_lookthrough(fund_id='BOVA11')
581
586
  funds.get_manager_aggregate_holdings(manager_id='ITAÚ ASSET MANAGEMENT')
582
587
  ```
583
588
 
@@ -591,6 +596,7 @@ ownership.get_ownership_current(company_id='ITUB4')
591
596
  ownership.get_ownership_history(company_id='PETR4', start_date='2023-01-01', end_date='2024-12-31')
592
597
  ownership.get_ownership_change_events(company_id='VALE3', start_date='2024-01-01', end_date='2024-12-31')
593
598
  ownership.get_ownership_official_notices(company_id='PETR4')
599
+ ownership.get_notice_summary(url='https://www.rad.cvm.gov.br/ENETWEB/frmGerenciaPastaDeArquivos.aspx?numProtocolo=1234567')
594
600
  ownership.get_ownership_control_group(company_id='VALE3')
595
601
  ownership.get_ownership_free_float(company_id='PETR4')
596
602
  ownership.get_shareholder_holdings(shareholder_id='00.000.000/0001-91')
@@ -613,6 +619,8 @@ macro.get_dpmfi(start_date='2024-01', end_date='2024-12', status='dados_oficiais
613
619
  macro.get_dpmfi_composition(bond_type='IPCA')
614
620
  ```
615
621
 
622
+ `AlternativeDataMacroMarkets` exposes the public-sources market-data endpoint for B3 maximum theoretical margin. The direct market-data `investor-categories` endpoint is intentionally not exposed in this package.
623
+
616
624
  ### Reference Data
617
625
 
618
626
  #### Corporate Events