Skip to main content

Cybotrade

Primitives and utilities for building automated trading strategies.

Cybotrade is a Python library for writing live, event-driven crypto trading strategies. It gives you a single, consistent interface across multiple exchanges (REST + private WebSocket), a built-in market-data layer, a job scheduler, and a BaseStrategy harness that wires everything together so you can focus on strategy logic instead of plumbing.

The performance-critical core (HTTP client, WebSocket transport, symbol/topic parsing) is implemented in Rust via PyO3 and shipped as a compiled extension, so there is no Rust toolchain required to use it.


Features

  • Unified exchange interface — one ExchangeClient abstraction for REST trading (place/cancel orders, positions, balances, order details, orderbook, symbol info) across all supported venues.
  • Private WebSocket streams — authenticated order-update streams with automatic heartbeating and reconnection.
  • Market data — pull historical and streaming data through cybotrade-datasource using a simple Topic model, delivered as Polars DataFrames.
  • Strategy harnessBaseStrategy runs your scheduled jobs, exchange events, and datasource stream together under one asyncio event loop, with graceful SIGINT/SIGTERM shutdown.
  • Built-in scheduler — cron/interval/date job scheduling via aion.
  • Typed throughout — ships with py.typed and stub files; rich dataclass models (OrderUpdate, Position, Balance, SymbolInfo, …) and Decimal precision for prices and quantities.
  • Logging helpers — colorized console and rotating-file handlers.

Supported exchanges

Exchange REST client Private WebSocket
Bybit BybitLinearClient BybitPrivateWS
Binance BinanceLinearClient BinancePrivateWS
KuCoin KucoinLinearClient KucoinPrivateWS
EdgeX EdgeXClient EdgeXPrivateWS

All exchange clients currently target linear (USDⓈ-M) perpetual markets.


Installation

pip install cybotrade

Requires Python 3.12+. Pre-built wheels are published for macOS (universal2), Linux (x86_64 + aarch64), and Windows (x86_64), so no compilation is needed on those platforms.


Quick start

Placing an order

import asyncio
from decimal import Decimal

from cybotrade import Symbol
from cybotrade.models import OrderSide
from cybotrade.bybit import BybitLinearClient


async def main():
    client = BybitLinearClient(api_key="...", api_secret="...", testnet=True)

    # Inspect the symbol's trading rules
    info = await client.get_symbol_info(Symbol("BTCUSDT"))
    print(info.quantity_precision, info.tick_size)

    # Market buy 0.001 BTC
    resp = await client.place_order(
        symbol=Symbol("BTCUSDT"),
        side=OrderSide.BUY,
        quantity=Decimal("0.001"),
    )
    print(resp.order_id)

    # Check the resulting position
    positions = await client.get_positions(Symbol("BTCUSDT"))
    print(positions)


asyncio.run(main())

Writing a strategy

BaseStrategy ties together three sources of work — a scheduler, an exchange event stream, and an optional datasource stream — and drives them from a single start() call. Subclass it and implement on_init, on_event, and on_shutdown.

import asyncio
from datetime import timedelta

from aion import Trigger
from cybotrade import Symbol, Topic
from cybotrade.io import Event, EventType
from cybotrade.strategy import BaseStrategy
from cybotrade.bybit import BybitLinearClient, BybitPrivateWS


class MyStrategy(BaseStrategy):
    def __init__(self, trader, events):
        self.trader = trader
        self.events = events
        super().__init__(
            datasource_api_key="DATASOURCE_API_KEY",
            datasource_topics=[
                Topic("bybit-linear", "candle", {"symbol": "BTCUSDT", "interval": "1m"}),
            ],
            lookback_size=200,
        )

    def on_init(self):
        # Register a recurring job (runs every 60s)
        asyncio.get_event_loop().create_task(
            self.schedule(self.rebalance, Trigger.Interval(duration=timedelta(minutes=1)))
        )

    async def rebalance(self):
        price = await self.trader.get_current_price(Symbol("BTCUSDT"))
        self.logger.info(f"mid price = {price}")

    async def on_event(self, event: Event):
        if event.event_type == EventType.DatasourceUpdate:
            topic = ...  # identify which subscribed Topic this update belongs to
            ready = self.maintain_datamap(topic, event.data["data"])
            if ready:
                df = self.datamap[topic]  # Polars DataFrame of the last N candles
                ...  # compute signals, place orders via self.trader
        elif event.event_type == EventType.OrderUpdate:
            self.logger.info(f"order update: {event.data}")

    def on_shutdown(self):
        self.logger.info("shutting down cleanly")


async def main():
    trader = BybitLinearClient(api_key="...", api_secret="...")
    events = BybitPrivateWS(api_key="...", api_secret="...", topics=["order"])
    strategy = MyStrategy(trader, events)
    await strategy.start(events)


asyncio.run(main())

Core concepts

Symbol

A parsed trading pair. Construct from a venue string and split into base/quote:

from cybotrade import Symbol

s = Symbol("BTCUSDT")
s.split()  # ("BTC", "USDT")

Topic — market data

A Topic identifies a data feed by provider, endpoint, and query params. It is the addressing scheme used by cybotrade-datasource for both historical queries and live streams.

from cybotrade import Topic

topic = Topic("bybit-linear", "candle", {"symbol": "BTCUSDT", "interval": "1m"})
topic.endpoint_with_query_params()  # "candle?symbol=BTCUSDT&interval=1m"
topic.interval()                    # timedelta(minutes=1)

# Or parse from a string
Topic.from_str("bybit-linear|candle?symbol=BTCUSDT&interval=1m")

When datasource_topics and datasource_api_key are supplied to BaseStrategy, the harness automatically backfills lookback_size rows into self.datamap[topic] (a Polars DataFrame) on startup and then streams live updates as EventType.DatasourceUpdate events. maintain_datamap() keeps each topic's rolling window at the configured size.

ExchangeClient

The REST trading interface implemented by every exchange client:

Method Returns
place_order(symbol, side, quantity, limit=None, ...) OrderResponse
cancel_order(symbol, order_id=None, client_order_id=None) OrderResponse
get_positions(symbol=None) list[Position]
get_wallet_balance(coin=None) Balance
get_order_details(symbol, order_id=None, client_order_id=None) OrderUpdate | None
get_order_details_from_history(...) OrderUpdate | None
get_open_orders(symbol=None) list[OrderUpdate]
get_symbol_info(symbol) SymbolInfo
get_orderbook_snapshot(symbol) OrderbookSnapshot
get_current_price(symbol) Decimal (mid of best bid/ask)

All prices and quantities are Decimal to avoid floating-point drift.

Events

on_event receives an Event whose event_type is one of:

Authenticated, Subscribed, OrderUpdate, DatasourceSubscribed, DatasourceUpdate, Error, Unknown.

event.data holds the parsed payload; event.orig holds the raw message.


Utilities

from decimal import Decimal
from cybotrade.utils import getenv, truncate_decimal, round_to_tick, extract_precision

getenv("BYBIT_API_KEY")                          # raises if unset
truncate_decimal(Decimal("1.23456"), 3)          # Decimal("1.234")
round_to_tick(Decimal("100.07"), Decimal("0.1")) # Decimal("100.1")
extract_precision(Decimal("0.001"))              # 3

Logging

import logging
from cybotrade.logging import setup_logger, make_colorlog_stream_handler

setup_logger(log_level=logging.INFO, handlers=[make_colorlog_stream_handler()])

Dependencies

Installed automatically with the package:


License

Copyright © Balaena Quant Sdn Bhd. All rights reserved. This software is proprietary; see LICENSE for terms.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

cybotrade-2.4.0-cp314-cp314-win_amd64.whl (3.1 MB view details)

Uploaded CPython 3.14Windows x86-64

cybotrade-2.4.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.5 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64

cybotrade-2.4.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.3 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ ARM64

cybotrade-2.4.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (6.3 MB view details)

Uploaded CPython 3.14macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

cybotrade-2.4.0-cp313-cp313-win_amd64.whl (3.1 MB view details)

Uploaded CPython 3.13Windows x86-64

cybotrade-2.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.5 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

cybotrade-2.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.3 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64

cybotrade-2.4.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (6.3 MB view details)

Uploaded CPython 3.13macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

cybotrade-2.4.0-cp312-cp312-win_amd64.whl (3.1 MB view details)

Uploaded CPython 3.12Windows x86-64

cybotrade-2.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.5 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

cybotrade-2.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.3 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

cybotrade-2.4.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (6.3 MB view details)

Uploaded CPython 3.12macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

File details

Details for the file cybotrade-2.4.0-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: cybotrade-2.4.0-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 3.1 MB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.0

File hashes

Hashes for cybotrade-2.4.0-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 49ae4f05473a8efa5c7a44d4e95bc44a378effa7f6dc32254ece0758de009740
MD5 44a15dd83f620fe42d5c28818711e324
BLAKE2b-256 5bd9d0ffa60ca66fd9a6e3ab5022e2c4a83879d6d26d3cc7f94f71fc410ef411

See more details on using hashes here.

File details

Details for the file cybotrade-2.4.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for cybotrade-2.4.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 6614a5390909377c43bbcfa3ab7e9aa89ea3784c3b9b8f4c40ac15b29941ff28
MD5 c4ee6ef63905fed7c4f8b8d67215a0fe
BLAKE2b-256 e1939343c38b383975a4b8e5c6ab6ecd805b6ec39965de3d481b90d66f33fc6b

See more details on using hashes here.

File details

Details for the file cybotrade-2.4.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for cybotrade-2.4.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 5a91992b6de0730c51d2258034fe28e4234e1b6e77b4c0e662e02ca32febd093
MD5 a3bea0fcb8426d04e52e52fba4af9d0c
BLAKE2b-256 b80adcb1cd8b947d91d346c2e41aad92356a5ac9d3e3e68931eb11bf419a8727

See more details on using hashes here.

File details

Details for the file cybotrade-2.4.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for cybotrade-2.4.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 c536c51828b35e501febe0713880b8cc57e77905cdc56acf4522535fdfb68563
MD5 4c728b2fed9125431e7fa5be71a2d5f0
BLAKE2b-256 1904fac9145e808ece312edc1d353571a0b8a24ca0479be710142317f2e7b5f8

See more details on using hashes here.

File details

Details for the file cybotrade-2.4.0-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: cybotrade-2.4.0-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 3.1 MB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.0

File hashes

Hashes for cybotrade-2.4.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 a0738c4eab3786d075a6afa1ae33053e4384b7fbd0fe50aed133f2f8c56379f0
MD5 17308b6102f0698de3525449a5c0b957
BLAKE2b-256 26878cf7ffec2b2fbf73f9bbce118d1853d04dafb0d094d9bc0aabf34f6f73ad

See more details on using hashes here.

File details

Details for the file cybotrade-2.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for cybotrade-2.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 c9a0ffd94ef24277768643652a0f65c4d231a0ca004be8d267a311680d61537a
MD5 aa3352245ef0d76011f2b4a7df2b1ce3
BLAKE2b-256 1fc30efbde8862582e168b672bf7553f9aee6597bc74a94a899819dcbeb389a2

See more details on using hashes here.

File details

Details for the file cybotrade-2.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for cybotrade-2.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 f3f063b7792ef4764a6d19b25e015db330f1b06cf749d6d5be5225079b74e058
MD5 25f6166edc6ea335db99e105a94897dc
BLAKE2b-256 c22e7bb8a9464be763484f86fc23b4a9072918b88d9adeeeb15102f7733613ea

See more details on using hashes here.

File details

Details for the file cybotrade-2.4.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for cybotrade-2.4.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 bbed0dd13daf8a2b0e592bf263e1f0f4399d2b0ca84e48e52ed26b702ddf6c7f
MD5 145376d25e8e09629823208222b4f956
BLAKE2b-256 8b986f7c904f78c5f7b265f3eb6e78fa9fdab3c89ce8159556158a77d6911577

See more details on using hashes here.

File details

Details for the file cybotrade-2.4.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: cybotrade-2.4.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 3.1 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.0

File hashes

Hashes for cybotrade-2.4.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 210de7367383274dea11bab4555c94da0c967019c5864207c8ec48f7c470a0a0
MD5 010290d731d8cb25976e6ef541d33951
BLAKE2b-256 ee3d421133462e39de3938768859eedfde238b1f1ad39b15f79ef0cd039bb271

See more details on using hashes here.

File details

Details for the file cybotrade-2.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for cybotrade-2.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 9bf2e9ceb2eec2891dcdd1ce5968ad89e7a61cac324af52ed6b66c29eea1b294
MD5 91ce21630a5c1a9ad5a274b9cffa1085
BLAKE2b-256 65c7af751f37378f3294ab5e41f4d2f216cab19e1d67e0f182e6b9b53c4b02fe

See more details on using hashes here.

File details

Details for the file cybotrade-2.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for cybotrade-2.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 94ab1a1cea872e7a4d111276035eca87029831a3009ee497d4a19d99aecc82b3
MD5 68f90349961e9cd20152856f1def061f
BLAKE2b-256 3305c29144bbeba637cd73e0861c28d4c8e7e4ab42e555c3ff48f3ec432cfecf

See more details on using hashes here.

File details

Details for the file cybotrade-2.4.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for cybotrade-2.4.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 e118028920de3a1dc962a49fc5146d7eeaa8d0b205bd5da5c306a105619282a5
MD5 bf6ff1e2ef697fa288649098a80e26d9
BLAKE2b-256 128d66d115a13f11ec163ca672aed93964d169f4cfc6227b090537ba8041f129

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

2.4.0 This release

12 files

2.3.1

12 files

2.3.0

12 files

2.2.0

12 files

2.1.0

12 files

2.0.18

12 files

2.0.17

12 files

1.5.5

6 files

1.5.4

8 files

1.5.3

18 files

1.5.2

8 files

1.5.1

11 files

1.5.0

17 files

1.4.35

8 files

1.4.34

8 files

1.4.33

3 files

1.4.32

4 files

1.4.31

10 files

1.4.30

10 files

1.4.29

10 files

1.4.28

10 files

1.4.27

10 files

1.4.26

10 files

1.4.25

10 files

1.4.24

10 files

1.4.23

10 files

1.4.22

9 files

1.4.21

5 files

1.4.20

10 files

1.4.19

9 files

1.4.18

6 files

1.4.17

10 files

1.4.16

10 files

1.4.15

10 files

1.4.14

10 files

1.4.13

10 files

1.4.12

10 files

1.4.11

10 files

1.4.10

10 files

1.4.9

10 files

1.4.8

10 files

1.4.7

8 files

1.4.6

10 files

1.4.5

10 files

1.4.4

10 files

1.4.3

10 files

1.4.2

10 files

1.4.1

2 files

1.4.0

10 files

1.3.9

10 files

1.3.8

10 files

1.3.7

10 files

1.3.6

10 files

1.3.5

9 files

1.3.4

10 files

1.3.3

10 files

1.3.2

10 files

1.3.1

10 files

1.3.0

10 files

1.2.6

8 files

1.2.5

8 files

1.2.4

6 files

1.2.3

7 files

1.2.2

6 files

1.2.1

2 files

1.2.0

8 files

1.1.1

8 files

1.1.0

6 files

0.1.8

16 files

0.1.7

1 file

0.1.6

1 file

0.1.5

3 files

0.1.4

2 files

0.1.3

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page