This commit is contained in:
songzhuoyuan
2026-08-11 20:41:31 +08:00
parent 2ce13e5bae
commit befdc32aea
24 changed files with 1311 additions and 530 deletions
+48 -30
View File
@@ -54,7 +54,7 @@ class SmartMonitorDataFetcher:
try:
import tushare as ts
ts.set_token(tushare_token)
self.ts_pro = ts.pro_api()
self.ts_pro = ts.pro_api(timeout=float(os.getenv('TUSHARE_TIMEOUT', '15')))
self.logger.info("Tushare备用数据源初始化成功")
except Exception as e:
self.logger.warning(f"Tushare初始化失败: {e}")
@@ -64,7 +64,7 @@ class SmartMonitorDataFetcher:
def get_realtime_quote(self, stock_code: str, retry: int = 1) -> Optional[Dict]:
"""
获取实时行情(带重试和降级机制)
优先使用TDX,失败时降级到AKShare,最后降级到Tushare
优先使用TDX,失败时降级到Tushare,最后降级到AKShare
Args:
stock_code: 股票代码(如:600519
@@ -82,11 +82,20 @@ class SmartMonitorDataFetcher:
if quote:
return quote
else:
self.logger.warning(f"TDX获取失败 {stock_code},尝试降级到AKShare")
self.logger.warning(f"TDX获取失败 {stock_code},尝试降级到Tushare")
except Exception as e:
self.logger.warning(f"TDX获取异常 {stock_code}: {e},尝试降级到AKShare")
self.logger.warning(f"TDX获取异常 {stock_code}: {e},尝试降级到Tushare")
# 方法2: 组合使用AKShare分钟行情 + 基本信息
# 方法2: 降级到Tushare(优先于AKShare
if self.ts_pro:
quote = self._get_realtime_quote_from_tushare(stock_code)
if quote:
return quote
self.logger.warning(f"Tushare获取失败 {stock_code},尝试降级到AKShare")
else:
self.logger.warning(f"未配置Tushare,尝试使用AKShare")
# 方法3: 组合使用AKShare分钟行情 + 基本信息
for attempt in range(retry):
try:
# 1.1 获取股票基本信息(名称)
@@ -167,18 +176,14 @@ class SmartMonitorDataFetcher:
else:
self.logger.warning(f"AKShare获取失败 {stock_code}(已重试{retry}次),尝试降级")
# 降级到Tushare
if self.ts_pro:
self.logger.info(f"降级到Tushare获取 {stock_code}...")
return self._get_realtime_quote_from_tushare(stock_code)
else:
self.logger.error(f"AKShare失败且未配置Tushare,无法获取 {stock_code} 行情")
return None
# 所有数据源都失败
self.logger.error(f"所有数据源都无法获取 {stock_code} 行情")
return None
def get_technical_indicators(self, stock_code: str, period: str = 'daily', retry: int = 1) -> Optional[Dict]:
"""
计算技术指标(带降级机制)
优先使用TDX,失败时降级到AKShare,最后降级到Tushare
优先使用TDX,失败时降级到Tushare,最后降级到AKShare
Args:
stock_code: 股票代码
@@ -197,11 +202,21 @@ class SmartMonitorDataFetcher:
if indicators:
return indicators
else:
self.logger.warning(f"TDX计算技术指标失败 {stock_code},尝试降级到AKShare")
self.logger.warning(f"TDX计算技术指标失败 {stock_code},尝试降级到Tushare")
except Exception as e:
self.logger.warning(f"TDX计算技术指标异常 {stock_code}: {e},尝试降级到AKShare")
self.logger.warning(f"TDX计算技术指标异常 {stock_code}: {e},尝试降级到Tushare")
# 方法2: 尝试使用AKShare
# 方法2: 降级到Tushare(优先于AKShare
if self.ts_pro:
self.logger.info(f"降级到Tushare获取 {stock_code} 历史数据...")
indicators = self._get_technical_indicators_from_tushare(stock_code, period)
if indicators:
return indicators
self.logger.warning(f"Tushare获取技术指标失败 {stock_code},尝试降级到AKShare")
else:
self.logger.warning(f"未配置Tushare,尝试使用AKShare")
# 方法3: 尝试使用AKShare
for attempt in range(retry):
try:
# 获取历史数据(最近200个交易日,用于计算指标)
@@ -237,13 +252,9 @@ class SmartMonitorDataFetcher:
self.logger.warning(f"AKShare获取历史数据失败 {stock_code}(已重试{retry}次),尝试降级到Tushare")
break
# 方法3: 降级到Tushare
if self.ts_pro:
self.logger.info(f"降级到Tushare获取 {stock_code} 历史数据...")
return self._get_technical_indicators_from_tushare(stock_code, period)
else:
self.logger.error(f"AKShare失败且未配置Tushare,无法获取 {stock_code} 技术指标")
return None
# 所有数据源都失败
self.logger.error(f"所有数据源都无法获取 {stock_code} 技术指标")
return None
def _calculate_all_indicators(self, df: pd.DataFrame, stock_code: str) -> Optional[Dict]:
"""
@@ -439,6 +450,17 @@ class SmartMonitorDataFetcher:
"""
import time
# 优先使用Tushare个股资金流向
if self.ts_pro:
try:
result = self._get_main_force_from_tushare(stock_code)
if result:
self.logger.info(f"✅ Tushare成功获取 {stock_code} 资金流向(主要数据源)")
return result
self.logger.warning(f"Tushare未获取到资金流向 {stock_code},尝试AKShare")
except Exception as e:
self.logger.warning(f"Tushare获取资金流向失败 {stock_code}: {e}")
for attempt in range(retry):
try:
# 获取个股资金流(新版AKShare API参数调整)
@@ -495,12 +517,9 @@ class SmartMonitorDataFetcher:
self.logger.warning(f"AKShare获取资金流向失败 {stock_code}(已重试{retry}次),尝试降级到Tushare")
break
# 降级到Tushare
if self.ts_pro:
return self._get_main_force_from_tushare(stock_code)
else:
self.logger.error(f"AKShare失败且未配置Tushare,无法获取 {stock_code} 资金流向")
return None
# 所有数据源都失败
self.logger.error(f"所有数据源都无法获取 {stock_code} 资金流向")
return None
def get_comprehensive_data(self, stock_code: str) -> Dict:
"""
@@ -822,4 +841,3 @@ if __name__ == '__main__':
print("\n主力资金:")
print(f" 主力净额: {data['main_force']['main_net']:.2f}")
print(f" 主力动向: {data['main_force']['trend']}")