Server Config Generator
Fill in the form to generate server.json for your local trading engine. Save the output as scripts/server.json (or mount it into the Docker container at /cfg/server.json).
Server
For Docker, use /data/engine.db and mount -v engine-data:/data.
Symbols
IDs are internal — they must be unique positive integers. The engine spins up one matching shard per symbol. Position caps reject any external order whose worst-case fill would push the user past the configured limit; the in-process market maker is exempt.
In-process Market Maker
Posts symmetric Buy/Sell quotes around the configured mid for every symbol so the book has liquidity before any external bot connects.
News-driven bots
Polls the backend's /news feed every poll_seconds, sends new headlines to Gemini for classification, and routes (symbol, direction, confidence) signals to one of three personas. Bots run in-process and are exempt from per-symbol position caps (same carve-out as the market maker).
GEMINI_API_KEY env var)Buys on bullish news, sells on bearish. Aggressive limit (50 bps cross) so the order takes liquidity from the MM book.
Inverts the headline reaction — fades over-eager moves. Same execution profile as momentum, opposite side.
Same direction as momentum but passive (10 bps inside the spread) and half-size — sits on the book hoping to scalp a small revert.
server.json
{
"server": {
"port": 9090,
"backend_url": "http://localhost:3010",
"db_path": "./engine.db",
"auth_cache_ttl_seconds": 300
},
"symbols": [
{
"name": "ES",
"id": 1,
"mid": 7400
},
{
"name": "NKD",
"id": 2,
"mid": 67475
},
{
"name": "NQ",
"id": 3,
"mid": 29678
},
{
"name": "YM",
"id": 4,
"mid": 51608
},
{
"name": "RTY",
"id": 5,
"mid": 2949
},
{
"name": "SPY",
"id": 6,
"mid": 740
},
{
"name": "EWJ",
"id": 7,
"mid": 92
},
{
"name": "EWH",
"id": 8,
"mid": 22
},
{
"name": "EWY",
"id": 9,
"mid": 197
},
{
"name": "FEZ",
"id": 10,
"mid": 69
}
],
"market_maker": {
"enabled": true,
"spread_bps": 20,
"size": 10,
"refresh_ms": 5000,
"track_trades": true
},
"news": {
"poll_seconds": 30,
"gemini_model": "gemini-2.5-flash",
"gemini_api_key": "",
"bots": [
{
"count": 0,
"persona": "momentum",
"size_per_signal": 5,
"confidence_threshold": 0.6,
"size_jitter_pct": 25,
"price_offset_jitter_bps": 15,
"noise_interval_seconds": 0
},
{
"count": 0,
"persona": "contrarian",
"size_per_signal": 3,
"confidence_threshold": 0.7,
"size_jitter_pct": 25,
"price_offset_jitter_bps": 15,
"noise_interval_seconds": 0
},
{
"count": 0,
"persona": "scalper",
"size_per_signal": 4,
"confidence_threshold": 0.65,
"size_jitter_pct": 30,
"price_offset_jitter_bps": 8,
"noise_interval_seconds": 0
}
]
}
}server.json../engine --config server.jsondocker run -p 9090:9090 -v $(pwd)/server.json:/cfg/server.json:ro -v engine-data:/data bubbles-engine