Database Best Practices
Connection Management
ALWAYS use the db_connection() context manager:
from src.data.db_connection import db_connection
with db_connection() as conn:
c = conn.cursor()
c.execute("SELECT * FROM trades")
# Commit happens automatically on success
- NEVER call
conn.commit() manually.
- Deadlock Prevention: When calling write functions (like
execute_trade) from within an existing transaction, MUST pass the active cursor.
Migration System
The migration system tracks versions in the schema_version table.
Adding a New Migration:
- Create a migration function in
src/data/migrations.py.
- Register it in the
MIGRATIONS list.
- Update the base schema in
src/data/database.py.
Rules:
- Check if columns/indices exist before creating.
- Migrations must be idempotent.
- Never delete or modify existing migrations.
Schema Overview
Main table: trades
- Core Fields:
id, timestamp, symbol, side, entry_price, size, bet_usd, edge
- Order Tracking:
order_id, order_status, limit_sell_order_id, scale_in_order_id
- Position Management:
scaled_in, is_reversal, target_price, reversal_triggered, reversal_triggered_at
- Settlement:
settled, settled_at, exited_early, final_outcome, exit_price, pnl_usd, roi_pct
- Timing:
window_start, window_end, last_scale_in_at
- Market Data:
slug, token_id, p_yes, best_bid, best_ask, imbalance, funding_bias
- Bayesian Comparison (v0.5.0+):
additive_confidence, additive_bias, bayesian_confidence, bayesian_bias, market_prior_p_up
Key Database Patterns
Position Queries
# Get open positions with all relevant data
c.execute("""
SELECT id, symbol, token_id, side, entry_price, size, bet_usd,
limit_sell_order_id, scale_in_order_id, scaled_in, edge,
last_scale_in_at, window_end
FROM trades
WHERE settled = 0 AND exited_early = 0
AND datetime(window_end) > datetime(?)
""", (now.isoformat(),))
Trade Updates
# Update position size after scale-in
c.execute("""
UPDATE trades
SET size = ?, bet_usd = ? * entry_price,
scaled_in = 1, last_scale_in_at = ?
WHERE id = ?
""", (new_size, new_size, now.isoformat(), trade_id))
Settlement
# Settle position with exit data
c.execute("""
UPDATE trades
SET settled = 1, exited_early = 1, exit_price = ?,
pnl_usd = ?, roi_pct = ?, settled_at = ?
WHERE id = ?
""", (exit_price, pnl_usd, roi_pct, now.isoformat(), trade_id))
WAL Mode
- Database uses Write-Ahead Logging (WAL) mode for better concurrency
- Enabled on initialization:
PRAGMA journal_mode=WAL
- Allows concurrent readers while writes are in progress
Migration History
- Migration 007 (v0.5.0): Added Bayesian confidence comparison columns (
additive_confidence, additive_bias, bayesian_confidence, bayesian_bias, market_prior_p_up) for A/B testing
- Migration 006 (v0.4.x): Added raw signal score columns (
up_total, down_total, momentum_score, momentum_dir, flow_score, flow_dir, divergence_score, divergence_dir, vwm_score, vwm_dir, pm_mom_score, pm_mom_dir, adx_score, adx_dir, lead_lag_bonus) for confidence formula calibration
- Migration 005: Added
last_scale_in_at column for tracking scale-in timing
- Migration 004: Added
reversal_triggered_at column for timing reversals
- Migration 003: Added
reversal_triggered column for reversal tracking
- Migration 002: Added timestamp verification
- Migration 001: Added
scale_in_order_id column for tracking pending scale-in orders
1---2name: database-sqlite3description: SQLite best practices, connection management, and migration system for PolyFlup.4---56## Database Best Practices78### Connection Management9**ALWAYS use the `db_connection()` context manager:**1011```python12from src.data.db_connection import db_connection1314with db_connection() as conn:15 c = conn.cursor()16 c.execute("SELECT * FROM trades")17 # Commit happens automatically on success18```1920- **NEVER** call `conn.commit()` manually.21- **Deadlock Prevention**: When calling write functions (like `execute_trade`) from within an existing transaction, **MUST pass the active cursor**.2223### Migration System24The migration system tracks versions in the `schema_version` table.2526#### Adding a New Migration:271. Create a migration function in `src/data/migrations.py`.282. Register it in the `MIGRATIONS` list.293. Update the base schema in `src/data/database.py`.3031#### Rules:32- Check if columns/indices exist before creating.33- Migrations must be idempotent.34- Never delete or modify existing migrations.3536### Schema Overview37Main table: `trades`38- Core Fields: `id`, `timestamp`, `symbol`, `side`, `entry_price`, `size`, `bet_usd`, `edge`39- Order Tracking: `order_id`, `order_status`, `limit_sell_order_id`, `scale_in_order_id`40- Position Management: `scaled_in`, `is_reversal`, `target_price`, `reversal_triggered`, `reversal_triggered_at`41- Settlement: `settled`, `settled_at`, `exited_early`, `final_outcome`, `exit_price`, `pnl_usd`, `roi_pct`42- Timing: `window_start`, `window_end`, `last_scale_in_at`43- Market Data: `slug`, `token_id`, `p_yes`, `best_bid`, `best_ask`, `imbalance`, `funding_bias`44- Bayesian Comparison (v0.5.0+): `additive_confidence`, `additive_bias`, `bayesian_confidence`, `bayesian_bias`, `market_prior_p_up`4546### Key Database Patterns4748#### Position Queries49```python50# Get open positions with all relevant data51c.execute("""52 SELECT id, symbol, token_id, side, entry_price, size, bet_usd, 53 limit_sell_order_id, scale_in_order_id, scaled_in, edge, 54 last_scale_in_at, window_end55 FROM trades 56 WHERE settled = 0 AND exited_early = 0 57 AND datetime(window_end) > datetime(?)58""", (now.isoformat(),))59```6061#### Trade Updates62```python63# Update position size after scale-in64c.execute("""65 UPDATE trades 66 SET size = ?, bet_usd = ? * entry_price, 67 scaled_in = 1, last_scale_in_at = ?68 WHERE id = ?69""", (new_size, new_size, now.isoformat(), trade_id))70```7172#### Settlement73```python74# Settle position with exit data75c.execute("""76 UPDATE trades 77 SET settled = 1, exited_early = 1, exit_price = ?, 78 pnl_usd = ?, roi_pct = ?, settled_at = ?79 WHERE id = ?80""", (exit_price, pnl_usd, roi_pct, now.isoformat(), trade_id))81```8283### WAL Mode84- Database uses Write-Ahead Logging (WAL) mode for better concurrency85- Enabled on initialization: `PRAGMA journal_mode=WAL`86- Allows concurrent readers while writes are in progress8788### Migration History89- **Migration 007** (v0.5.0): Added Bayesian confidence comparison columns (`additive_confidence`, `additive_bias`, `bayesian_confidence`, `bayesian_bias`, `market_prior_p_up`) for A/B testing90- **Migration 006** (v0.4.x): Added raw signal score columns (`up_total`, `down_total`, `momentum_score`, `momentum_dir`, `flow_score`, `flow_dir`, `divergence_score`, `divergence_dir`, `vwm_score`, `vwm_dir`, `pm_mom_score`, `pm_mom_dir`, `adx_score`, `adx_dir`, `lead_lag_bonus`) for confidence formula calibration91- **Migration 005**: Added `last_scale_in_at` column for tracking scale-in timing92- **Migration 004**: Added `reversal_triggered_at` column for timing reversals93- **Migration 003**: Added `reversal_triggered` column for reversal tracking94- **Migration 002**: Added timestamp verification95- **Migration 001**: Added `scale_in_order_id` column for tracking pending scale-in orders