Maintain a valid Spot Orderbook
The following examples demonstrate how to use the python-kraken-sdk to retrieve
valid realtime orderbooks. The current implementation of the
kraken.spot.OrderbookClientV2
uses the websocket API v2 and
kraken.spot.OrderbookClientV1
provides the legacy support for websocket
API v2.
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 v2**
10
11This module provides an example on how to use the Spot Orderbook client of the
12python-kraken-sdk (https://github.com/btschwertfeger/python-kraken-sdk) to
13retrieve and maintain a valid Spot order book for (a) specific asset pair(s).
14It can be run directly without any credentials if the python-kraken-sdk is
15installed.
16
17 python3 -m pip install python-kraken-sdk
18
19The output when running this snippet looks like the following table and updates
20the book as soon as Kraken sent any order book update.
21
22Bid Volume Ask Volume
2327076.00000 (8.28552127) 27076.10000 (2.85897056)
2427075.90000 (3.75748052) 27077.30000 (0.57243521)
2527074.40000 (0.57249652) 27080.80000 (0.00100000)
2627072.90000 (0.01200917) 27081.00000 (0.00012345)
2727072.80000 (0.25000000) 27081.70000 (0.30000000)
2827072.30000 (4.89735970) 27082.70000 (0.05539777)
2927072.20000 (2.65896716) 27082.80000 (0.00400000)
3027072.10000 (2.77037635) 27082.90000 (0.57231684)
3127072.00000 (0.81770000) 27083.00000 (0.38934000)
3227071.50000 (0.07194657) 27083.80000 (2.76918992)
33
34This can be the basis of an order book based trading strategy where realtime
35data and fast price movements are considered.
36"""
37
38from __future__ import annotations
39
40import asyncio
41import logging
42from typing import Any
43
44from kraken.spot import OrderbookClientV2
45
46logging.basicConfig(
47 format="%(asctime)s %(module)s,line: %(lineno)d %(levelname)8s | %(message)s",
48 datefmt="%Y/%m/%d %H:%M:%S",
49 level=logging.INFO,
50)
51logging.getLogger().setLevel(logging.INFO)
52logging.getLogger("requests").setLevel(logging.WARNING)
53
54
55class Orderbook(OrderbookClientV2):
56 """
57 This is a wrapper class that is used to overload the :func:`on_book_update`
58 function. It can also be used as a base for trading strategy. Since the
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.
62 """
63
64 async def on_book_update(
65 self: Orderbook,
66 pair: str,
67 message: list, # noqa: ARG002
68 ) -> None:
69 """
70 This function is called every time the order book of ``pair`` gets
71 updated.
72
73 The ``pair`` parameter can be used to access the updated order book as
74 shown in the function body below.
75
76 :param pair: The currency pair of the updated order book
77 :type pair: str
78 :param message: The message sent by Kraken (not needed in most cases)
79 :type message: list
80 """
81 book: dict[str, Any] = self.get(pair=pair)
82 bid: list[tuple[str, str]] = list(book["bid"].items())
83 ask: list[tuple[str, str]] = list(book["ask"].items())
84
85 print("Bid Volume\t\t Ask Volume")
86 for level in range(self.depth):
87 print(
88 f"{bid[level][0]} ({bid[level][1][0]}) \t {ask[level][0]} ({ask[level][1][0]})",
89 )
90
91 assert book["valid"] # ensure that the checksum is valid
92 # … the client will automatically resubscribe to a book feed if the
93 # checksum is not valid. The user must not do anything for that, but
94 # will get informed.
95
96
97async def main() -> None:
98 """
99 Here we depth of the order book and also a pair. We could
100 subscribe to multiple pairs, but for simplicity only XBT/USD is chosen.
101
102 The Orderbook class can be instantiated, which receives the order
103 book-related messages, after we subscribed to the book feed.
104
105 Finally we need some "game loop" - so we create a while loop
106 that runs as long as there is no error.
107 """
108 orderbook: Orderbook = Orderbook(depth=10)
109
110 await orderbook.add_book(
111 pairs=["BTC/USD"], # we can also subscribe to more currency pairs
112 )
113
114 while not orderbook.exception_occur:
115 await asyncio.sleep(10)
116
117
118if __name__ == "__main__":
119 try:
120 asyncio.run(main())
121 except KeyboardInterrupt:
122 print("KeyboardInterrupt!")
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
11This module provides an example on how to use the Spot Orderbook client of the
12python-kraken-sdk (https://github.com/btschwertfeger/python-kraken-sdk) to
13retrieve and maintain a valid Spot order book for (a) specific asset pair(s).
14It can be run directly without any credentials if the python-kraken-sdk is
15installed.
16
17 python3 -m pip install python-kraken-sdk
18
19The output when running this snippet looks like the following table and updates
20the book as soon as Kraken sent any order book update.
21
22Bid Volume Ask Volume
2327076.00000 (8.28552127) 27076.10000 (2.85897056)
2427075.90000 (3.75748052) 27077.30000 (0.57243521)
2527074.40000 (0.57249652) 27080.80000 (0.00100000)
2627072.90000 (0.01200917) 27081.00000 (0.00012345)
2727072.80000 (0.25000000) 27081.70000 (0.30000000)
2827072.30000 (4.89735970) 27082.70000 (0.05539777)
2927072.20000 (2.65896716) 27082.80000 (0.00400000)
3027072.10000 (2.77037635) 27082.90000 (0.57231684)
3127072.00000 (0.81770000) 27083.00000 (0.38934000)
3227071.50000 (0.07194657) 27083.80000 (2.76918992)
33
34This can be the basis of an order book based trading strategy where realtime
35data and fast price movements are considered.
36"""
37
38from __future__ import annotations
39
40import asyncio
41from typing import Any
42
43from kraken.spot import OrderbookClientV1
44
45
46class 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.KrakenSpotWSClientV1` 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(
56 self: Orderbook,
57 pair: str,
58 message: list, # noqa: ARG002
59 ) -> None:
60 """
61 This function is called every time the order book of ``pair`` gets
62 updated.
63
64 The ``pair`` parameter can be used to access the updated order book as
65 shown in the function body below.
66
67 :param pair: The currency pair of the updated order book
68 :type pair: str
69 :param message: The message sent by Kraken (not needed in most cases)
70 :type message: list
71 """
72
73 book: dict[str, Any] = self.get(pair=pair)
74 bid: list[tuple[str, str]] = list(book["bid"].items())
75 ask: list[tuple[str, str]] = list(book["ask"].items())
76
77 print("Bid Volume\t\t Ask Volume")
78 for level in range(self.depth):
79 print(
80 f"{bid[level][0]} ({bid[level][1][0]}) \t {ask[level][0]} ({ask[level][1][0]})",
81 )
82 # assert book["valid"] # ensure that the checksum is valid (will be
83 # false after reconnect -- but the client handles the removal and
84 # resubscription of the book)
85
86
87async def main() -> None:
88 """
89 Here we depth of the order book and also a pair. We could
90 subscribe to multiple pairs, but for simplicity only XBT/USD is chosen.
91
92 The Orderbook class can be instantiated, which receives the order
93 book-related messages, after we subscribed to the book feed.
94
95 Finally we need some "game loop" - so we create a while loop
96 that runs as long as there is no error.
97 """
98 orderbook: Orderbook = Orderbook()
99
100 await orderbook.add_book(
101 pairs=["XBT/USD"], # we can also subscribe to more currency pairs
102 )
103
104 while not orderbook.exception_occur:
105 await asyncio.sleep(10)
106
107
108if __name__ == "__main__":
109 try:
110 asyncio.run(main())
111 except KeyboardInterrupt:
112 print("KeyboardInterrupt!")
References: - https://gist.github.com/btschwertfeger/6eea0eeff193f7cd1b262cfce4f0eb51