"""
dashboard.py — MoneyMaker live monitoring dashboard.
Usage:
python dashboard.py # starts on http://localhost:5001
python dashboard.py --port 5002
Auto-refreshes every 60 seconds. Shows:
- Portfolio P&L + C25 benchmark
- Equity curve, win/loss, position charts (Apache ECharts)
- Open positions with live prices
- Closed trades (win/loss)
- Signal accuracy
- Recent runner log tail
"""
import argparse
import json
import os
import time
from datetime import datetime, timezone
from pathlib import Path
import yfinance as yf
from flask import Flask, jsonify, render_template_string
from db import get_conn, DB_TYPE
from report import _c25_day_return, _unrealised_pnl, _realised_pnl, _total_fees, _signal_accuracy
CAPITAL = 10_000
LOG_DIR = Path(os.getenv("LOG_DIR", str(Path(__file__).parent / "logs")))
METRICS_FILE = Path(__file__).parent / "metrics.json"
REFRESH = 60 # seconds
app = Flask(__name__)
# ── Metrics dashboard template ────────────────────────────────────────────────
METRICS_TEMPLATE = """
Total Cost
${{ "%.4f"|format(total_cost_usd) }}
USD spent
Claude Calls
{{ total_calls }}
articles analyzed
Input Tokens
{{ "{:,}".format(total_input_tokens) }}
${{ "%.4f"|format(cost_input) }} · {{ input_pct }}%
Output Tokens
{{ "{:,}".format(total_output_tokens) }}
${{ "%.4f"|format(cost_output) }} · {{ output_pct }}%
Cost / Article
${{ "%.5f"|format(cost_per_call) }}
avg per Claude call
Token Breakdown
Input tokens
{{ "{:,}".format(total_input_tokens) }}
Output tokens
{{ "{:,}".format(total_output_tokens) }}
Total tokens
{{ "{:,}".format(total_input_tokens + total_output_tokens) }}
Net P&L
{{ "{:+,.0f}".format(net_pnl) }}
{{ "{:+.2f}%".format(net_pct) }} af kapital
Urealiseret
{{ "{:+,.0f}".format(unreal) }}
{{ open_count }} position{{ 'er' if open_count != 1 else '' }}
Realiseret
{{ "{:+,.0f}".format(realised) }}
gebyrer: {{ "{:,.0f}".format(fees) }} kr
C25 i dag
{% if c25_ret is not none %}
{{ "{:+.2f}%".format(c25_ret) }}
vs benchmark: {{ "{:+.2f}%".format(vs_bench) if vs_bench is not none else "—" }}
{% else %}
—
marked lukket
{% endif %}
Signal accuracy
{% if sig.total_trades > 0 %}
{{ "{:.0f}%".format(sig.accuracy_pct) }}
{{ sig.correct }}/{{ sig.total_trades }} handler
{% else %}
—
ingen handler endnu
{% endif %}
Kapital
{{ "{:,.0f}".format(capital) }}
kontant: {{ "{:,.0f}".format(cash) }} kr