47 lines
1.7 KiB
Python
47 lines
1.7 KiB
Python
from __future__ import annotations
|
|
|
|
from crypto_spot_bot.analytics import risk_guard_snapshot
|
|
from crypto_spot_bot.data_quality import analyze_symbol_quality
|
|
from crypto_spot_bot.models import Candle, Ticker, Trade, utc_now
|
|
from crypto_spot_bot.storage import Storage
|
|
|
|
|
|
def test_risk_guard_blocks_after_consecutive_losses(make_settings, tmp_path) -> None:
|
|
settings = make_settings(tmp_path, risk_max_consecutive_losses=2)
|
|
storage = Storage(settings.database_path)
|
|
now = utc_now()
|
|
for _ in range(2):
|
|
storage.insert_trade(
|
|
Trade(
|
|
id=None,
|
|
symbol="BTCUSDT",
|
|
side="SELL",
|
|
qty=1.0,
|
|
entry_price=100.0,
|
|
exit_price=99.0,
|
|
net_pnl=-1.0,
|
|
opened_at=now,
|
|
closed_at=now,
|
|
entry_diagnostics={"forecast": {"probability_up": 0.64, "model": "torch_gru"}},
|
|
)
|
|
)
|
|
|
|
guard = risk_guard_snapshot(settings, storage.closed_trades(), storage.latest_equity())
|
|
|
|
assert guard["block_new_entries"] is True
|
|
assert "consecutive_losses" in guard["reasons"]
|
|
assert guard["position_size_multiplier"] == 0.0
|
|
|
|
|
|
def test_data_quality_flags_missing_candle_gap() -> None:
|
|
candles = [
|
|
Candle(1_000_000, 100, 101, 99, 100.5, 10),
|
|
Candle(1_000_000 + 60 * 60 * 1000 * 3, 100.5, 102, 100, 101, 12),
|
|
]
|
|
ticker = Ticker("BTCUSDT", 101, 100.99, 101.01, 1_000_000, 100, 0)
|
|
|
|
row = analyze_symbol_quality(symbol="BTCUSDT", candles=candles, ticker=ticker, interval="60")
|
|
|
|
assert row["status"] == "warn"
|
|
assert any(issue["code"] == "missing_candles" for issue in row["issues"])
|