from db.db_connection import create_client def check_institutional_sponsorship(symbol): """ Determines if a stock has strong institutional sponsorship. Criteria: - Should have at least several institutional sponsors - Look for increasing institutional ownership - Focus on higher-quality institutions - Avoid stocks with too much institutional ownership (>80-90%) Args: symbol (str): Stock ticker symbol. Returns: float: 1 (Pass), 0 (Fail), 0.25 (Insufficient Data) """ client = create_client() # Get current institutional ownership data query = """ SELECT COUNT(DISTINCT holder_name) as num_institutions, SUM(percentage_held) as total_ownership, MAX(date_reported) as latest_date FROM stock_db.yf_institutional_holders WHERE ticker = '{}' GROUP BY ticker """.format(symbol) result = client.query(query) if not result.result_rows: return 0.25 # Insufficient data num_institutions, total_ownership, _ = result.result_rows[0] # Get ownership trend (comparing with 3 months ago) trend_query = """ WITH current AS ( SELECT SUM(percentage_held) as current_ownership, MAX(date_reported) as latest_date FROM stock_db.yf_institutional_holders WHERE ticker = '{}' ), previous AS ( SELECT SUM(percentage_held) as previous_ownership FROM stock_db.yf_institutional_holders WHERE ticker = '{}' AND date_reported <= (SELECT latest_date - INTERVAL 3 MONTH FROM current) ) SELECT current_ownership, previous_ownership FROM current, previous """.format(symbol, symbol) trend_result = client.query(trend_query) # Evaluate criteria if num_institutions is None or total_ownership is None: return 0.25 # Convert total_ownership to percentage (0-100 scale) total_ownership = float(total_ownership) # Criteria thresholds MIN_INSTITUTIONS = 10 MIN_OWNERSHIP = 20 # percentage MAX_OWNERSHIP = 85 # percentage # Basic institutional presence check has_sufficient_institutions = num_institutions >= MIN_INSTITUTIONS has_healthy_ownership = MIN_OWNERSHIP <= total_ownership <= MAX_OWNERSHIP # Check ownership trend ownership_increasing = False if trend_result.result_rows: current_ownership, previous_ownership = trend_result.result_rows[0] if current_ownership and previous_ownership: ownership_increasing = current_ownership > previous_ownership # Final evaluation if has_sufficient_institutions and has_healthy_ownership and ownership_increasing: return 1 elif not has_sufficient_institutions or total_ownership < MIN_OWNERSHIP: return 0 else: return 0.25 # Borderline cases