2026-02-09 05:46:54 +07:00
# *Database Module* — *PostgreSQL* Integration
2026-02-06 09:17:20 +07:00
> **File:** `src/db/connection.py`, `src/db/repository.py`
2026-02-09 05:46:54 +07:00
> **Database:** *PostgreSQL*
> **Library:** psycopg2 (*connection pooling*)
2026-02-06 09:17:20 +07:00
---
2026-02-09 05:46:54 +07:00
## Apa Itu *Database Module*?
2026-02-06 09:17:20 +07:00
2026-02-09 05:46:54 +07:00
*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.
2026-02-06 09:17:20 +07:00
2026-02-09 05:46:54 +07:00
**Analogi:** *Database Module* seperti **arsip perpustakaan** — menyimpan semua catatan trading secara terorganisir, bisa dicari kapan saja, dan tidak hilang meski bot di-restart.
2026-02-06 09:17:20 +07:00
---
## Arsitektur
2026-02-09 05:46:54 +07:00
```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
2026-02-06 09:17:20 +07:00
```
---
2026-02-09 05:46:54 +07:00
## Connection (*Singleton* + Pooling)
2026-02-06 09:17:20 +07:00
```python
class DatabaseConnection :
"""
Thread-safe singleton dengan connection pooling.
- Hanya 1 instance (singleton pattern)
- Pool: 1-10 koneksi (ThreadedConnectionPool)
- Auto-reconnect jika putus
- Context manager support
"""
```
2026-02-09 05:46:54 +07:00
`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.
2026-02-06 09:17:20 +07:00
### Konfigurasi
```
DB_HOST=localhost
DB_PORT=5432
DB_NAME=trading_db
DB_USER=trading_bot
DB_PASSWORD=trading_bot_2026
```
### Penggunaan
```python
from src.db import get_db , init_db
# Initialize
if init_db ():
db = get_db ()
2026-02-09 05:46:54 +07:00
# Query dengan context manager
2026-02-06 09:17:20 +07:00
with db . get_cursor () as cur :
cur . execute ( "SELECT * FROM trades WHERE profit_usd > 0" )
rows = cur . fetchall ()
# Simple execute
result = db . execute ( "SELECT count(*) FROM trades" , fetch = True )
```
---
2026-02-09 05:46:54 +07:00
## 6 *Repository*
Setiap *repository* bertanggung jawab atas satu tabel dan menyediakan method khusus untuk operasi CRUD.
2026-02-06 09:17:20 +07:00
### 1. TradeRepository
| Method | Fungsi |
|--------|--------|
| `insert_trade()` | Insert trade baru (saat open) |
| `update_trade_close()` | Update exit data (saat close) |
| `get_trade_by_ticket()` | Cari trade per ticket |
| `get_open_trades()` | Trade yang belum ditutup |
| `get_recent_trades(100)` | 100 trade terakhir |
| `get_trades_for_training(30)` | Trade 30 hari untuk ML |
| `get_daily_stats(date)` | Statistik per hari |
| `get_session_stats("London", 30)` | Statistik per sesi |
| `get_smc_pattern_stats(30)` | Performa per pola SMC |
### 2. TrainingRepository
| Method | Fungsi |
|--------|--------|
| `insert_training_run()` | Catat mulai training |
| `update_training_complete()` | Update hasil training |
| `mark_rollback()` | Tandai model di-rollback |
| `get_latest_successful()` | Training sukses terakhir |
| `get_training_history(20)` | 20 training terakhir |
### 3. SignalRepository
| Method | Fungsi |
|--------|--------|
| `insert_signal()` | Catat sinyal yang dihasilkan |
| `mark_executed()` | Tandai sinyal yang dieksekusi |
| `get_recent_signals(100)` | 100 sinyal terakhir |
| `get_signal_stats(24)` | Statistik 24 jam |
### 4. MarketSnapshotRepository
| Method | Fungsi |
|--------|--------|
| `insert_snapshot()` | Simpan snapshot pasar |
| `get_recent_snapshots(60)` | Snapshot 60 menit terakhir |
### 5. BotStatusRepository
| Method | Fungsi |
|--------|--------|
| `insert_status()` | Catat status bot |
| `get_latest_status()` | Status terbaru |
### 6. DailySummaryRepository
| Method | Fungsi |
|--------|--------|
| `upsert_summary()` | Insert/update ringkasan harian |
| `get_summary(date)` | Ringkasan per tanggal |
| `get_recent_summaries(30)` | 30 hari terakhir |
---
## Tabel Database
2026-02-09 05:46:54 +07:00
### 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"
```
2026-02-06 09:17:20 +07:00
### trades
```sql
├── ticket , symbol , direction
├── entry_price , exit_price , stop_loss , take_profit
├── lot_size , profit_usd , profit_pips
├── opened_at , closed_at , duration_seconds
├── entry_regime , entry_volatility , entry_session
├── smc_signal , smc_confidence , smc_reason
├── smc_fvg_detected , smc_ob_detected , smc_bos_detected , smc_choch_detected
├── ml_signal , ml_confidence
├── market_quality , market_score , dynamic_threshold
├── exit_reason , exit_regime , exit_ml_signal
├── balance_before , balance_after , equity_at_entry
├── features_entry ( JSON ), features_exit ( JSON )
└── bot_version , trade_mode
```
### training_runs
```sql
├── training_type , bars_used , num_boost_rounds
├── hmm_trained , hmm_n_regimes
├── xgb_trained , train_auc , test_auc
├── train_accuracy , test_accuracy
├── model_path , backup_path
├── success , error_message
├── started_at , completed_at , duration_seconds
└── rolled_back , rollback_reason , rollback_at
```
### signals
```sql
├── signal_time , symbol , price
├── signal_type , signal_source , combined_confidence
├── smc_ * , ml_ *
├── regime , session , volatility , market_score
└── executed , execution_reason , trade_ticket
```
### market_snapshots
```sql
├── snapshot_time , symbol , price , OHLC
├── regime , volatility , session , ATR , spread
├── ml_signal , ml_confidence , smc_signal , smc_confidence
└── open_positions , floating_pnl , features ( JSON )
```
### bot_status
```sql
├── status_time , is_running , status
├── loop_count , avg_execution_ms , uptime_seconds
├── balance , equity , margin_used
├── open_positions , floating_pnl , daily_pnl
└── risk_mode , current_session , is_golden_time
```
### daily_summaries
```sql
├── summary_date
├── total / winning / losing / breakeven_trades
├── gross_profit , gross_loss , net_profit
├── start_balance , end_balance
├── win_rate , profit_factor , avg win / loss
├── trades per session ( sydney / tokyo / london / ny / golden )
└── SMC pattern stats ( fvg / ob trades & wins )
```
---
2026-02-09 05:46:54 +07:00
## *Graceful Degradation*
2026-02-06 09:17:20 +07:00
```
PostgreSQL tersedia?
├── Ya → Gunakan DB + CSV backup
└── Tidak → CSV saja (semua tetap berjalan)
Bot TIDAK pernah crash karena database.
```
2026-02-09 05:46:54 +07:00
*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.