oxarchive 0.4.1__tar.gz → 0.4.4__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.
- {oxarchive-0.4.1 → oxarchive-0.4.4}/PKG-INFO +90 -4
- {oxarchive-0.4.1 → oxarchive-0.4.4}/README.md +89 -3
- {oxarchive-0.4.1 → oxarchive-0.4.4}/oxarchive/__init__.py +5 -1
- {oxarchive-0.4.1 → oxarchive-0.4.4}/oxarchive/exchanges.py +5 -2
- {oxarchive-0.4.1 → oxarchive-0.4.4}/oxarchive/resources/__init__.py +2 -1
- oxarchive-0.4.4/oxarchive/resources/instruments.py +110 -0
- {oxarchive-0.4.1 → oxarchive-0.4.4}/oxarchive/resources/orderbook.py +18 -1
- {oxarchive-0.4.1 → oxarchive-0.4.4}/oxarchive/types.py +48 -1
- {oxarchive-0.4.1 → oxarchive-0.4.4}/pyproject.toml +1 -1
- oxarchive-0.4.1/oxarchive/resources/instruments.py +0 -56
- {oxarchive-0.4.1 → oxarchive-0.4.4}/.gitignore +0 -0
- {oxarchive-0.4.1 → oxarchive-0.4.4}/oxarchive/client.py +0 -0
- {oxarchive-0.4.1 → oxarchive-0.4.4}/oxarchive/http.py +0 -0
- {oxarchive-0.4.1 → oxarchive-0.4.4}/oxarchive/resources/funding.py +0 -0
- {oxarchive-0.4.1 → oxarchive-0.4.4}/oxarchive/resources/openinterest.py +0 -0
- {oxarchive-0.4.1 → oxarchive-0.4.4}/oxarchive/resources/trades.py +0 -0
- {oxarchive-0.4.1 → oxarchive-0.4.4}/oxarchive/websocket.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: oxarchive
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.4
|
|
4
4
|
Summary: Official Python SDK for 0xarchive - Hyperliquid Historical Data API
|
|
5
5
|
Project-URL: Homepage, https://0xarchive.io
|
|
6
6
|
Project-URL: Documentation, https://0xarchive.io/docs/sdks
|
|
@@ -153,6 +153,59 @@ orderbook = await client.hyperliquid.orderbook.aget("BTC")
|
|
|
153
153
|
history = await client.hyperliquid.orderbook.ahistory("BTC", start=..., end=...)
|
|
154
154
|
```
|
|
155
155
|
|
|
156
|
+
#### Orderbook Depth Limits
|
|
157
|
+
|
|
158
|
+
The `depth` parameter controls how many price levels are returned per side. Tier-based limits apply:
|
|
159
|
+
|
|
160
|
+
| Tier | Max Depth |
|
|
161
|
+
|------|-----------|
|
|
162
|
+
| Free | 20 |
|
|
163
|
+
| Build | 50 |
|
|
164
|
+
| Pro | 100 |
|
|
165
|
+
| Enterprise | Full Depth |
|
|
166
|
+
|
|
167
|
+
**Note:** Hyperliquid source data only contains 20 levels. Higher limits apply to Lighter.xyz data.
|
|
168
|
+
|
|
169
|
+
#### Lighter Orderbook Granularity
|
|
170
|
+
|
|
171
|
+
Lighter.xyz orderbook history supports a `granularity` parameter for different data resolutions. Tier restrictions apply.
|
|
172
|
+
|
|
173
|
+
| Granularity | Interval | Tier Required | Credit Multiplier |
|
|
174
|
+
|-------------|----------|---------------|-------------------|
|
|
175
|
+
| `checkpoint` | ~60s | Free+ | 1x |
|
|
176
|
+
| `30s` | 30s | Build+ | 2x |
|
|
177
|
+
| `10s` | 10s | Build+ | 3x |
|
|
178
|
+
| `1s` | 1s | Pro+ | 10x |
|
|
179
|
+
| `tick` | tick-level | Enterprise | 20x |
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
# Get Lighter orderbook history with 10s resolution (Build+ tier)
|
|
183
|
+
history = client.lighter.orderbook.history(
|
|
184
|
+
"BTC",
|
|
185
|
+
start="2024-01-01",
|
|
186
|
+
end="2024-01-02",
|
|
187
|
+
granularity="10s"
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
# Get 1-second resolution (Pro+ tier)
|
|
191
|
+
history = client.lighter.orderbook.history(
|
|
192
|
+
"BTC",
|
|
193
|
+
start="2024-01-01",
|
|
194
|
+
end="2024-01-02",
|
|
195
|
+
granularity="1s"
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
# Tick-level data (Enterprise tier) - returns checkpoint + raw deltas
|
|
199
|
+
history = client.lighter.orderbook.history(
|
|
200
|
+
"BTC",
|
|
201
|
+
start="2024-01-01",
|
|
202
|
+
end="2024-01-02",
|
|
203
|
+
granularity="tick"
|
|
204
|
+
)
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
**Note:** The `granularity` parameter is ignored for Hyperliquid orderbook history.
|
|
208
|
+
|
|
156
209
|
### Trades
|
|
157
210
|
|
|
158
211
|
The trades API uses cursor-based pagination for efficient retrieval of large datasets.
|
|
@@ -187,17 +240,47 @@ result = await client.hyperliquid.trades.alist("ETH", start=..., end=...)
|
|
|
187
240
|
### Instruments
|
|
188
241
|
|
|
189
242
|
```python
|
|
190
|
-
# List all trading instruments
|
|
243
|
+
# List all trading instruments (Hyperliquid)
|
|
191
244
|
instruments = client.hyperliquid.instruments.list()
|
|
192
245
|
|
|
193
246
|
# Get specific instrument details
|
|
194
247
|
btc = client.hyperliquid.instruments.get("BTC")
|
|
248
|
+
print(f"BTC size decimals: {btc.sz_decimals}")
|
|
195
249
|
|
|
196
250
|
# Async versions
|
|
197
251
|
instruments = await client.hyperliquid.instruments.alist()
|
|
198
252
|
btc = await client.hyperliquid.instruments.aget("BTC")
|
|
199
253
|
```
|
|
200
254
|
|
|
255
|
+
#### Lighter.xyz Instruments
|
|
256
|
+
|
|
257
|
+
Lighter instruments have a different schema with additional fields for fees, market IDs, and minimum order amounts:
|
|
258
|
+
|
|
259
|
+
```python
|
|
260
|
+
# List Lighter instruments (returns LighterInstrument, not Instrument)
|
|
261
|
+
lighter_instruments = client.lighter.instruments.list()
|
|
262
|
+
|
|
263
|
+
# Get specific Lighter instrument
|
|
264
|
+
eth = client.lighter.instruments.get("ETH")
|
|
265
|
+
print(f"ETH taker fee: {eth.taker_fee}")
|
|
266
|
+
print(f"ETH maker fee: {eth.maker_fee}")
|
|
267
|
+
print(f"ETH market ID: {eth.market_id}")
|
|
268
|
+
print(f"ETH min base amount: {eth.min_base_amount}")
|
|
269
|
+
|
|
270
|
+
# Async versions
|
|
271
|
+
lighter_instruments = await client.lighter.instruments.alist()
|
|
272
|
+
eth = await client.lighter.instruments.aget("ETH")
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
**Key differences:**
|
|
276
|
+
| Field | Hyperliquid (`Instrument`) | Lighter (`LighterInstrument`) |
|
|
277
|
+
|-------|---------------------------|------------------------------|
|
|
278
|
+
| Symbol | `name` | `symbol` |
|
|
279
|
+
| Size decimals | `sz_decimals` | `size_decimals` |
|
|
280
|
+
| Fee info | Not available | `taker_fee`, `maker_fee`, `liquidation_fee` |
|
|
281
|
+
| Market ID | Not available | `market_id` |
|
|
282
|
+
| Min amounts | Not available | `min_base_amount`, `min_quote_amount` |
|
|
283
|
+
|
|
201
284
|
### Funding Rates
|
|
202
285
|
|
|
203
286
|
```python
|
|
@@ -449,8 +532,8 @@ except OxArchiveError as e:
|
|
|
449
532
|
Full type hint support with Pydantic models:
|
|
450
533
|
|
|
451
534
|
```python
|
|
452
|
-
from oxarchive import Client
|
|
453
|
-
from oxarchive.types import OrderBook, Trade, Instrument, FundingRate, OpenInterest
|
|
535
|
+
from oxarchive import Client, LighterGranularity
|
|
536
|
+
from oxarchive.types import OrderBook, Trade, Instrument, LighterInstrument, FundingRate, OpenInterest
|
|
454
537
|
from oxarchive.resources.trades import CursorResponse
|
|
455
538
|
|
|
456
539
|
client = Client(api_key="ox_your_api_key")
|
|
@@ -458,6 +541,9 @@ client = Client(api_key="ox_your_api_key")
|
|
|
458
541
|
orderbook: OrderBook = client.orderbook.get("BTC")
|
|
459
542
|
trades: list[Trade] = client.trades.recent("BTC")
|
|
460
543
|
result: CursorResponse = client.trades.list("BTC", start=..., end=...)
|
|
544
|
+
|
|
545
|
+
# Lighter granularity type hint
|
|
546
|
+
granularity: LighterGranularity = "10s"
|
|
461
547
|
```
|
|
462
548
|
|
|
463
549
|
## Requirements
|
|
@@ -116,6 +116,59 @@ orderbook = await client.hyperliquid.orderbook.aget("BTC")
|
|
|
116
116
|
history = await client.hyperliquid.orderbook.ahistory("BTC", start=..., end=...)
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
+
#### Orderbook Depth Limits
|
|
120
|
+
|
|
121
|
+
The `depth` parameter controls how many price levels are returned per side. Tier-based limits apply:
|
|
122
|
+
|
|
123
|
+
| Tier | Max Depth |
|
|
124
|
+
|------|-----------|
|
|
125
|
+
| Free | 20 |
|
|
126
|
+
| Build | 50 |
|
|
127
|
+
| Pro | 100 |
|
|
128
|
+
| Enterprise | Full Depth |
|
|
129
|
+
|
|
130
|
+
**Note:** Hyperliquid source data only contains 20 levels. Higher limits apply to Lighter.xyz data.
|
|
131
|
+
|
|
132
|
+
#### Lighter Orderbook Granularity
|
|
133
|
+
|
|
134
|
+
Lighter.xyz orderbook history supports a `granularity` parameter for different data resolutions. Tier restrictions apply.
|
|
135
|
+
|
|
136
|
+
| Granularity | Interval | Tier Required | Credit Multiplier |
|
|
137
|
+
|-------------|----------|---------------|-------------------|
|
|
138
|
+
| `checkpoint` | ~60s | Free+ | 1x |
|
|
139
|
+
| `30s` | 30s | Build+ | 2x |
|
|
140
|
+
| `10s` | 10s | Build+ | 3x |
|
|
141
|
+
| `1s` | 1s | Pro+ | 10x |
|
|
142
|
+
| `tick` | tick-level | Enterprise | 20x |
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
# Get Lighter orderbook history with 10s resolution (Build+ tier)
|
|
146
|
+
history = client.lighter.orderbook.history(
|
|
147
|
+
"BTC",
|
|
148
|
+
start="2024-01-01",
|
|
149
|
+
end="2024-01-02",
|
|
150
|
+
granularity="10s"
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
# Get 1-second resolution (Pro+ tier)
|
|
154
|
+
history = client.lighter.orderbook.history(
|
|
155
|
+
"BTC",
|
|
156
|
+
start="2024-01-01",
|
|
157
|
+
end="2024-01-02",
|
|
158
|
+
granularity="1s"
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
# Tick-level data (Enterprise tier) - returns checkpoint + raw deltas
|
|
162
|
+
history = client.lighter.orderbook.history(
|
|
163
|
+
"BTC",
|
|
164
|
+
start="2024-01-01",
|
|
165
|
+
end="2024-01-02",
|
|
166
|
+
granularity="tick"
|
|
167
|
+
)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**Note:** The `granularity` parameter is ignored for Hyperliquid orderbook history.
|
|
171
|
+
|
|
119
172
|
### Trades
|
|
120
173
|
|
|
121
174
|
The trades API uses cursor-based pagination for efficient retrieval of large datasets.
|
|
@@ -150,17 +203,47 @@ result = await client.hyperliquid.trades.alist("ETH", start=..., end=...)
|
|
|
150
203
|
### Instruments
|
|
151
204
|
|
|
152
205
|
```python
|
|
153
|
-
# List all trading instruments
|
|
206
|
+
# List all trading instruments (Hyperliquid)
|
|
154
207
|
instruments = client.hyperliquid.instruments.list()
|
|
155
208
|
|
|
156
209
|
# Get specific instrument details
|
|
157
210
|
btc = client.hyperliquid.instruments.get("BTC")
|
|
211
|
+
print(f"BTC size decimals: {btc.sz_decimals}")
|
|
158
212
|
|
|
159
213
|
# Async versions
|
|
160
214
|
instruments = await client.hyperliquid.instruments.alist()
|
|
161
215
|
btc = await client.hyperliquid.instruments.aget("BTC")
|
|
162
216
|
```
|
|
163
217
|
|
|
218
|
+
#### Lighter.xyz Instruments
|
|
219
|
+
|
|
220
|
+
Lighter instruments have a different schema with additional fields for fees, market IDs, and minimum order amounts:
|
|
221
|
+
|
|
222
|
+
```python
|
|
223
|
+
# List Lighter instruments (returns LighterInstrument, not Instrument)
|
|
224
|
+
lighter_instruments = client.lighter.instruments.list()
|
|
225
|
+
|
|
226
|
+
# Get specific Lighter instrument
|
|
227
|
+
eth = client.lighter.instruments.get("ETH")
|
|
228
|
+
print(f"ETH taker fee: {eth.taker_fee}")
|
|
229
|
+
print(f"ETH maker fee: {eth.maker_fee}")
|
|
230
|
+
print(f"ETH market ID: {eth.market_id}")
|
|
231
|
+
print(f"ETH min base amount: {eth.min_base_amount}")
|
|
232
|
+
|
|
233
|
+
# Async versions
|
|
234
|
+
lighter_instruments = await client.lighter.instruments.alist()
|
|
235
|
+
eth = await client.lighter.instruments.aget("ETH")
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
**Key differences:**
|
|
239
|
+
| Field | Hyperliquid (`Instrument`) | Lighter (`LighterInstrument`) |
|
|
240
|
+
|-------|---------------------------|------------------------------|
|
|
241
|
+
| Symbol | `name` | `symbol` |
|
|
242
|
+
| Size decimals | `sz_decimals` | `size_decimals` |
|
|
243
|
+
| Fee info | Not available | `taker_fee`, `maker_fee`, `liquidation_fee` |
|
|
244
|
+
| Market ID | Not available | `market_id` |
|
|
245
|
+
| Min amounts | Not available | `min_base_amount`, `min_quote_amount` |
|
|
246
|
+
|
|
164
247
|
### Funding Rates
|
|
165
248
|
|
|
166
249
|
```python
|
|
@@ -412,8 +495,8 @@ except OxArchiveError as e:
|
|
|
412
495
|
Full type hint support with Pydantic models:
|
|
413
496
|
|
|
414
497
|
```python
|
|
415
|
-
from oxarchive import Client
|
|
416
|
-
from oxarchive.types import OrderBook, Trade, Instrument, FundingRate, OpenInterest
|
|
498
|
+
from oxarchive import Client, LighterGranularity
|
|
499
|
+
from oxarchive.types import OrderBook, Trade, Instrument, LighterInstrument, FundingRate, OpenInterest
|
|
417
500
|
from oxarchive.resources.trades import CursorResponse
|
|
418
501
|
|
|
419
502
|
client = Client(api_key="ox_your_api_key")
|
|
@@ -421,6 +504,9 @@ client = Client(api_key="ox_your_api_key")
|
|
|
421
504
|
orderbook: OrderBook = client.orderbook.get("BTC")
|
|
422
505
|
trades: list[Trade] = client.trades.recent("BTC")
|
|
423
506
|
result: CursorResponse = client.trades.list("BTC", start=..., end=...)
|
|
507
|
+
|
|
508
|
+
# Lighter granularity type hint
|
|
509
|
+
granularity: LighterGranularity = "10s"
|
|
424
510
|
```
|
|
425
511
|
|
|
426
512
|
## Requirements
|
|
@@ -23,10 +23,12 @@ Example:
|
|
|
23
23
|
|
|
24
24
|
from .client import Client
|
|
25
25
|
from .exchanges import HyperliquidClient, LighterClient
|
|
26
|
+
from .resources.orderbook import LighterGranularity
|
|
26
27
|
from .types import (
|
|
27
28
|
OrderBook,
|
|
28
29
|
Trade,
|
|
29
30
|
Instrument,
|
|
31
|
+
LighterInstrument,
|
|
30
32
|
FundingRate,
|
|
31
33
|
OpenInterest,
|
|
32
34
|
OxArchiveError,
|
|
@@ -63,7 +65,7 @@ except ImportError:
|
|
|
63
65
|
OxArchiveWs = None # type: ignore
|
|
64
66
|
WsOptions = None # type: ignore
|
|
65
67
|
|
|
66
|
-
__version__ = "0.4.
|
|
68
|
+
__version__ = "0.4.4"
|
|
67
69
|
|
|
68
70
|
__all__ = [
|
|
69
71
|
# Client
|
|
@@ -78,6 +80,8 @@ __all__ = [
|
|
|
78
80
|
"OrderBook",
|
|
79
81
|
"Trade",
|
|
80
82
|
"Instrument",
|
|
83
|
+
"LighterInstrument",
|
|
84
|
+
"LighterGranularity",
|
|
81
85
|
"FundingRate",
|
|
82
86
|
"OpenInterest",
|
|
83
87
|
"OxArchiveError",
|
|
@@ -7,6 +7,7 @@ from .resources import (
|
|
|
7
7
|
OrderBookResource,
|
|
8
8
|
TradesResource,
|
|
9
9
|
InstrumentsResource,
|
|
10
|
+
LighterInstrumentsResource,
|
|
10
11
|
FundingResource,
|
|
11
12
|
OpenInterestResource,
|
|
12
13
|
)
|
|
@@ -54,6 +55,8 @@ class LighterClient:
|
|
|
54
55
|
>>> client = oxarchive.Client(api_key="...")
|
|
55
56
|
>>> orderbook = client.lighter.orderbook.get("BTC")
|
|
56
57
|
>>> trades = client.lighter.trades.list("ETH", start=..., end=...)
|
|
58
|
+
>>> instruments = client.lighter.instruments.list()
|
|
59
|
+
>>> print(f"ETH taker fee: {instruments[0].taker_fee}")
|
|
57
60
|
"""
|
|
58
61
|
|
|
59
62
|
def __init__(self, http: HttpClient):
|
|
@@ -66,8 +69,8 @@ class LighterClient:
|
|
|
66
69
|
self.trades = TradesResource(http, base_path)
|
|
67
70
|
"""Trade/fill history"""
|
|
68
71
|
|
|
69
|
-
self.instruments =
|
|
70
|
-
"""Trading instruments metadata"""
|
|
72
|
+
self.instruments = LighterInstrumentsResource(http, base_path)
|
|
73
|
+
"""Trading instruments metadata (returns LighterInstrument with fees, min amounts, etc.)"""
|
|
71
74
|
|
|
72
75
|
self.funding = FundingResource(http, base_path)
|
|
73
76
|
"""Funding rates"""
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from .orderbook import OrderBookResource
|
|
4
4
|
from .trades import TradesResource
|
|
5
|
-
from .instruments import InstrumentsResource
|
|
5
|
+
from .instruments import InstrumentsResource, LighterInstrumentsResource
|
|
6
6
|
from .funding import FundingResource
|
|
7
7
|
from .openinterest import OpenInterestResource
|
|
8
8
|
|
|
@@ -10,6 +10,7 @@ __all__ = [
|
|
|
10
10
|
"OrderBookResource",
|
|
11
11
|
"TradesResource",
|
|
12
12
|
"InstrumentsResource",
|
|
13
|
+
"LighterInstrumentsResource",
|
|
13
14
|
"FundingResource",
|
|
14
15
|
"OpenInterestResource",
|
|
15
16
|
]
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"""Instruments API resource."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from ..http import HttpClient
|
|
6
|
+
from ..types import Instrument, LighterInstrument
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class InstrumentsResource:
|
|
10
|
+
"""
|
|
11
|
+
Instruments API resource.
|
|
12
|
+
|
|
13
|
+
Example:
|
|
14
|
+
>>> # List all instruments
|
|
15
|
+
>>> instruments = client.instruments.list()
|
|
16
|
+
>>>
|
|
17
|
+
>>> # Get specific instrument
|
|
18
|
+
>>> btc = client.instruments.get("BTC")
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, http: HttpClient, base_path: str = "/v1"):
|
|
22
|
+
self._http = http
|
|
23
|
+
self._base_path = base_path
|
|
24
|
+
|
|
25
|
+
def list(self) -> list[Instrument]:
|
|
26
|
+
"""
|
|
27
|
+
List all available trading instruments.
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
List of instruments
|
|
31
|
+
"""
|
|
32
|
+
data = self._http.get(f"{self._base_path}/instruments")
|
|
33
|
+
return [Instrument.model_validate(item) for item in data["data"]]
|
|
34
|
+
|
|
35
|
+
async def alist(self) -> list[Instrument]:
|
|
36
|
+
"""Async version of list()."""
|
|
37
|
+
data = await self._http.aget(f"{self._base_path}/instruments")
|
|
38
|
+
return [Instrument.model_validate(item) for item in data["data"]]
|
|
39
|
+
|
|
40
|
+
def get(self, coin: str) -> Instrument:
|
|
41
|
+
"""
|
|
42
|
+
Get a specific instrument by coin symbol.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
coin: The coin symbol (e.g., 'BTC', 'ETH')
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
Instrument details
|
|
49
|
+
"""
|
|
50
|
+
data = self._http.get(f"{self._base_path}/instruments/{coin.upper()}")
|
|
51
|
+
return Instrument.model_validate(data["data"])
|
|
52
|
+
|
|
53
|
+
async def aget(self, coin: str) -> Instrument:
|
|
54
|
+
"""Async version of get()."""
|
|
55
|
+
data = await self._http.aget(f"{self._base_path}/instruments/{coin.upper()}")
|
|
56
|
+
return Instrument.model_validate(data["data"])
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class LighterInstrumentsResource:
|
|
60
|
+
"""
|
|
61
|
+
Lighter.xyz Instruments API resource.
|
|
62
|
+
|
|
63
|
+
Lighter instruments have a different schema than Hyperliquid with more
|
|
64
|
+
detailed market configuration including fees and minimum amounts.
|
|
65
|
+
|
|
66
|
+
Example:
|
|
67
|
+
>>> # List all Lighter instruments
|
|
68
|
+
>>> instruments = client.lighter.instruments.list()
|
|
69
|
+
>>>
|
|
70
|
+
>>> # Get specific instrument
|
|
71
|
+
>>> btc = client.lighter.instruments.get("BTC")
|
|
72
|
+
>>> print(f"Taker fee: {btc.taker_fee}")
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
def __init__(self, http: HttpClient, base_path: str = "/v1/lighter"):
|
|
76
|
+
self._http = http
|
|
77
|
+
self._base_path = base_path
|
|
78
|
+
|
|
79
|
+
def list(self) -> list[LighterInstrument]:
|
|
80
|
+
"""
|
|
81
|
+
List all available Lighter trading instruments.
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
List of Lighter instruments with full market configuration
|
|
85
|
+
"""
|
|
86
|
+
data = self._http.get(f"{self._base_path}/instruments")
|
|
87
|
+
return [LighterInstrument.model_validate(item) for item in data["data"]]
|
|
88
|
+
|
|
89
|
+
async def alist(self) -> list[LighterInstrument]:
|
|
90
|
+
"""Async version of list()."""
|
|
91
|
+
data = await self._http.aget(f"{self._base_path}/instruments")
|
|
92
|
+
return [LighterInstrument.model_validate(item) for item in data["data"]]
|
|
93
|
+
|
|
94
|
+
def get(self, coin: str) -> LighterInstrument:
|
|
95
|
+
"""
|
|
96
|
+
Get a specific Lighter instrument by coin symbol.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
coin: The coin symbol (e.g., 'BTC', 'ETH')
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
Lighter instrument details with full market configuration
|
|
103
|
+
"""
|
|
104
|
+
data = self._http.get(f"{self._base_path}/instruments/{coin.upper()}")
|
|
105
|
+
return LighterInstrument.model_validate(data["data"])
|
|
106
|
+
|
|
107
|
+
async def aget(self, coin: str) -> LighterInstrument:
|
|
108
|
+
"""Async version of get()."""
|
|
109
|
+
data = await self._http.aget(f"{self._base_path}/instruments/{coin.upper()}")
|
|
110
|
+
return LighterInstrument.model_validate(data["data"])
|
|
@@ -6,8 +6,13 @@ from datetime import datetime
|
|
|
6
6
|
from typing import Optional, Union
|
|
7
7
|
|
|
8
8
|
from ..http import HttpClient
|
|
9
|
+
from typing import Literal
|
|
10
|
+
|
|
9
11
|
from ..types import CursorResponse, OrderBook, Timestamp
|
|
10
12
|
|
|
13
|
+
# Lighter orderbook granularity levels (Lighter.xyz only)
|
|
14
|
+
LighterGranularity = Literal["checkpoint", "30s", "10s", "1s", "tick"]
|
|
15
|
+
|
|
11
16
|
|
|
12
17
|
class OrderBookResource:
|
|
13
18
|
"""
|
|
@@ -101,6 +106,7 @@ class OrderBookResource:
|
|
|
101
106
|
cursor: Optional[Timestamp] = None,
|
|
102
107
|
limit: Optional[int] = None,
|
|
103
108
|
depth: Optional[int] = None,
|
|
109
|
+
granularity: Optional[LighterGranularity] = None,
|
|
104
110
|
) -> CursorResponse[list[OrderBook]]:
|
|
105
111
|
"""
|
|
106
112
|
Get historical order book snapshots with cursor-based pagination.
|
|
@@ -112,6 +118,9 @@ class OrderBookResource:
|
|
|
112
118
|
cursor: Cursor from previous response's next_cursor (timestamp)
|
|
113
119
|
limit: Maximum number of results (default: 100, max: 1000)
|
|
114
120
|
depth: Number of price levels per side
|
|
121
|
+
granularity: Data resolution for Lighter orderbook (Lighter.xyz only, ignored for Hyperliquid).
|
|
122
|
+
Options: 'checkpoint' (1min, default), '30s', '10s', '1s', 'tick'.
|
|
123
|
+
Tier restrictions apply. Credit multipliers: checkpoint=1x, 30s=2x, 10s=3x, 1s=10x, tick=20x.
|
|
115
124
|
|
|
116
125
|
Returns:
|
|
117
126
|
CursorResponse with order book snapshots and next_cursor for pagination
|
|
@@ -124,6 +133,11 @@ class OrderBookResource:
|
|
|
124
133
|
... "BTC", start=start, end=end, cursor=result.next_cursor, limit=1000
|
|
125
134
|
... )
|
|
126
135
|
... snapshots.extend(result.data)
|
|
136
|
+
>>>
|
|
137
|
+
>>> # Lighter.xyz with 10s granularity (Build+ tier)
|
|
138
|
+
>>> result = client.lighter.orderbook.history(
|
|
139
|
+
... "BTC", start=start, end=end, granularity="10s"
|
|
140
|
+
... )
|
|
127
141
|
"""
|
|
128
142
|
data = self._http.get(
|
|
129
143
|
f"{self._base_path}/orderbook/{coin.upper()}/history",
|
|
@@ -133,6 +147,7 @@ class OrderBookResource:
|
|
|
133
147
|
"cursor": self._convert_timestamp(cursor),
|
|
134
148
|
"limit": limit,
|
|
135
149
|
"depth": depth,
|
|
150
|
+
"granularity": granularity,
|
|
136
151
|
},
|
|
137
152
|
)
|
|
138
153
|
return CursorResponse(
|
|
@@ -149,8 +164,9 @@ class OrderBookResource:
|
|
|
149
164
|
cursor: Optional[Timestamp] = None,
|
|
150
165
|
limit: Optional[int] = None,
|
|
151
166
|
depth: Optional[int] = None,
|
|
167
|
+
granularity: Optional[LighterGranularity] = None,
|
|
152
168
|
) -> CursorResponse[list[OrderBook]]:
|
|
153
|
-
"""Async version of history(). start and end are required."""
|
|
169
|
+
"""Async version of history(). start and end are required. See history() for granularity details."""
|
|
154
170
|
data = await self._http.aget(
|
|
155
171
|
f"{self._base_path}/orderbook/{coin.upper()}/history",
|
|
156
172
|
params={
|
|
@@ -159,6 +175,7 @@ class OrderBookResource:
|
|
|
159
175
|
"cursor": self._convert_timestamp(cursor),
|
|
160
176
|
"limit": limit,
|
|
161
177
|
"depth": depth,
|
|
178
|
+
"granularity": granularity,
|
|
162
179
|
},
|
|
163
180
|
)
|
|
164
181
|
return CursorResponse(
|
|
@@ -140,7 +140,7 @@ class Trade(BaseModel):
|
|
|
140
140
|
|
|
141
141
|
|
|
142
142
|
class Instrument(BaseModel):
|
|
143
|
-
"""Trading instrument specification."""
|
|
143
|
+
"""Trading instrument specification (Hyperliquid)."""
|
|
144
144
|
|
|
145
145
|
model_config = {"populate_by_name": True}
|
|
146
146
|
|
|
@@ -163,6 +163,53 @@ class Instrument(BaseModel):
|
|
|
163
163
|
"""Whether the instrument is currently tradeable."""
|
|
164
164
|
|
|
165
165
|
|
|
166
|
+
class LighterInstrument(BaseModel):
|
|
167
|
+
"""Trading instrument specification (Lighter.xyz).
|
|
168
|
+
|
|
169
|
+
Lighter instruments have a different schema than Hyperliquid with more
|
|
170
|
+
detailed market configuration including fees and minimum amounts.
|
|
171
|
+
"""
|
|
172
|
+
|
|
173
|
+
symbol: str
|
|
174
|
+
"""Instrument symbol (e.g., BTC, ETH)."""
|
|
175
|
+
|
|
176
|
+
market_id: int
|
|
177
|
+
"""Unique market identifier."""
|
|
178
|
+
|
|
179
|
+
market_type: str
|
|
180
|
+
"""Market type (e.g., 'perp')."""
|
|
181
|
+
|
|
182
|
+
status: str
|
|
183
|
+
"""Market status (e.g., 'active')."""
|
|
184
|
+
|
|
185
|
+
taker_fee: float
|
|
186
|
+
"""Taker fee rate (e.g., 0.0005 = 0.05%)."""
|
|
187
|
+
|
|
188
|
+
maker_fee: float
|
|
189
|
+
"""Maker fee rate (e.g., 0.0002 = 0.02%)."""
|
|
190
|
+
|
|
191
|
+
liquidation_fee: float
|
|
192
|
+
"""Liquidation fee rate."""
|
|
193
|
+
|
|
194
|
+
min_base_amount: float
|
|
195
|
+
"""Minimum order size in base currency."""
|
|
196
|
+
|
|
197
|
+
min_quote_amount: float
|
|
198
|
+
"""Minimum order size in quote currency."""
|
|
199
|
+
|
|
200
|
+
size_decimals: int
|
|
201
|
+
"""Size decimal precision."""
|
|
202
|
+
|
|
203
|
+
price_decimals: int
|
|
204
|
+
"""Price decimal precision."""
|
|
205
|
+
|
|
206
|
+
quote_decimals: int
|
|
207
|
+
"""Quote currency decimal precision."""
|
|
208
|
+
|
|
209
|
+
is_active: bool
|
|
210
|
+
"""Whether the instrument is currently tradeable."""
|
|
211
|
+
|
|
212
|
+
|
|
166
213
|
# =============================================================================
|
|
167
214
|
# Funding Types
|
|
168
215
|
# =============================================================================
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
"""Instruments API resource."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from ..http import HttpClient
|
|
6
|
-
from ..types import Instrument
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class InstrumentsResource:
|
|
10
|
-
"""
|
|
11
|
-
Instruments API resource.
|
|
12
|
-
|
|
13
|
-
Example:
|
|
14
|
-
>>> # List all instruments
|
|
15
|
-
>>> instruments = client.instruments.list()
|
|
16
|
-
>>>
|
|
17
|
-
>>> # Get specific instrument
|
|
18
|
-
>>> btc = client.instruments.get("BTC")
|
|
19
|
-
"""
|
|
20
|
-
|
|
21
|
-
def __init__(self, http: HttpClient, base_path: str = "/v1"):
|
|
22
|
-
self._http = http
|
|
23
|
-
self._base_path = base_path
|
|
24
|
-
|
|
25
|
-
def list(self) -> list[Instrument]:
|
|
26
|
-
"""
|
|
27
|
-
List all available trading instruments.
|
|
28
|
-
|
|
29
|
-
Returns:
|
|
30
|
-
List of instruments
|
|
31
|
-
"""
|
|
32
|
-
data = self._http.get(f"{self._base_path}/instruments")
|
|
33
|
-
return [Instrument.model_validate(item) for item in data["data"]]
|
|
34
|
-
|
|
35
|
-
async def alist(self) -> list[Instrument]:
|
|
36
|
-
"""Async version of list()."""
|
|
37
|
-
data = await self._http.aget(f"{self._base_path}/instruments")
|
|
38
|
-
return [Instrument.model_validate(item) for item in data["data"]]
|
|
39
|
-
|
|
40
|
-
def get(self, coin: str) -> Instrument:
|
|
41
|
-
"""
|
|
42
|
-
Get a specific instrument by coin symbol.
|
|
43
|
-
|
|
44
|
-
Args:
|
|
45
|
-
coin: The coin symbol (e.g., 'BTC', 'ETH')
|
|
46
|
-
|
|
47
|
-
Returns:
|
|
48
|
-
Instrument details
|
|
49
|
-
"""
|
|
50
|
-
data = self._http.get(f"{self._base_path}/instruments/{coin.upper()}")
|
|
51
|
-
return Instrument.model_validate(data["data"])
|
|
52
|
-
|
|
53
|
-
async def aget(self, coin: str) -> Instrument:
|
|
54
|
-
"""Async version of get()."""
|
|
55
|
-
data = await self._http.aget(f"{self._base_path}/instruments/{coin.upper()}")
|
|
56
|
-
return Instrument.model_validate(data["data"])
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|