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

Uploaded CPython 3.14Windows x86-64

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

Uploaded CPython 3.13Windows x86-64

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

Uploaded CPython 3.12Windows x86-64

cybotrade-2.3.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.3.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.3.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.3.0-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: cybotrade-2.3.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.3.0-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 2ca37bc1aeab881f2515031302b422cd71f90c7357bbab0b1a086cc9dd059d84
MD5 d72a34ac9cf51b289c2db200652f8be5
BLAKE2b-256 de0f715b3822377881e01b402e792a14873e2f30c410f8f49a83ea5f1692bb9c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.3.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 cfa939584991891e95b116eb026f5823cc6bdc499e5dad41b27d4aac941dd85a
MD5 8c24a0ca3bd9ca311b775fd8e933d3e9
BLAKE2b-256 7ba8bed9dd7f325d47f32de642a0837e692420c23b9e8b8311a1f782bf9bf222

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.3.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 e499c25da850f3a878a565563f78d1fddb087e206e9ae6057d45be01b157ef2b
MD5 7c341524e4bb575ed42c0e4070ffcaf0
BLAKE2b-256 60cac21a9b881b5ae2be11c98e994fce5dc9dd0cbcd190e735e0d4c8e6eefa15

See more details on using hashes here.

File details

Details for the file cybotrade-2.3.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.3.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 92edd5ece9a4fca14ae98cbde520349b6d612a03abc51955f57da01a9f629df0
MD5 cbeb062debafe2d2cab3d1207ad22dbd
BLAKE2b-256 3df94e756753da113caeaaa741079dcc1a4bffb864873e7ad98431bb5e6d6f0e

See more details on using hashes here.

File details

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

File metadata

  • Download URL: cybotrade-2.3.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.3.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 1a960fcdaca5def0f66d3c9bf4845987d6ea70d05b3d300a871b7d36e3e2cbac
MD5 21004c0a14fe3ed0a4acce64b3c48e13
BLAKE2b-256 566da9482971e5a5d1d7dd2f7dd153ce4dbd0d56b96ca24cbd904cfae0feab93

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 7bc6f4ef5268e2e8b449d8f7da5c4c6aa874d0e6e82fd7241b279d87fa30efbb
MD5 4ce3ab77b9fc3e5aff562aa050c8eaf1
BLAKE2b-256 804837e0ad207d14f965a25b89c77fba578e2be12cfd959ab3ee0a6ae35a5f41

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 e9ee890889a33f4488a44c2403931e7bfd0f9aca1abb941a2171c22dc0ee334a
MD5 e2b610abf536f8f802bd44a2a82d78fe
BLAKE2b-256 379f8db189f3267aa9400c0d58e5f71b27a43b5120f467ae21e9eaf2cc3873ac

See more details on using hashes here.

File details

Details for the file cybotrade-2.3.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.3.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 93fbbf82a926a06cb8707aec4254726efbb4c8a6175fa65f1c06e68bbb7fcf6d
MD5 c263da78eb083ff21125419df97b8802
BLAKE2b-256 70bf29bbf6efc4394638cf05334de4c7a070b10e4e42fa946d0efc254931b5d3

See more details on using hashes here.

File details

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

File metadata

  • Download URL: cybotrade-2.3.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.3.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 554eed55b062c61b4b09a635ebe28a9cdb35bdc8e5ddf06bae3489f8b79d22c6
MD5 9e99b14bde503890f4df0a598a80e701
BLAKE2b-256 eb1352edc0f1ded9732346c5b22eea79eb20531f82654e2279f777e98f60be7d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 508bbd8b90794a1ef94fe7816a77d28bd384df36b73a647748ceba5a209af6f6
MD5 3541e08336466609afecaf3094026cc8
BLAKE2b-256 79683e9a996213a6df193e674fd235202317a8603e755887ede42923e7f058e6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cybotrade-2.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 f6baff93ee554ba59b51c67d924c27c58db755959d2a42a38ef0b30b10d228a3
MD5 36d2adc71fef66709b35f2a39076bfd4
BLAKE2b-256 e6b6dd2dd1bfa24b44b3dc95b0d0dce9998d6684c12bb48c181262b33ef177c8

See more details on using hashes here.

File details

Details for the file cybotrade-2.3.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.3.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 aa1deb291e403d1f28d263e57a4be384799767f6f64ad95f0cbfb49b810fd7cd
MD5 d56154587c4b905bd61d4a8657fd0edc
BLAKE2b-256 034c80959e6846a0e469ef6fc2778ab64f3a95eb8246cfc2b2b58c22a9e6e987

See more details on using hashes here.

Release history Release notifications | RSS feed

2.4.0

12 files

2.3.1

12 files

This release

2.3.0 This release

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