Skip to main content

Collection of REST and websocket clients to interact with the Kraken cryptocurrency exchange.

Project description

Futures and Spot Websocket and REST API Python SDK for the Kraken Cryptocurrency Exchange 🐙

GitHub License: GPL v3 Generic badge Downloads

Typing CodeQL CI/CD codecov

release release DOI Documentation Status stable

⚠️ This is an unofficial collection of REST and websocket clients for Spot and Futures trading on the Kraken cryptocurrency exchange using Python. Payward Ltd. and Kraken are in no way associated with the authors of this module and documentation.


📌 Disclaimer

There is no guarantee that this software will work flawlessly at this or later times. Of course, no responsibility is taken for possible profits or losses. This software probably has some errors in it, so use it at your own risk. Also no one should be motivated or tempted to invest assets in speculative forms of investment. By using this software you release the authors from any liability regarding the use of this software.


Features

Clients:

  • Spot REST Clients
  • Spot Websocket Client
  • Spot Orderbook Client
  • Futures REST Clients
  • Futures Websocket Client

General:

  • access both public and private endpoints
  • responsive error handling and custom exceptions
  • extensive example scripts (see /examples and /tests)
  • tested using the pytest framework
  • releases are permanently archived at Zenodo

Documentation:


❗️ Attention

ONLY tagged releases are available at PyPI. So the content of the master may not match with the content of the latest release. - Please have a look at the release specific READMEs and changelogs.


Table of Contents


🛠 Installation and setup

1. Install the Python module:

python3 -m pip install python-kraken-sdk

2. Register at Kraken and generate API Keys:

3. Start using the provided example scripts

4. Error handling

If any unexpected behavior occurs, please check your API permissions, rate limits, update the python-kraken-sdk, see the Troubleshooting section, and if the error persists please open an issue.


📍 Spot Client Example Usage

A template Spot trading bot using both websocket and REST clients can be found in /examples/spot_trading_bot_template.py.

For those who need a realtime order book - a script that demonstrates how to maintain a valid order book can be found here: /examples/spot_orderbook.py.

Spot REST API

... can be found in /examples/spot_examples.py

from kraken.spot import User, Market, Trade, Funding, Staking

def main():
    key = "kraken-public-key"
    secret = "kraken-secret-key"

    # ____USER________________________
    user = User(key=key, secret=secret)
    print(user.get_account_balance())
    print(user.get_open_orders())
    # ...

    # ____MARKET____
    market = Market()
    print(market.get_ticker(pair="BTCUSD"))
    # ...

    # ____TRADE_________________________
    trade = Trade(key=key, secret=secret)
    print(trade.create_order(
         ordertype="limit",
         side="buy",
         volume=1,
         pair="BTC/EUR",
         price=20000
    ))
    # ...

    # ____FUNDING___________________________
    funding = Funding(key=key, secret=secret)
    print(
        funding.withdraw_funds(
            asset="DOT", key="MyPolkadotWallet", amount=200
        )
    )
    print(funding.cancel_withdraw(asset="DOT", refid="<some id>"))
    # ...

    # ____STAKING___________________________
    staking = Staking(key=key, secret=secret)
    print(staking.list_stakeable_assets())
    print(
        staking.stake_asset(
            asset="DOT", amount=20, method="polkadot-staked"
        )
    )
    # ...

if __name__ == "__main__":
    main()

Websockets

... can be found in /examples/spot_ws_examples.py

import time
import asyncio
from kraken.spot import KrakenSpotWSClient

async def main()

    key = "kraken-public-key"
    secret = "kraken-secret-key"

    class Bot(KrakenSpotWSClient):
        async def on_message(self, msg):
            if isinstance(msg, dict) and "event" in msg:
                if msg["event"] in ("pong", "heartbeat"):
                    return

            print(msg)
            # if condition:
            #     await self.create_order(
            #         ordertype="limit",
            #         side="buy",
            #         pair="BTC/EUR",
            #         price=20000,
            #         volume=1
            #     )
            # ... it is also possible to call regular Spot REST endpoints
            # but using the WsClient's functions is more efficient
            # because the requests will be sent via the ws connection

    # ___Public_Websocket_Feeds__
    bot = Bot() # only use the unauthenticated client if you don't need private feeds
    print(bot.public_sub_names) # list public subscription names

    await bot.subscribe(subscription={ "name": "ticker" }, pair=["XBT/EUR", "DOT/EUR"])
    await bot.subscribe(subscription={ "name": "spread" }, pair=["XBT/EUR", "DOT/EUR"])
    # await bot.subscribe(subscription={ "name": "book" }, pair=["BTC/EUR"])
    # await bot.subscribe(subscription={ "name": "book", "depth": 25}, pair=["BTC/EUR"])
    # await bot.subscribe(subscription={ "name": "ohlc" }, pair=["BTC/EUR"])
    # await bot.subscribe(subscription={ "name": "ohlc", "interval": 15}, pair=["XBT/EUR", "DOT/EUR"])
    # await bot.subscribe(subscription={ "name": "trade" }, pair=["BTC/EUR"])
    # await bot.subscribe(subscription={ "name": "*" } , pair=["BTC/EUR"])

    time.sleep(2) # wait because unsubscribing is faster than subscribing ...
    await bot.unsubscribe(subscription={ "name": "ticker" }, pair=["XBT/EUR","DOT/EUR"])
    await bot.unsubscribe(subscription={ "name": "spread" }, pair=["XBT/EUR"])
    await bot.unsubscribe(subscription={ "name": "spread" }, pair=["DOT/EUR"])
    # ...

    # ___Authenticated_Websocket_________
    # when using the authenticated client, you can also subscribe to public feeds
    auth_bot = Bot(key=key, secret=secret)
    print(auth_bot.private_sub_names) # list private subscription names
    await auth_bot.subscribe(subscription={ "name": "ownTrades" })
    await auth_bot.subscribe(subscription={ "name": "openOrders" })

    time.sleep(2)
    await auth_bot.unsubscribe(subscription={ "name": "ownTrades" })
    await auth_bot.unsubscribe(subscription={ "name": "openOrders" })

    while True:
        await asyncio.sleep(6)

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        # do some exception handling ...
        pass

Note: Authenticated Spot websocket clients can also un/subscribe from/to public feeds.


📍 Futures Client Example Usage

Kraken provides a sandbox environment at https://demo-futures.kraken.com for paper trading. When using this API keys you have to set the sandbox parameter to True when instantiating the respective client.

A template Futures trading bot using both websocket and REST clients can be found in /examples/futures_trading_bot_template.py.

Futures REST API

The following example can be found in /examples/futures_examples.py.

from kraken.futures import Market, User, Trade, Funding

def main():

    key = "futures-api-key"
    secret = "futures-secret-key"

    # ____USER________________________
    user = User(key=key, secret=secret) # optional: sandbox=True
    print(user.get_wallets())
    print(user.get_open_orders())
    print(user.get_open_positions())
    print(user.get_subaccounts())
    # ...

    # ____MARKET____
    market = Market()
    print(market.get_ohlc(tick_type="trade", symbol="PI_XBTUSD", resolution="5m"))

    priv_market = Market(key=key, secret=secret)
    print(priv_market.get_fee_schedules_vol())
    print(priv_market.get_execution_events())
    # ...

    # ____TRADE_________________________
    trade = Trade(key=key, secret=secret)
    print(trade.get_fills())
    print(trade.create_batch_order(
        batchorder_list = [{
            "order": "send",
            "order_tag": "1",
            "orderType": "lmt",
            "symbol": "PI_XBTUSD",
            "side": "buy",
            "size": 1,
            "limitPrice": 12000,
            "cliOrdId": "some-client-id"
        }, {
            "order": "send",
            "order_tag": "2",
            "orderType": "stp",
            "symbol": "PI_XBTUSD",
            "side": "buy",
            "size": 1,
            "limitPrice": 10000,
            "stopPrice": 11000,
        }, {
            "order": "cancel",
            "order_id": "e35dsdfsdfsddd-8a30-4d5f-a574-b5593esdf0",
        }, {
            "order": "cancel",
            "cliOrdId": "another-client-id",
        }],
    ))
    print(trade.cancel_all_orders())
    print(
        trade.create_order(
            orderType="lmt",
            side="buy",
            size=1,
            limitPrice=4,
            symbol="pf_bchusd"
        )
    )
    # ...

    # ____FUNDING___________________________
    funding = Funding(key=key, secret=secret)
    # ...

if __name__ == "__main__":
    main()

Futures Websocket Client

The following example can be found in /examples/futures_ws_examples.py.

import asyncio
from kraken.futures import KrakenFuturesWSClient

async def main():

    key = "futures-api-key"
    secret = "futures-secret-key"

    # ___Custom_Trading_Bot________
    class Bot(KrakenFuturesWSClient):

        async def on_message(self, event):
            print(event)
            # >> apply your trading strategy here <<
            # you can also combine this with the Futures REST clients

    # ___Public_Websocket_Feeds____
    bot = Bot()
    # print(bot.get_available_public_subscription_feeds())

    products = ["PI_XBTUSD", "PF_ETHUSD"]

    # subscribe to a public websocket feed
    await bot.subscribe(feed="ticker", products=products)
    # await bot.subscribe(feed="book", products=products)
    # ...

    # unsubscribe from a public websocket feed
    # await bot.unsubscribe(feed="ticker", products=products)

    # ___Authenticated_Websocket_________
    auth_bot = Bot(key=key, secret=secret)
    # print(auth_bot.get_available_private_subscription_feeds())

    # subscribe to a private/authenticated websocket feed
    await auth_bot.subscribe(feed="fills")
    await auth_bot.subscribe(feed="open_positions")
    await auth_bot.subscribe(feed="open_orders")
    # ...

    # unsubscribe from a private/authenticated websocket feed
    await auth_bot.unsubscribe(feed="fills")

    while True:
        await asyncio.sleep(6)

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        # do some exception handling ...
        pass

Note: Authenticated Futures websocket clients can also un-/subscribe from/to public feeds.


🆕 Contributions

… are welcome! - Please have a look at CONTRIBUTION.md.


🚨 Troubleshooting

  • Check if you downloaded and installed the latest version of the python-kraken-sdk.
  • Check the permissions of your API keys and the required permissions on the respective endpoints.
  • If you get some Cloudflare or rate limit errors, please check your Kraken Tier level and maybe apply for a higher rank if required.
  • Use different API keys for different algorithms, because the nonce calculation is based on timestamps and a sent nonce must always be the highest nonce ever sent of that API key. Having multiple algorithms using the same keys will result in invalid nonce errors.

📝 Notes

  • Coding standards are not always followed to make arguments and function names as similar as possible to those in the Kraken API documentations.

🔭 References


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

python-kraken-sdk-1.5.0.tar.gz (415.2 kB view hashes)

Uploaded Source

Built Distribution

python_kraken_sdk-1.5.0-py3-none-any.whl (99.0 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page