Commit Graph

7 Commits

Author SHA1 Message Date
nicolas 9e0866c9e7 fix: remove double fee hold on legs 1-2; fix sell order_param dimension
- Remove apply_fee_hold from input path (legs 1-2) — fee hold
  is already applied at end-of-leg cascade. Both evaluate.c and executor.c.
- Fix sell order_param: set from base amount instead of quote_volume
  (A5/A8). Sell order size was incorrectly computed as a quote-equivalent.
2026-05-28 09:19:48 -03:00
nicolas 728f41679a fix: replace evaluate.c cascade with paper-trade simulation from executor
The evaluation now runs the exact same paper-mode simulation code that
the executor uses, instead of a separate cascade with different formulas.
predicted_bps comes from the simulation PnL, matching effective_bps.
2026-05-27 23:44:14 -03:00
nicolas 174b7570fa feat: concurrent executor slots; fix: fundsIncrement for market buys, remove double-counted leg0 fee hold
- Add concurrent_slots config (fused_engine section, default 1)
- Create executor_shared_t with shared in_flight table + queue mutex for multi-thread
- Move in_flight state from executor_thread_t to executor_shared_t (cross-thread isolation)
- event_executor_thread: per-thread entry point, N threads created in main.c
- Add fundsIncrement to trading_pair_t, triangle_t, signal_leg_t (fetch from KuCoin API)
- Use funds_increment for rounding market buy quote_cost (evaluate.c) and increment floor (executor.c)
- Fix leg 0: remove double-counted apply_fee_hold (evaluate already accounts via ff)
2026-05-27 13:18:53 -03:00
nicolas 8739c871d5 fix: separate screen-only logging from file logging
- Add log_write_screen() for status/stats output (stderr only)
- Change STATUS line to use log_write_screen (not in log file)
- SIGNAL, ORDER, FILL, FILLED/FAILED still go to both screen and log file
- Log file at /tmp/engine.log
2026-05-27 09:31:49 -03:00
nicolas 3828e2b104 fix: cross-leg increment floor, ceiling-to-floor rounding, balance WS subscription, order-level logging
src/evaluate.c:
- Add cross-leg increment floor after each leg's output
- Fix sell-leg min_volume conversion (was understated by rates[leg])
- Change ceil to floor for all leg rounding (round input down, then compute)

executor/ws_client.py:
- Subscribe to /account/balance via Classic WS (subject: account.balance)
- Add await_balance() with ack tracking and per-currency futures
- Handle balance events and store latest available per currency

executor/executor.py:
- Reject order detail included in fills list with real attempted volume/latency
- Screen/log output shows fills, book tops, profit for all statuses
- side field in order_placed/order_rejected logs
- predicted_bps read early from signal (no more hardcoded 0.0)
- timings in failed/aborted reports
- Paper mode rounding: buy funds/base floored to qi/bi
2026-05-25 20:21:19 -03:00
nicolas 71ed25fe56 refactor: move order sizing to engine, simplify executor
Engine (evaluate.c):
- Compute per-leg minimum order size from quoteMinSize
  (max(baseMinSize * price, quoteMinSize), rounded to quoteIncrement)
- Convert each leg's minimum to starting-quote via pure-rate product (no fees)
- Viability gate: skip triangle if candidate < min_volume (strictest leg)
- Floor starting_volume at min_volume; supersedes old base_min_size guard

Data (symbols_api.h, triangle.h, symbols_api.c):
- Parse quoteMinSize from KuCoin /api/v2/symbols; propagate to triangle struct

Executor (executor.py):
- Remove _precheck_volume: sizing is the engine's responsibility
- Live mode: don't deduct estimated fee from filled_volume (exchange nets fees)
- Live mode: LegFill.fee always zero
2026-05-24 17:49:09 -03:00
nicolas 2a82086683 Add initial triangular arbitrage bot
Two-process architecture: a C17 fused engine (WebSocket order book
mirror, triangle enumeration, real-time profitability evaluation)
communicating via Unix domain socket to a Python 3 executor (order
placement with paper/live trading modes, REST control API).
Targets KuCoin spot market.
2026-05-24 16:12:04 -03:00