Skip to content

Commit dc82f12

Browse files
Resolve "150 add the legacy OrderbookClient for Krakens websocket API v1" (#151)
1 parent e2ab268 commit dc82f12

25 files changed

Lines changed: 10787 additions & 125 deletions

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Available Clients:
4444

4545
- Spot REST Clients
4646
- Spot Websocket Clients (Websocket API v1 and v2)
47-
- Spot Orderbook Client
47+
- Spot Orderbook Client (Websocket API v1 and v2)
4848
- Futures REST Clients
4949
- Futures Websocket Client
5050

@@ -70,6 +70,9 @@ Documentation:
7070
not match with the content of the latest release. - Please have a look at the
7171
release specific READMEs and changelogs.
7272

73+
It is also recommended to _pin the used version_ to avoid unexpected behavior on
74+
new releases.
75+
7376
---
7477

7578
## Table of Contents
@@ -124,7 +127,7 @@ in `examples/spot_trading_bot_template_v2.py`.
124127

125128
For those who need a realtime order book - a script that demonstrates how to
126129
maintain a valid order book using the Orderbook client can be found in
127-
`examples/spot_orderbook.py`.
130+
`examples/spot_orderbook_v2.py`.
128131

129132
<a name="spotrest"></a>
130133

docs/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
.. GitHub: https://github.com/btschwertfeger
44
..
55
.. Python Kraken SDK documentation master file, created by
6-
sphinx-quickstart on Sun Apr 2 11:32:02 2023.
6+
sphinx-quickstart on Sun Apr, 2 11:32:02 2023.
77
You can adapt this file completely to your liking, but it should at least
88
contain the root ``toctree``` directive.
99

docs/src/examples/spot_orderbook.rst

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,23 @@
77
Maintain a valid Spot order book
88
--------------------------------
99

10-
The following example demonstrate how to use the python-kraken-sdk to retrieve a
11-
valid realtime orderbook. The current implementation of the
12-
:class:`kraken.spot.OrderbookClient` uses the Kraken Spot API v1 but will be
13-
updated soon to use the websocket API v2.
10+
The following examples demonstrate how to use the python-kraken-sdk to retrieve
11+
valid realtime orderbooks. The current implementation of the
12+
:class:`kraken.spot.OrderbookClientV2` uses the websocket API v2 and
13+
:class:`kraken.spot.OrderbookClientV1` provides the legacy support for websocket
14+
API v2.
1415

15-
References:
16-
- https://gist.github.com/btschwertfeger/6eea0eeff193f7cd1b262cfce4f0eb51
16+
.. literalinclude:: ../../../examples/spot_orderbook_v2.py
17+
:language: python
18+
:linenos:
19+
:caption: Sample on how to maintain a valid orderbook w/ websocket API v2
1720

1821

19-
.. literalinclude:: ../../../examples/spot_orderbook.py
22+
.. literalinclude:: ../../../examples/spot_orderbook_v1.py
2023
:language: python
2124
:linenos:
22-
:caption: Sample on how to maintain a valid orderbook using the python-kraken-sdk
25+
:caption: Sample on how to maintain a valid orderbook w/ websocket API v1
26+
27+
28+
References:
29+
- https://gist.github.com/btschwertfeger/6eea0eeff193f7cd1b262cfce4f0eb51

docs/src/introduction.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Available Clients:
5454

5555
- Spot REST Clients
5656
- Spot Websocket Clients (Websocket API v1 and v2)
57-
- Spot Orderbook Client
57+
- Spot Orderbook Client (Websocket API v1 and v2)
5858
- Futures REST Clients
5959
- Futures Websocket Client
6060

docs/src/spot/websockets.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@ Spot Websockets
1515
:show-inheritance:
1616
:inherited-members:
1717

18-
.. autoclass:: kraken.spot.OrderbookClient
18+
.. autoclass:: kraken.spot.OrderbookClientV2
19+
:members:
20+
:show-inheritance:
21+
:inherited-members:
22+
23+
.. autoclass:: kraken.spot.OrderbookClientV1
1924
:members:
2025
:show-inheritance:
2126
:inherited-members:

examples/spot_orderbook_v1.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
# Copyright (C) 2023 Benjamin Thomas Schwertfeger
4+
# GitHub: https://github.com/btschwertfeger
5+
#
6+
7+
"""
8+
9+
**For websocket API v1**
10+
11+
This module provides an example on how to use the Spot Orderbook client of the
12+
python-kraken-sdk (https://github.com/btschwertfeger/python-kraken-sdk) to
13+
retrieve and maintain a valid Spot order book for (a) specific asset pair(s).
14+
It can be run directly without any credentials if the python-kraken-sdk is
15+
installed.
16+
17+
python3 -m pip install python-kraken-sdk
18+
19+
The output when running this snippet looks like the following table and updates
20+
the book as soon as Kraken sent any order book update.
21+
22+
Bid Volume Ask Volume
23+
27076.00000 (8.28552127) 27076.10000 (2.85897056)
24+
27075.90000 (3.75748052) 27077.30000 (0.57243521)
25+
27074.40000 (0.57249652) 27080.80000 (0.00100000)
26+
27072.90000 (0.01200917) 27081.00000 (0.00012345)
27+
27072.80000 (0.25000000) 27081.70000 (0.30000000)
28+
27072.30000 (4.89735970) 27082.70000 (0.05539777)
29+
27072.20000 (2.65896716) 27082.80000 (0.00400000)
30+
27072.10000 (2.77037635) 27082.90000 (0.57231684)
31+
27072.00000 (0.81770000) 27083.00000 (0.38934000)
32+
27071.50000 (0.07194657) 27083.80000 (2.76918992)
33+
34+
This can be the basis of an order book based trading strategy where realtime
35+
data and fast price movements are considered.
36+
"""
37+
38+
from __future__ import annotations
39+
40+
import asyncio
41+
from typing import Any
42+
43+
from kraken.spot import OrderbookClientV1
44+
45+
46+
class Orderbook(OrderbookClientV1):
47+
"""
48+
This is a wrapper class that is used to overload the :func:`on_book_update`
49+
function. It can also be used as a base for trading strategy. Since the
50+
:class:`kraken.spot.OrderbookClientV1` is derived from
51+
:class:`kraken.spot.KrakenSpotWSClient` it can also be used to access the
52+
:func:`subscribe` function and any other provided utility.
53+
"""
54+
55+
async def on_book_update(self: Orderbook, pair: str, message: list) -> None:
56+
"""
57+
This function is called every time the order book of ``pair`` gets
58+
updated.
59+
60+
The ``pair`` parameter can be used to access the updated order book as
61+
shown in the function body below.
62+
63+
:param pair: The currency pair of the updated order book
64+
:type pair: str
65+
:param message: The message sent by Kraken (not needed in most cases)
66+
:type message: list
67+
"""
68+
69+
book: dict[str, Any] = self.get(pair=pair)
70+
bid: list[tuple[str, str]] = list(book["bid"].items())
71+
ask: list[tuple[str, str]] = list(book["ask"].items())
72+
73+
print("Bid Volume\t\t Ask Volume")
74+
for level in range(self.depth):
75+
print(
76+
f"{bid[level][0]} ({bid[level][1][0]}) \t {ask[level][0]} ({ask[level][1][0]})",
77+
)
78+
# assert book["valid"] # ensure that the checksum is valid (will be
79+
# false after reconnect -- but the client handles the removal and
80+
# resubscription of the book)
81+
82+
83+
async def main() -> None:
84+
"""
85+
Here we depth of the order book and also a pair. We could
86+
subscribe to multiple pairs, but for simplicity only XBT/USD is chosen.
87+
88+
The Orderbook class can be instantiated, which receives the order
89+
book-related messages, after we subscribed to the book feed.
90+
91+
Finally we need some "game loop" - so we create a while loop
92+
that runs as long as there is no error.
93+
"""
94+
orderbook: Orderbook = Orderbook()
95+
96+
await orderbook.add_book(
97+
pairs=["XBT/USD"], # we can also subscribe to more currency pairs
98+
)
99+
100+
while not orderbook.exception_occur:
101+
await asyncio.sleep(10)
102+
103+
104+
if __name__ == "__main__":
105+
try:
106+
asyncio.run(main())
107+
except KeyboardInterrupt:
108+
print("KeyboardInterrupt!")
Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
#
66

77
"""
8+
9+
**For websocket API v2**
10+
811
This module provides an example on how to use the Spot Orderbook client of the
912
python-kraken-sdk (https://github.com/btschwertfeger/python-kraken-sdk) to
1013
retrieve and maintain a valid Spot order book for (a) specific asset pair(s).
@@ -36,9 +39,9 @@
3639

3740
import asyncio
3841
import logging
39-
from typing import Any, Dict, List, Tuple
42+
from typing import Any
4043

41-
from kraken.spot import OrderbookClient
44+
from kraken.spot import OrderbookClientV2
4245

4346
logging.basicConfig(
4447
format="%(asctime)s %(module)s,line: %(lineno)d %(levelname)8s | %(message)s",
@@ -49,13 +52,13 @@
4952
logging.getLogger("requests").setLevel(logging.WARNING)
5053

5154

52-
class Orderbook(OrderbookClient):
55+
class Orderbook(OrderbookClientV2):
5356
"""
5457
This is a wrapper class that is used to overload the :func:`on_book_update`
5558
function. It can also be used as a base for trading strategy. Since the
56-
:class:`OrderbookClient` is derived from :class:`KrakenSpotWSClient`
57-
it can also be used to access the :func:`subscribe` function and any
58-
other provided utility.
59+
:class:`kraken.spot.OrderbookClientV2` is derived from
60+
:class:`kraken.spot.KrakenSpotWSClientV2` it can also be used to access the
61+
:func:`subscribe` function and any other provided utility.
5962
"""
6063

6164
async def on_book_update(self: Orderbook, pair: str, message: list) -> None:
@@ -71,9 +74,9 @@ async def on_book_update(self: Orderbook, pair: str, message: list) -> None:
7174
:param message: The message sent by Kraken (not needed in most cases)
7275
:type message: list
7376
"""
74-
book: Dict[str, Any] = self.get(pair=pair)
75-
bid: List[Tuple[str, str]] = list(book["bid"].items())
76-
ask: List[Tuple[str, str]] = list(book["ask"].items())
77+
book: dict[str, Any] = self.get(pair=pair)
78+
bid: list[tuple[str, str]] = list(book["bid"].items())
79+
ask: list[tuple[str, str]] = list(book["ask"].items())
7780

7881
print("Bid Volume\t\t Ask Volume")
7982
for level in range(self.depth):

kraken/futures/ws_client.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ async def unsubscribe(
254254
:param feed: The websocket feed/channel to unsubscribe from
255255
:type feed: str
256256
:param products: The products/futures contracts to unsubscribe from
257-
:type products: List[str], optional
257+
:type products: list[str], optional
258258
:raises TypeError: If the parameters don't match the requirements set
259259
by the Kraken API
260260
@@ -306,7 +306,7 @@ def get_available_public_subscription_feeds() -> list[str]:
306306
Kraken Futures API.
307307
308308
:return: List of available public feeds
309-
:rtype: List[str]
309+
:rtype: list[str]
310310
311311
.. code-block:: python
312312
:linenos:
@@ -328,7 +328,7 @@ def get_available_private_subscription_feeds() -> list[str]:
328328
using the Kraken Futures API
329329
330330
:return: List of available private feeds
331-
:rtype: List[str]
331+
:rtype: list[str]
332332
333333
.. code-block:: python
334334
:linenos:
@@ -384,7 +384,7 @@ def get_active_subscriptions(self: KrakenFuturesWSClient) -> list[dict]:
384384
385385
:return: List of active subscriptions including the feed names, products
386386
and additional information.
387-
:rtype: List[dict]
387+
:rtype: list[dict]
388388
389389
Initialize your client as described in :class:`kraken.futures.KrakenFuturesWSClient` to
390390
run the following example:

kraken/spot/__init__.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88

99
from kraken.spot.funding import Funding
1010
from kraken.spot.market import Market
11-
from kraken.spot.orderbook import OrderbookClient
11+
from kraken.spot.orderbook_v1 import OrderbookClientV1
12+
from kraken.spot.orderbook_v2 import OrderbookClientV2
1213
from kraken.spot.staking import Staking
1314
from kraken.spot.trade import Trade
1415
from kraken.spot.user import User
@@ -18,10 +19,11 @@
1819
__all__ = [
1920
"Funding",
2021
"Market",
21-
"OrderbookClient",
2222
"Staking",
2323
"Trade",
2424
"User",
25+
"OrderbookClientV1",
26+
"OrderbookClientV2",
2527
"KrakenSpotWSClient",
2628
"KrakenSpotWSClientV2",
2729
]

0 commit comments

Comments
 (0)