Implements Task 2: creates db/schema.sql with five tables (signals, trades, positions, portfolio, settings) and indexes; data/db.py with a Database class covering all CRUD operations; tests/test_db.py with 6 passing pytest tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
52 lines
1.5 KiB
Python
52 lines
1.5 KiB
Python
import os
|
|
import pytest
|
|
from data.db import Database
|
|
|
|
@pytest.fixture
|
|
def db(tmp_path):
|
|
db_path = str(tmp_path / "test.db")
|
|
database = Database(db_path)
|
|
database.init()
|
|
yield database
|
|
database.close()
|
|
|
|
def test_init_creates_tables(db):
|
|
tables = db.execute("SELECT name FROM sqlite_master WHERE type='table'").fetchall()
|
|
names = {r[0] for r in tables}
|
|
assert "signals" in names
|
|
assert "trades" in names
|
|
assert "positions" in names
|
|
assert "portfolio" in names
|
|
assert "settings" in names
|
|
|
|
def test_insert_signal(db):
|
|
db.insert_signal("BTCUSDT", 75.0, 60.0, 55.0, 70.0, 68.5, "HOLD")
|
|
rows = db.get_latest_signals()
|
|
assert len(rows) == 1
|
|
assert rows[0]["coin"] == "BTCUSDT"
|
|
assert rows[0]["composite_score"] == 68.5
|
|
|
|
def test_insert_trade(db):
|
|
db.insert_trade("ETHUSDT", "BUY", 3500.0, 0.01, 35.0, "signal")
|
|
trades = db.get_trades()
|
|
assert len(trades) == 1
|
|
assert trades[0]["coin"] == "ETHUSDT"
|
|
|
|
def test_open_close_position(db):
|
|
db.open_position("SOLUSDT", 140.0, 0.5, 70.0)
|
|
positions = db.get_open_positions()
|
|
assert len(positions) == 1
|
|
db.close_position(positions[0]["id"])
|
|
assert len(db.get_open_positions()) == 0
|
|
|
|
def test_save_load_setting(db):
|
|
db.save_setting("weights", '{"technical": 0.7}')
|
|
val = db.load_setting("weights")
|
|
assert val == '{"technical": 0.7}'
|
|
|
|
def test_portfolio_snapshot(db):
|
|
db.insert_portfolio_snapshot(210.0, 50.0, 10.0, 5.0)
|
|
snaps = db.get_portfolio_history()
|
|
assert len(snaps) == 1
|
|
assert snaps[0]["total_value"] == 210.0
|