A trading simulator for OKX exchange. Reads OKX websocket data and tries to make smart trades based on your Strategy configuration settings.
The trading simulation logic implemented is super rough and kinda dumb (im still experimenting with it tho).
The scheduler will try to follow the line going up, by querying all tokens and buying whatever one is doing good numbers.
I'm just sharing this because i think its a good template to start with a stream based: producer -> consumer -> app architecture. (not event driven, at least for now)
That being said, im not responsible if you lose money by using it to trade with money.
Each setting in config.toml is explained but feel free open an issue to ask questions if something is not clear.
- Redpanda
- Scylla
- Pushover (optional)
- Producer (Okx websocket messages -> Redpanda)
- Consumer (Redpanda messages -> Scylla)
- Scheduler (ScyllaDB Queries -> Token evaluation -> UI)
The provision.sh script brings up all containers, waits for Scylla and
Redpanda to become ready, runs the CQL migration, and creates the topics
with the right retention. It's idempotent — safe to re-run.
./provision.shOn macOS the script also bumps fs.aio-max-nr inside Docker Desktop's VM,
which is required by both Scylla and Redpanda (both are seastar-based).
If you'd rather do it by hand, the equivalent steps are:
docker compose up -d
# Wait until Scylla shows 'UN' (up-normal)
docker exec -it scylla nodetool status
# Run migrations
docker exec -it scylla cqlsh -f /tmp/migration.cql
# Create topics and set 12h retention
docker exec redpanda rpk topic create candle1m tickers trades --partitions 10 --replicas 1
docker exec redpanda rpk topic alter-config candle1m tickers trades --set retention.ms=43200000Note: these topics are append-only streams, so they use the default
cleanup.policy=deletecombined withretention.msabove. Do not setcleanup.policy=compacthere — compaction keeps only the latest value per key, which would silently drop trades.
ScyllaDB: 127.0.0.1:9042
Redpanda: 127.0.0.1:9092
Redpanda console: http://localhost:8080/topicscargo run --bin producer
cargo run --bin consumervim config.tomlStart
cargo run --bin schedulerThis is how the scheduler UI looks with ui.enable = true

If using the scheduler with websocket server enabled you can connect to it using a very rough expermiental wasm UI made with egui and ewebsock.
The console is just a listener, so can't send stuff back to the scheduler for now.
Run the app with:
cargo run --bin consoleOr build web and run with:
cd console && ./build_web.sh && ./start_server.shOr run compiled version in the repo with:
basic-http-server --addr 0.0.0.0:8082 .The scheduler can send status updates every 30 minutes informing you about your current balance, bot uptime and account change % if. It will also send a notification when cash-outs and stop loss trigger.
Connect to Scylla using cqlsh
docker exec -it scylla cqlsh
Use HELP for help.
cqlsh> use okx;
cqlsh:okx> describe tables;
candle1m tickers trades
cqlsh:okx> SELECT * FROM trades WHERE instid='XCH-USDT' ORDER BY ts DESC LIMIT 10;
instid | ts | tradeid | px | side | sz
----------+---------------------------------+----------+-------+------+----------
XCH-USDT | 2022-10-01 21:34:00.425000+0000 | 19102621 | 33.4 | buy | 0.040482
XCH-USDT | 2022-10-01 21:33:59.339000+0000 | 19102620 | 33.41 | buy | 0.132378
XCH-USDT | 2022-10-01 21:33:49.342000+0000 | 19102619 | 33.41 | buy | 0.103742
XCH-USDT | 2022-10-01 21:33:48.423000+0000 | 19102618 | 33.41 | buy | 0.088245
XCH-USDT | 2022-10-01 21:33:40.424000+0000 | 19102617 | 33.4 | buy | 0.103606
XCH-USDT | 2022-10-01 21:33:36.340000+0000 | 19102616 | 33.42 | buy | 0.086683
XCH-USDT | 2022-10-01 21:33:31.423000+0000 | 19102615 | 33.41 | buy | 0.066893
XCH-USDT | 2022-10-01 21:33:26.423000+0000 | 19102614 | 33.41 | sell | 0.102778
XCH-USDT | 2022-10-01 21:33:23.340000+0000 | 19102613 | 33.41 | buy | 0.043765
XCH-USDT | 2022-10-01 21:33:15.339000+0000 | 19102612 | 33.42 | buy | 0.071039
(10 rows)Delete topics from redpanda
docker exec redpanda rpk topic delete candle1m trades tickersdocker compose down -vThe -v flag also removes the scylla_data named volume, which is where
Scylla's data actually lives (bind mounts don't work reliably on Docker
Desktop for Mac due to O_DIRECT alignment requirements).
