The dashboard can now control execution mode (DRY_RUN, DEMO, LIVE) via a REST API without manual .env editing.
Get available modes and current configuration.
curl http://localhost:8000/api/mode/infoResponse:
{
"current_mode": "DEMO",
"available_modes": [
{
"mode": "DRY_RUN",
"description": "Logging only, no orders",
"money_risk": "None"
},
{
"mode": "DEMO",
"description": "Paper trading on demo account",
"money_risk": "None (demo funds)"
},
{
"mode": "LIVE",
"description": "Real money trading",
"money_risk": "REAL MONEY ⚠️"
}
]
}Get current execution mode.
curl http://localhost:8000/api/mode/currentResponse:
{
"mode": "DEMO"
}Change execution mode (use for DRY_RUN or DEMO).
curl -X POST http://localhost:8000/api/mode/set \
-H "Content-Type: application/json" \
-d '{"mode": "DEMO"}'Response (success):
{
"success": true,
"message": "Mode changed to DEMO. Bot will use new mode on next restart.",
"previous_mode": "DRY_RUN",
"new_mode": "DEMO",
"requires_restart": true
}Response (LIVE attempted without confirmation):
{
"success": false,
"error": "LIVE mode requires explicit confirmation. Use set_mode_confirmed() instead.",
"warning": "LIVE mode trades with REAL MONEY. This is irreversible."
}Change execution mode with LIVE confirmation (use for LIVE only).
curl -X POST http://localhost:8000/api/mode/set-confirmed \
-H "Content-Type: application/json" \
-d '{"mode": "LIVE"}'Response:
{
"success": true,
"message": "Mode changed to LIVE. Bot will use new mode on next restart.",
"previous_mode": "DEMO",
"new_mode": "LIVE",
"requires_restart": true
}The API server runs alongside the bot on port 8000.
Modify polytracker/main.py to start the API server:
from polytracker.api.server import start_api_server
# In main() function, alongside scheduler start:
asyncio.create_task(start_api_server(port=8000))cd ~/code/openclaw/projects/PolyTrackerBot
source venv/bin/activate
python -m polytracker.api.serverThe ModeControl component now calls the API:
// In ModeControl.tsx
const handleModeSwitch = async (mode: ExecutionMode) => {
const response = await fetch('http://localhost:8000/api/mode/set', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ mode })
});
const data = await response.json();
if (data.success) {
// Show success message
}
};- UI Click — User clicks mode button in dashboard
- API Request — Dashboard sends POST to
/api/mode/setor/api/mode/set-confirmed - File Update — API updates EXECUTION_MODE in
.env - Response — API returns success/error message
- Restart — User restarts bot (or auto-restart logic)
- New Mode — Bot reads updated .env and uses new mode
- Requires explicit confirmation endpoint (
/api/mode/set-confirmed) - Dashboard prompts user with warning before calling confirmed endpoint
- Separate endpoint prevents accidental LIVE mode activation
- Only accepts: DRY_RUN, DEMO, LIVE
- Returns error for invalid mode values
- Mode changes logged to bot logs
- LIVE mode changes trigger warning message
User clicks "DEMO" button in dashboard
↓
ModeControl sends POST /api/mode/set with {"mode": "DEMO"}
↓
API validates mode ✓
↓
API updates .env: EXECUTION_MODE=DEMO
↓
API returns success response
↓
Dashboard shows "✅ Mode changed to DEMO"
↓
User restarts bot (or auto-restart triggered)
↓
Bot reads new .env value
↓
Bot now runs in DEMO mode (real orders on demo account)
When mode changes via API:
✅ Execution mode changed: DRY_RUN → DEMO
📡 Mode control API server started on 127.0.0.1:8000
When LIVE mode is confirmed:
⚠️ SWITCHING TO LIVE MODE - REAL MONEY TRADING ENABLED
✅ Execution mode changed: DEMO → LIVE
- Success message — Green banner with message, auto-hides after 5s
- Error message — Red banner showing what went wrong
- Loading state — Cyan banner "Changing mode..." while request pending
- Button disabled — While changing mode to prevent double-clicks
- API Server:
polytracker/api/server.py - Mode Controller:
polytracker/api/mode_control.py - Dashboard Component:
dashboard/src/components/ModeControl.tsx - Config:
.env(updated by API)
- Check API server is running on port 8000
- Verify bot is running:
pgrep -f polytracker
- Check API logs:
tail -f logs/polytracker.log | grep "mode\|Mode" - Verify .env file is writable:
ls -l .env
- Use
/api/mode/set-confirmedendpoint instead - This is intentional safety restriction
Status: ✅ Production Ready
API Port: 8000 (localhost)
CORS: Enabled for dashboard access