oxarchive 0.4.4__tar.gz → 0.4.5__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.4 → oxarchive-0.4.5}/PKG-INFO +22 -1
- {oxarchive-0.4.4 → oxarchive-0.4.5}/README.md +21 -0
- {oxarchive-0.4.4 → oxarchive-0.4.5}/oxarchive/__init__.py +1 -1
- {oxarchive-0.4.4 → oxarchive-0.4.5}/oxarchive/types.py +35 -0
- {oxarchive-0.4.4 → oxarchive-0.4.5}/oxarchive/websocket.py +31 -3
- {oxarchive-0.4.4 → oxarchive-0.4.5}/pyproject.toml +1 -1
- {oxarchive-0.4.4 → oxarchive-0.4.5}/.gitignore +0 -0
- {oxarchive-0.4.4 → oxarchive-0.4.5}/oxarchive/client.py +0 -0
- {oxarchive-0.4.4 → oxarchive-0.4.5}/oxarchive/exchanges.py +0 -0
- {oxarchive-0.4.4 → oxarchive-0.4.5}/oxarchive/http.py +0 -0
- {oxarchive-0.4.4 → oxarchive-0.4.5}/oxarchive/resources/__init__.py +0 -0
- {oxarchive-0.4.4 → oxarchive-0.4.5}/oxarchive/resources/funding.py +0 -0
- {oxarchive-0.4.4 → oxarchive-0.4.5}/oxarchive/resources/instruments.py +0 -0
- {oxarchive-0.4.4 → oxarchive-0.4.5}/oxarchive/resources/openinterest.py +0 -0
- {oxarchive-0.4.4 → oxarchive-0.4.5}/oxarchive/resources/orderbook.py +0 -0
- {oxarchive-0.4.4 → oxarchive-0.4.5}/oxarchive/resources/trades.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.5
|
|
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
|
|
@@ -418,6 +418,19 @@ async def main():
|
|
|
418
418
|
speed=10 # Optional, defaults to 1x
|
|
419
419
|
)
|
|
420
420
|
|
|
421
|
+
# Lighter.xyz replay with granularity (tier restrictions apply)
|
|
422
|
+
await ws.replay(
|
|
423
|
+
"orderbook", "BTC",
|
|
424
|
+
start=int(time.time() * 1000) - 86400000,
|
|
425
|
+
speed=10,
|
|
426
|
+
granularity="10s" # Options: 'checkpoint', '30s', '10s', '1s', 'tick'
|
|
427
|
+
)
|
|
428
|
+
|
|
429
|
+
# Handle tick-level data (granularity='tick', Enterprise tier)
|
|
430
|
+
ws.on_historical_tick_data(lambda coin, checkpoint, deltas:
|
|
431
|
+
print(f"Checkpoint: {len(checkpoint['bids'])} bids, Deltas: {len(deltas)}")
|
|
432
|
+
)
|
|
433
|
+
|
|
421
434
|
# Control playback
|
|
422
435
|
await ws.replay_pause()
|
|
423
436
|
await ws.replay_resume()
|
|
@@ -463,6 +476,14 @@ async def main():
|
|
|
463
476
|
batch_size=1000 # Optional, defaults to 1000
|
|
464
477
|
)
|
|
465
478
|
|
|
479
|
+
# Lighter.xyz stream with granularity (tier restrictions apply)
|
|
480
|
+
await ws.stream(
|
|
481
|
+
"orderbook", "BTC",
|
|
482
|
+
start=int(time.time() * 1000) - 3600000,
|
|
483
|
+
end=int(time.time() * 1000),
|
|
484
|
+
granularity="10s" # Options: 'checkpoint', '30s', '10s', '1s', 'tick'
|
|
485
|
+
)
|
|
486
|
+
|
|
466
487
|
# Stop if needed
|
|
467
488
|
await ws.stream_stop()
|
|
468
489
|
|
|
@@ -381,6 +381,19 @@ async def main():
|
|
|
381
381
|
speed=10 # Optional, defaults to 1x
|
|
382
382
|
)
|
|
383
383
|
|
|
384
|
+
# Lighter.xyz replay with granularity (tier restrictions apply)
|
|
385
|
+
await ws.replay(
|
|
386
|
+
"orderbook", "BTC",
|
|
387
|
+
start=int(time.time() * 1000) - 86400000,
|
|
388
|
+
speed=10,
|
|
389
|
+
granularity="10s" # Options: 'checkpoint', '30s', '10s', '1s', 'tick'
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
# Handle tick-level data (granularity='tick', Enterprise tier)
|
|
393
|
+
ws.on_historical_tick_data(lambda coin, checkpoint, deltas:
|
|
394
|
+
print(f"Checkpoint: {len(checkpoint['bids'])} bids, Deltas: {len(deltas)}")
|
|
395
|
+
)
|
|
396
|
+
|
|
384
397
|
# Control playback
|
|
385
398
|
await ws.replay_pause()
|
|
386
399
|
await ws.replay_resume()
|
|
@@ -426,6 +439,14 @@ async def main():
|
|
|
426
439
|
batch_size=1000 # Optional, defaults to 1000
|
|
427
440
|
)
|
|
428
441
|
|
|
442
|
+
# Lighter.xyz stream with granularity (tier restrictions apply)
|
|
443
|
+
await ws.stream(
|
|
444
|
+
"orderbook", "BTC",
|
|
445
|
+
start=int(time.time() * 1000) - 3600000,
|
|
446
|
+
end=int(time.time() * 1000),
|
|
447
|
+
granularity="10s" # Options: 'checkpoint', '30s', '10s', '1s', 'tick'
|
|
448
|
+
)
|
|
449
|
+
|
|
429
450
|
# Stop if needed
|
|
430
451
|
await ws.stream_stop()
|
|
431
452
|
|
|
@@ -382,6 +382,41 @@ class WsHistoricalData(BaseModel):
|
|
|
382
382
|
data: dict[str, Any]
|
|
383
383
|
|
|
384
384
|
|
|
385
|
+
class OrderbookDelta(BaseModel):
|
|
386
|
+
"""Orderbook delta for tick-level data."""
|
|
387
|
+
|
|
388
|
+
timestamp: int
|
|
389
|
+
"""Timestamp in milliseconds."""
|
|
390
|
+
|
|
391
|
+
side: Literal["bid", "ask"]
|
|
392
|
+
"""Side: 'bid' or 'ask'."""
|
|
393
|
+
|
|
394
|
+
price: float
|
|
395
|
+
"""Price level."""
|
|
396
|
+
|
|
397
|
+
size: float
|
|
398
|
+
"""New size (0 = level removed)."""
|
|
399
|
+
|
|
400
|
+
sequence: int
|
|
401
|
+
"""Sequence number for ordering."""
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
class WsHistoricalTickData(BaseModel):
|
|
405
|
+
"""Historical tick data (granularity='tick' mode) - checkpoint + deltas.
|
|
406
|
+
|
|
407
|
+
This message type is sent when using granularity='tick' for Lighter.xyz
|
|
408
|
+
orderbook data. It provides a full checkpoint followed by incremental deltas.
|
|
409
|
+
"""
|
|
410
|
+
|
|
411
|
+
type: Literal["historical_tick_data"]
|
|
412
|
+
channel: WsChannel
|
|
413
|
+
coin: str
|
|
414
|
+
checkpoint: dict[str, Any]
|
|
415
|
+
"""Initial checkpoint (full orderbook snapshot)."""
|
|
416
|
+
deltas: list[OrderbookDelta]
|
|
417
|
+
"""Incremental deltas to apply after checkpoint."""
|
|
418
|
+
|
|
419
|
+
|
|
385
420
|
# =============================================================================
|
|
386
421
|
# WebSocket Bulk Stream Types (Bulk Download Mode)
|
|
387
422
|
# =============================================================================
|
|
@@ -42,6 +42,7 @@ except ImportError:
|
|
|
42
42
|
|
|
43
43
|
from .types import (
|
|
44
44
|
OrderBook,
|
|
45
|
+
OrderbookDelta,
|
|
45
46
|
PriceLevel,
|
|
46
47
|
Trade,
|
|
47
48
|
WsChannel,
|
|
@@ -57,6 +58,7 @@ from .types import (
|
|
|
57
58
|
WsReplayCompleted,
|
|
58
59
|
WsReplayStopped,
|
|
59
60
|
WsHistoricalData,
|
|
61
|
+
WsHistoricalTickData,
|
|
60
62
|
WsStreamStarted,
|
|
61
63
|
WsStreamProgress,
|
|
62
64
|
WsHistoricalBatch,
|
|
@@ -110,6 +112,7 @@ ErrorHandler = Callable[[Exception], None]
|
|
|
110
112
|
|
|
111
113
|
# Replay handlers
|
|
112
114
|
HistoricalDataHandler = Callable[[str, int, dict], None]
|
|
115
|
+
HistoricalTickDataHandler = Callable[[str, dict, list[OrderbookDelta]], None] # coin, checkpoint, deltas
|
|
113
116
|
ReplayStartHandler = Callable[[WsChannel, str, int, int, float], None] # channel, coin, start, end, speed
|
|
114
117
|
ReplayCompleteHandler = Callable[[WsChannel, str, int], None] # channel, coin, snapshots_sent
|
|
115
118
|
|
|
@@ -276,6 +279,7 @@ class OxArchiveWs:
|
|
|
276
279
|
|
|
277
280
|
# Replay handlers (Option B)
|
|
278
281
|
self._on_historical_data: Optional[HistoricalDataHandler] = None
|
|
282
|
+
self._on_historical_tick_data: Optional[HistoricalTickDataHandler] = None
|
|
279
283
|
self._on_replay_start: Optional[ReplayStartHandler] = None
|
|
280
284
|
self._on_replay_complete: Optional[ReplayCompleteHandler] = None
|
|
281
285
|
|
|
@@ -307,7 +311,8 @@ class OxArchiveWs:
|
|
|
307
311
|
url = f"{self.options.ws_url}?apiKey={self.options.api_key}"
|
|
308
312
|
|
|
309
313
|
try:
|
|
310
|
-
|
|
314
|
+
# Increase max_size from default 1MB to 10MB for large Lighter orderbook data
|
|
315
|
+
self._ws = await ws_connect(url, max_size=10 * 1024 * 1024)
|
|
311
316
|
self._reconnect_attempts = 0
|
|
312
317
|
self._set_state("connected")
|
|
313
318
|
|
|
@@ -427,6 +432,7 @@ class OxArchiveWs:
|
|
|
427
432
|
start: int,
|
|
428
433
|
end: Optional[int] = None,
|
|
429
434
|
speed: float = 1.0,
|
|
435
|
+
granularity: Optional[str] = None,
|
|
430
436
|
) -> None:
|
|
431
437
|
"""Start historical replay with timing preserved.
|
|
432
438
|
|
|
@@ -436,6 +442,7 @@ class OxArchiveWs:
|
|
|
436
442
|
start: Start timestamp (Unix ms)
|
|
437
443
|
end: End timestamp (Unix ms, defaults to now)
|
|
438
444
|
speed: Playback speed multiplier (1 = real-time, 10 = 10x faster)
|
|
445
|
+
granularity: Data resolution for Lighter orderbook ('checkpoint', '30s', '10s', '1s', 'tick')
|
|
439
446
|
|
|
440
447
|
Example:
|
|
441
448
|
>>> await ws.replay("orderbook", "BTC", start=time.time()*1000 - 86400000, speed=10)
|
|
@@ -449,6 +456,8 @@ class OxArchiveWs:
|
|
|
449
456
|
}
|
|
450
457
|
if end is not None:
|
|
451
458
|
msg["end"] = end
|
|
459
|
+
if granularity is not None:
|
|
460
|
+
msg["granularity"] = granularity
|
|
452
461
|
await self._send(msg)
|
|
453
462
|
|
|
454
463
|
async def replay_pause(self) -> None:
|
|
@@ -482,6 +491,7 @@ class OxArchiveWs:
|
|
|
482
491
|
start: int,
|
|
483
492
|
end: int,
|
|
484
493
|
batch_size: int = 1000,
|
|
494
|
+
granularity: Optional[str] = None,
|
|
485
495
|
) -> None:
|
|
486
496
|
"""Start bulk streaming for fast data download.
|
|
487
497
|
|
|
@@ -491,18 +501,22 @@ class OxArchiveWs:
|
|
|
491
501
|
start: Start timestamp (Unix ms)
|
|
492
502
|
end: End timestamp (Unix ms)
|
|
493
503
|
batch_size: Records per batch message
|
|
504
|
+
granularity: Data resolution for Lighter orderbook ('checkpoint', '30s', '10s', '1s', 'tick')
|
|
494
505
|
|
|
495
506
|
Example:
|
|
496
507
|
>>> await ws.stream("orderbook", "ETH", start=..., end=..., batch_size=1000)
|
|
497
508
|
"""
|
|
498
|
-
|
|
509
|
+
msg = {
|
|
499
510
|
"op": "stream",
|
|
500
511
|
"channel": channel,
|
|
501
512
|
"coin": coin,
|
|
502
513
|
"start": start,
|
|
503
514
|
"end": end,
|
|
504
515
|
"batch_size": batch_size,
|
|
505
|
-
}
|
|
516
|
+
}
|
|
517
|
+
if granularity is not None:
|
|
518
|
+
msg["granularity"] = granularity
|
|
519
|
+
await self._send(msg)
|
|
506
520
|
|
|
507
521
|
async def stream_stop(self) -> None:
|
|
508
522
|
"""Stop the current bulk stream."""
|
|
@@ -547,6 +561,16 @@ class OxArchiveWs:
|
|
|
547
561
|
"""
|
|
548
562
|
self._on_historical_data = handler
|
|
549
563
|
|
|
564
|
+
def on_historical_tick_data(self, handler: HistoricalTickDataHandler) -> None:
|
|
565
|
+
"""Set handler for historical tick data (granularity='tick' mode).
|
|
566
|
+
|
|
567
|
+
This is for tick-level granularity on Lighter.xyz orderbook data.
|
|
568
|
+
Receives a checkpoint (full orderbook) followed by incremental deltas.
|
|
569
|
+
|
|
570
|
+
Handler receives: (coin, checkpoint, deltas)
|
|
571
|
+
"""
|
|
572
|
+
self._on_historical_tick_data = handler
|
|
573
|
+
|
|
550
574
|
def on_replay_start(self, handler: ReplayStartHandler) -> None:
|
|
551
575
|
"""Set handler for replay started event.
|
|
552
576
|
|
|
@@ -722,6 +746,10 @@ class OxArchiveWs:
|
|
|
722
746
|
elif msg_type == "historical_data" and self._on_historical_data:
|
|
723
747
|
self._on_historical_data(data["coin"], data["timestamp"], data["data"])
|
|
724
748
|
|
|
749
|
+
elif msg_type == "historical_tick_data" and self._on_historical_tick_data:
|
|
750
|
+
msg = WsHistoricalTickData(**data)
|
|
751
|
+
self._on_historical_tick_data(msg.coin, msg.checkpoint, msg.deltas)
|
|
752
|
+
|
|
725
753
|
elif msg_type == "replay_completed" and self._on_replay_complete:
|
|
726
754
|
self._on_replay_complete(data["channel"], data["coin"], data["snapshots_sent"])
|
|
727
755
|
|
|
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
|