btgsolutions-dataservices-python-client 2.16.0__py3-none-any.whl → 2.17.1__py3-none-any.whl

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.
@@ -10,4 +10,5 @@ from .corporate_events import CorporateEvents
10
10
  from .company_data import CompanyData
11
11
  from .public_sources import PublicSources
12
12
  from .reference_data import ReferenceData
13
- from .stock_loan import StockLoan
13
+ from .stock_loan import StockLoan
14
+ from .ticker_last_event_polling import TickerLastEventPolling
@@ -0,0 +1,149 @@
1
+ import time
2
+ from typing import Optional, List
3
+ from ..exceptions import BadResponse
4
+ import requests
5
+ from ..config import url_api_v1
6
+ from .authenticator import Authenticator
7
+ import pandas as pd
8
+ import json
9
+ from datetime import datetime, timezone, timedelta
10
+ import threading
11
+
12
+ class TickerLastEventPolling:
13
+ """
14
+ This class continuously polls and caches the latest ticker market data in the background for quick and up-to-date access.
15
+
16
+ * Main use case:
17
+
18
+ >>> from btgsolutions_dataservices import TickerLastEventPolling
19
+ >>> last_event = TickerLastEventPolling(
20
+ >>> api_key='YOUR_API_KEY',
21
+ >>> data_type='top-of-books',
22
+ >>> data_subtype='stocks',
23
+ >>> )
24
+
25
+ >>> last_event.get(
26
+ >>> raw_data=False
27
+ >>> )
28
+
29
+ Parameters
30
+ ----------------
31
+ api_key: str
32
+ User identification key.
33
+ Field is required.
34
+ data_type: str
35
+ Market Data type.
36
+ Options: 'top-of-books'
37
+ Field is required.
38
+ data_subtype: str
39
+ Market Data subtype.
40
+ Options: 'stocks', 'options', 'derivatives'.
41
+ Field is required.
42
+ """
43
+ def __init__(
44
+ self,
45
+ api_key:Optional[str],
46
+ data_type: str,
47
+ data_subtype: str,
48
+ interval_seconds: float = 1.0
49
+ ):
50
+ self.api_key = api_key
51
+ self.authenticator = Authenticator(self.api_key)
52
+ self.interval_seconds = interval_seconds
53
+ self.data_type = data_type
54
+
55
+ self._last_request_datetime = None
56
+ self._cache = {}
57
+
58
+ self._available_data_types = {
59
+ "top-of-books": ['stocks', 'derivatives', 'options']
60
+ }
61
+
62
+ self._available_url = {
63
+ "top-of-books": {
64
+ "data": f"{url_api_v1}/marketdata/last-event/books/top/{data_subtype}/batch",
65
+ "available": f"{url_api_v1}/marketdata/last-event/books/{data_subtype}/availables"
66
+ }
67
+ }
68
+
69
+ if data_type not in self._available_data_types:
70
+ raise Exception(f"Must provide a valid data_type. Valid data types are: {self._available_data_types}")
71
+
72
+ if data_subtype not in self._available_data_types[data_type]:
73
+ raise Exception(f"Must provide a valid data_subtype. Valid data subtypes are: {self._available_data_types[data_type]}")
74
+
75
+ self.url = self._available_url[self.data_type]["data"]
76
+
77
+ self._update_data()
78
+
79
+ threading.Thread(target=self._polling_loop, daemon=True).start()
80
+
81
+ def _polling_loop(self):
82
+
83
+ while True:
84
+ try:
85
+ self._update_data()
86
+ except Exception as e:
87
+ print("error on updating data:", e)
88
+ continue
89
+
90
+ time.sleep(self.interval_seconds)
91
+
92
+
93
+ def _update_data(self):
94
+ url = self.url + (f"?dt={(self._last_request_datetime - timedelta(seconds=60)).strftime('%Y-%m-%dT%H:%M:%S.000Z')}" if self._last_request_datetime else "")
95
+
96
+ request_datetime = datetime.now(timezone.utc)
97
+
98
+ response = requests.request("GET", url, headers={"authorization": f"Bearer {self.authenticator.token}"})
99
+
100
+ if response.status_code != 200:
101
+ return
102
+
103
+
104
+ self._last_request_datetime = request_datetime
105
+
106
+ new_data = { tob["sb"]: tob for tob in response.json() if tob.get("sb")}
107
+
108
+ self._cache.update(new_data)
109
+
110
+
111
+ def get(self, force_update: bool=False, raw_data:bool=False):
112
+
113
+ """
114
+ This method provides the last events for all tickers of the given data type and data subtype.
115
+
116
+ Parameters
117
+ ----------------
118
+ force_update: bool
119
+ If true, forces an update before returning the data. If false, returns the data.
120
+ Field is not required. Default: False.
121
+ raw_data: bool
122
+ If false, returns data in a dataframe. If true, returns raw data.
123
+ Field is not required. Default: False.
124
+ """
125
+ if force_update:
126
+ self._update_data()
127
+
128
+ if raw_data:
129
+ return list(self._cache.values())
130
+ else:
131
+ return pd.DataFrame(self._cache.values())
132
+
133
+
134
+
135
+ def get_available_tickers(self):
136
+
137
+ """
138
+ This method provides all the available tickers for the specific data type and data subtype.
139
+
140
+ """
141
+
142
+ url = self._available_url[self.data_type]["available"]
143
+
144
+ response = requests.request("GET", url, headers={"authorization": f"Bearer {self.authenticator.token}"})
145
+ if response.status_code == 200:
146
+ return response.json()
147
+ else:
148
+ response = json.loads(response.text)
149
+ raise BadResponse(f'Error: {response.get("error", "")}')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: btgsolutions-dataservices-python-client
3
- Version: 2.16.0
3
+ Version: 2.17.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
@@ -253,6 +253,15 @@ last_event = btg.TickerLastEvent(api_key='YOUR_API_KEY')
253
253
  last_event.get_status(tickers=['PETR4','VALE3'])
254
254
  ```
255
255
 
256
+ #### Ticker Last Polling - Top of Books
257
+
258
+ ```python
259
+ import btgsolutions_dataservices as btg
260
+ last_event = btg.TickerLastEventPolling(api_key='YOUR_API_KEY', data_type='top-of-books', data_subtype='stocks')
261
+ last_event.get()
262
+ ```
263
+
264
+
256
265
  ### Historical Data
257
266
 
258
267
  #### Historical Candles
@@ -1,7 +1,7 @@
1
1
  btgsolutions_dataservices/__init__.py,sha256=reSSb9MBIp5WQ5o872fX__moJYXx0sQgkhUf3QmfEjI,93
2
2
  btgsolutions_dataservices/config.py,sha256=9L9bIGL1j7XSAkpYMxLS8oqIu-F4CQ2EyAywIT496p8,5285
3
3
  btgsolutions_dataservices/exceptions.py,sha256=QlwQTDEohtVsTER0lHbQrDgAGvjiZBmoyDuqLkUcvh8,599
4
- btgsolutions_dataservices/rest/__init__.py,sha256=0G1mlZ2cyWWuctx3JZfBZn9KLs-BqIXafxuDHCMiOrE,528
4
+ btgsolutions_dataservices/rest/__init__.py,sha256=NEar641a2Mosioj-D3HrcdrJqgjaFRCwos3rftnUhq0,591
5
5
  btgsolutions_dataservices/rest/authenticator.py,sha256=uBLARz5lCRhIDc_PZaC4a2rSQtrFJajmAC4Bdg9BnX0,1363
6
6
  btgsolutions_dataservices/rest/bulk_data.py,sha256=26CrFH-IVMUbpPLx0HaN-BePs5R9A1ZUINSir7qtfhE,9032
7
7
  btgsolutions_dataservices/rest/company_data.py,sha256=yhsgR-P7g5e6TDdpoMZoyiyqI85roBCXJGyob4g1P_8,7318
@@ -15,13 +15,14 @@ btgsolutions_dataservices/rest/quotes.py,sha256=sirlG1-_aCtE7auwYM7lTZkpMcW3UYis
15
15
  btgsolutions_dataservices/rest/reference_data.py,sha256=ntcHEMapKULGPHJvmzAnccUo8ZTGokt1M9bDBceV5Tk,2112
16
16
  btgsolutions_dataservices/rest/stock_loan.py,sha256=_EYxywO-qA-zC7CeAo8a1omUb327g13P1R1B-plPKtI,3207
17
17
  btgsolutions_dataservices/rest/ticker_last_event.py,sha256=1DR4fVsareRDr1iGya7E8308kDcciK5XtlS2SI56c1o,6328
18
+ btgsolutions_dataservices/rest/ticker_last_event_polling.py,sha256=wCDplal8k5xHXI4JD69D5j-djYkL16SiNiso7Of3UCI,4656
18
19
  btgsolutions_dataservices/websocket/__init__.py,sha256=Bifok6zQFenYNIA-NE8hYSooZVIQ2MCeTCjIOYnfHzI,165
19
20
  btgsolutions_dataservices/websocket/hfn_websocket_client.py,sha256=wzyPXtXFsv31cVFcTWrTA5uhFBebgM2IpIxXQvPSP54,6253
20
21
  btgsolutions_dataservices/websocket/market_data_feed.py,sha256=HAVA4thvYyvmcVrHm4_exGaq4y9RCGjwl98yuXR8KVc,16209
21
22
  btgsolutions_dataservices/websocket/market_data_websocket_client.py,sha256=ix6EH6yHJcRc69RWuvUjHxr0H17zRSM_o9YjsO6OZIw,13812
22
23
  btgsolutions_dataservices/websocket/websocket_default_functions.py,sha256=JWbOR4uX14BI9JB3zXMbwqVsF8AtfDbEC83fgs8O5PY,335
23
- btgsolutions_dataservices_python_client-2.16.0.dist-info/licenses/LICENSE,sha256=vePSp4Jry-f15vZ48xge2vljuhNgkMZD6wU0XmuFBgA,1057
24
- btgsolutions_dataservices_python_client-2.16.0.dist-info/METADATA,sha256=YrFRqKVgoh2AeTSoYS-NZWTdJh-ig5r0ixnd4vB9oHw,12942
25
- btgsolutions_dataservices_python_client-2.16.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
26
- btgsolutions_dataservices_python_client-2.16.0.dist-info/top_level.txt,sha256=OaseSN41lI9j_Z-kHIE_XVo_m1hmGdAHE3EK1h5_Ce0,26
27
- btgsolutions_dataservices_python_client-2.16.0.dist-info/RECORD,,
24
+ btgsolutions_dataservices_python_client-2.17.1.dist-info/licenses/LICENSE,sha256=vePSp4Jry-f15vZ48xge2vljuhNgkMZD6wU0XmuFBgA,1057
25
+ btgsolutions_dataservices_python_client-2.17.1.dist-info/METADATA,sha256=cDuPuZOmolVyzvEqaHub2x0wvWAwv2kuAqeGSYPNYVg,13169
26
+ btgsolutions_dataservices_python_client-2.17.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
+ btgsolutions_dataservices_python_client-2.17.1.dist-info/top_level.txt,sha256=OaseSN41lI9j_Z-kHIE_XVo_m1hmGdAHE3EK1h5_Ce0,26
28
+ btgsolutions_dataservices_python_client-2.17.1.dist-info/RECORD,,