feat: add 5 dashboard features — dark mode, trade history, backtests, model insights, alerts

- Dark mode: class-based theme toggle with localStorage persistence and flash prevention
- Trade History (/trades): paginated table, stats cards, equity curve chart with DB API endpoints
- Backtest Viewer (/backtests): log parser for 35 backtest results, sidebar + detail + comparison tabs
- Model Insights: dashboard card + dialog showing feature importance, regime distribution, training history
- Alert/Signal Log (/alerts): signal stats, filterable table with execution tracking
- API: 8 new endpoints with psycopg2 DB connection pool
- Dark mode sweep across books page, about dialog, and all dashboard components
- Architecture docs rewritten with Mermaid diagrams (23 docs)
- README and FEATURES.md rewritten bilingual (Indonesian + English)
- main_live.py: write model_metrics.json on startup and retrain

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
GifariKemal
2026-02-09 05:46:54 +07:00
co-authored by Claude Opus 4.6
parent b2dc2dacd7
commit e8355b3f62
230 changed files with 69573 additions and 5673 deletions
+202 -25
View File
@@ -1,41 +1,54 @@
# Database Module — PostgreSQL Integration
# *Database Module**PostgreSQL* Integration
> **File:** `src/db/connection.py`, `src/db/repository.py`
> **Database:** PostgreSQL
> **Library:** psycopg2 (connection pooling)
> **Database:** *PostgreSQL*
> **Library:** psycopg2 (*connection pooling*)
---
## Apa Itu Database Module?
## Apa Itu *Database Module*?
Database Module menyediakan **penyimpanan persisten** untuk semua data trading — trade history, training log, sinyal, snapshot pasar, dan status bot. Menggunakan PostgreSQL dengan connection pooling untuk performa tinggi.
*Database Module* menyediakan **penyimpanan persisten** untuk semua data trading — trade history, training log, sinyal, snapshot pasar, dan status bot. Menggunakan *PostgreSQL* dengan *connection pooling* untuk performa tinggi.
**Analogi:** Database Module seperti **arsip perpustakaan** — menyimpan semua catatan trading secara terorganisir, bisa dicari kapan saja, dan tidak hilang meski bot di-restart.
**Analogi:** *Database Module* seperti **arsip perpustakaan** — menyimpan semua catatan trading secara terorganisir, bisa dicari kapan saja, dan tidak hilang meski bot di-restart.
---
## Arsitektur
```
Bot Components
├── TradeLogger → TradeRepository, SignalRepository, MarketSnapshotRepository
├── AutoTrainer → TrainingRepository
├── main_live.py → BotStatusRepository, DailySummaryRepository
└── Dashboard → Semua repository (READ)
|
v
DatabaseConnection (Singleton)
|
v
ThreadedConnectionPool (1-10 koneksi)
|
v
PostgreSQL Server
```mermaid
graph TD
TL[TradeLogger] -->|write| TR[TradeRepository]
TL -->|write| SigR[SignalRepository]
TL -->|write| MSR[MarketSnapshotRepository]
AT[AutoTrainer] -->|write| TrR[TrainingRepository]
ML[main_live.py] -->|write| BSR[BotStatusRepository]
ML -->|write| DSR[DailySummaryRepository]
DASH[Dashboard] -.->|read| TR
DASH -.->|read| SigR
DASH -.->|read| MSR
DASH -.->|read| TrR
DASH -.->|read| BSR
DASH -.->|read| DSR
TR --> DC[DatabaseConnection<br/><i>Singleton</i>]
SigR --> DC
MSR --> DC
TrR --> DC
BSR --> DC
DSR --> DC
DC --> POOL[ThreadedConnectionPool<br/>1 10 koneksi]
POOL --> PG[(PostgreSQL Server)]
style DC fill:#2d6a4f,stroke:#1b4332,color:#fff
style PG fill:#1b4332,stroke:#081c15,color:#fff
style POOL fill:#40916c,stroke:#2d6a4f,color:#fff
```
---
## Connection (Singleton + Pooling)
## Connection (*Singleton* + Pooling)
```python
class DatabaseConnection:
@@ -49,6 +62,8 @@ class DatabaseConnection:
"""
```
`DatabaseConnection` menerapkan pola *singleton* yang *thread-safe* — hanya satu instance yang pernah dibuat selama proses berjalan. Akses ke database dilakukan melalui *context manager* (`with db.get_cursor() as cur`) sehingga koneksi selalu dikembalikan ke pool setelah selesai.
### Konfigurasi
```
@@ -68,7 +83,7 @@ from src.db import get_db, init_db
if init_db():
db = get_db()
# Query
# Query dengan context manager
with db.get_cursor() as cur:
cur.execute("SELECT * FROM trades WHERE profit_usd > 0")
rows = cur.fetchall()
@@ -79,7 +94,9 @@ if init_db():
---
## 6 Repository
## 6 *Repository*
Setiap *repository* bertanggung jawab atas satu tabel dan menyediakan method khusus untuk operasi CRUD.
### 1. TradeRepository
@@ -140,6 +157,164 @@ if init_db():
## Tabel Database
### Entity-Relationship Diagram
```mermaid
erDiagram
trades {
bigint ticket PK
varchar symbol
varchar direction
float entry_price
float exit_price
float stop_loss
float take_profit
float lot_size
float profit_usd
float profit_pips
timestamp opened_at
timestamp closed_at
int duration_seconds
varchar entry_regime
float entry_volatility
varchar entry_session
varchar smc_signal
float smc_confidence
text smc_reason
bool smc_fvg_detected
bool smc_ob_detected
bool smc_bos_detected
bool smc_choch_detected
varchar ml_signal
float ml_confidence
varchar market_quality
float market_score
float dynamic_threshold
varchar exit_reason
varchar exit_regime
varchar exit_ml_signal
float balance_before
float balance_after
float equity_at_entry
json features_entry
json features_exit
varchar bot_version
varchar trade_mode
}
training_runs {
serial id PK
varchar training_type
int bars_used
int num_boost_rounds
bool hmm_trained
int hmm_n_regimes
bool xgb_trained
float train_auc
float test_auc
float train_accuracy
float test_accuracy
varchar model_path
varchar backup_path
bool success
text error_message
timestamp started_at
timestamp completed_at
int duration_seconds
bool rolled_back
text rollback_reason
timestamp rollback_at
}
signals {
serial id PK
timestamp signal_time
varchar symbol
float price
varchar signal_type
varchar signal_source
float combined_confidence
varchar regime
varchar session
float volatility
float market_score
bool executed
text execution_reason
bigint trade_ticket FK
}
market_snapshots {
serial id PK
timestamp snapshot_time
varchar symbol
float price
float open
float high
float low
float close
varchar regime
float volatility
varchar session
float atr
float spread
varchar ml_signal
float ml_confidence
varchar smc_signal
float smc_confidence
int open_positions
float floating_pnl
json features
}
bot_status {
serial id PK
timestamp status_time
bool is_running
varchar status
int loop_count
float avg_execution_ms
int uptime_seconds
float balance
float equity
float margin_used
int open_positions
float floating_pnl
float daily_pnl
varchar risk_mode
varchar current_session
bool is_golden_time
}
daily_summaries {
date summary_date PK
int total_trades
int winning_trades
int losing_trades
int breakeven_trades
float gross_profit
float gross_loss
float net_profit
float start_balance
float end_balance
float win_rate
float profit_factor
float avg_win
float avg_loss
int sydney_trades
int tokyo_trades
int london_trades
int ny_trades
int golden_trades
int fvg_trades
int fvg_wins
int ob_trades
int ob_wins
}
trades ||--o{ signals : "trade_ticket"
daily_summaries ||--o{ trades : "summary_date covers opened_at"
```
### trades
```sql
@@ -214,7 +389,7 @@ if init_db():
---
## Graceful Degradation
## *Graceful Degradation*
```
PostgreSQL tersedia?
@@ -223,3 +398,5 @@ PostgreSQL tersedia?
Bot TIDAK pernah crash karena database.
```
*Graceful degradation* memastikan bot tetap beroperasi penuh meskipun *PostgreSQL* tidak tersedia. Semua operasi database dibungkus dengan `try/except` — jika koneksi gagal, data ditulis ke CSV sebagai fallback. Saat database kembali online, bot otomatis menggunakan koneksi pool kembali tanpa restart.