tushare
This commit is contained in:
+48
-30
@@ -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']}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user