diff --git a/src/screener/t_sunnyband.py b/src/screener/t_sunnyband.py index c003514..6cb3c12 100644 --- a/src/screener/t_sunnyband.py +++ b/src/screener/t_sunnyband.py @@ -21,12 +21,20 @@ def get_stock_data(ticker: str, start_date: datetime, end_date: datetime) -> pd. ORDER BY date ASC """ - result = client.query(query) - - return pd.DataFrame( - result.result_rows, - columns=['date', 'open', 'high', 'low', 'close', 'volume'] - ) + try: + result = client.query(query) + if not result.result_rows: + print(f"No data found for {ticker}") + return pd.DataFrame() + + df = pd.DataFrame( + result.result_rows, + columns=['date', 'open', 'high', 'low', 'close', 'volume'] + ) + return df + except Exception as e: + print(f"Error fetching data for {ticker}: {str(e)}") + return pd.DataFrame() def get_valid_tickers(min_price: float, max_price: float, min_volume: int) -> list: """Get tickers that meet the price and volume criteria""" @@ -46,32 +54,50 @@ def get_valid_tickers(min_price: float, max_price: float, min_volume: int) -> li def run_sunny_scanner(min_price: float, max_price: float, min_volume: int) -> None: """Run the SunnyBand scanner and save results""" + print(f"\nInitializing scan for stocks between ${min_price:.2f} and ${max_price:.2f}") + print(f"Minimum volume: {min_volume:,}") + # Get date range (60 days of data for calculations) end_date = datetime.now() start_date = end_date - timedelta(days=60) # Get valid tickers + print("\nFetching qualified stocks...") tickers = get_valid_tickers(min_price, max_price, min_volume) if not tickers: print("No stocks found matching your criteria.") return - print(f"\nScanning {len(tickers)} stocks...") + print(f"\nFound {len(tickers)} stocks to scan") + print("Looking for SunnyBand crossovers...") + print("This may take a few minutes...") # Initialize results lists bullish_signals = [] bearish_signals = [] + errors = [] # Initialize SunnyBands indicator sunny = SunnyBands() + # Track progress + total = len(tickers) + processed = 0 + # Scan each ticker for ticker in tickers: + processed += 1 + if processed % 10 == 0: # Show progress every 10 stocks + print(f"Progress: {processed}/{total} stocks processed ({(processed/total)*100:.1f}%)") + try: # Get price data df = get_stock_data(ticker, start_date, end_date) + if df.empty: + continue + if len(df) < 50: # Need enough data for the indicator continue @@ -82,37 +108,51 @@ def run_sunny_scanner(min_price: float, max_price: float, min_volume: int) -> No last_day = df.iloc[-1] if results['bullish_signal'].iloc[-1]: - bullish_signals.append({ + signal_data = { 'ticker': ticker, 'price': last_day['close'], 'volume': last_day['volume'], 'date': last_day['date'], 'dma': results['dma'].iloc[-1], 'lower_band': results['lower_band'].iloc[-1] - }) + } + bullish_signals.append(signal_data) + print(f"🟢 Bullish Signal: {ticker} at ${last_day['close']:.2f}") elif results['bearish_signal'].iloc[-1]: - bearish_signals.append({ + signal_data = { 'ticker': ticker, 'price': last_day['close'], 'volume': last_day['volume'], 'date': last_day['date'], 'dma': results['dma'].iloc[-1], 'upper_band': results['upper_band'].iloc[-1] - }) + } + bearish_signals.append(signal_data) + print(f"šŸ”“ Bearish Signal: {ticker} at ${last_day['close']:.2f}") except Exception as e: - print(f"Error processing {ticker}: {str(e)}") + errors.append(f"{ticker}: {str(e)}") + continue # Save and display results output_date = datetime.now().strftime("%Y%m%d") + print(f"\nScan Complete! Processed {total} stocks.") + + if errors: + print(f"\nEncountered {len(errors)} errors during scan:") + for error in errors[:5]: # Show first 5 errors + print(error) + if len(errors) > 5: + print(f"...and {len(errors) - 5} more errors") + if bullish_signals: - print("\n🟢 Bullish Signals:") + print(f"\n🟢 Found {len(bullish_signals)} Bullish Signals:") df_bullish = pd.DataFrame(bullish_signals) bullish_file = f'src/reports/sunny_bullish_{output_date}.csv' df_bullish.to_csv(bullish_file, index=False) - print(f"\nSaved {len(bullish_signals)} bullish signals to {bullish_file}") + print(f"Saved to {bullish_file}") for signal in bullish_signals: print(f"\n{signal['ticker']}:") @@ -122,11 +162,11 @@ def run_sunny_scanner(min_price: float, max_price: float, min_volume: int) -> No print(f"Lower Band: ${signal['lower_band']:.2f}") if bearish_signals: - print("\nšŸ”“ Bearish Signals:") + print(f"\nšŸ”“ Found {len(bearish_signals)} Bearish Signals:") df_bearish = pd.DataFrame(bearish_signals) bearish_file = f'src/reports/sunny_bearish_{output_date}.csv' df_bearish.to_csv(bearish_file, index=False) - print(f"\nSaved {len(bearish_signals)} bearish signals to {bearish_file}") + print(f"Saved to {bearish_file}") for signal in bearish_signals: print(f"\n{signal['ticker']}:")