Code by

Carter

Phan

Freqtrade Multi-Bot Dashboard

Freqtrade Multi-Bot Dashboard

Year2026
PythonFreqtradeDockerNext.jsSQLite

Project Description

Advanced Freqtrade setup running 5 strategies in parallel with a real-time Next.js dashboard featuring performance analytics.

Most trading bots share the same fatal flaw: they bet everything on one strategy. When the market regime shifts — trending to range-bound, high-vol to low-vol — a single strategy doesn't just underperform, it bleeds capital while you watch from the sidelines.

I built AlphaVault to solve this not by finding a better strategy, but by running five of them at once.

The premise is simple: distribute risk across uncorrelated strategies so no single market regime can wipe you out. The execution, as it turns out, is anything but simple.

Architecture diagram showing 5 Freqtrade Docker containers feeding into an aggregator engine that powers a Next.js dashboard with equity curves and performance metrics.

Five Strategies, One Orchestrator

Each strategy runs inside its own isolated Docker container — a full Freqtrade instance with its own SQLite database, config, and exchange connection:

| Strategy | Style | Edge Case | |---|---|---| | BinHV45 | High-volatility momentum | Catches explosive moves others miss | | ClucMay72018 | Trend-following with EMA crossovers | Smooth through directional markets | | UniversalMACD | MACD-based mean reversion | Profits from overbought/oversold flips | | SmoothScalp | Low-TF scalping | Constant small wins during chop | | Bandtastic | Bollinger Band breakout | Captures volatility expansions |

They all run in dry-run mode by default, connected to Binance testnet. No real money at risk, but real market data flowing through every decision.

The docker-compose.multi.yml file is the conductor. A single command spins up all five bots plus the aggregator:

yaml
services:
  freqtrade-binhv45:
    image: freqtradeorg/freqtrade:stable
    volumes:
      - ./user_data/binhv45:/freqtrade/user_data
    command: >
      trade --strategy BinHV45
      --db-url sqlite:///freqtrade/user_data/trades.sqlite

  freqtrade-clucmay:
    image: freqtradeorg/freqtrade:stable
    volumes:
      - ./user_data/clucmay:/freqtrade/user_data
    command: >
      trade --strategy ClucMay72018
      --db-url sqlite:///freqtrade/user_data/trades.sqlite

  # ... 3 more identical blocks for UniversalMACD, SmoothScalp, Bandtastic

  aggregator:
    build: .
    depends_on:
      - freqtrade-binhv45
      - freqtrade-clucmay
      - freqtrade-universalmacd
      - freqtrade-smoothscalp
      - freqtrade-bandtastic

Five databases, five processes, one problem: how do you see the full picture?

The Aggregator: Watching Five Databases at Once

The core innovation is a background Python service (aggregator.py) that monitors all five bot databases simultaneously. It uses filesystem-watch patterns to detect new trades as they're written, then consolidates them into a single dashboard.sqlite database.

The aggregator doesn't poll. It listens. When a bot writes a new trade to its local DB, the aggregator picks it up within milliseconds and normalizes it into the unified schema. This means the dashboard always reflects the latest state across all strategies without any polling overhead.

python
def watch_databases():
    """Monitor all bot databases for new trades."""
    for bot_name, db_path in BOT_DATABASES.items():
        last_id = get_last_processed_id(bot_name)
        conn = sqlite3.connect(db_path)
        cursor = conn.cursor()
        cursor.execute(
            "SELECT * FROM trades WHERE id > ? ORDER BY id ASC",
            (last_id,)
        )
        for row in cursor.fetchall():
            normalized = normalize_trade(bot_name, row)
            insert_into_dashboard(normalized)
        conn.close()

The result is real-time aggregation across five isolated data sources — no message queue, no complex ETL pipeline, just smart database watching.

The Analytics Dashboard

The Next.js frontend reads from the consolidated database and computes the metrics that actually matter for trading decisions:

Sharpe Ratio — risk-adjusted return, computed as (mean return − risk-free rate) / standard deviation of returns. Values above 1.0 are decent; above 2.0 are exceptional.

Max Drawdown — the largest peak-to-trough decline across the entire trading history. This is the single most important risk metric. A strategy with 200% return but 60% drawdown is a strategy that will make you abandon it during the trough.

Win Rate — percentage of trades that closed in profit. Surprising insight: high win rate doesn't mean high profitability. SmoothScalp might win 70% of trades but each win is tiny, while BinHV45 wins 40% but the wins are 3x the size of losses.

Hourly Equity Curve — rendered from 10,000+ data points using bezier interpolation for smooth visualization. The curve tells the real story: how your portfolio value evolved hour by hour, which strategies carried which periods, and where the drawdowns hit.

Demo Mode: Test Without Risk

A practical concern drove the demo mode: you shouldn't need a live exchange connection to validate the UI. The dashboard can load compressed backtest .zip files containing 8,000+ simulated trades, letting you stress-test every visualization and metric calculation instantly.

Switching between live and demo mode is a single command:

bash
# Load demo data
docker compose -f docker-compose.multi.yml stop aggregator
rm user_data/dashboard.sqlite
docker compose run --rm --entrypoint python3 freqtrade \
  /freqtrade/user_data/load_demo.py

# Switch back to live
rm user_data/dashboard.sqlite
docker compose -f docker-compose.multi.yml restart aggregator

What I Learned

Trading infrastructure taught me that data plumbing matters more than strategy selection. A mediocre strategy with reliable execution outperforms a brilliant strategy with fragile infrastructure every time.

Isolation is freedom. Running each strategy in its own container with its own database means no strategy can corrupt another's data, crash another's process, or consume another's resources. The cost is operational complexity — five databases to manage — but the aggregator pattern makes that cost manageable.

Real-time is a spectrum. I initially wanted sub-second updates on every metric. What I learned is that trading analytics don't need true real-time — they need fresh-enough data displayed with confidence. The aggregator's watch-loop gives me ~500ms latency, which is invisible to a human trader but avoids the complexity of streaming infrastructure.

Backtest data is a UI superpower. The demo mode started as a debugging tool but became one of the most praised features. Loading 8,000 backtest trades instantly populated every chart and metric, letting me iterate on the UI design orders of magnitude faster than waiting for live trades to accumulate.

The full stack — Python, Freqtrade, Next.js, Docker, SQLite — is open source on GitHub. The dashboard is live at freq-trading-bot.vercel.app, running in demo mode with a full backtest dataset loaded.