Spot Websocket¶
The examples presented below serve to demonstrate the usage of the Spot websocket clients provided by python-kraken-sdk to access Kraken’s Websocket API v2.
For questions, feedback, additions, suggestions for improvement or problems python-kraken-sdk/discussions or python-kraken-sdk/issues may be helpful.
Example access and usage for Kraken Spot 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# SPDX-License-Identifier: Apache-2.0
9#
10
11"""
12Module that provides an example usage for the KrakenSpotWebsocketClient.
13It uses the Kraken Websocket API v2.
14"""
15
16from __future__ import annotations
17
18import asyncio
19import logging
20import os
21
22from kraken.spot import SpotWSClient
23
24logging.basicConfig(
25 format="%(asctime)s %(module)s,line: %(lineno)d %(levelname)8s | %(message)s",
26 datefmt="%Y/%m/%d %H:%M:%S",
27 level=logging.INFO,
28)
29logging.getLogger("requests").setLevel(logging.WARNING)
30logging.getLogger("urllib3").setLevel(logging.WARNING)
31
32clients = []
33
34
35class Client(SpotWSClient):
36 """Can be used to create a custom trading strategy"""
37
38 async def on_message(self: Client, message: dict) -> None:
39 """Receives the websocket messages"""
40 if message.get("method") == "pong" or message.get("channel") == "heartbeat":
41 return
42
43 print(message)
44 # now you can access lots of methods, for example to create an order:
45 # if self._is_auth: # only if the client is authenticated …
46 # await self.send_message(
47 # message={
48 # "method": "add_order",
49 # "params": {
50 # "limit_price": 1234.56,
51 # "order_type": "limit",
52 # "order_userref": 123456789,
53 # "order_qty": 1.0,
54 # "side": "buy",
55 # "symbol": "BTC/USD",
56 # "validate": True,
57 # },
58 # }
59 # )
60 # ... it is also possible to call regular REST endpoints
61 # but using the websocket messages is more efficient.
62 # You can also un-/subscribe here using self.subscribe/self.unsubscribe.
63
64
65async def main() -> None:
66 key: str = os.getenv("SPOT_API_KEY")
67 secret: str = os.getenv("SPOT_SECRET_KEY")
68
69 try:
70 # Public/unauthenticated websocket client
71 client: Client = Client() # only use this one if you don't need private feeds
72 clients.append(client)
73 await client.start()
74 # print(client.public_channel_names) # list public subscription names
75
76 await client.subscribe(
77 params={"channel": "ticker", "symbol": ["BTC/USD", "DOT/USD"]},
78 )
79 await client.subscribe(
80 params={"channel": "book", "depth": 25, "symbol": ["BTC/USD"]},
81 )
82 # await client.subscribe(params={"channel": "ohlc", "symbol": ["BTC/USD"]})
83 await client.subscribe(
84 params={
85 "channel": "ohlc",
86 "interval": 15,
87 "snapshot": False,
88 "symbol": ["BTC/USD", "DOT/USD"],
89 },
90 )
91 await client.subscribe(params={"channel": "trade", "symbol": ["BTC/USD"]})
92
93 # wait because unsubscribing is faster than unsubscribing ... (just for that example)
94 await asyncio.sleep(3)
95 # print(client.active_public_subscriptions) # … to list active subscriptions
96 await client.unsubscribe(
97 params={"channel": "ticker", "symbol": ["BTC/USD", "DOT/USD"]},
98 )
99 # ...
100
101 if key and secret:
102 # Per default, the authenticated client starts two websocket connections,
103 # one for authenticated and one for public messages. If there is no need
104 # for a public connection, it can be disabled using the ``no_public``
105 # parameter.
106 client_auth = Client(key=key, secret=secret, no_public=True)
107 clients.append(client_auth)
108 await client_auth.start()
109 # print(client_auth.private_channel_names) # … list private channel names
110 # when using the authenticated client, you can also subscribe to public feeds
111 await client_auth.subscribe(params={"channel": "executions"})
112
113 await asyncio.sleep(5)
114 await client_auth.unsubscribe(params={"channel": "executions"})
115
116 while not client.exception_occur: # and not client_auth.exception_occur:
117 await asyncio.sleep(6)
118 finally:
119 # Stop the sessions properly.
120 for open_client in clients:
121 await open_client.close()
122
123
124if __name__ == "__main__":
125 asyncio.run(main())
126
127# ============================================================
128# Alternative - as ContextManager:
129
130# from kraken.spot import SpotWSClient
131# import asyncio
132
133
134# async def on_message(message: dict) -> None:
135# print(message)
136
137
138# async def main() -> None:
139# async with SpotWSClient(callback=on_message) as session:
140# await session.subscribe(params={"channel": "ticker", "symbol": ["BTC/USD"]})
141
142# while True:
143# await asyncio.sleep(6)
144
145
146# if __name__ == "__main__":
147# try:
148# asyncio.run(main())
149# except KeyboardInterrupt:
150# pass