主站重建前完整 dispose、去掉重复 sync 监听,自动刷新默认增量更新;顺带消除首屏重复 analyze、复用 ChanMACD,以及全版 TV 指标/未完成中枢/布局本地缓存。 Co-authored-by: Cursor <cursoragent@cursor.com>
79 lines
2.6 KiB
Python
79 lines
2.6 KiB
Python
"""页面路由。"""
|
|
from flask import Blueprint, render_template, send_from_directory
|
|
from config import DATA_SERVICE_URL, DATA_SERVICE_WS_URL
|
|
from services.runtime import * # noqa: F403
|
|
from services import runtime as R
|
|
|
|
bp = Blueprint("pages", __name__)
|
|
|
|
@bp.route('/chan_tv')
|
|
def chan_tv():
|
|
"""缠论 TradingView 高级图表页面"""
|
|
return render_template(
|
|
'chan_tv.html',
|
|
data_service_url=DATA_SERVICE_URL,
|
|
data_service_ws_url=DATA_SERVICE_WS_URL,
|
|
)
|
|
|
|
@bp.route('/charting_library/<path:filename>')
|
|
def serve_charting_library(filename):
|
|
"""提供 TradingView Charting Library 静态文件"""
|
|
return send_from_directory('charting_library', filename)
|
|
|
|
@bp.route('/')
|
|
def index():
|
|
"""主页"""
|
|
refresh_data_service_metadata()
|
|
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
|
|
|
|
default_symbol = 'BTC/USDT:USDT' if 'BTC/USDT:USDT' in symbols else (symbols[0] if symbols else '')
|
|
|
|
return render_template(
|
|
'index.html',
|
|
timeframes=tf_map,
|
|
symbols=symbols,
|
|
a_stock_symbols=A_STOCK_SYMBOLS,
|
|
default_main_timeframe=default_main,
|
|
default_element_timeframe=default_element,
|
|
default_sub_sub_timeframe=default_sub_sub,
|
|
default_symbol=default_symbol,
|
|
timeframe_keys_json=json.dumps(timeframe_keys),
|
|
data_service_available=DATA_SERVICE_AVAILABLE,
|
|
)
|
|
|
|
|
|
@bp.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
|
|
|
|
|