import sqlite3 import os class Database: def __init__(self, db_path: str): self.db_path = db_path self.conn = None def init(self): self.conn = sqlite3.connect(self.db_path, check_same_thread=False) self.conn.execute("PRAGMA journal_mode=WAL") self.conn.execute("PRAGMA busy_timeout=5000") self.conn.row_factory = sqlite3.Row schema_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "schema.sql") with open(schema_path) as f: self.conn.executescript(f.read()) def close(self): if self.conn: self.conn.close() def execute(self, sql, params=()): return self.conn.execute(sql, params) def insert_signal(self, coin, technical, news, social, ai, composite, signal): self.conn.execute( "INSERT INTO signals (coin, technical_score, news_score, social_score, ai_score, composite_score, signal) VALUES (?,?,?,?,?,?,?)", (coin, technical, news, social, ai, composite, signal), ) self.conn.commit() def get_latest_signals(self, limit=50): return self.conn.execute( "SELECT * FROM signals WHERE id IN (SELECT MAX(id) FROM signals GROUP BY coin) ORDER BY composite_score DESC LIMIT ?", (limit,), ).fetchall() def insert_trade(self, coin, side, price, quantity, amount_usd, reason): self.conn.execute( "INSERT INTO trades (coin, side, price, quantity, amount_usd, reason) VALUES (?,?,?,?,?,?)", (coin, side, price, quantity, amount_usd, reason), ) self.conn.commit() def get_trades(self, limit=100): return self.conn.execute( "SELECT * FROM trades ORDER BY timestamp DESC LIMIT ?", (limit,) ).fetchall() def open_position(self, coin, entry_price, quantity, invested_usd): self.conn.execute( "INSERT INTO positions (coin, entry_price, quantity, invested_usd) VALUES (?,?,?,?)", (coin, entry_price, quantity, invested_usd), ) self.conn.commit() def get_open_positions(self): return self.conn.execute( "SELECT * FROM positions WHERE status='OPEN'" ).fetchall() def close_position(self, position_id): self.conn.execute( "UPDATE positions SET status='CLOSED', closed_at=CURRENT_TIMESTAMP WHERE id=?", (position_id,), ) self.conn.commit() def update_position_quantity(self, position_id, new_quantity): self.conn.execute( "UPDATE positions SET quantity=? WHERE id=?", (new_quantity, position_id), ) self.conn.commit() def insert_portfolio_snapshot(self, total_value, cash, pnl, pnl_pct): self.conn.execute( "INSERT INTO portfolio (total_value, cash, pnl, pnl_pct) VALUES (?,?,?,?)", (total_value, cash, pnl, pnl_pct), ) self.conn.commit() def get_portfolio_history(self, limit=100): return self.conn.execute( "SELECT * FROM portfolio ORDER BY timestamp DESC LIMIT ?", (limit,) ).fetchall() def save_setting(self, key, value): self.conn.execute( "INSERT OR REPLACE INTO settings (key, value) VALUES (?,?)", (key, value), ) self.conn.commit() def load_setting(self, key): row = self.conn.execute( "SELECT value FROM settings WHERE key=?", (key,) ).fetchone() return row["value"] if row else None