btgsolutions-dataservices-python-client 3.2.11__tar.gz → 3.2.12__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.
- {btgsolutions_dataservices_python_client-3.2.11/btgsolutions_dataservices_python_client.egg-info → btgsolutions_dataservices_python_client-3.2.12}/PKG-INFO +28 -18
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/README.md +26 -8
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/__init__.py +1 -1
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/rest/__init__.py +1 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/rest/book_scope.py +31 -23
- btgsolutions_dataservices_python_client-3.2.12/btgsolutions_dataservices/rest/broker_analytics.py +173 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/rest/historical_candles.py +66 -6
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12/btgsolutions_dataservices_python_client.egg-info}/PKG-INFO +28 -18
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices_python_client.egg-info/SOURCES.txt +1 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/LICENSE +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/MANIFEST.in +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/config.py +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/exceptions.py +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/rest/authenticator.py +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/rest/broker_reference.py +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/rest/bulk_data.py +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/rest/company_data.py +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/rest/corporate_events.py +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/rest/hfn.py +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/rest/historical_candles_crypto.py +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/rest/intraday_candles.py +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/rest/intraday_tick_data.py +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/rest/public_sources.py +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/rest/quotes.py +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/rest/reference_data.py +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/rest/stock_loan.py +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/rest/ticker_last_event.py +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/rest/ticker_last_event_polling.py +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/websocket/__init__.py +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/websocket/broker_analytics.py +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/websocket/hfn_websocket_client.py +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/websocket/market_data_feed.py +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/websocket/market_data_websocket_client.py +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices/websocket/websocket_default_functions.py +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices_python_client.egg-info/dependency_links.txt +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices_python_client.egg-info/requires.txt +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/btgsolutions_dataservices_python_client.egg-info/top_level.txt +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/pyproject.toml +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/requirements.txt +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/setup.cfg +0 -0
- {btgsolutions_dataservices_python_client-3.2.11 → btgsolutions_dataservices_python_client-3.2.12}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
2
|
Name: btgsolutions_dataservices_python_client
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.12
|
|
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
|
|
@@ -12,14 +12,6 @@ Requires-Dist: websocket-client>=1.8.0
|
|
|
12
12
|
Requires-Dist: PyJWT>=2.8.0
|
|
13
13
|
Requires-Dist: requests>=2.32.3
|
|
14
14
|
Requires-Dist: pyarrow>=17.0.0
|
|
15
|
-
Dynamic: author
|
|
16
|
-
Dynamic: description
|
|
17
|
-
Dynamic: description-content-type
|
|
18
|
-
Dynamic: home-page
|
|
19
|
-
Dynamic: license-file
|
|
20
|
-
Dynamic: requires-dist
|
|
21
|
-
Dynamic: requires-python
|
|
22
|
-
Dynamic: summary
|
|
23
15
|
|
|
24
16
|
# BTG Solutions - Data Services
|
|
25
17
|
|
|
@@ -280,6 +272,14 @@ hist_candles = btg.HistoricalCandles(api_key='YOUR_API_KEY')
|
|
|
280
272
|
hist_candles.get_intraday_history_candles(ticker='PETR4', market_type='stocks', corporate_events_adj=True, date='2023-10-06', candle='1m', rmv_after_market=True, timezone='UTC', raw_data=False, round=True)
|
|
281
273
|
```
|
|
282
274
|
|
|
275
|
+
##### Interday Batch
|
|
276
|
+
|
|
277
|
+
```python
|
|
278
|
+
import btgsolutions_dataservices as btg
|
|
279
|
+
hist_candles = btg.HistoricalCandles(api_key='YOUR_API_KEY')
|
|
280
|
+
hist_candles.get_interday_history_candles_batch(market_type='stocks', tickers=['PETR4', 'VALE3'], start_date='2023-10-01', end_date='2023-10-13', corporate_events_adj=True, rmv_after_market=True, timezone='UTC', raw_data=False, round=True)
|
|
281
|
+
```
|
|
282
|
+
|
|
283
283
|
##### Available Tickers
|
|
284
284
|
|
|
285
285
|
```python
|
|
@@ -510,23 +510,33 @@ import btgsolutions_dataservices as btg
|
|
|
510
510
|
book_scope = btg.BookScope(api_key='YOUR_API_KEY')
|
|
511
511
|
|
|
512
512
|
result = book_scope.get(
|
|
513
|
-
symbol='
|
|
514
|
-
market_type='
|
|
515
|
-
start_time='2026-05-
|
|
516
|
-
end_time='2026-05-
|
|
513
|
+
symbol='DOLM26',
|
|
514
|
+
market_type='derivatives',
|
|
515
|
+
start_time='2026-05-28T14:12:00Z',
|
|
516
|
+
end_time='2026-05-28T14:15:00Z',
|
|
517
517
|
select=['trades', 'book_snapshot', 'book_incremental'], # choose one, two, or all three
|
|
518
518
|
)
|
|
519
519
|
|
|
520
520
|
single_file_result = book_scope.get(
|
|
521
|
-
symbol='
|
|
522
|
-
market_type='
|
|
523
|
-
start_time='2026-05-
|
|
524
|
-
end_time='2026-05-
|
|
521
|
+
symbol='DOLM26',
|
|
522
|
+
market_type='derivatives',
|
|
523
|
+
start_time='2026-05-28T14:12:00Z',
|
|
524
|
+
end_time='2026-05-28T14:15:00Z',
|
|
525
525
|
select=['trades', 'book_snapshot', 'book_incremental'],
|
|
526
526
|
aggregate_info=True,
|
|
527
527
|
)
|
|
528
528
|
```
|
|
529
529
|
|
|
530
|
+
#### Broker Analytics
|
|
531
|
+
|
|
532
|
+
```python
|
|
533
|
+
import btgsolutions_dataservices as btg
|
|
534
|
+
broker_analytics = btg.BrokerAnalytics(api_key='YOUR_API_KEY', market_type='stocks')
|
|
535
|
+
summary = broker_analytics.get_summary(brokers=['85', '3'], tickers=['PETR4', 'ABCB4'])
|
|
536
|
+
top_brokers = broker_analytics.get_top_brokers(n=10)
|
|
537
|
+
top_tickers = broker_analytics.get_top_tickers(n=10, brokers=['85', '3'])
|
|
538
|
+
```
|
|
539
|
+
|
|
530
540
|
#### Ticker Reference Data
|
|
531
541
|
|
|
532
542
|
```python
|
|
@@ -257,6 +257,14 @@ hist_candles = btg.HistoricalCandles(api_key='YOUR_API_KEY')
|
|
|
257
257
|
hist_candles.get_intraday_history_candles(ticker='PETR4', market_type='stocks', corporate_events_adj=True, date='2023-10-06', candle='1m', rmv_after_market=True, timezone='UTC', raw_data=False, round=True)
|
|
258
258
|
```
|
|
259
259
|
|
|
260
|
+
##### Interday Batch
|
|
261
|
+
|
|
262
|
+
```python
|
|
263
|
+
import btgsolutions_dataservices as btg
|
|
264
|
+
hist_candles = btg.HistoricalCandles(api_key='YOUR_API_KEY')
|
|
265
|
+
hist_candles.get_interday_history_candles_batch(market_type='stocks', tickers=['PETR4', 'VALE3'], start_date='2023-10-01', end_date='2023-10-13', corporate_events_adj=True, rmv_after_market=True, timezone='UTC', raw_data=False, round=True)
|
|
266
|
+
```
|
|
267
|
+
|
|
260
268
|
##### Available Tickers
|
|
261
269
|
|
|
262
270
|
```python
|
|
@@ -487,23 +495,33 @@ import btgsolutions_dataservices as btg
|
|
|
487
495
|
book_scope = btg.BookScope(api_key='YOUR_API_KEY')
|
|
488
496
|
|
|
489
497
|
result = book_scope.get(
|
|
490
|
-
symbol='
|
|
491
|
-
market_type='
|
|
492
|
-
start_time='2026-05-
|
|
493
|
-
end_time='2026-05-
|
|
498
|
+
symbol='DOLM26',
|
|
499
|
+
market_type='derivatives',
|
|
500
|
+
start_time='2026-05-28T14:12:00Z',
|
|
501
|
+
end_time='2026-05-28T14:15:00Z',
|
|
494
502
|
select=['trades', 'book_snapshot', 'book_incremental'], # choose one, two, or all three
|
|
495
503
|
)
|
|
496
504
|
|
|
497
505
|
single_file_result = book_scope.get(
|
|
498
|
-
symbol='
|
|
499
|
-
market_type='
|
|
500
|
-
start_time='2026-05-
|
|
501
|
-
end_time='2026-05-
|
|
506
|
+
symbol='DOLM26',
|
|
507
|
+
market_type='derivatives',
|
|
508
|
+
start_time='2026-05-28T14:12:00Z',
|
|
509
|
+
end_time='2026-05-28T14:15:00Z',
|
|
502
510
|
select=['trades', 'book_snapshot', 'book_incremental'],
|
|
503
511
|
aggregate_info=True,
|
|
504
512
|
)
|
|
505
513
|
```
|
|
506
514
|
|
|
515
|
+
#### Broker Analytics
|
|
516
|
+
|
|
517
|
+
```python
|
|
518
|
+
import btgsolutions_dataservices as btg
|
|
519
|
+
broker_analytics = btg.BrokerAnalytics(api_key='YOUR_API_KEY', market_type='stocks')
|
|
520
|
+
summary = broker_analytics.get_summary(brokers=['85', '3'], tickers=['PETR4', 'ABCB4'])
|
|
521
|
+
top_brokers = broker_analytics.get_top_brokers(n=10)
|
|
522
|
+
top_tickers = broker_analytics.get_top_tickers(n=10, brokers=['85', '3'])
|
|
523
|
+
```
|
|
524
|
+
|
|
507
525
|
#### Ticker Reference Data
|
|
508
526
|
|
|
509
527
|
```python
|
|
@@ -9,6 +9,7 @@ import pyarrow as pa
|
|
|
9
9
|
import pyarrow.parquet as pq
|
|
10
10
|
|
|
11
11
|
VALID_SELECT_OPTIONS = {"trades", "book_snapshot", "book_incremental"}
|
|
12
|
+
VALID_MARKET_TYPES = {"derivatives", "options", "stocks"}
|
|
12
13
|
MAX_MARKET_SCOPE_WINDOW = timedelta(minutes=10)
|
|
13
14
|
ROW_LIMIT = 10000
|
|
14
15
|
|
|
@@ -25,10 +26,10 @@ class BookScope:
|
|
|
25
26
|
>>> api_key='YOUR_API_KEY',
|
|
26
27
|
>>> )
|
|
27
28
|
>>> book_scope.get(
|
|
28
|
-
>>> symbol='
|
|
29
|
-
>>> market_type='
|
|
30
|
-
>>> start_time='2026-05-
|
|
31
|
-
>>> end_time='2026-05-
|
|
29
|
+
>>> symbol='DOLM26',
|
|
30
|
+
>>> market_type='derivatives',
|
|
31
|
+
>>> start_time='2026-05-28T14:12:00Z',
|
|
32
|
+
>>> end_time='2026-05-28T14:15:00Z',
|
|
32
33
|
>>> )
|
|
33
34
|
|
|
34
35
|
Parameters
|
|
@@ -55,8 +56,8 @@ class BookScope:
|
|
|
55
56
|
page_params = {**params}
|
|
56
57
|
if rpt_seq is not None:
|
|
57
58
|
page_params["rpt_seq"] = rpt_seq
|
|
58
|
-
|
|
59
|
-
response = requests.get(endpoint_url, params=page_params, headers=self.headers)
|
|
59
|
+
|
|
60
|
+
response = requests.get(endpoint_url, params=page_params, headers=self.headers, timeout=50)
|
|
60
61
|
if response.status_code != 200:
|
|
61
62
|
try:
|
|
62
63
|
error_body = response.json()
|
|
@@ -134,7 +135,7 @@ class BookScope:
|
|
|
134
135
|
Pagination is handled automatically: if the API returns the maximum number of rows
|
|
135
136
|
(10 000), additional pages are fetched using the rpt_seq cursor until all events
|
|
136
137
|
in the requested horizon are retrieved. The caller always receives a single,
|
|
137
|
-
complete
|
|
138
|
+
complete DataFrame per dataset.
|
|
138
139
|
|
|
139
140
|
Parameters
|
|
140
141
|
----------------
|
|
@@ -143,29 +144,36 @@ class BookScope:
|
|
|
143
144
|
Field is required. Example: 'PETR4', 'DOLM26'.
|
|
144
145
|
market_type: str
|
|
145
146
|
Market type.
|
|
146
|
-
Field is required. Allowed values: '
|
|
147
|
+
Field is required. Allowed values: 'derivatives', 'options', 'stocks'.
|
|
147
148
|
start_time: str
|
|
148
|
-
Start of the analysis window in ISO-8601 format.
|
|
149
|
-
Field is required. Example: '2026-05-
|
|
149
|
+
Start of the analysis window in ISO-8601 UTC format.
|
|
150
|
+
Field is required. Example: '2026-05-28T14:12:00Z'.
|
|
150
151
|
end_time: str
|
|
151
|
-
End of the analysis window in ISO-8601 format.
|
|
152
|
-
Field is required. Example: '2026-05-
|
|
152
|
+
End of the analysis window in ISO-8601 UTC format.
|
|
153
|
+
Field is required. Example: '2026-05-28T14:15:00Z'.
|
|
153
154
|
select: list of str
|
|
154
155
|
Which datasets to return.
|
|
155
156
|
Field is optional. Default: ['trades', 'book_snapshot', 'book_incremental'].
|
|
156
157
|
Allowed values: 'trades', 'book_snapshot', 'book_incremental'.
|
|
157
158
|
aggregate_info: bool
|
|
158
|
-
When True, returns a single
|
|
159
|
+
When True, returns a single pandas.DataFrame containing the selected datasets.
|
|
159
160
|
Field is optional. Default: False.
|
|
160
161
|
|
|
161
162
|
Returns
|
|
162
163
|
----------------
|
|
163
|
-
dict
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
164
|
+
dict or pandas.DataFrame
|
|
165
|
+
When aggregate_info is False (default): dictionary with the selected keys
|
|
166
|
+
('trades', 'book_snapshot', 'book_incremental'), each mapping directly to
|
|
167
|
+
a pandas.DataFrame with all rows for the requested time window.
|
|
168
|
+
When aggregate_info is True: returns a single pandas.DataFrame with all
|
|
169
|
+
selected datasets combined.
|
|
168
170
|
"""
|
|
171
|
+
normalized_market_type = market_type.lower()
|
|
172
|
+
if normalized_market_type not in VALID_MARKET_TYPES:
|
|
173
|
+
raise ValueError(
|
|
174
|
+
f"Invalid market_type: {market_type}. Valid options are: {VALID_MARKET_TYPES}"
|
|
175
|
+
)
|
|
176
|
+
|
|
169
177
|
invalid = set(select) - VALID_SELECT_OPTIONS
|
|
170
178
|
if invalid:
|
|
171
179
|
raise ValueError(f"Invalid select options: {invalid}. Valid options are: {VALID_SELECT_OPTIONS}")
|
|
@@ -184,9 +192,9 @@ class BookScope:
|
|
|
184
192
|
scope = self._resolve_scope(parsed_end_time)
|
|
185
193
|
|
|
186
194
|
endpoint_map = {
|
|
187
|
-
"trades": f"{self.base_url}/marketdata/br/b3/book-scope/{scope}/{
|
|
188
|
-
"book_snapshot": f"{self.base_url}/marketdata/br/b3/book-scope/{scope}/{
|
|
189
|
-
"book_incremental": f"{self.base_url}/marketdata/br/b3/book-scope/{scope}/{
|
|
195
|
+
"trades": f"{self.base_url}/marketdata/br/b3/book-scope/{scope}/{normalized_market_type}/trades",
|
|
196
|
+
"book_snapshot": f"{self.base_url}/marketdata/br/b3/book-scope/{scope}/{normalized_market_type}/book-snapshot",
|
|
197
|
+
"book_incremental": f"{self.base_url}/marketdata/br/b3/book-scope/{scope}/{normalized_market_type}/book-incremental",
|
|
190
198
|
}
|
|
191
199
|
|
|
192
200
|
result = {}
|
|
@@ -196,9 +204,9 @@ class BookScope:
|
|
|
196
204
|
if aggregate_info:
|
|
197
205
|
parquet_payloads.append(data)
|
|
198
206
|
else:
|
|
199
|
-
result[key] =
|
|
207
|
+
result[key] = pq.read_table(BytesIO(data)).to_pandas()
|
|
200
208
|
|
|
201
209
|
if aggregate_info:
|
|
202
|
-
|
|
210
|
+
return pq.read_table(BytesIO(self._combine_parquets(parquet_payloads))).to_pandas()
|
|
203
211
|
|
|
204
212
|
return result
|
btgsolutions_dataservices_python_client-3.2.12/btgsolutions_dataservices/rest/broker_analytics.py
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
from typing import Optional, List
|
|
2
|
+
from ..exceptions import BadResponse
|
|
3
|
+
import requests
|
|
4
|
+
from ..config import url_api_v1
|
|
5
|
+
from .authenticator import Authenticator
|
|
6
|
+
|
|
7
|
+
VALID_MARKET_TYPES = {"derivatives", "stocks", "options"}
|
|
8
|
+
|
|
9
|
+
class BrokerAnalytics:
|
|
10
|
+
"""
|
|
11
|
+
This class provides broker analytics data (summary, top brokers, top tickers)
|
|
12
|
+
for a given market type.
|
|
13
|
+
|
|
14
|
+
* Main use case:
|
|
15
|
+
|
|
16
|
+
>>> from btgsolutions_dataservices import BrokerAnalytics
|
|
17
|
+
>>> broker_analytics = BrokerAnalytics(
|
|
18
|
+
>>> api_key='YOUR_API_KEY',
|
|
19
|
+
>>> market_type='stocks',
|
|
20
|
+
>>> )
|
|
21
|
+
>>> broker_analytics.get_summary(
|
|
22
|
+
>>> brokers=['85', '3'],
|
|
23
|
+
>>> tickers=['ABCB4', 'PETR4'],
|
|
24
|
+
>>> )
|
|
25
|
+
>>> broker_analytics.get_top_brokers(n=10, tickers=['ABCB4'])
|
|
26
|
+
>>> broker_analytics.get_top_tickers(n=10, brokers=['85', '3'])
|
|
27
|
+
|
|
28
|
+
Parameters
|
|
29
|
+
----------------
|
|
30
|
+
api_key: str
|
|
31
|
+
User identification key.
|
|
32
|
+
Field is required.
|
|
33
|
+
market_type: str
|
|
34
|
+
Market type to query. One of: 'derivatives', 'stocks', 'options'.
|
|
35
|
+
Field is required.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
def __init__(
|
|
39
|
+
self,
|
|
40
|
+
api_key: str,
|
|
41
|
+
market_type: str,
|
|
42
|
+
):
|
|
43
|
+
self.api_key = api_key
|
|
44
|
+
self.token = Authenticator(self.api_key).token
|
|
45
|
+
self.headers = {"authorization": f"authorization {self.token}"}
|
|
46
|
+
|
|
47
|
+
market_type = market_type.strip().lower()
|
|
48
|
+
if market_type not in VALID_MARKET_TYPES:
|
|
49
|
+
raise ValueError(
|
|
50
|
+
f"Invalid market_type '{market_type}'. Must be one of: {sorted(VALID_MARKET_TYPES)}"
|
|
51
|
+
)
|
|
52
|
+
self.market_type = market_type
|
|
53
|
+
|
|
54
|
+
def _build_url(self, suffix: str) -> str:
|
|
55
|
+
return f"{url_api_v1}/marketdata/br/b3/realtime/broker-analytics/{self.market_type}/{suffix}"
|
|
56
|
+
|
|
57
|
+
def get_summary(
|
|
58
|
+
self,
|
|
59
|
+
brokers: List[str],
|
|
60
|
+
tickers: List[str],
|
|
61
|
+
side: Optional[str] = None,
|
|
62
|
+
) -> dict:
|
|
63
|
+
"""
|
|
64
|
+
Get day analytics summary for specific brokers and tickers.
|
|
65
|
+
|
|
66
|
+
Parameters
|
|
67
|
+
----------
|
|
68
|
+
brokers : List[str]
|
|
69
|
+
List of broker names to filter. Required.
|
|
70
|
+
tickers : List[str]
|
|
71
|
+
List of ticker symbols to filter. Required.
|
|
72
|
+
side : str, optional
|
|
73
|
+
Filter by side ('buy' or 'sell'). If None, both sides are returned.
|
|
74
|
+
|
|
75
|
+
Returns
|
|
76
|
+
-------
|
|
77
|
+
dict
|
|
78
|
+
JSON response with broker analytics summary data.
|
|
79
|
+
"""
|
|
80
|
+
params = {
|
|
81
|
+
"brokers": ",".join(brokers),
|
|
82
|
+
"tickers": ",".join(tickers),
|
|
83
|
+
}
|
|
84
|
+
if side is not None: params["side"] = side
|
|
85
|
+
|
|
86
|
+
url = self._build_url("summary")
|
|
87
|
+
response = requests.get(url, params=params, headers=self.headers, timeout=30)
|
|
88
|
+
|
|
89
|
+
if response.status_code != 200:
|
|
90
|
+
self._raise_error(response)
|
|
91
|
+
|
|
92
|
+
return response.json()
|
|
93
|
+
|
|
94
|
+
def get_top_brokers(
|
|
95
|
+
self,
|
|
96
|
+
n: int,
|
|
97
|
+
tickers: Optional[List[str]] = None,
|
|
98
|
+
side: Optional[str] = None,
|
|
99
|
+
) -> dict:
|
|
100
|
+
"""
|
|
101
|
+
Get top N brokers ranked by financial volume, with ticker breakdown.
|
|
102
|
+
|
|
103
|
+
Parameters
|
|
104
|
+
----------
|
|
105
|
+
n : int
|
|
106
|
+
Number of top brokers to return. Required.
|
|
107
|
+
tickers : List[str], optional
|
|
108
|
+
List of ticker symbols to filter.
|
|
109
|
+
side : str, optional
|
|
110
|
+
Filter by side ('buy' or 'sell').
|
|
111
|
+
|
|
112
|
+
Returns
|
|
113
|
+
-------
|
|
114
|
+
dict
|
|
115
|
+
JSON response with top brokers and their top assets breakdown.
|
|
116
|
+
"""
|
|
117
|
+
params = {"n": str(n)}
|
|
118
|
+
|
|
119
|
+
if tickers: params["tickers"] = ",".join(tickers)
|
|
120
|
+
if side is not None: params["side"] = side
|
|
121
|
+
|
|
122
|
+
url = self._build_url("top-brokers")
|
|
123
|
+
response = requests.get(url, params=params, headers=self.headers, timeout=30)
|
|
124
|
+
|
|
125
|
+
if response.status_code != 200:
|
|
126
|
+
self._raise_error(response)
|
|
127
|
+
|
|
128
|
+
return response.json()
|
|
129
|
+
|
|
130
|
+
def get_top_tickers(
|
|
131
|
+
self,
|
|
132
|
+
n: int,
|
|
133
|
+
brokers: Optional[List[str]] = None,
|
|
134
|
+
side: Optional[str] = None,
|
|
135
|
+
) -> dict:
|
|
136
|
+
"""
|
|
137
|
+
Get top N tickers ranked by financial volume, with broker breakdown.
|
|
138
|
+
|
|
139
|
+
Parameters
|
|
140
|
+
----------
|
|
141
|
+
n : int
|
|
142
|
+
Number of top tickers to return. Required.
|
|
143
|
+
brokers : List[str], optional
|
|
144
|
+
List of broker names to filter.
|
|
145
|
+
side : str, optional
|
|
146
|
+
Filter by side ('buy' or 'sell').
|
|
147
|
+
|
|
148
|
+
Returns
|
|
149
|
+
-------
|
|
150
|
+
dict
|
|
151
|
+
JSON response with top tickers and their top brokers breakdown.
|
|
152
|
+
"""
|
|
153
|
+
params = {"n": str(n)}
|
|
154
|
+
|
|
155
|
+
if brokers: params["brokers"] = ",".join(brokers)
|
|
156
|
+
if side is not None: params["side"] = side
|
|
157
|
+
|
|
158
|
+
url = self._build_url("top-tickers")
|
|
159
|
+
response = requests.get(url, params=params, headers=self.headers, timeout=30)
|
|
160
|
+
|
|
161
|
+
if response.status_code != 200:
|
|
162
|
+
self._raise_error(response)
|
|
163
|
+
|
|
164
|
+
return response.json()
|
|
165
|
+
|
|
166
|
+
@staticmethod
|
|
167
|
+
def _raise_error(response):
|
|
168
|
+
try:
|
|
169
|
+
error_body = response.json()
|
|
170
|
+
detail = error_body.get("detail", error_body.get("error", response.text))
|
|
171
|
+
except Exception:
|
|
172
|
+
detail = response.text
|
|
173
|
+
raise BadResponse(f"Error {response.status_code}: {detail}")
|
|
@@ -74,7 +74,7 @@ class HistoricalCandles:
|
|
|
74
74
|
Parameters
|
|
75
75
|
----------------
|
|
76
76
|
market_type: str
|
|
77
|
-
Field is required. Allowed values: 'stocks' or '
|
|
77
|
+
Field is required. Allowed values: 'stocks', 'derivatives' or 'indices'.
|
|
78
78
|
ticker: str
|
|
79
79
|
Ticker that needs to be returned.
|
|
80
80
|
Field is required. Example: 'PETR4'.
|
|
@@ -103,8 +103,8 @@ class HistoricalCandles:
|
|
|
103
103
|
Field is not required. Default: True.
|
|
104
104
|
"""
|
|
105
105
|
|
|
106
|
-
if market_type not in ['stocks', 'derivatives']:
|
|
107
|
-
raise MarketTypeError(f'Allowed values: "stocks" or "
|
|
106
|
+
if market_type not in ['stocks', 'derivatives', 'indices']:
|
|
107
|
+
raise MarketTypeError(f'Allowed values: "stocks", "derivatives" or "indices". Input value: "{market_type}".')
|
|
108
108
|
|
|
109
109
|
url = f"{url_apis_v3}/marketdata/history/candles/intraday/{market_type}?ticker={ticker}&corporate_events_adj={corporate_events_adj}&rmv_after_market={rmv_after_market}&timezone={timezone}&date={date}&candle={candle}&round={round}"
|
|
110
110
|
response = requests.request("GET", url, headers=self.headers)
|
|
@@ -133,7 +133,7 @@ class HistoricalCandles:
|
|
|
133
133
|
Parameters
|
|
134
134
|
----------------
|
|
135
135
|
market_type: str
|
|
136
|
-
Field is required. Allowed values: 'stocks' or '
|
|
136
|
+
Field is required. Allowed values: 'stocks', 'derivatives' or 'indices'.
|
|
137
137
|
ticker: str
|
|
138
138
|
Ticker that needs to be returned.
|
|
139
139
|
Field is required. Example: 'PETR4'.
|
|
@@ -162,8 +162,8 @@ class HistoricalCandles:
|
|
|
162
162
|
Field is not required. Default: True.
|
|
163
163
|
"""
|
|
164
164
|
|
|
165
|
-
if market_type not in ['stocks', 'derivatives']:
|
|
166
|
-
raise MarketTypeError(f'Allowed values: "stocks" or "
|
|
165
|
+
if market_type not in ['stocks', 'derivatives', 'indices']:
|
|
166
|
+
raise MarketTypeError(f'Allowed values: "stocks", "derivatives" or "indices". Input value: "{market_type}".')
|
|
167
167
|
|
|
168
168
|
url = f"{url_apis_v3}/marketdata/history/candles/interday/{market_type}?ticker={ticker}&corporate_events_adj={corporate_events_adj}&rmv_after_market={rmv_after_market}&timezone={timezone}&start_date={start_date}&end_date={end_date}&round={round}"
|
|
169
169
|
response = requests.request("GET", url, headers=self.headers)
|
|
@@ -174,6 +174,66 @@ class HistoricalCandles:
|
|
|
174
174
|
response = json.loads(response.text)
|
|
175
175
|
raise BadResponse(f'Error: {response.get("ApiClientError", "")}.\n{response.get("SuggestedAction", "")}')
|
|
176
176
|
|
|
177
|
+
def get_interday_history_candles_batch(
|
|
178
|
+
self,
|
|
179
|
+
market_type:str,
|
|
180
|
+
tickers:list,
|
|
181
|
+
start_date:str,
|
|
182
|
+
end_date:str,
|
|
183
|
+
corporate_events_adj:bool,
|
|
184
|
+
rmv_after_market:bool,
|
|
185
|
+
timezone:str,
|
|
186
|
+
raw_data:bool=False,
|
|
187
|
+
round:bool=True
|
|
188
|
+
):
|
|
189
|
+
"""
|
|
190
|
+
This method provides historical candles for a batch of tickers in determined period.
|
|
191
|
+
|
|
192
|
+
Parameters
|
|
193
|
+
----------------
|
|
194
|
+
market_type: str
|
|
195
|
+
Field is required. Allowed values: 'stocks' or 'derivatives'.
|
|
196
|
+
tickers: list
|
|
197
|
+
Tickers that need to be returned.
|
|
198
|
+
Field is required. Example: ['PETR4', 'VALE3'].
|
|
199
|
+
start_date: string<date>
|
|
200
|
+
Start date of analysis. Format: "YYYY-MM-DD".
|
|
201
|
+
Field is required. Example: '2022-10-06'.
|
|
202
|
+
end_date: string<date>
|
|
203
|
+
End date of analysis. Format: "YYYY-MM-DD".
|
|
204
|
+
Field is required. Example: '2023-01-22'.
|
|
205
|
+
corporate_events_adj: bool
|
|
206
|
+
Corporate events adjustment.
|
|
207
|
+
Field is required. Allowed values: 'true' or 'false'.
|
|
208
|
+
rmv_after_market: bool
|
|
209
|
+
Remove trades after market close.
|
|
210
|
+
Field is required. Allowed values: 'true' or 'false'.
|
|
211
|
+
timezone: str
|
|
212
|
+
Timezone of the datetime.
|
|
213
|
+
Field is required. Allowed values: 'America/Sao_Paulo' or 'UTC'.
|
|
214
|
+
raw_data: bool
|
|
215
|
+
If false, returns data in a dataframe. If true, returns raw data.
|
|
216
|
+
Field is not required. Default: False.
|
|
217
|
+
round: bool
|
|
218
|
+
Apply rounding to prices.
|
|
219
|
+
Useful when corporate_events_adj=True, since price adjustment factors
|
|
220
|
+
may generate values with many decimal places.
|
|
221
|
+
Field is not required. Default: True.
|
|
222
|
+
"""
|
|
223
|
+
|
|
224
|
+
if market_type not in ['stocks', 'derivatives']:
|
|
225
|
+
raise MarketTypeError(f'Allowed values: "stocks" or "derivatives". Input value: "{market_type}".')
|
|
226
|
+
|
|
227
|
+
url = f"{url_apis_v3}/marketdata/history/candles/interday/{market_type}/batch?corporate_events_adj={corporate_events_adj}&rmv_after_market={rmv_after_market}&timezone={timezone}&start_date={start_date}&end_date={end_date}&round={round}"
|
|
228
|
+
payload = {"tickers": tickers}
|
|
229
|
+
response = requests.request("POST", url, headers=self.headers, json=payload)
|
|
230
|
+
if response.status_code == 200:
|
|
231
|
+
response_data = json.loads(response.text)
|
|
232
|
+
return response_data if raw_data else pd.DataFrame(pd.concat([pd.DataFrame(v) for v in response_data.values()], ignore_index=True))
|
|
233
|
+
|
|
234
|
+
response = json.loads(response.text)
|
|
235
|
+
raise BadResponse(f'Error: {response.get("ApiClientError", "")}.\n{response.get("SuggestedAction", "")}')
|
|
236
|
+
|
|
177
237
|
def get_available_tickers(
|
|
178
238
|
self,
|
|
179
239
|
market_type:str,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
2
|
Name: btgsolutions_dataservices_python_client
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.12
|
|
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
|
|
@@ -12,14 +12,6 @@ Requires-Dist: websocket-client>=1.8.0
|
|
|
12
12
|
Requires-Dist: PyJWT>=2.8.0
|
|
13
13
|
Requires-Dist: requests>=2.32.3
|
|
14
14
|
Requires-Dist: pyarrow>=17.0.0
|
|
15
|
-
Dynamic: author
|
|
16
|
-
Dynamic: description
|
|
17
|
-
Dynamic: description-content-type
|
|
18
|
-
Dynamic: home-page
|
|
19
|
-
Dynamic: license-file
|
|
20
|
-
Dynamic: requires-dist
|
|
21
|
-
Dynamic: requires-python
|
|
22
|
-
Dynamic: summary
|
|
23
15
|
|
|
24
16
|
# BTG Solutions - Data Services
|
|
25
17
|
|
|
@@ -280,6 +272,14 @@ hist_candles = btg.HistoricalCandles(api_key='YOUR_API_KEY')
|
|
|
280
272
|
hist_candles.get_intraday_history_candles(ticker='PETR4', market_type='stocks', corporate_events_adj=True, date='2023-10-06', candle='1m', rmv_after_market=True, timezone='UTC', raw_data=False, round=True)
|
|
281
273
|
```
|
|
282
274
|
|
|
275
|
+
##### Interday Batch
|
|
276
|
+
|
|
277
|
+
```python
|
|
278
|
+
import btgsolutions_dataservices as btg
|
|
279
|
+
hist_candles = btg.HistoricalCandles(api_key='YOUR_API_KEY')
|
|
280
|
+
hist_candles.get_interday_history_candles_batch(market_type='stocks', tickers=['PETR4', 'VALE3'], start_date='2023-10-01', end_date='2023-10-13', corporate_events_adj=True, rmv_after_market=True, timezone='UTC', raw_data=False, round=True)
|
|
281
|
+
```
|
|
282
|
+
|
|
283
283
|
##### Available Tickers
|
|
284
284
|
|
|
285
285
|
```python
|
|
@@ -510,23 +510,33 @@ import btgsolutions_dataservices as btg
|
|
|
510
510
|
book_scope = btg.BookScope(api_key='YOUR_API_KEY')
|
|
511
511
|
|
|
512
512
|
result = book_scope.get(
|
|
513
|
-
symbol='
|
|
514
|
-
market_type='
|
|
515
|
-
start_time='2026-05-
|
|
516
|
-
end_time='2026-05-
|
|
513
|
+
symbol='DOLM26',
|
|
514
|
+
market_type='derivatives',
|
|
515
|
+
start_time='2026-05-28T14:12:00Z',
|
|
516
|
+
end_time='2026-05-28T14:15:00Z',
|
|
517
517
|
select=['trades', 'book_snapshot', 'book_incremental'], # choose one, two, or all three
|
|
518
518
|
)
|
|
519
519
|
|
|
520
520
|
single_file_result = book_scope.get(
|
|
521
|
-
symbol='
|
|
522
|
-
market_type='
|
|
523
|
-
start_time='2026-05-
|
|
524
|
-
end_time='2026-05-
|
|
521
|
+
symbol='DOLM26',
|
|
522
|
+
market_type='derivatives',
|
|
523
|
+
start_time='2026-05-28T14:12:00Z',
|
|
524
|
+
end_time='2026-05-28T14:15:00Z',
|
|
525
525
|
select=['trades', 'book_snapshot', 'book_incremental'],
|
|
526
526
|
aggregate_info=True,
|
|
527
527
|
)
|
|
528
528
|
```
|
|
529
529
|
|
|
530
|
+
#### Broker Analytics
|
|
531
|
+
|
|
532
|
+
```python
|
|
533
|
+
import btgsolutions_dataservices as btg
|
|
534
|
+
broker_analytics = btg.BrokerAnalytics(api_key='YOUR_API_KEY', market_type='stocks')
|
|
535
|
+
summary = broker_analytics.get_summary(brokers=['85', '3'], tickers=['PETR4', 'ABCB4'])
|
|
536
|
+
top_brokers = broker_analytics.get_top_brokers(n=10)
|
|
537
|
+
top_tickers = broker_analytics.get_top_tickers(n=10, brokers=['85', '3'])
|
|
538
|
+
```
|
|
539
|
+
|
|
530
540
|
#### Ticker Reference Data
|
|
531
541
|
|
|
532
542
|
```python
|
|
@@ -10,6 +10,7 @@ btgsolutions_dataservices/exceptions.py
|
|
|
10
10
|
btgsolutions_dataservices/rest/__init__.py
|
|
11
11
|
btgsolutions_dataservices/rest/authenticator.py
|
|
12
12
|
btgsolutions_dataservices/rest/book_scope.py
|
|
13
|
+
btgsolutions_dataservices/rest/broker_analytics.py
|
|
13
14
|
btgsolutions_dataservices/rest/broker_reference.py
|
|
14
15
|
btgsolutions_dataservices/rest/bulk_data.py
|
|
15
16
|
btgsolutions_dataservices/rest/company_data.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|