@@ -492,11 +492,83 @@ def __init__(self, fetchers: Optional[List[BaseFetcher]] = None):
492492 # 默认数据源将在首次使用时延迟加载
493493 self ._init_default_fetchers ()
494494 self ._fundamental_adapter = AkshareFundamentalAdapter ()
495+ self ._tickflow_fetcher = None
496+ self ._tickflow_api_key : Optional [str ] = None
497+ self ._tickflow_lock = RLock ()
495498 self ._fundamental_cache : Dict [str , Dict [str , Any ]] = {}
496499 self ._fundamental_cache_lock = RLock ()
497500 self ._fundamental_timeout_worker_limit = 8
498501 self ._fundamental_timeout_slots = BoundedSemaphore (self ._fundamental_timeout_worker_limit )
499502
503+ def _get_tickflow_fetcher (self ):
504+ """Lazily create a TickFlow fetcher for market-review-only calls."""
505+ from src .config import get_config
506+
507+ config = get_config ()
508+ api_key = (getattr (config , "tickflow_api_key" , None ) or "" ).strip ()
509+
510+ if not hasattr (self , "_tickflow_lock" ) or self ._tickflow_lock is None :
511+ self ._tickflow_lock = RLock ()
512+
513+ with self ._tickflow_lock :
514+ current_fetcher = getattr (self , "_tickflow_fetcher" , None )
515+ current_key = getattr (self , "_tickflow_api_key" , None )
516+
517+ if not api_key :
518+ if current_fetcher is not None and hasattr (current_fetcher , "close" ):
519+ try :
520+ current_fetcher .close ()
521+ except Exception as exc :
522+ logger .debug ("[TickFlowFetcher] 关闭旧实例失败: %s" , exc )
523+ self ._tickflow_fetcher = None
524+ self ._tickflow_api_key = None
525+ return None
526+
527+ if current_fetcher is not None and current_key == api_key :
528+ return current_fetcher
529+
530+ if current_fetcher is not None and hasattr (current_fetcher , "close" ):
531+ try :
532+ current_fetcher .close ()
533+ except Exception as exc :
534+ logger .debug ("[TickFlowFetcher] 切换实例时关闭失败: %s" , exc )
535+
536+ try :
537+ from .tickflow_fetcher import TickFlowFetcher
538+
539+ fetcher = TickFlowFetcher (api_key = api_key )
540+ self ._tickflow_fetcher = fetcher
541+ self ._tickflow_api_key = api_key
542+ return fetcher
543+ except Exception as exc :
544+ logger .warning ("[TickFlowFetcher] 初始化失败: %s" , exc )
545+ self ._tickflow_fetcher = None
546+ self ._tickflow_api_key = None
547+ return None
548+
549+ def close (self ) -> None :
550+ """Best-effort release of manager-owned resources."""
551+ if not hasattr (self , "_tickflow_lock" ) or self ._tickflow_lock is None :
552+ self ._tickflow_lock = RLock ()
553+
554+ with self ._tickflow_lock :
555+ current_fetcher = getattr (self , "_tickflow_fetcher" , None )
556+ self ._tickflow_fetcher = None
557+ self ._tickflow_api_key = None
558+
559+ if current_fetcher is not None and hasattr (current_fetcher , "close" ):
560+ try :
561+ current_fetcher .close ()
562+ except Exception as exc :
563+ logger .debug ("[TickFlowFetcher] 关闭管理器资源失败: %s" , exc )
564+
565+ def __del__ (self ) -> None :
566+ try :
567+ self .close ()
568+ except Exception :
569+ # Best-effort cleanup during interpreter shutdown.
570+ pass
571+
500572 def _get_fundamental_cache_key (self , stock_code : str , budget_seconds : Optional [float ] = None ) -> str :
501573 """生成基本面缓存 key(包含预算分桶以避免低预算结果污染高预算请求)。"""
502574 normalized_code = normalize_stock_code (stock_code )
@@ -1348,6 +1420,17 @@ def batch_get_stock_names(self, stock_codes: List[str]) -> Dict[str, str]:
13481420
13491421 def get_main_indices (self , region : str = "cn" ) -> List [Dict [str , Any ]]:
13501422 """获取主要指数实时行情(自动切换数据源)"""
1423+ if region == "cn" :
1424+ tickflow_fetcher = self ._get_tickflow_fetcher ()
1425+ if tickflow_fetcher is not None :
1426+ try :
1427+ data = tickflow_fetcher .get_main_indices (region = region )
1428+ if data :
1429+ logger .info ("[TickFlowFetcher] 获取指数行情成功" )
1430+ return data
1431+ except Exception as e :
1432+ logger .warning (f"[TickFlowFetcher] 获取指数行情失败: { e } " )
1433+
13511434 for fetcher in self ._fetchers :
13521435 try :
13531436 data = fetcher .get_main_indices (region = region )
@@ -1361,6 +1444,16 @@ def get_main_indices(self, region: str = "cn") -> List[Dict[str, Any]]:
13611444
13621445 def get_market_stats (self ) -> Dict [str , Any ]:
13631446 """获取市场涨跌统计(自动切换数据源)"""
1447+ tickflow_fetcher = self ._get_tickflow_fetcher ()
1448+ if tickflow_fetcher is not None :
1449+ try :
1450+ data = tickflow_fetcher .get_market_stats ()
1451+ if data :
1452+ logger .info ("[TickFlowFetcher] 获取市场统计成功" )
1453+ return data
1454+ except Exception as e :
1455+ logger .warning (f"[TickFlowFetcher] 获取市场统计失败: { e } " )
1456+
13641457 for fetcher in self ._fetchers :
13651458 try :
13661459 data = fetcher .get_market_stats ()
0 commit comments