update pay ui

This commit is contained in:
2025-12-02 10:33:55 +08:00
parent 5799984fd0
commit a3a2960297
4 changed files with 473 additions and 44 deletions

120
app.py
View File

@@ -7289,6 +7289,126 @@ def get_timeline_data(stock_code, event_datetime, stock_name):
# ==================== 指数行情API与股票逻辑一致数据表为 index_minute ====================
@app.route('/api/index/<index_code>/realtime')
def get_index_realtime(index_code):
"""
获取指数实时行情(用于交易时间内的行情更新)
从 index_minute 表获取最新的分钟数据
返回: 最新价、涨跌幅、涨跌额、开盘价、最高价、最低价、昨收价
"""
client = get_clickhouse_client()
today = date.today()
# 判断今天是否是交易日
if today not in trading_days_set:
# 非交易日,获取最近一个交易日的收盘数据
target_date = get_trading_day_near_date(today)
if not target_date:
return jsonify({
'success': False,
'error': 'No trading day found',
'data': None
})
is_trading = False
else:
target_date = today
# 判断是否在交易时间内
now = datetime.now()
current_minutes = now.hour * 60 + now.minute
# 9:30-11:30 = 570-690, 13:00-15:00 = 780-900
is_trading = (570 <= current_minutes <= 690) or (780 <= current_minutes <= 900)
try:
# 获取当天/最近交易日的第一条数据(开盘价)和最后一条数据(最新价)
# 同时获取最高价和最低价
data = client.execute(
"""
SELECT
min(open) as first_open,
max(high) as day_high,
min(low) as day_low,
argMax(close, timestamp) as latest_close,
argMax(timestamp, timestamp) as latest_time
FROM index_minute
WHERE code = %(code)s
AND toDate(timestamp) = %(date)s
""",
{
'code': index_code,
'date': target_date,
}
)
if not data or not data[0] or data[0][3] is None:
return jsonify({
'success': False,
'error': 'No data available',
'data': None
})
row = data[0]
first_open = float(row[0]) if row[0] else None
day_high = float(row[1]) if row[1] else None
day_low = float(row[2]) if row[2] else None
latest_close = float(row[3]) if row[3] else None
latest_time = row[4]
# 获取昨收价(从 MySQL ea_exchangetrade 表)
code_no_suffix = index_code.split('.')[0]
prev_close = None
with engine.connect() as conn:
# 获取前一个交易日的收盘价
prev_result = conn.execute(text(
"""
SELECT F006N
FROM ea_exchangetrade
WHERE INDEXCODE = :code
AND TRADEDATE < :today
ORDER BY TRADEDATE DESC LIMIT 1
"""
), {
'code': code_no_suffix,
'today': datetime.combine(target_date, dt_time(0, 0, 0))
}).fetchone()
if prev_result and prev_result[0]:
prev_close = float(prev_result[0])
# 计算涨跌额和涨跌幅
change_amount = None
change_pct = None
if latest_close is not None and prev_close is not None and prev_close > 0:
change_amount = latest_close - prev_close
change_pct = (change_amount / prev_close) * 100
return jsonify({
'success': True,
'data': {
'code': index_code,
'price': latest_close,
'open': first_open,
'high': day_high,
'low': day_low,
'prev_close': prev_close,
'change': change_amount,
'change_pct': change_pct,
'update_time': latest_time.strftime('%H:%M:%S') if latest_time else None,
'trade_date': target_date.strftime('%Y-%m-%d'),
'is_trading': is_trading,
}
})
except Exception as e:
logger.error(f"获取指数实时行情失败: {index_code}, 错误: {str(e)}")
return jsonify({
'success': False,
'error': str(e),
'data': None
}), 500
@app.route('/api/index/<index_code>/kline')
def get_index_kline(index_code):
chart_type = request.args.get('type', 'minute')