fix: 修复外部因素数据源 - 北向资金改为南向资金,修复P0-P7全部外部因素

- P0资金面:DB数据过期时用麦蕊API获取资金流向
- P1市场情绪:去掉turnover字段依赖(DB无此字段)
- P2南向资金:北向实时数据已停公布,改用南向资金(港股通)替代
- P3美股:用腾讯财经API替代失效的AKShare接口
- P4大宗商品:用腾讯财经API替代,修复var_name解析
- P7汇率:用新浪财经API替代失效的AKShare接口
- 修复评分详情API技术得分硬编码问题
- 前端传入tech_score参数确保明细与列表分数一致
This commit is contained in:
selfrelease
2026-07-18 16:45:58 +08:00
parent bb5a72767f
commit 79e869eeda
13 changed files with 637 additions and 193 deletions
+117
View File
@@ -73,10 +73,105 @@ def get_fund_flow_history(stock_code, days=10):
put_db(conn)
def _get_fund_flow_from_mairui(stock_code, days=10):
"""从麦蕊智数API获取资金流向数据,转换为与DB记录相同的格式。
API: https://api.mairuiapi.com/hsstock/history/transaction/{code}/{licence}?lt={n}
字段: zmbtdcje=主买特大单, zmbddcje=主买大单, zmbzdcje=主买中单, zmbxdcje=主买小单
zmstdcje=主卖特大单, zmsddcje=主卖大单, zmszdcje=主卖中单, zmsxdcje=主卖小单
"""
try:
import requests
from config import Config
LICENCE = Config.MAIRUI_LICENCE or "5352ED2F-94E5-4E96-8B7F-B57BA75284E3"
url = f"https://api.mairuiapi.com/hsstock/history/transaction/{stock_code}/{LICENCE}?lt={days}"
resp = requests.get(url, timeout=10)
if resp.status_code != 200:
logger.warning(f"麦蕊资金流向API返回{resp.status_code}")
return []
data = resp.json()
if not data or not isinstance(data, list):
return []
records = []
for item in data:
# 主买总额 = 特大单+大单+中单+小单
buy_total = (
float(item.get('zmbtdcje', 0) or 0) +
float(item.get('zmbddcje', 0) or 0) +
float(item.get('zmbzdcje', 0) or 0) +
float(item.get('zmbxdcje', 0) or 0)
)
# 主卖总额
sell_total = (
float(item.get('zmstdcje', 0) or 0) +
float(item.get('zmsddcje', 0) or 0) +
float(item.get('zmszdcje', 0) or 0) +
float(item.get('zmsxdcje', 0) or 0)
)
# 主力净流入 = (特大单+大单)买 - (特大单+大单)卖
main_buy = float(item.get('zmbtdcje', 0) or 0) + float(item.get('zmbddcje', 0) or 0)
main_sell = float(item.get('zmstdcje', 0) or 0) + float(item.get('zmsddcje', 0) or 0)
main_net = main_buy - main_sell
# 超大单净流入
super_net = float(item.get('zmbtdcje', 0) or 0) - float(item.get('zmstdcje', 0) or 0)
# 总成交额
total_amount = buy_total + sell_total
main_net_pct = round(main_net / total_amount * 100, 2) if total_amount > 0 else 0
super_net_pct = round(super_net / total_amount * 100, 2) if total_amount > 0 else 0
# 大单净流入
big_net = float(item.get('zmbddcje', 0) or 0) - float(item.get('zmsddcje', 0) or 0)
big_net_pct = round(big_net / total_amount * 100, 2) if total_amount > 0 else 0
# 中单净流入
mid_net = float(item.get('zmbzdcje', 0) or 0) - float(item.get('zmszdcje', 0) or 0)
mid_net_pct = round(mid_net / total_amount * 100, 2) if total_amount > 0 else 0
# 小单净流入
small_net = float(item.get('zmbxdcje', 0) or 0) - float(item.get('zmsxdcje', 0) or 0)
small_net_pct = round(small_net / total_amount * 100, 2) if total_amount > 0 else 0
# 日期解析
t_str = str(item.get('t', ''))
date_str = t_str[:10] if t_str else ''
records.append({
'date': date_str,
'close_price': 0,
'change_pct': 0,
'main_net_inflow': round(main_net, 2),
'main_net_inflow_pct': main_net_pct,
'super_net_inflow': round(super_net, 2),
'super_net_inflow_pct': super_net_pct,
'big_net_inflow': round(big_net, 2),
'big_net_inflow_pct': big_net_pct,
'mid_net_inflow': round(mid_net, 2),
'mid_net_inflow_pct': mid_net_pct,
'small_net_inflow': round(small_net, 2),
'small_net_inflow_pct': small_net_pct,
})
# 按日期升序排列
records.sort(key=lambda x: x['date'])
logger.info(f"麦蕊API获取{stock_code}资金流向{len(records)}")
return records
except Exception as e:
logger.warning(f"麦蕊资金流向API失败({stock_code}): {e}")
return []
def analyze_fund_flow(stock_code, days=5):
"""
分析主力资金流向,返回资金面评分和信号
数据源优先级:
1. DB stock_fund_flow_history 表(有最新数据时)
2. 麦蕊智数API hsstock/history/transactionDB数据过期时补充)
参数:
stock_code: 股票代码
days: 分析最近几天的资金流向
@@ -91,6 +186,28 @@ def analyze_fund_flow(stock_code, days=5):
}
"""
records = get_fund_flow_history(stock_code, days=days + 5)
# 检查DB数据是否足够新(最近3天内有数据)
use_mairui = False
if len(records) < 2:
use_mairui = True
else:
from datetime import date
latest_date = records[-1].get('date', '')
if latest_date:
try:
latest = datetime.strptime(latest_date, '%Y-%m-%d').date()
if (date.today() - latest).days > 5:
use_mairui = True
except ValueError:
use_mairui = True
if use_mairui:
# 用麦蕊API获取资金流向数据
mairui_records = _get_fund_flow_from_mairui(stock_code, days + 5)
if mairui_records:
records = mairui_records
if len(records) < 2:
return {
'score': 0,