"""Tests for the kevin trading SA models (audit + backtest).""" import uuid from datetime import datetime, timezone from decimal import Decimal import pytest from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from shared.models.meet_kevin import ( KevinAnalysis, KevinChannel, KevinMarketOutlook, KevinStockMention, KevinTickerAction, KevinTimeHorizon, KevinVideo, KevinVideoStatus, ) from shared.models.meet_kevin_trading import ( BridgeStatus, KevinBacktestRun, KevinBacktestRunStatus, KevinBacktestTrade, KevinSignalBridgeState, TriggerSource, ) async def _seed_mention(db_session: AsyncSession) -> KevinStockMention: channel = KevinChannel(youtube_channel_id="UCtest", title="t") db_session.add(channel) await db_session.flush() video = KevinVideo( channel_id=channel.id, youtube_video_id="v1", title="t", published_at=datetime.now(timezone.utc), status=KevinVideoStatus.ANALYZED, ) db_session.add(video) await db_session.flush() analysis = KevinAnalysis( video_id=video.id, model="claude-sonnet", prompt_version="v1", market_outlook_direction=KevinMarketOutlook.NEUTRAL, market_outlook_reasoning="x", summary="x", prompt_tokens=10, completion_tokens=10, cost_usd=Decimal("0.01"), ) db_session.add(analysis) await db_session.flush() mention = KevinStockMention( video_id=video.id, analysis_id=analysis.id, symbol="NVDA", action=KevinTickerAction.BUY, conviction=Decimal("0.7"), time_horizon=KevinTimeHorizon.WEEKS, rationale_quote="x", ) db_session.add(mention) await db_session.flush() return mention @pytest.mark.asyncio async def test_bridge_state_inserts_and_loads(db_session: AsyncSession): mention = await _seed_mention(db_session) state = KevinSignalBridgeState( mention_id=mention.id, bridge_status=BridgeStatus.EMITTED, effective_conviction=Decimal("0.75"), notes="boosted +0.05", ) db_session.add(state) await db_session.flush() row = ( await db_session.execute( select(KevinSignalBridgeState).where( KevinSignalBridgeState.mention_id == mention.id ) ) ).scalar_one() assert row.bridge_status == BridgeStatus.EMITTED assert row.effective_conviction == Decimal("0.750") @pytest.mark.asyncio async def test_backtest_run_and_trade_cascade(db_session: AsyncSession): run = KevinBacktestRun( run_uuid=uuid.uuid4(), status=KevinBacktestRunStatus.COMPLETED, trigger_source=TriggerSource.MANUAL, params_json={"holding_days": 10}, metrics_json={"total_return_pct": 3.4}, ) db_session.add(run) await db_session.flush() trade = KevinBacktestTrade( run_id=run.id, symbol="NVDA", entry_at=datetime.now(timezone.utc), entry_price=Decimal("180.00"), qty=Decimal("11"), ) db_session.add(trade) await db_session.flush() # Cascade: delete run -> trade gone await db_session.delete(run) await db_session.flush() trades = (await db_session.execute(select(KevinBacktestTrade))).scalars().all() assert trades == []