"""Query CLI subcommands for ad-hoc data queries.""" from __future__ import annotations from datetime import date, datetime import typer from ashare_dp.core.models import Freq from ashare_dp.data.store.database import get_db from ashare_dp.data.store.repository import KLineRepository query_app = typer.Typer() @query_app.command("kline") def query_kline( freq: str = typer.Argument(..., help="Frequency: 1m,5m,15m,30m,1h,2h,1d,1w,1M"), ts_code: str = typer.Argument(..., help="Stock code, e.g. 000001.SZ"), start: str = typer.Option(None, help="Start date YYYY-MM-DD"), end: str = typer.Option(None, help="End date YYYY-MM-DD"), limit: int = typer.Option(100, help="Max records"), ): """Query K-line data from the command line.""" freq_enum = Freq(freq) repo = KLineRepository() sd = date.fromisoformat(start) if start else None ed = date.fromisoformat(end) if end else None df = repo.read_klines(freq=freq_enum, ts_code=ts_code, start_date=sd, end_date=ed, limit=limit) if df.empty: typer.echo("No data found") return typer.echo(f"\n{freq} K-line for {ts_code}:") typer.echo(df.to_string(index=False)) typer.echo(f"\n{len(df)} records") @query_app.command("latest") def query_latest( freq: str = typer.Option("1d", help="Frequency"), ts_code: str = typer.Option(None, help="Stock code (optional)"), ): """Show latest K-line data.""" freq_enum = Freq(freq) repo = KLineRepository() df = repo.get_latest(freq=freq_enum, ts_code=ts_code) if df.empty: typer.echo("No data found") return typer.echo(f"\nLatest {freq} K-line:") typer.echo(df.to_string(index=False)) typer.echo(f"\n{len(df)} records") @query_app.command("stocks") def query_stocks( exchange: str = typer.Option(None, help="Exchange: SH, SZ, BJ"), limit: int = typer.Option(50, help="Max records"), ): """List stocks.""" with get_db(read_only=True) as db: if exchange: rows = db.query( "SELECT ts_code, symbol, name, exchange, market, list_date FROM stock_info WHERE exchange = ? LIMIT ?", (exchange.upper(), limit), ) else: rows = db.query( "SELECT ts_code, symbol, name, exchange, market, list_date FROM stock_info LIMIT ?", (limit,), ) typer.echo(f"\n{'ts_code':<12} {'symbol':<8} {'name':<12} {'exchange':<8} {'market':<10} {'list_date'}") typer.echo("-" * 60) for row in rows: ts, sym, name, ex, mkt, ld = row ld_str = str(ld) if ld else "" typer.echo(f"{ts:<12} {sym:<8} {name:<12} {ex:<8} {mkt or '':<10} {ld_str}") @query_app.command("stats") def query_stats(): """Show database statistics.""" repo = KLineRepository() typer.echo("\nDatabase Statistics:") typer.echo("-" * 40) # Stock count with get_db(read_only=True) as db: n = db.query("SELECT count(*) FROM stock_info")[0][0] typer.echo(f" Stocks: {n}") # Record count and date range per frequency for freq_repr in [Freq.d1, Freq.w1, Freq.M1, Freq.h1, Freq.m5, Freq.m1]: count = repo.count_records(freq_repr) dr = repo.get_date_range(freq_repr) typer.echo(f" {freq_repr.value}: {count} records, range {dr[0]} ~ {dr[1]}")