Easy Kraken Websockets. Just wrap your triggers and build.
Project description
kraken-sockets
Access Kraken's WebSocket API v2 for real-time market information and trading data. Kraken-sockets is intended to be used in conjunction with the REST API client along with an LLM agent to create a fully featured trading bot. Organization and naming scheme for responses/requests follows Kraken API structure.
https://docs.kraken.com/api/docs/websocket-v2/add_order
Quick Start
import asyncio
async def main():
# 1. Initialize the websocket client.
from kraken_sockets.api import KrakenWebSocketAPI
kraken = KrakenWebSocketAPI()
# 2. Decide which channels to listen to.
from kraken_sockets.schema.requests.market_data_requests import (
TickerSubscriptionRequest,
TradesSubscriptionRequest,
OHLCSubscriptionRequest
)
subscriptions = [
TickerSubscriptionRequest(["ETH/USD"]),
TradesSubscriptionRequest(["BTC/USD"]),
OHLCSubscriptionRequest(["ETH/USD"], 1)
]
# 3. Use the decorator to handle those channel messages as they are broadcast
from kraken_sockets.schema.responses import (
TickerUpdateResponse,
TradesUpdateResponse,
OHLCUpdateResponse
)
@kraken.trigger(TickerUpdateResponse)
async def ticker_handler(response: TickerUpdateResponse) -> None:
kraken.log(f"Last price {response.symbol}: ${response.last}", "info")
@kraken.trigger(TradesUpdateResponse)
async def trades_handler(response: TradesUpdateResponse) -> None:
for trade in response.trades:
kraken.log(f"{trade.symbol} {trade.side.upper()} {trade.price} @ {trade.qty}", "info")
@kraken.trigger(OHLCUpdateResponse)
async def ohlc_handler(response: OHLCUpdateResponse) -> None:
kraken.log(f"{response.timestamp} - {response.candles}", "info")
# 4. Run the async listener loop for those subscriptions
await kraken.run(subscriptions)
if __name__ == "__main__":
asyncio.run(main())
Available Subscriptions
Subscribe to an available channel to listen for responses on that channel. Typically channels broadcast a response each time an update occurs on that channel, and for many channels can optionally specify broadcasting a snapshot when channel is subscribed to to recieve an immediate update.
Admin
kraken_sockets.schema.requests.admin_requests
Market Data
kraken_sockets.schema.requests.market_data_requests
-
TickerSubscriptionRequest -
TickerUnsubscribeRequest -
BookSubscriptionRequest -
BookUnsubscribeRequest -
OHLCSubscriptionRequest -
OHLCUnsubscribeRequest -
TradesSubscriptionRequest -
TradesUnsubscribeRequest -
InstrumentSubscriptionRequest -
InstrumentUnsubscribeRequest -
OrdersSubscriptionRequest -
OrdersUnsubscribeRequest
User Data
kraken_sockets.schema.requests.user_data_requests
-
BalancesSubscriptionRequest -
BalancesUnsubscribeRequest -
ExecutionSubscriptionRequest -
ExecutionUnsubscribeRequest
Available Responses
Admin
HeartbeatResponsePingResponseStatusResponse
Market Data
-
Book
-
BookSnapshotResponse -
BookUpdateResponse
-
-
Ticker
-
TickerSnapshotResponse -
TickerUpdateResponse
-
-
Trades
-
TradesSnapshotResponse -
TradesUpdateResponse
-
-
OHLC
-
OHLCSnapshotResponse -
OHLCUpdateResponse
-
-
Instruments
-
InstrumentsSnapshotResponse -
InstrumentsUpdateResponse
-
-
Order
-
OrderSnapshotResponse -
OrderUpdateResponse
-
Subscription
SubscriptionResponseUnsubscribeResponse
Available Decorators
Wrap a function in decorators so that it will be registered in the async loop and conditionally fire depending on the behavior of the decorator.
Trigger
@kraken.trigger(ResponseType)
- Execute function when specific response type is received. Check the response types above for a list of available
Logger
@kraken.user_logger
- Register a custom logging handler. Wrapped function recieves the
Custom tasks
@kraken.user_task
- Add function as a custom task to the async loop. These tasks will be run with each loop. Control the execution using your own logic.
Control API
Run the client with an optional local REST API to manage subscriptions at runtime — no restart required. This is the intended integration point for agentic trading: keep the websocket loop always on with your triggers registered, and let an LLM agent (or any HTTP client) subscribe, unsubscribe, and check status by calling local endpoints.
Enabling
Pass controls=True to run(). The server runs inside the same asyncio loop as the websocket listeners, and the public websocket connects even with no initial subscriptions.
import asyncio
from kraken_sockets.api import KrakenWebSocketAPI
async def main():
kraken = KrakenWebSocketAPI()
# Register triggers for the channels your agent may subscribe to
from kraken_sockets.schema.responses import TickerUpdateResponse
@kraken.trigger(TickerUpdateResponse)
async def ticker_handler(response: TickerUpdateResponse) -> None:
kraken.log(f"Last price {response.symbol}: ${response.last}", "info")
# Start with no subscriptions — the agent adds them over HTTP at runtime
await kraken.run(controls=True, host="127.0.0.1", port=8000)
if __name__ == "__main__":
asyncio.run(main())
Interactive OpenAPI docs are served at http://127.0.0.1:8000/docs — useful for exploring request bodies, and the schema can be handed directly to an agent as its tool definition.
Endpoints
Admin
| Method | Path | Body example | Description |
|---|---|---|---|
| GET | /status |
— | List currently active channel subscriptions |
| POST | /ping |
{"target": "public"} |
Ping the public or private websocket |
Market Data
| Method | Path | Body example |
|---|---|---|
| POST | /subscribe/ticker |
{"symbol": ["BTC/USD"]} |
| POST | /subscribe/book |
{"symbol": ["BTC/USD"], "depth": 10} |
| POST | /subscribe/ohlc |
{"symbol": ["BTC/USD"], "interval": 1} |
| POST | /subscribe/trades |
{"symbol": ["BTC/USD"]} |
| POST | /subscribe/instrument |
{} |
| POST | /subscribe/orders |
{"symbol": ["BTC/USD"], "depth": 10} |
Each channel has a matching /unsubscribe/... endpoint taking the same identifying fields (e.g. POST /unsubscribe/ticker with {"symbol": ["BTC/USD"]}).
User Data
| Method | Path | Body example |
|---|---|---|
| POST | /subscribe/executions |
{} |
| POST | /subscribe/balances |
{} |
| POST | /unsubscribe/executions |
{} |
| POST | /unsubscribe/balances |
{} |
Example
# Subscribe to a ticker channel
curl -X POST http://127.0.0.1:8000/subscribe/ticker \
-H "Content-Type: application/json" \
-d '{"symbol": ["BTC/USD"]}'
# Check which channels are active
curl http://127.0.0.1:8000/status
# Unsubscribe when done
curl -X POST http://127.0.0.1:8000/unsubscribe/ticker \
-H "Content-Type: application/json" \
-d '{"symbol": ["BTC/USD"]}'
Notes
- Endpoint responses return
{"status": "queued"}— the command has been placed on the outbound queue, not yet confirmed by Kraken. Confirmation arrives over the websocket as aSubscriptionResponse/UnsubscribeResponseand fires any trigger you registered for it. Your agent should treat the websocket stream, not the HTTP response, as the source of truth. - The server binds to
127.0.0.1by default and has no authentication. Keep it local; do not expose it to a network. - User Data endpoints (
executions,balances) andordersrequire authentication. The first private command automatically fetches a session token and connects the private websocket — no private subscription is needed at startup, only theKRAKEN_REST_API_*environment variables.
Private Endpoints
For authenticated endpoints, set environment variables:
KRAKEN_REST_API_KEYKRAKEN_REST_API_PRIVATE_KEY
For complete API documentation, see Kraken WebSocket API v2 docs.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kraken_sockets-0.1.3.tar.gz.
File metadata
- Download URL: kraken_sockets-0.1.3.tar.gz
- Upload date:
- Size: 22.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.0 {"installer":{"name":"uv","version":"0.11.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5db07a3608090835d4ca3a2f18433a81d51ee4c7cfc5ce0982a3aab2ea5eef34
|
|
| MD5 |
9610dc2a9b043a4c2c6daee79e5d8744
|
|
| BLAKE2b-256 |
8a612cd1f2e58fd918007931cb55171ecde31e190a610081861e31c4151ad49f
|
File details
Details for the file kraken_sockets-0.1.3-py3-none-any.whl.
File metadata
- Download URL: kraken_sockets-0.1.3-py3-none-any.whl
- Upload date:
- Size: 24.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.0 {"installer":{"name":"uv","version":"0.11.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f9d5bb87c4bbcf0e9821e32ae289acd6805edefda1a30bb584b9101dc1334759
|
|
| MD5 |
c0aa41fe7abce869175d56db2b045483
|
|
| BLAKE2b-256 |
956d847b8bed39d471df442a33b02003bb1fca7d7db571059e3f49191d339089
|