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

Uploaded CPython 3.14Windows x86-64

cybotrade-2.3.1-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.3.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.3 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ ARM64

cybotrade-2.3.1-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.3.1-cp313-cp313-win_amd64.whl (3.1 MB view details)

Uploaded CPython 3.13Windows x86-64

cybotrade-2.3.1-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.3.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.3 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64

cybotrade-2.3.1-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.3.1-cp312-cp312-win_amd64.whl (3.1 MB view details)

Uploaded CPython 3.12Windows x86-64

cybotrade-2.3.1-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.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.3 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

cybotrade-2.3.1-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.3.1-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: cybotrade-2.3.1-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.3.1-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 352ce4220e1b93f4f9d825f1fda06041e9fabc5e1eec28e7703cc316da4bbdd5
MD5 94665c8922d6a9bc9599d6d30d20c3d1
BLAKE2b-256 363d9660b072ac603e9db5bbd8b8ee304c38d623b3b9fd98226c85beaa684d23

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.3.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 bd42151cadbf2288bdf532c14c5aa579b522edf0283d13512d5614717f8a4363
MD5 c204a0e125500ba2edb967494815f554
BLAKE2b-256 1d9bb14b127c9d26c5fa104874b664ec1b8489eb202b7531e7790e5d8deafdc2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.3.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 292f91374753b0184a6787d60874bb481e247192690c1c156f52d0ed89c4d7e3
MD5 16667aa6e069a27feb978fce14ba7d11
BLAKE2b-256 7a124e5b82e4cb0e80658b0571e3730c23a7e0e75597e4446101d4da60ddf035

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.3.1-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 a3e81932925bd7d78953c039a193ccc17faf7ef5bb40704312de05df36eb9a76
MD5 1194cbb5f7fc0f4b22194ae19f8a7468
BLAKE2b-256 efce1e19eb8d8c2562055e18b0a727fefefd42a2e33065439300757055b596c6

See more details on using hashes here.

File details

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

File metadata

  • Download URL: cybotrade-2.3.1-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.3.1-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 c1ae1df9c5a300ec5c54c64d3528b031a1c5215e48e39470b968996bad7fd220
MD5 df9b07f4e412e8eaee5b2b24ba9a736f
BLAKE2b-256 126ee9364f2e689c4c7cf07b409f1a39bd3332a405de36ff6068665ec369f881

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.3.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 769bc076e6e17e348da8ae85495a62312d70282e4274f68fd6738520e24e5594
MD5 f375438049aa8e7a0038a39f4375c827
BLAKE2b-256 10d3dd8b60170d18ee2516912378084238e4675b08dadee323643ca20ef06c12

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.3.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 0a2b720a443f2ccfc3304fb92380ae8ddf7c6df47c4d777a5e58f1847df89db0
MD5 12b487ab8a4c541dff13eb312708d5a7
BLAKE2b-256 4f716d6378eb9cddd3f2f78b6fe6ee6f2f30216d688f5b904073bdd191ee7ed1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.3.1-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 c56c07b5342839de913f032a4710372b6354e854eb319035aceb9733c0c06165
MD5 d336778a321bc7cd7c230095caecf679
BLAKE2b-256 f08483daaa17e5b236aa34de235d1484134289b006b8c291f4ad04b01216c719

See more details on using hashes here.

File details

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

File metadata

  • Download URL: cybotrade-2.3.1-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.3.1-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 0cf27fb208b5959e63aa2b0b5ddf08869c60b154da0de1e2e2d154195e0923f5
MD5 e0b707288740af2d98560733a7895e41
BLAKE2b-256 c9b85854a0f60c1125dc6581f0ba211dca1b4d699645827200ed4452d8c21883

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b15c8b38443839ea507b3c12709e1d22fa1b7063362491f2b7d6961a9a4ccf05
MD5 6661972b6d981b8c9a3c0b43f5fcd080
BLAKE2b-256 2c20d4c91f53abd5c172945c59e235bc7ce744feca1ef771bf087deb4de48a77

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 25ce98d5ae637c63cd96b9c05e042d76c25ff46ee7da86d9920934e21cad2731
MD5 18a8eb4734651f85aad0d9166b8f0c89
BLAKE2b-256 ec7de64493ccf92b5471a8d9d9579669c929b997e8d414c71c191124048b69f2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.3.1-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 c149c7811a8d325ac54956d3acf0c3183fac2085d00726e17845c225e87c4ae5
MD5 9cef54abacc03dfc147fdaeaa38aae18
BLAKE2b-256 40fb81c5054f0759a0ee192484ce0c3f86ba358208d43290e5cb6462cbdef8a4

See more details on using hashes here.

Release history Release notifications | RSS feed

2.4.0

12 files

This release

2.3.1 This release

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