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:
co-authored by
Claude Opus 4.6
parent
b2dc2dacd7
commit
e8355b3f62
@@ -2,15 +2,43 @@
|
||||
|
||||
> **File:** `src/trade_logger.py`
|
||||
> **Class:** `TradeLogger`
|
||||
> **Storage:** PostgreSQL (primary) + CSV (fallback)
|
||||
> **Storage:** PostgreSQL (primary) + CSV (*fallback*)
|
||||
|
||||
---
|
||||
|
||||
## Apa Itu Trade Logger?
|
||||
## Apa Itu *Trade Logger*?
|
||||
|
||||
Trade Logger mencatat **setiap trade, sinyal, dan kondisi pasar** secara otomatis ke database dan file CSV. Data ini digunakan untuk analisis performa, retraining ML model, dan debugging.
|
||||
*Trade Logger* mencatat **setiap trade, sinyal, dan kondisi pasar** secara otomatis ke database dan file CSV. Data ini digunakan untuk analisis performa, retraining ML model, dan debugging.
|
||||
|
||||
**Analogi:** Trade Logger seperti **black box di pesawat** — merekam semua yang terjadi untuk analisis setelah penerbangan (trading).
|
||||
**Analogi:** *Trade Logger* seperti ***black box* di pesawat** — merekam semua yang terjadi untuk analisis setelah penerbangan (trading).
|
||||
|
||||
---
|
||||
|
||||
## Alur *Dual Storage*
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["Event Terjadi\n(trade / signal / snapshot)"] --> B[TradeLogger]
|
||||
B --> C{DB tersedia?}
|
||||
C -- Ya --> D["PostgreSQL\n(Primary)"]
|
||||
C -- Ya --> E["CSV\n(Backup)"]
|
||||
C -- Tidak --> E
|
||||
D --> F["trades table\nsignals table\nmarket_snapshots\nbot_status"]
|
||||
E --> G["data/trade_logs/\ntrades/ | signals/ | snapshots/\n(file bulanan YYYY_MM.csv)"]
|
||||
style A fill:#2d333b,stroke:#adbac7,color:#adbac7
|
||||
style B fill:#1f6feb,stroke:#58a6ff,color:#fff
|
||||
style C fill:#3d444d,stroke:#adbac7,color:#adbac7
|
||||
style D fill:#238636,stroke:#3fb950,color:#fff
|
||||
style E fill:#9e6a03,stroke:#d29922,color:#fff
|
||||
style F fill:#238636,stroke:#3fb950,color:#fff
|
||||
style G fill:#9e6a03,stroke:#d29922,color:#fff
|
||||
```
|
||||
|
||||
**Prinsip *dual storage*:**
|
||||
|
||||
- **DB tersedia?** — Tulis ke PostgreSQL **DAN** CSV (double safety)
|
||||
- **DB tidak tersedia?** — CSV saja (*graceful degradation*)
|
||||
- CSV **selalu** ditulis sebagai *fallback*, tidak peduli status DB
|
||||
|
||||
---
|
||||
|
||||
@@ -27,14 +55,14 @@ Setiap trade dibuka/ditutup dicatat lengkap:
|
||||
| **Hasil** | profit_usd, profit_pips, duration_seconds |
|
||||
| **Waktu** | open_time, close_time |
|
||||
| **Market** | regime, volatility, session, spread, ATR |
|
||||
| **SMC** | signal, confidence, reason, FVG/OB/BOS/CHoCH flags |
|
||||
| **ML** | signal, confidence |
|
||||
| **SMC** | *signal*, confidence, reason, FVG/OB/BOS/CHoCH flags |
|
||||
| **ML** | *signal*, confidence |
|
||||
| **Dynamic** | market_quality, market_score, threshold |
|
||||
| **Exit** | exit_reason, exit_regime, exit_ml_signal |
|
||||
| **Balance** | balance_before, balance_after, equity_at_entry |
|
||||
| **Features** | JSON snapshot fitur saat entry & exit |
|
||||
| **Features** | JSON *snapshot* fitur saat entry & exit |
|
||||
|
||||
### 2. Signal Record (Per Sinyal)
|
||||
### 2. *Signal* Record (Per Sinyal)
|
||||
|
||||
Setiap sinyal yang dihasilkan (termasuk yang **tidak** dieksekusi):
|
||||
|
||||
@@ -47,9 +75,9 @@ trade_executed (bool)
|
||||
execution_reason ("executed" / "below_threshold" / "max_positions" / ...)
|
||||
```
|
||||
|
||||
### 3. Market Snapshot (Periodik)
|
||||
### 3. Market *Snapshot* (Periodik)
|
||||
|
||||
Snapshot kondisi pasar secara berkala:
|
||||
*Snapshot* kondisi pasar secara berkala:
|
||||
|
||||
```
|
||||
timestamp, symbol, price, OHLC
|
||||
@@ -62,56 +90,38 @@ features (JSON)
|
||||
|
||||
---
|
||||
|
||||
## Dual Storage
|
||||
## *Dual Storage*
|
||||
|
||||
```
|
||||
Event Terjadi (trade/signal/snapshot)
|
||||
|
|
||||
v
|
||||
┌─────────────────────┐ ┌──────────────────┐
|
||||
│ PostgreSQL (Primary) │ │ CSV (Fallback) │
|
||||
│ │ │ │
|
||||
│ ├── trades table │ │ data/trade_logs/│
|
||||
│ ├── signals table │ │ ├── trades/ │
|
||||
│ ├── market_snapshots │ │ │ └── trades_2025_02.csv
|
||||
│ └── bot_status │ │ ├── signals/ │
|
||||
│ │ │ │ └── signals_2025_02.csv
|
||||
│ Cepat, queryable, │ │ └── snapshots/ │
|
||||
│ thread-safe pooling │ │ └── snapshots_2025_02.csv
|
||||
└─────────────────────┘ │ │
|
||||
│ Selalu ditulis │
|
||||
│ (backup) │
|
||||
└──────────────────┘
|
||||
```mermaid
|
||||
flowchart TD
|
||||
EV["Event Terjadi<br/>(trade / signal / snapshot)"] --> PG["PostgreSQL (Primary)<br/>trades, signals,<br/>market_snapshots, bot_status<br/>Cepat, queryable, thread-safe pooling"]
|
||||
EV --> CSV["CSV (Fallback)<br/>data/trade_logs/<br/>trades/, signals/, snapshots/<br/>Selalu ditulis (backup)"]
|
||||
```
|
||||
|
||||
- **DB tidak tersedia?** → CSV saja (graceful degradation)
|
||||
- **DB tidak tersedia?** → CSV saja (*graceful degradation*)
|
||||
- **DB tersedia?** → Tulis ke DB **DAN** CSV (double safety)
|
||||
|
||||
---
|
||||
|
||||
## Proses Log Trade
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
OPEN["Trade Dibuka"] --> LOG_OPEN["log_trade_open()<br/>ticket, entry_price, regime, smc, ml"]
|
||||
LOG_OPEN --> MEM["Simpan ke _pending_trades di memory"]
|
||||
LOG_OPEN --> DB_INS["INSERT ke database (trades table)"]
|
||||
MEM --> WAIT["... trading berjalan ..."]
|
||||
DB_INS --> WAIT
|
||||
WAIT --> CLOSE["Trade Ditutup"]
|
||||
CLOSE --> LOG_CLOSE["log_trade_close()<br/>ticket, exit_price, profit, exit_reason"]
|
||||
LOG_CLOSE --> FETCH["Ambil data pending dari memory"]
|
||||
LOG_CLOSE --> DUR["Hitung durasi: close - open"]
|
||||
FETCH --> UPD["UPDATE database<br/>(exit_price, profit, duration)"]
|
||||
DUR --> UPD
|
||||
UPD --> CSV["APPEND ke CSV<br/>(trades_YYYY_MM.csv)"]
|
||||
```
|
||||
Trade Dibuka:
|
||||
|
|
||||
v
|
||||
log_trade_open(ticket, entry_price, regime, smc_*, ml_*, ...)
|
||||
|
|
||||
├── Simpan ke _pending_trades[ticket] (di memory)
|
||||
└── INSERT ke database (trades table)
|
||||
|
||||
... trading berjalan ...
|
||||
|
||||
Trade Ditutup:
|
||||
|
|
||||
v
|
||||
log_trade_close(ticket, exit_price, profit, exit_reason, ...)
|
||||
|
|
||||
├── Ambil data pending dari memory
|
||||
├── Hitung durasi: close_time - open_time
|
||||
├── UPDATE database (exit_price, profit, duration, ...)
|
||||
└── APPEND ke CSV (trades_YYYY_MM.csv)
|
||||
```
|
||||
Data *pending* disimpan dalam dictionary `_pending_trades[ticket]` selama trade masih terbuka. Ketika trade ditutup, data entry digabung dengan data exit menjadi satu `TradeRecord` lengkap sebelum ditulis ke CSV.
|
||||
|
||||
---
|
||||
|
||||
@@ -125,9 +135,11 @@ log_trade_close(ticket, exit_price, profit, exit_reason, ...)
|
||||
| `get_trades_for_training(30)` | Data untuk ML retraining |
|
||||
| `get_stats()` | Statistik logger |
|
||||
|
||||
Setiap helper method mencoba query dari PostgreSQL terlebih dahulu. Jika DB tidak tersedia, otomatis *fallback* ke pembacaan file CSV — konsisten dengan prinsip *graceful degradation*.
|
||||
|
||||
---
|
||||
|
||||
## Thread Safety
|
||||
## *Thread Safety*
|
||||
|
||||
```python
|
||||
self._lock = threading.Lock()
|
||||
@@ -137,6 +149,8 @@ with self._lock:
|
||||
# Write to CSV
|
||||
```
|
||||
|
||||
Semua operasi tulis ke file CSV dilindungi oleh `threading.Lock()` untuk menjamin *thread safety*. Ini mencegah korupsi data ketika multiple thread mencoba menulis ke file yang sama secara bersamaan (misalnya log trade close dan log *signal* terjadi hampir bersamaan).
|
||||
|
||||
---
|
||||
|
||||
## File CSV (Terorganisir per Bulan)
|
||||
|
||||
Reference in New Issue
Block a user