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.0.18-cp314-cp314-win_amd64.whl (3.0 MB view details)

Uploaded CPython 3.14Windows x86-64

cybotrade-2.0.18-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.4 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64

cybotrade-2.0.18-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.2 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ ARM64

cybotrade-2.0.18-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.0.18-cp313-cp313-win_amd64.whl (3.0 MB view details)

Uploaded CPython 3.13Windows x86-64

cybotrade-2.0.18-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.4 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

cybotrade-2.0.18-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.2 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64

cybotrade-2.0.18-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.0.18-cp312-cp312-win_amd64.whl (3.0 MB view details)

Uploaded CPython 3.12Windows x86-64

cybotrade-2.0.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.4 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

cybotrade-2.0.18-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.2 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

cybotrade-2.0.18-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.0.18-cp314-cp314-win_amd64.whl.

File metadata

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

File hashes

Hashes for cybotrade-2.0.18-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 2d07b51ad7f6c4a525f5ec0d5552ca50f33e9377b980aa9ac3031a93076ae183
MD5 0edf77dd5933e50b71076e7328564568
BLAKE2b-256 8f0ffdb80e2dac837aace442f0bf35494de5e09d17739c8ea50e439e401b0b0e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.0.18-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 c1847044c0df4b4f81d4006b6a01cb029e1ba4cdc95c663ab815a2ae6754fa3c
MD5 79bcd3ec100061af8975902fed9967af
BLAKE2b-256 aae79c1f05bf04d4ebfe25cdea57ddf8b27e537ef5a312350133073f70f5005b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.0.18-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 e563f6b0663d80a3e3686b6d45253d1766a842ae5922552f2416e5c5d3c18599
MD5 d582d65d5a65527ad441899ed6b43ff1
BLAKE2b-256 4703c49c46e0f56c9dfe1b9fba30c92998d59518684d849ed0c6cb070877861d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.0.18-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 a2ce1eb7fbb114b4b07fd5502241cf830ff7aaa20ded171b2ba2002c24efac49
MD5 7a47c493453f703088d9e7793da1d1e0
BLAKE2b-256 a57409f4349dacd6bbde8d3e5cbc482eb5a7f4b71ea5648c96b25fd083f94349

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for cybotrade-2.0.18-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 0857213538ce12735b3a8727d951bc0c257fa3ff32a01e1008ec9a46563ac98c
MD5 f3334bfb6093d2590682c275ff92c3b3
BLAKE2b-256 39775c4e55026f70cccd7217adb9f52319822e2986828fa271af1eccef78a997

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.0.18-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 8521b8619501d464c7b80236a3f762b011f9b7d18c822de92cb3451aa14b5d9a
MD5 837d97804f6f52e43e4fa6b569ab4ab7
BLAKE2b-256 0acd34f01c09a5f80cb6fa8b5e8db41c57ab9c46c81fb3cc51aa6e5ad0539f5b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.0.18-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 404d8f38a2ff3ae22d3a8ac8000e1816ef2b5527e06a3fa6c0210ed23cd2865c
MD5 d0fd87464c84cf66423a3865fa07ab4d
BLAKE2b-256 e052c539631be451f21523a3c0d4ca6c168bec3cadd8e7688b8046acc1aacd9b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.0.18-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 47ce0bd6fbe65a302e522cbda168c82022981065c3164d77f57790794dd779ea
MD5 effd611fca052491cdf98a14ed21241d
BLAKE2b-256 259b9e23d51da4abc794f76210cb93bd4cca09b0a4b3e1c6ea28358827c1e9a7

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for cybotrade-2.0.18-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 eaec35c63edadebf42909cd00fbd28c4cdbfc327952aadb02f294089361054ed
MD5 1a080d614eb52fd9aa75fe1fad00f3d7
BLAKE2b-256 7e5902ba21e41826f89999ed93a834ef9757687cb469e6be35cfeae13592dbfb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.0.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 745517b2f9c70aedcf9a5cc5f07c2a3ca8a8d2e1fa79d6b0b6b6f2b2b31db521
MD5 28158e739fe827444765a6a1ce646e58
BLAKE2b-256 88dfe4fc90f324a58ef2f69684e376fdd32906072872b81ae12909bb6c74478e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.0.18-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 ba0cf7c5ed5ab6be2fb76a18da566767d8695fef15c3df257f3ad9bbe883f0a4
MD5 d41d70582c7c27b45f03aef6f51ddb26
BLAKE2b-256 7449c62bf3f287a661e7c9c4f680629fb0b117c774b540c847e71ae697aa9d53

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.0.18-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 5af7433edca7ed4cb11b7283b21e66f1b8c52c7af8d4366aab322c0891edcd9a
MD5 3a374d6f91a837dbce165d7f62e18ccc
BLAKE2b-256 b40e805a373f3336b7daffac0186c509f702de7cf0dcfab9ce08c0148a67cd55

See more details on using hashes here.

Release history Release notifications | RSS feed

2.4.0

12 files

2.3.1

12 files

2.3.0

12 files

2.2.0

12 files

2.1.0

12 files

This release

2.0.18 This release

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