Why Trading Bots Need a Live Dashboard

When you run multiple auto-trading bots across Solana, KuCoin, and HyperLiquid, the logs pile up fast. Every trade, every signal, every error -- they all scroll past in a terminal window that nobody watches. The problem isnt that the data isnt there. Its that raw logs are noise, not signal.

DeFiKit runs a fleet of bots: the AutoGunSOL sniping scanner on Solana, the Freqtrade-based auto-trader with Ichimoku strategies on KuCoin, and the experimental HyperLiquid prediction bot. Each generates hundreds of log lines per hour. Buried in that noise are the signals that matter: which strategies are winning, which pairs are bleeding, and where the system is about to hit a rate limit.

A live Telegram dashboard solves this. Instead of scraping log files, you get real-time trade notifications, daily P&L summaries, pair-level heatmaps, and system health alerts -- all delivered to the same Telegram chat where you manage your bots.

Architecture: From Bot Logs to Telegram Messages

The dashboard pipeline has three layers:

- **Data ingestion:** Each bot writes structured JSON log lines (not plain text) to a shared log stream. The format is always `{timestamp, bot_id, event_type, data}`.

- **Aggregation layer:** A lightweight Cloudflare Worker runs every 5 minutes, pulls the last hours worth of logs, and computes metrics: win rate, total volume, open positions, drawdown.

- **Delivery layer:** The worker calls the Telegram Bot API to send formatted messages to the admin chat. No database needed -- just Workers + Bot API.

Structured Log Format

Instead of `INFO: Bought 0.5 SOL at $145.32`, bots log structured JSON:

```json

{

"ts": "2026-05-07T14:30:00Z",

"bot": "autogun-sol-mainnet",

"event": "trade_executed",

"data": {

"pair": "SOL/USDC",

"side": "buy",

"size": 0.5,

"price": 145.32,

"slippage_bps": 3,

"strategy": "momentum_breakout_v2"

}

}

```

This makes aggregation trivial -- no regex parsing, no fragile text scraping.

Building the Aggregation Worker

The Cloudflare Worker that powers the dashboard runs on a cron trigger (every 5 minutes during market hours, every 30 minutes overnight). Heres the core logic:

```javascript

async function aggregateMetrics(logs, since) {

const recent = logs.filter(l => l.ts > since);

// Per-bot stats

const byBot = {};

for (const entry of recent) {

if (!byBot[entry.bot]) byBot[entry.bot] = { trades: 0, wins: 0, losses: 0, volume: 0 };

if (entry.event === 'trade_executed') {

byBot[entry.bot].trades++;

byBot[entry.bot].volume += entry.data.size * entry.data.price;

}

if (entry.event === 'trade_closed') {

if (entry.data.pnl > 0) byBot[entry.bot].wins++;

else byBot[entry.bot].losses++;

}

}

return Object.entries(byBot).map(([name, stats]) => ({

name,

...stats,

winRate: stats.trades > 0 ? (stats.wins / (stats.wins + stats.losses) * 100).toFixed(1) : 0,

avgVolume: stats.trades > 0 ? (stats.volume / stats.trades).toFixed(2) : 0

}));

}

```

The worker stores the last aggregated state in Workers KV so it can compute deltas (today vs yesterday) without polling a database.

Telegram Message Format

Each dashboard push is a single message with inline formatting. Heres the template:

```

📊 DeFiKit Dashboard -- 14:30 CT

🤖 AutoGun SOL Mainnet

Trades: 12 | Win Rate: 75%

Volume: $8,420 | P&L: +$342 (+4.2%)

Active: 3 positions

🤖 Freqtrade KuCoin (Ichimoku)

Trades: 8 | Win Rate: 62.5%

Volume: $12,100 | P&L: +$187 (+1.5%)

Active: 2 positions

🤖 HyperLiquid Prediction

Trades: 3 | Win Rate: 100%

Volume: $450 | P&L: +$28 (+6.6%)

Active: 0 positions

⚠️ Alerts

• AutoGun SOL: Slippage exceeded 5bps on last 3 trades

• Freqtrade: Position SOL/USDT approaching stop-loss at $138

Last updated: 14:30 CT | Next update: 14:35 CT

```

The emoji header makes it scannable at a glance. Critical alerts (slippage, drawdown, exchange errors) get highlighted with emoji markers.

Deploying With Cloudflare Workers

Deployment is a single wrangler command. The worker itself is ~150 lines of JavaScript:

```bash

npx wrangler deploy src/dashboard-worker.js \

--name defikit-dashboard \

--kv DASHBOARD_STATE \

--secret TELEGRAM_BOT_TOKEN \

--secret TELEGRAM_CHAT_ID

```

Set the cron schedule in `wrangler.jsonc`:

```json

{

"triggers": {

"crons": ["*/5 9-23 * * 1-5", "*/30 0-8,0-23 * * 0,6"]

}

}

```

This runs every 5 minutes during market hours (9 AM to 11 PM CT, weekdays) and every 30 minutes outside those hours.

Extending the Dashboard

The same pipeline can power richer analytics:

- **Daily digest:** A separate worker runs at 8 AM and 8 PM CT, sending a fuller report with charts (generated as inline Telegram images using chart.js on Workers).

- **Strategy comparison:** Side-by-side win rates, Sharpe ratios, and max drawdown for each active strategy.

- **Gas/ fee tracking:** For Solana bots, track transaction fees and compute net P&L after fees.

- **Alert thresholds:** Configurable alerts -- notify when win rate drops below 40%, drawdown exceeds 15%, or a bot goes silent for more than 10 minutes.

Why Telegram Instead of a Web Dashboard

A web dashboard is nice to have, but Telegram wins for trading bots for three reasons:

1. **Push, not pull.** You dont open a browser to check -- the data comes to you. On mobile, Telegram notifications are instant.

2. **Same channel as bot commands.** You can reply to a dashboard message with `/pause autogun-sol` and the bot stops trading, all in one chat.

3. **Zero infrastructure.** No database, no frontend, no domain. Just a Worker and the Bot API.

This is the hybrid dev-marketing philosophy in action: build tools that double as communication channels. The dashboard isnt just an internal tool -- its the same interface youd show a partner or investor who wants to see how the bots are performing.

What We Learned

Running this in production for DeFiKit for the last month taught us a few things:

- **Structured logging pays for itself.** The upfront cost of changing bot log formats was two hours of refactoring. It saved ten hours of regex debugging in the first week.

- **Cron-based aggregation is simpler than streaming.** We tried WebSocket streaming first. For a dashboard that updates every 5 minutes, a cron worker triggered by Cloudflare Scheduler is cheaper and more reliable.

- **Keep messages under 4096 characters.** Telegrams message length limit means you need to truncate or paginate. We split long dashboards into a summary message + detail thread.

- **Include a timestamp.** When a dashboard message sits in chat for hours, the reader needs to know how stale the data is. Every message carries a "Last updated" line.

Next Steps

With the dashboard live, the next move is adding two-way interaction -- being able to reply to a dashboard message with a command like `/toggle botname` or `/adjust strategy_name threshold 0.5`. That turns the dashboard from a read-only view into a control panel, all inside Telegram.