perf: 6项性能与正确性优化

1. get_stock_name: 延迟批量保存缓存(60秒去抖),避免每次新缓存都写文件
2. get_stock_name: 优先从DB stock_realtime_price查name,未命中再调腾讯API
3. compute_comprehensive_score: 单股模式也使用_fund_flow_cache(30分钟TTL)
4. _get_kline_from_local_db: 移除conn.autocommit=True,避免污染连接池事务模式
5. deep_analyze: K线天数从180改为120,与实时检测统一
6. detect_all_signals: 已有指标列时跳过重复calc_all_indicators
This commit is contained in:
freedakgmail
2026-07-22 08:00:27 +08:00
parent 037d9cd26c
commit cf7341fc63
5 changed files with 60 additions and 19 deletions
+47 -13
View File
@@ -7,11 +7,16 @@ from datetime import datetime, timedelta
import traceback
import json
import os
import time
import threading
from config import Config
# ========== 股票名称缓存 ==========
_stock_name_cache = {}
_name_cache_dirty = False
_name_cache_last_save = 0.0
_name_cache_lock = threading.Lock()
def _load_stock_name_cache():
@@ -26,23 +31,51 @@ def _load_stock_name_cache():
print(f"加载股票名称缓存失败: {e}")
def _save_stock_name_cache():
"""保存股票名称缓存到本地"""
try:
with open(Config.STOCK_NAME_CACHE_FILE, 'w', encoding='utf-8') as f:
json.dump(_stock_name_cache, f, ensure_ascii=False, indent=2)
except Exception as e:
print(f"保存股票名称缓存失败: {e}")
def _save_stock_name_cache(force=False):
"""保存股票名称缓存到本地(延迟批量保存,60秒去抖)"""
global _name_cache_dirty, _name_cache_last_save
if not force and not _name_cache_dirty:
return
now = time.time()
if not force and (now - _name_cache_last_save) < 60:
return
with _name_cache_lock:
try:
with open(Config.STOCK_NAME_CACHE_FILE, 'w', encoding='utf-8') as f:
json.dump(_stock_name_cache, f, ensure_ascii=False, indent=2)
_name_cache_dirty = False
_name_cache_last_save = now
except Exception as e:
print(f"保存股票名称缓存失败: {e}")
def get_stock_name(stock_code):
"""获取股票名称 — 使用腾讯财经API"""
global _stock_name_cache
"""获取股票名称 — 优先内存缓存 → DB stock_realtime_price → 腾讯财经API"""
global _stock_name_cache, _name_cache_dirty
if stock_code in _stock_name_cache:
return _stock_name_cache[stock_code]
# 腾讯财经API获取股票名称
# 优先从数据库 stock_realtime_price 表查(毫秒级)
try:
from db import get_db, put_db
conn = get_db()
if conn:
try:
with conn.cursor() as cur:
cur.execute("SELECT name FROM stock_realtime_price WHERE code = %s", (stock_code,))
row = cur.fetchone()
if row and row[0]:
_stock_name_cache[stock_code] = row[0]
_name_cache_dirty = True
_save_stock_name_cache()
return row[0]
finally:
put_db(conn)
except Exception:
pass
# 回退到腾讯财经API
try:
import requests as _req
tcode = ('sh' if stock_code.startswith('6') else 'bj' if stock_code.startswith(('8', '9')) else 'sz') + stock_code
@@ -52,11 +85,12 @@ def get_stock_name(stock_code):
_fields = _r.text.split('\"')[1].split('~')
if len(_fields) > 2 and _fields[1]:
_stock_name_cache[stock_code] = _fields[1]
_name_cache_dirty = True
_save_stock_name_cache()
return _fields[1]
except Exception as e:
print(f"获取股票名称失败(腾讯): {e}")
return None