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