|
|
||
|---|---|---|
| docs | ||
| notes | ||
| scripts | ||
| src | ||
| .gitignore | ||
| AGENTS.md | ||
| README.md | ||
| compare_enum.py | ||
| config.yaml.example | ||
| pyproject.toml | ||
| response.txt | ||
| session | ||
| test_fused.py | ||
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 N+1 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, delivers to first free executor slot |
| Executor thread(s) | Spin on per-thread slot via atomic state machine; pick up signal, place 3-leg HF market orders via KuCoin REST API, wait for fills via WebSocket, optional balance-wait between legs |
[KuCoin WS] ──▶ Hot Thread ──▶ Evaluator ──▶ Slot[0..N] ──▶ Executor Thread(s)
│ (CAS state machine) │
Order Book KuCoin REST
Each executor thread owns one slot. The evaluator writes the signal directly into the slot via a CAS state machine (FREE → CLAIMED → READY). The executor picks it up on the next spin iteration (nanoseconds). If all slots are busy or no free slot available, the signal is dropped — no queueing.
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 |
| Per-slot signal delivery | Complete — per-thread slot with atomic CAS state machine, no queue |
| 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)
│ ├── slot.c/h # Per-executor signal slot with atomic CAS delivery
│ ├── 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