xtb-api-python 0.5.2__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.
@@ -0,0 +1,257 @@
1
+ Metadata-Version: 2.4
2
+ Name: xtb-api-python
3
+ Version: 0.5.2
4
+ Summary: Python port of unofficial XTB xStation5 API client
5
+ Project-URL: Homepage, https://github.com/liskeee/xtb-api-python
6
+ Project-URL: Repository, https://github.com/liskeee/xtb-api-python
7
+ Project-URL: Issues, https://github.com/liskeee/xtb-api-python/issues
8
+ Project-URL: Changelog, https://github.com/liskeee/xtb-api-python/blob/master/CHANGELOG.md
9
+ Author-email: Łukasz Lis <ll.lukasz.lis@gmail.com>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: api,trading,websocket,xstation5,xtb
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Framework :: AsyncIO
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Office/Business :: Financial :: Investment
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.12
25
+ Requires-Dist: httpx>=0.27
26
+ Requires-Dist: playwright>=1.40
27
+ Requires-Dist: pydantic>=2.5
28
+ Requires-Dist: websockets>=13.0
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
31
+ Requires-Dist: pytest-httpx>=0.30; extra == 'dev'
32
+ Requires-Dist: pytest>=8.0; extra == 'dev'
33
+ Provides-Extra: totp
34
+ Requires-Dist: pyotp>=2.9.0; extra == 'totp'
35
+ Description-Content-Type: text/markdown
36
+
37
+ [![PyPI version](https://img.shields.io/pypi/v/xtb-api-python.svg)](https://pypi.org/project/xtb-api-python/)
38
+ [![Python versions](https://img.shields.io/pypi/pyversions/xtb-api-python.svg)](https://pypi.org/project/xtb-api-python/)
39
+ [![CI](https://github.com/liskeee/xtb-api-python/actions/workflows/ci.yml/badge.svg)](https://github.com/liskeee/xtb-api-python/actions/workflows/ci.yml)
40
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
41
+
42
+ # xtb-api-python
43
+
44
+ > **Unofficial** — Reverse-engineered from xStation5. Not affiliated with XTB. Use at your own risk.
45
+
46
+ Python client for the XTB xStation5 trading platform. Dead-simple API that handles all authentication, token refresh, and transport selection transparently.
47
+
48
+ ## Features
49
+
50
+ - **Single Client** — One `XTBClient` handles everything, no mode selection needed
51
+ - **Auto Auth** — Full CAS login flow with automatic TGT/JWT refresh
52
+ - **2FA Support** — Automatic TOTP handling when `totp_secret` is provided
53
+ - **Real-time Data** — Live quotes, positions, balance via WebSocket push events
54
+ - **Trading** — Buy/sell market orders with SL/TP via gRPC-web
55
+ - **11,888+ Instruments** — Full symbol search with caching
56
+ - **Modern Python** — async/await, Pydantic models, strict typing, Python 3.12+
57
+
58
+ ## Requirements
59
+
60
+ - Python **3.12 or 3.13**
61
+ - Chromium browser (installed via playwright — see post-install step below)
62
+ - An XTB trading account
63
+
64
+ ## Install
65
+
66
+ ```bash
67
+ pip install xtb-api-python
68
+
69
+ # With automatic 2FA handling:
70
+ pip install "xtb-api-python[totp]"
71
+ ```
72
+
73
+ ### Post-install setup (REQUIRED)
74
+
75
+ This library uses [Playwright](https://playwright.dev/python/) to authenticate with
76
+ XTB's servers (the REST login path is blocked by a WAF). **After** `pip install`,
77
+ you must download the Chromium binary:
78
+
79
+ ```bash
80
+ playwright install chromium
81
+ ```
82
+
83
+ Without this step, the first call to `client.connect()` will fail with a
84
+ `CASError("BROWSER_CHROMIUM_MISSING", ...)` and a pointer back here.
85
+
86
+ To verify your install is complete, run:
87
+
88
+ ```bash
89
+ python -m xtb_api doctor
90
+ ```
91
+
92
+ ### Development install
93
+
94
+ ```bash
95
+ pip install -e ".[dev,totp]"
96
+ playwright install chromium
97
+ pre-commit install
98
+ ```
99
+
100
+ ## Quick Start
101
+
102
+ ```python
103
+ import asyncio
104
+ from xtb_api import XTBClient
105
+
106
+ async def main():
107
+ client = XTBClient(
108
+ email="your@email.com",
109
+ password="your-password",
110
+ account_number=12345678,
111
+ totp_secret="BASE32SECRET", # optional, auto-handles 2FA
112
+ session_file="~/.xtb_session", # optional, persists auth across restarts
113
+ )
114
+
115
+ await client.connect()
116
+
117
+ # Account data
118
+ balance = await client.get_balance()
119
+ print(f"Balance: {balance.balance} {balance.currency}")
120
+
121
+ positions = await client.get_positions()
122
+ orders = await client.get_orders()
123
+
124
+ # Live quote
125
+ quote = await client.get_quote("EURUSD")
126
+ if quote:
127
+ print(f"Bid: {quote.bid}, Ask: {quote.ask}")
128
+
129
+ # Search instruments
130
+ results = await client.search_instrument("Apple")
131
+
132
+ # Trading (USE WITH CAUTION!)
133
+ result = await client.buy("AAPL.US", volume=1, stop_loss=150.0, take_profit=200.0)
134
+ print(f"Order: {result.order_id}")
135
+
136
+ await client.disconnect()
137
+
138
+ asyncio.run(main())
139
+ ```
140
+
141
+ ### Real-time Events
142
+
143
+ ```python
144
+ client.on("tick", lambda tick: print(f"{tick['symbol']}: {tick['bid']}/{tick['ask']}"))
145
+ client.on("position", lambda pos: print(f"Position update: {pos['symbol']}"))
146
+
147
+ await client.subscribe_ticks("EURUSD")
148
+ ```
149
+
150
+ ### Advanced Trade Options
151
+
152
+ ```python
153
+ from xtb_api import TradeOptions
154
+
155
+ # Simple: flat kwargs
156
+ await client.buy("EURUSD", volume=1, stop_loss=1.0850, take_profit=1.0950)
157
+
158
+ # Advanced: TradeOptions object
159
+ await client.sell("CIG.PL", volume=100, options=TradeOptions(
160
+ trailing_stop=50,
161
+ amount=1000.0, # amount-based sizing
162
+ ))
163
+ ```
164
+
165
+ ## API Reference
166
+
167
+ ### `XTBClient`
168
+
169
+ | Method | Returns | Description |
170
+ |--------|---------|-------------|
171
+ | `connect()` | `None` | Connect and authenticate |
172
+ | `disconnect()` | `None` | Disconnect and clean up |
173
+ | `get_balance()` | `AccountBalance` | Account balance, equity, free margin |
174
+ | `get_positions()` | `list[Position]` | Open trading positions |
175
+ | `get_orders()` | `list[PendingOrder]` | Pending limit/stop orders |
176
+ | `get_quote(symbol)` | `Quote \| None` | Current bid/ask for a symbol |
177
+ | `search_instrument(query)` | `list[InstrumentSearchResult]` | Search instruments |
178
+ | `buy(symbol, volume, ...)` | `TradeResult` | Execute BUY order |
179
+ | `sell(symbol, volume, ...)` | `TradeResult` | Execute SELL order |
180
+ | `on(event, callback)` | `None` | Register event handler |
181
+ | `subscribe_ticks(symbol)` | `None` | Subscribe to real-time ticks |
182
+
183
+ ### Constructor Parameters
184
+
185
+ | Parameter | Required | Default | Description |
186
+ |-----------|----------|---------|-------------|
187
+ | `email` | Yes | — | XTB account email |
188
+ | `password` | Yes | — | XTB account password |
189
+ | `account_number` | Yes | — | XTB account number |
190
+ | `totp_secret` | No | `""` | Base32 TOTP secret for auto 2FA |
191
+ | `session_file` | No | `None` | Path to persist auth session |
192
+ | `ws_url` | No | Real server | WebSocket endpoint URL |
193
+ | `endpoint` | No | `"meta1"` | Server endpoint name |
194
+ | `account_server` | No | `"XS-real1"` | gRPC account server |
195
+ | `auto_reconnect` | No | `True` | Auto-reconnect on disconnect |
196
+
197
+ ### WebSocket URLs
198
+
199
+ | Environment | URL |
200
+ |-------------|-----|
201
+ | Real | `wss://api5reala.x-station.eu/v1/xstation` (default) |
202
+ | Demo | `wss://api5demoa.x-station.eu/v1/xstation` |
203
+
204
+ ### Advanced: Direct Access
205
+
206
+ For advanced use cases, access the underlying clients:
207
+
208
+ ```python
209
+ # WebSocket client (always available)
210
+ ws = client.ws
211
+
212
+ # gRPC client (available after first trade)
213
+ grpc = client.grpc_client
214
+
215
+ # Auth manager
216
+ auth = client.auth
217
+ tgt = await auth.get_tgt()
218
+ ```
219
+
220
+ ## Architecture
221
+
222
+ ```
223
+ XTBClient (public facade)
224
+ |
225
+ +-- AuthManager (shared auth session)
226
+ | +-- CASClient (REST + Playwright browser auth)
227
+ | +-- TGT cache (memory + disk)
228
+ |
229
+ +-- XTBWebSocketClient (quotes, positions, balance)
230
+ | +-- Auto-reconnect with fresh service tickets
231
+ |
232
+ +-- GrpcClient (trading, lazy-initialized)
233
+ +-- JWT auto-refresh from shared TGT
234
+ ```
235
+
236
+ ## How Authentication Works
237
+
238
+ 1. **Login** — REST CAS attempt, falls back to Playwright browser if WAF blocks
239
+ 2. **TGT** — 8-hour token, cached in memory + optional session file
240
+ 3. **Service Ticket** — Derived from TGT, used for WebSocket login
241
+ 4. **JWT** — 5-minute token for gRPC trading, auto-refreshed from TGT
242
+ 5. **2FA** — Automatic TOTP if `totp_secret` provided
243
+
244
+ All token refresh is transparent. If a TGT expires mid-session, the full auth chain re-runs automatically.
245
+
246
+ ## Disclaimer
247
+
248
+ This is an **unofficial**, community-driven project. NOT affiliated with, endorsed by, or connected to XTB S.A.
249
+
250
+ - **Use at your own risk** — trading involves financial risk
251
+ - **No warranty** — provided "as is"
252
+ - **API stability** — XTB may change their internal APIs at any time
253
+ - **Always test on demo accounts first**
254
+
255
+ ## License
256
+
257
+ MIT
@@ -0,0 +1,28 @@
1
+ xtb_api/__init__.py,sha256=4uuWQIVA508vYbb6_KOsyUXkWRIC3Jxv9vhCVcky8Q0,1581
2
+ xtb_api/__main__.py,sha256=r0Du6KYGst8U0l9dkLV55EwxqBFsQqwwPZ1wq5UdgZE,4688
3
+ xtb_api/client.py,sha256=DDDdQFrSLcwT3OlImam4s9lFiTbZ5M1a6pxA-iu30C4,17168
4
+ xtb_api/exceptions.py,sha256=Im69z0LPxhR6mV3XTrh99V8ai-hteczZJkhayjQC55Q,1522
5
+ xtb_api/instruments.py,sha256=GAfVtIX9siIkbyxRCi_cFWI9TWLoLnBm4zw-3_AzWQE,4857
6
+ xtb_api/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ xtb_api/utils.py,sha256=xpJ3QTfeCkMnhOu_YCdRq2KPL0hTMC7Y_wqvvCWLM4s,1781
8
+ xtb_api/auth/__init__.py,sha256=p9Devj_dJBgH6awKdUU4uJwBkZaYSz5v932SqEEWHY4,229
9
+ xtb_api/auth/auth_manager.py,sha256=JCViygItScN3Dpwzjxy-ZuywFB6r5fAYycg-HW9l_ss,12174
10
+ xtb_api/auth/browser_auth.py,sha256=Z9CkbcyZ_AyeFWVaRS3QlqTpC2st7_tSb3UMU5UMh6o,12383
11
+ xtb_api/auth/cas_client.py,sha256=f4Rs9LI8A1Y4wTJ1itOGS8cjwnfjAUT5o_Q8TFKplE0,20292
12
+ xtb_api/grpc/__init__.py,sha256=puaZSuPIJ8XWt29c02G95wfWFem5YPDa73Z3PgQI7sM,569
13
+ xtb_api/grpc/client.py,sha256=fdmkCVbZqLQgxrr7olWuPFvAmJdDVX2k-fzsCcO5IGE,11173
14
+ xtb_api/grpc/proto.py,sha256=jglStrhkWrKzEGO2PWXL2iTEm-wulFK99OijD2rQFKU,8753
15
+ xtb_api/grpc/types.py,sha256=178wH9tm1vge7D3O0trOIZCk9qmSzH0PAfiHfjUml8Y,298
16
+ xtb_api/types/__init__.py,sha256=XY4_GL07XDS_wo7iqHB-tsu3SCOm0s9dwg-kr62t6rA,236
17
+ xtb_api/types/enums.py,sha256=p-jzwyAevBFhzwO25Xh3EAIDmd6WMVuI5_I8yd3GvOQ,1837
18
+ xtb_api/types/instrument.py,sha256=uxGB3LrE1IgP3UeEMu9c50Mvqmplr3DmgUbLwjg4i14,927
19
+ xtb_api/types/trading.py,sha256=fGLGga-kMX7vDvE848H7lUnw-kHpTcqq6a8P25RDu2k,3033
20
+ xtb_api/types/websocket.py,sha256=66vZSC6hdlglO5EEqPSciBbtBVunGV0L-0pLiZwVrQo,3705
21
+ xtb_api/ws/__init__.py,sha256=6QNzj6rXiGWa9vU-o_IvVTqU7nDqPaYDJnTQhX-1pXY,106
22
+ xtb_api/ws/parsers.py,sha256=ApEjm3uX-QhiyaM8U1RpZByVbU0ijL5jnm4FFIApyNk,6222
23
+ xtb_api/ws/ws_client.py,sha256=X_bBaAw80aHEECRol33aDJqMfVu5onqrQ8a7ANrrZ8s,34077
24
+ xtb_api_python-0.5.2.dist-info/METADATA,sha256=QNHFjD2C2vtf_aqSVn6pT9ikkPhBcfEK9K0pN6Coxpc,8464
25
+ xtb_api_python-0.5.2.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
26
+ xtb_api_python-0.5.2.dist-info/entry_points.txt,sha256=HhB6G6gQU-c43Y0YowXSqXXOTCd1CK8fvy5guFdzy0s,50
27
+ xtb_api_python-0.5.2.dist-info/licenses/LICENSE,sha256=fEnrQRlNl8P7GRU9YAaLjbNRfQ0qe0At5LRkCmM4j0I,1073
28
+ xtb_api_python-0.5.2.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ xtb-api = xtb_api.__main__:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-2026 Łukasz Lis
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.