from __future__ import annotations from typing import Any class AuctionRepositoryMixin: def upsert_auction_factors(self, rows: list[dict[str, Any]]) -> int: values = [] for row in rows: trade_date = str(row.get("trade_date") or "") ts_code = str(row.get("ts_code") or "") price = float(row.get("price") or 0) pre_close = float(row.get("pre_close") or 0) if not trade_date or not ts_code or price <= 0 or pre_close <= 0: continue values.append( ( trade_date, ts_code, price, pre_close, (price / pre_close - 1) * 100, float(row.get("vol") or 0), float(row.get("amount") or 0), float(row.get("turnover_rate") or 0), float(row.get("volume_ratio") or 0), ) ) with self.connect() as connection: connection.executemany( """ INSERT INTO auction_factors (trade_date, ts_code, price, pre_close, change, vol, amount, turnover_rate, volume_ratio) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(trade_date, ts_code) DO UPDATE SET price=excluded.price, pre_close=excluded.pre_close, change=excluded.change, vol=excluded.vol, amount=excluded.amount, turnover_rate=excluded.turnover_rate, volume_ratio=excluded.volume_ratio """, values, ) return len(values) def auction_factor_dates(self, end_date: str = "", limit: int = 80) -> list[str]: where = "WHERE trade_date <= ?" if end_date else "" parameters: tuple[Any, ...] = (end_date, limit) if end_date else (limit,) with self.connect() as connection: rows = connection.execute( f"SELECT DISTINCT trade_date FROM auction_factors {where} " "ORDER BY trade_date DESC LIMIT ?", parameters, ).fetchall() return [row["trade_date"] for row in reversed(rows)] def auction_factors_for_date(self, trade_date: str) -> list[dict[str, Any]]: with self.connect() as connection: rows = connection.execute( "SELECT * FROM auction_factors WHERE trade_date = ? ORDER BY ts_code", (trade_date,), ).fetchall() return [dict(row) for row in rows]