#!/usr/bin/env python from sys import exit from dotenv import load_dotenv from typing import NoReturn import argparse from datetime import datetime from paperone.database import TradingDataCRUD from rich.console import Console from rich.table import Table load_dotenv() DB_FILE = "trading_data.db" def parse_args(): """Parse command line arguments.""" parser = argparse.ArgumentParser( description="Fetch and display OHLCV and indicators for a ticker and date" ) parser.add_argument("ticker", type=str, help="Ticker symbol (e.g., AAPL)") parser.add_argument( "date", type=str, help="Date in YYYYMMDD format (e.g., 20251017)" ) return parser.parse_args() def format_ohlcv_table(ticker: str, date: datetime, ohlcv) -> Table: """Create a rich table for OHLCV data.""" table = Table(title=f"OHLCV Data for {ticker} on {date.strftime('%Y-%m-%d')}") table.add_column("Metric", style="cyan", no_wrap=True) table.add_column("Value", style="magenta") table.add_row("Open", f"${ohlcv.open:.2f}") table.add_row("High", f"${ohlcv.high:.2f}") table.add_row("Low", f"${ohlcv.low:.2f}") table.add_row("Close", f"${ohlcv.close:.2f}") table.add_row("Average", f"${ohlcv.avg:.2f}") table.add_row("Volume", f"{ohlcv.volume:,}") return table def format_indicators_table(ticker: str, date: datetime, indicators) -> Table: """Create a rich table for technical indicators.""" table = Table( title=f"Technical Indicators for {ticker} on {date.strftime('%Y-%m-%d')}" ) table.add_column("Category", style="cyan", no_wrap=True) table.add_column("Indicator", style="green") table.add_column("Value", style="magenta") # Momentum Indicators table.add_row("Momentum", "RSI (14)", f"{indicators.rsi_14:.2f}") table.add_row("", "RSI (20)", f"{indicators.rsi_20:.2f}") table.add_row("", "MACD Line", f"{indicators.macd_line:.4f}") table.add_row("", "MACD Signal", f"{indicators.macd_signal:.4f}") table.add_row("", "MACD Histogram", f"{indicators.macd_histogram:.4f}") table.add_row("", "Stochastic %K", f"{indicators.stoch_k:.2f}") table.add_row("", "Stochastic %D", f"{indicators.stoch_d:.2f}") # Volatility Indicators table.add_row("Volatility", "BB Upper", f"${indicators.bb_upper:.2f}") table.add_row("", "BB Middle", f"${indicators.bb_middle:.2f}") table.add_row("", "BB Lower", f"${indicators.bb_lower:.2f}") table.add_row("", "BB Width", f"{indicators.bb_width:.2f}") table.add_row("", "BB Percent", f"{indicators.bb_percent:.4f}") table.add_row("", "ATR (14)", f"{indicators.atr_14:.2f}") # Trend Indicators table.add_row("Trend", "ADX (14)", f"{indicators.adx_14:.2f}") table.add_row("", "+DI", f"{indicators.di_plus:.2f}") table.add_row("", "-DI", f"{indicators.di_minus:.2f}") table.add_row("", "Parabolic SAR", f"${indicators.sar:.2f}") # Volume Indicators table.add_row("Volume", "OBV", f"{indicators.obv:,.0f}") table.add_row("", "OBV SMA (20)", f"{indicators.obv_sma_20:,.0f}") table.add_row("", "Volume ROC (5)", f"{indicators.volume_roc_5:.2f}%") # Support/Resistance table.add_row("Support/Resistance", "Fib 23.6%", f"${indicators.fib_236:.2f}") table.add_row("", "Fib 38.2%", f"${indicators.fib_382:.2f}") table.add_row("", "Fib 61.8%", f"${indicators.fib_618:.2f}") table.add_row("", "Pivot Point", f"${indicators.pivot_point:.2f}") table.add_row("", "Resistance 1", f"${indicators.resistance_1:.2f}") table.add_row("", "Support 1", f"${indicators.support_1:.2f}") # Market Regime table.add_row("Market Regime", "CCI (20)", f"{indicators.cci_20:.2f}") table.add_row("", "Williams %R (14)", f"{indicators.williams_r_14:.2f}") return table def main() -> NoReturn: """Main execution function.""" args = parse_args() console = Console() # Parse date try: target_date = datetime.strptime(args.date, "%Y%m%d") except ValueError: console.print( f"[red]Error:[/red] Invalid date format '{args.date}'. " "Please use YYYYMMDD (e.g., 20251017)" ) exit(1) # Initialize database connection crud = TradingDataCRUD(f"sqlite:///{DB_FILE}") # Fetch OHLCV data ohlcv = crud.get_ohlcv(args.ticker, target_date) if not ohlcv: console.print( f"[red]Error:[/red] No OHLCV data found for {args.ticker} " f"on {target_date.strftime('%Y-%m-%d')}" ) exit(1) # Fetch indicators indicators = crud.get_indicators(args.ticker, target_date) # Display OHLCV table console.print() console.print(format_ohlcv_table(args.ticker, target_date, ohlcv)) # Display indicators table if available if indicators: console.print() console.print(format_indicators_table(args.ticker, target_date, indicators)) else: console.print() console.print( f"[yellow]Warning:[/yellow] No indicator data found for {args.ticker} " f"on {target_date.strftime('%Y-%m-%d')}" ) exit(0) if __name__ == "__main__": main()