修改了bsp state,继续测试

This commit is contained in:
jackyu66git
2026-05-20 00:49:53 +08:00
parent 91148a648a
commit 9b876c45ed
7 changed files with 430 additions and 161 deletions
+74 -29
View File
@@ -45,7 +45,7 @@ exchange = ccxt.binance({
'enableRateLimit': True,
})
# 初始化A股数据获取器
# 初始化 A 股数据获取器K 线优先请求 A-Share Data Platform,默认 http://103.179.242.166:8000 ,见 /api/v1/klines 文档;ASHARE_DP_URL 覆盖,置空则仅用 AKShare
china_stock = ChinaStockData()
logger = logging.getLogger(__name__)
@@ -65,6 +65,7 @@ def _zone_cache_ttl(tf_name: str) -> int:
else:
return 1800 # 4h+: 30分钟
# 加密货币本地/自建行情服务(与 A 股 ASHARE_DP_URL 端口可不同)
DATA_SERVICE_URL = os.environ.get("DATA_SERVICE_URL", os.environ.get("DATASVC_URL", "http://103.179.242.166"))
DEFAULT_TIMEFRAME_LABELS = OrderedDict([
@@ -150,6 +151,40 @@ def build_timeframe_labels(timeframes):
return labels
def compute_timeframe_defaults(labels_ordered):
"""
根据已排序的「周期 → 中文标签」映射,计算主 / 次 / 次次周期默认值。
labels_ordered: OrderedDict 或按插入顺序排列的 dict。
"""
if not labels_ordered:
labels_ordered = DEFAULT_TIMEFRAME_LABELS.copy()
timeframe_keys = list(labels_ordered.keys())
preferred_main = next((tf for tf in ['5m', '15m', '1h'] if tf in labels_ordered), None)
default_main = preferred_main or (timeframe_keys[0] if timeframe_keys else '1m')
if default_main not in labels_ordered and timeframe_keys:
default_main = timeframe_keys[0]
if timeframe_keys:
try:
idx = timeframe_keys.index(default_main)
default_element = timeframe_keys[idx - 1] if idx > 0 else timeframe_keys[0]
except ValueError:
default_element = timeframe_keys[0]
else:
default_element = default_main
if timeframe_keys:
try:
idx_el = timeframe_keys.index(default_element)
default_sub_sub = timeframe_keys[idx_el - 1] if idx_el > 0 else timeframe_keys[0]
except ValueError:
default_sub_sub = timeframe_keys[0]
else:
default_sub_sub = default_element
return default_main, default_element, default_sub_sub, timeframe_keys
def _parse_time_input(value):
if value in (None, '', 0):
return None
@@ -230,7 +265,8 @@ def _fetch_kl_from_datasvc(symbol, timeframe, start_ms=None, end_ms=None, limit=
refresh_data_service_metadata(force=True)
# A股热门股票
A_STOCK_SYMBOLS = china_stock.get_popular_stocks()
# 模板中 A 股下拉仅放默认一项;用户切换到「A股」时由前端请求 /api/a_stocks 填充全市场(约 5500+
A_STOCK_SYMBOLS = [{'symbol': '000001', 'name': '平安银行'}]
def detect_symbol_type(symbol):
"""检测交易对类型:crypto 或 a_stock"""
@@ -1226,39 +1262,15 @@ def serve_charting_library(filename):
def index():
"""主页"""
refresh_data_service_metadata()
timeframe_items = list(TIMEFRAMES.items())
timeframe_keys = [item[0] for item in timeframe_items]
tf_map = TIMEFRAMES if TIMEFRAMES else DEFAULT_TIMEFRAME_LABELS.copy()
default_main, default_element, default_sub_sub, timeframe_keys = compute_timeframe_defaults(OrderedDict(tf_map))
symbols = SYMBOLS if SYMBOLS else DEFAULT_SYMBOLS
preferred_main = next((tf for tf in ['5m', '15m', '1h'] if tf in TIMEFRAMES), None)
default_main = preferred_main or (timeframe_keys[0] if timeframe_keys else '1m')
if default_main not in TIMEFRAMES and timeframe_keys:
default_main = timeframe_keys[0]
if timeframe_keys:
try:
idx = timeframe_keys.index(default_main)
default_element = timeframe_keys[idx - 1] if idx > 0 else timeframe_keys[0]
except ValueError:
default_element = timeframe_keys[0]
else:
default_element = default_main
# 次次周期默认比次周期小一档
if timeframe_keys:
try:
idx_el = timeframe_keys.index(default_element)
default_sub_sub = timeframe_keys[idx_el - 1] if idx_el > 0 else timeframe_keys[0]
except ValueError:
default_sub_sub = timeframe_keys[0]
else:
default_sub_sub = default_element
default_symbol = 'BTC/USDT:USDT' if 'BTC/USDT:USDT' in symbols else (symbols[0] if symbols else '')
return render_template(
'index.html',
timeframes=TIMEFRAMES,
timeframes=tf_map,
symbols=symbols,
a_stock_symbols=A_STOCK_SYMBOLS,
default_main_timeframe=default_main,
@@ -1269,6 +1281,39 @@ def index():
data_service_available=DATA_SERVICE_AVAILABLE,
)
@app.route('/api/chart_metadata')
def api_chart_metadata():
"""
按数据源返回图表用 K 线周期(中文标签)及主/次/次次默认周期。
crypto:强制刷新 DATA_SERVICE_URL /health 元信息;
a_stock:读取 ASHARE_DP_URL 的 /api/v1/klines/available-freqs,不修改全局加密货币 TIMEFRAMES。
"""
source = (request.args.get('source') or 'crypto').strip().lower()
if source not in ('crypto', 'a_stock'):
source = 'crypto'
try:
if source == 'a_stock':
raw = china_stock.get_available_kline_freqs()
labels_od = build_timeframe_labels(raw)
else:
refresh_data_service_metadata(force=True)
labels_od = OrderedDict(TIMEFRAMES if TIMEFRAMES else DEFAULT_TIMEFRAME_LABELS.copy())
default_main, default_element, default_sub_sub, keys = compute_timeframe_defaults(labels_od)
return jsonify({
'source': source,
'timeframes': {k: v for k, v in labels_od.items()},
'timeframe_keys': keys,
'default_main': default_main,
'default_element': default_element,
'default_sub_sub': default_sub_sub,
})
except Exception as exc:
logger.exception('chart_metadata 失败: %s', exc)
return jsonify({'error': str(exc)}), 500
@app.route('/api/analyze')
def analyze():
"""分析接口"""