Go to file
nicolas f2c50b37ea docs: update README to reflect single-binary architecture and current config 2026-05-28 20:50:03 -03:00
docs Add initial triangular arbitrage bot 2026-05-24 16:12:04 -03:00
notes fix: cascade-based threshold gate, status log, best_net_bps tracking 2026-05-28 10:01:17 -03:00
scripts Add initial triangular arbitrage bot 2026-05-24 16:12:04 -03:00
src fix: tear down SSL connection on read failure to force reconnect 2026-05-28 20:39:02 -03:00
.gitignore Add initial triangular arbitrage bot 2026-05-24 16:12:04 -03:00
AGENTS.md fix: drain signal eventfd after pop to prevent CPU spin; fix all warnings 2026-05-28 15:43:43 -03:00
README.md docs: update README to reflect single-binary architecture and current config 2026-05-28 20:50:03 -03:00
compare_enum.py Add initial triangular arbitrage bot 2026-05-24 16:12:04 -03:00
config.yaml.example feat: make balance wait between live legs configurable, default off 2026-05-28 16:37:32 -03:00
pyproject.toml Add initial triangular arbitrage bot 2026-05-24 16:12:04 -03:00
response.txt Add initial triangular arbitrage bot 2026-05-24 16:12:04 -03:00
session Add initial triangular arbitrage bot 2026-05-24 16:12:04 -03:00
test_fused.py Add initial triangular arbitrage bot 2026-05-24 16:12:04 -03:00

README.md

Triangular Arbitrage Bot

Real-time triangular arbitrage detection and execution for KuCoin Spot. Single C binary — WebSocket book feeds, triangle evaluation, and order placement in one process.

Architecture

Monolithic single-process design using three pthreads:

Thread Role
Hot thread WebSocket I/O via epoll, order book maintenance, book update dispatch to evaluator
Evaluator (embedded in hot thread) Triangle profitability evaluation on every book update, pushes signals to SPSC queue
Executor thread(s) Pops signals from queue, places 3-leg HF market orders via KuCoin REST API, waits for fills via WebSocket, optional balance-wait between legs
[KuCoin WS] ──▶ Hot Thread ──▶ Evaluator ──▶ SPSC Queue ──▶ Executor Thread(s)
                     │                                              |
               Order Book                                        KuCoin REST

The evaluator runs in-process on every book update (no cooldown). The executor does not re-evaluate — it trusts the signal as valid at emission time.

Status

Component Status
WebSocket client (level2/top5 depth) Complete — multi-connection, reconnect, private balance/orderChange channels
Order book store Complete — bid/ask cache with sequence tracking
Triangle enumeration Complete — builder pattern from /api/v2/symbols
Profitability evaluation Complete — paper-trade simulation cascade matching executor
SPSC signal queue Complete — lock-free ring buffer + eventfd wakeup
Order execution Complete — HF market orders, fill event wait, balance wait
Fill channel Complete — eventfd-based cross-thread fill delivery
Concurrent execution Optional — configurable concurrent_slots (default 1)
Fee table Complete — fetched from /api/v1/base-fee, pair-specific lookup
Balance wait Optional — configurable balance_wait_enabled

Prerequisites

  • C compiler (gcc/clang), CMake 3.22+, OpenSSL, libyaml, pthreads

Building

mkdir -p build && cd build
cmake ../src -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)

Binary at build/fused_engine.

Configuration

Edit config.yaml (see config.yaml.example):

Key Description
live_mode false = paper trades (test endpoint), true = real orders
signal_threshold_bps Minimum predicted bps to fire a signal (default: 2)
hold_currencies Currencies held as capital; triangles must start/end in one of these
excluded_currencies Currencies to exclude from triangle enumeration
kcs_discount_active Whether KCS fee discount applies
balance_wait_enabled Wait for WS balance settlement between live legs (default: false)
concurrent_slots Number of executor threads (default: 1, max 16)
initial_capital Map of currency to max quote per signal
kucoin_api_key/secret/passphrase KuCoin API credentials

Running

./build/fused_engine

Fetches fee table and symbol list, connects to KuCoin WebSocket, subscribes to order books, enumerates triangles, evaluates on every book update, and executes signals via REST.

Project Structure

tri_arb/
├── src/                     # C source
│   ├── main.c              # Entry point, thread spawn
│   ├── ws_client.c/h       # KuCoin WebSocket client (TLS, epoll, book/balance/order frames)
│   ├── book.c/h            # Order book store (top-5 bid/ask)
│   ├── symbols_api.c/h     # Symbol discovery, triangle enumeration
│   ├── triangle.c/h        # Triangle set, leg, signal types
│   ├── evaluate.c/h        # Triangle evaluation and signal dispatch
│   ├── executor.c/h        # Signal execution, REST order placement, fill+balance wait
│   ├── events.c/h          # Event loops (hot thread + executor thread(s))
│   ├── fill_handler.c/h    # Cross-thread fill event channel (SPSC ring + eventfd)
│   ├── rest_client.c/h     # KuCoin REST API client (signed requests, keepalive)
│   ├── http_client.c/h     # One-shot HTTPS requests (token fetch, fee table)
│   ├── queue.c/h           # SPSC lock-free queue (evaluator to executor)
│   ├── config.c/h          # YAML config parser
│   ├── hash.c/h            # Hash table
│   ├── cJSON.c/h           # JSON parser
│   ├── log.c/h             # Logging
│   └── CMakeLists.txt
├── build/                   # Build output
├── config.yaml              # Runtime config (gitignored)
├── config.yaml.example      # Config template
└── scripts/                 # Deployment scripts