@@ -77,10 +77,50 @@ def get_tech_losers(self) -> List[FilteredStock]:
7777 losers = self .fmp .get_biggest_losers_fmp ()
7878 self ._stats ["total_scanned" ] = len (losers )
7979 elif self .scan_source == "fmp-quotes" :
80- print ("[Source] Using FMP single-symbol quotes" )
81- losers = self .fmp .scan_tech_universe_fmp (limit = self .sample_size )
82- from .tech_universe import get_universe_size
83- self ._stats ["total_scanned" ] = get_universe_size (limit = self .sample_size )
80+ print ("[Source] Using FMP single-symbol quotes (Safe Mode)" )
81+ from .tech_universe import get_tech_universe
82+
83+ # User Constraint: "Scan 250 stocks using A [FMP]... and B [TD] as fallback"
84+ # We cap at 250 to respect FMP's daily free tier limit.
85+ safe_limit = 250
86+ if self .sample_size and self .sample_size > 0 :
87+ limit = min (self .sample_size , safe_limit )
88+ else :
89+ limit = safe_limit
90+
91+ universe = get_tech_universe (limit = limit )
92+ print (f"[Priority] Scanning Top { len (universe )} stocks (Limit: { safe_limit } )" )
93+
94+ try :
95+ # Primary: FMP
96+ print ("[Primary] Attempting scan via FMP..." )
97+ # Use scan_subset_fmp if available (added recently), else standard
98+ if hasattr (self .fmp , 'scan_subset_fmp' ):
99+ losers = self .fmp .scan_subset_fmp (universe )
100+ else :
101+ self .fmp .scan_tech_universe_fmp (limit = limit ) # Fallback if method missing
102+
103+ self ._stats ["total_scanned" ] = len (universe )
104+
105+ except Exception as e :
106+ # Fallback: Twelve Data
107+ print (f"[Primary] FMP Failed: { e } " )
108+ print ("[Fallback] Switching to Twelve Data (Source B)..." )
109+
110+ if hasattr (self .fmp , 'scan_subset_td' ):
111+ losers = self .fmp .scan_subset_td (universe )
112+ else :
113+ # Provide manual fallback using legacy methods if needed
114+ print ("[Error] Fallback method missing, skipping scan." )
115+ losers = []
116+
117+ self ._stats ["total_scanned" ] = len (universe )
118+
119+ elif self .scan_source == "hybrid" :
120+ # Legacy/Removed - redirecting to standard fmp-quotes if called
121+ print ("[Config] 'hybrid' deprecated, using 'fmp-quotes' fallback logic" )
122+ self .scan_source = "fmp-quotes"
123+ return self .get_tech_losers () # Recursively call with new mode
84124 else :
85125 losers = self .fmp .scan_tech_universe (limit = self .sample_size )
86126 from .tech_universe import get_universe_size
0 commit comments