$csv_data['error']]); exit; } $lines = str_getcsv($csv_data, "\n"); $header = str_getcsv(array_shift($lines)); $stocks = []; foreach ($lines as $line) { if (empty(trim($line))) continue; $stocks[] = array_combine($header, str_getcsv($line)); } // 2. Take a small, random sample to avoid hitting API limits shuffle($stocks); $sample_size = 5; // Limit to 5 API calls per scan to stay within free tier limits $sample = array_slice($stocks, 0, $sample_size); // 3. Analyze the sample foreach ($sample as $stock) { $symbol = $stock['symbol']; // Skip non-US stocks for now for data consistency if (!in_array($stock['exchange'], ['NASDAQ', 'NYSE', 'AMEX'])) { continue; } // To avoid hitting API limits, wait between calls. // The free tier is very restrictive (5 calls/min). sleep(15); $overview = get_stock_overview($symbol); if (isset($overview['error'])) { $errors[] = "Could not fetch data for {$symbol}: " . $overview['error']; continue; } $market_cap = (float)($overview['MarketCapitalization'] ?? 0); $price = 0; // We'll get price from the quote call $volume_str = $overview['Volume'] ?? '0'; $volume = (int) $volume_str; // Check market cap and volume first to avoid unnecessary price checks if ($market_cap >= $min_market_cap && $market_cap <= $max_market_cap && $volume >= $min_volume) { sleep(15); // Another wait before the next API call $quote = get_stock_quote($symbol); if (isset($quote['Global Quote']['05. price'])) { $price = (float)$quote['Global Quote']['05. price']; if ($price >= $min_price) { $results[] = [ 'symbol' => $symbol, 'company_name' => $overview['Name'] ?? 'N/A', 'price' => $price, 'market_cap' => $market_cap ]; } } } } if (!empty($errors)) { // If there were non-fatal errors, we can return them for debugging // For now, we just return the successful results. } echo json_encode($results);