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

Uploaded CPython 3.14Windows x86-64

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

Uploaded CPython 3.13Windows x86-64

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

Uploaded CPython 3.12Windows x86-64

cybotrade-2.2.0-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.2.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.2.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.2.0-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: cybotrade-2.2.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.2.0-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 ff59358c064d5ccf05c6820d60bba4e3e31283a9e9124809e2f66619766714c1
MD5 e4b2ccf3f6bac24009ad1d594ec13ab1
BLAKE2b-256 666fae7fcda5a4db554da030f70bae2c92779f0f007bab2f1d80eeacc9e9e73c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.2.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 2f393504e674b1fa98fdec11072ceed4a77cd6e6fffe1c54c2f168cb131db8fe
MD5 c3d69993ec5b2ea6ebbf81e9e6a377a2
BLAKE2b-256 fd4a293ef765328bf20cb8bfc914e38381f7779feb699ff6b9a646172b8e3a8b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.2.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 b2a267635b18683ff3676a1c9c816d02a2b798885cff01c90cb31626a385c291
MD5 4035fd3774ca95f0aff111553f82f2db
BLAKE2b-256 916e3bf6e2c34e375ac9fb75d3c50b242f7445e5d2429674796c40d995b5eaf8

See more details on using hashes here.

File details

Details for the file cybotrade-2.2.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.2.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 518c39ddd38a0020e599b93eaf903653ba0233a9cbe06d315e8944d62d4f56b4
MD5 b5c51c3c333c63ab056ad04a5a7691ff
BLAKE2b-256 2b65f341a9d70599d37b0014c7d6c378918f9a4fdce43c03efbc291a3d480fec

See more details on using hashes here.

File details

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

File metadata

  • Download URL: cybotrade-2.2.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.2.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 4e2c31cf072da7ef840dda85d7e28922a7be66cd33a58bad867ffa0df360edaf
MD5 e2040bcb20ede13bf0cd977521d26286
BLAKE2b-256 edfbc84d1a8c4ce68f75f55a68ee1495ecd7300bb5187d5a2a8297085022034f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 240d2624ab151ab6d1e8ef6795f78508c5d4a4ddc14d94bd122de99970dda106
MD5 640140238f7650e2d623fc5af424b3db
BLAKE2b-256 73b727393aae9045f9c9106fc5bfcd00196793f0e9038ec50867f4bcdae90434

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 a0ae71d4a5fd181a1517f9e7d4b0f57e087fdb940ee5f1de4b3dfa6349ebb591
MD5 3c2cb61f091818d01bd46ca266f8e7b7
BLAKE2b-256 39c6f595df8b40d9a9d55a33d05de510f18ff3416079d714576ac122857e03e3

See more details on using hashes here.

File details

Details for the file cybotrade-2.2.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.2.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 890eb10fe236775a344e75f0953f6cbb51c272aeb00d8540c91c93923355071b
MD5 35986de36cb655be8284457a8a8af1c2
BLAKE2b-256 a8a1506cdd7bcef334d9e545fd8060fe1d2cda7dcba3d03216d771f75ce44aa0

See more details on using hashes here.

File details

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

File metadata

  • Download URL: cybotrade-2.2.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.2.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 d6d61ffbf807ddd4c411bc08cfd4650a4d030e5df07cb33b3dab5a6b88c133a1
MD5 f7d939dd8501b7f41dbf4db5ff81d897
BLAKE2b-256 a2c6855824313df16eb0eb03c57dd0d4a2c31960a2b0f7932fd8ed5becbdd4d4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f14e2a2c0b8ad2191c5daa4eff195047e35f91eb06f3424d83f4808fb6fb80ed
MD5 5f9b83d563a0b82c1512afe3567d600c
BLAKE2b-256 bdcaa8ea61956833eeddbb394e4cf7c24b5cdc77666687989a8757753216547d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 910a1f1941a1f02753f9787f22f7ec5c782f6472927a19d9b34391d7832bfe43
MD5 e7c387c9e556c281b9477cd2627f9aaa
BLAKE2b-256 8e94b8471fd7508344751ab1e432e23e6db739c752d34b5169782cf68b34ca77

See more details on using hashes here.

File details

Details for the file cybotrade-2.2.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.2.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 78ca69897dfab34ec03b92da083317386002dc349cbfafaec60c4df68333c4fc
MD5 16b226cbd595700dc68a0dc574f5735c
BLAKE2b-256 067ec2351b8b48a0ac1d5c78aacbee7a62f780b5d34b08f29a4912de6bac4c43

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

This release

2.2.0 This release

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