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