update pay promo
This commit is contained in:
211
app.py
211
app.py
@@ -17583,6 +17583,217 @@ def get_market_heatmap():
|
||||
}), 500
|
||||
|
||||
|
||||
@app.route('/api/market/realtime-stats', methods=['GET'])
|
||||
def get_market_realtime_stats():
|
||||
"""
|
||||
获取市场实时统计数据(从 ClickHouse 实时行情表)
|
||||
返回:大盘涨跌幅、涨停/跌停数、多空对比、成交额等
|
||||
"""
|
||||
from clickhouse_driver import Client as CHClient
|
||||
|
||||
try:
|
||||
ch_client = CHClient(
|
||||
host=os.environ.get('CLICKHOUSE_HOST', 'localhost'),
|
||||
port=int(os.environ.get('CLICKHOUSE_PORT', 9000)),
|
||||
user=os.environ.get('CLICKHOUSE_USER', 'default'),
|
||||
password=os.environ.get('CLICKHOUSE_PASSWORD', ''),
|
||||
database='stock'
|
||||
)
|
||||
|
||||
result = {
|
||||
'success': True,
|
||||
'data': {
|
||||
'index': None, # 大盘指数
|
||||
'limit_up_count': 0, # 涨停数
|
||||
'limit_down_count': 0, # 跌停数
|
||||
'rising_count': 0, # 上涨家数
|
||||
'falling_count': 0, # 下跌家数
|
||||
'flat_count': 0, # 平盘家数
|
||||
'total_amount': 0, # 总成交额
|
||||
'continuous_limit': [], # 连板股
|
||||
'update_time': None
|
||||
}
|
||||
}
|
||||
|
||||
# 1. 获取上证指数实时数据
|
||||
try:
|
||||
index_query = """
|
||||
SELECT
|
||||
security_id,
|
||||
current_index,
|
||||
prev_close,
|
||||
open_index,
|
||||
high_index,
|
||||
low_index,
|
||||
amount,
|
||||
trade_time
|
||||
FROM stock.szse_index_realtime
|
||||
WHERE trade_date = today()
|
||||
AND security_id = '399001'
|
||||
ORDER BY trade_time DESC
|
||||
LIMIT 1
|
||||
"""
|
||||
index_data = ch_client.execute(index_query)
|
||||
if index_data:
|
||||
row = index_data[0]
|
||||
prev_close = float(row[2]) if row[2] else 0
|
||||
current = float(row[1]) if row[1] else 0
|
||||
change_pct = ((current - prev_close) / prev_close * 100) if prev_close else 0
|
||||
result['data']['index'] = {
|
||||
'code': '399001.SZ',
|
||||
'name': '深证成指',
|
||||
'current': current,
|
||||
'prev_close': prev_close,
|
||||
'change_pct': round(change_pct, 2),
|
||||
'open': float(row[3]) if row[3] else 0,
|
||||
'high': float(row[4]) if row[4] else 0,
|
||||
'low': float(row[5]) if row[5] else 0,
|
||||
}
|
||||
result['data']['update_time'] = str(row[7]) if row[7] else None
|
||||
except Exception as e:
|
||||
app.logger.warning(f"获取指数实时数据失败: {e}")
|
||||
|
||||
# 2. 统计深交所股票涨跌情况
|
||||
try:
|
||||
szse_stats_query = """
|
||||
SELECT
|
||||
security_id,
|
||||
last_price,
|
||||
prev_close,
|
||||
upper_limit_price,
|
||||
lower_limit_price,
|
||||
amount
|
||||
FROM stock.szse_stock_realtime
|
||||
WHERE trade_date = today()
|
||||
AND last_price > 0
|
||||
AND prev_close > 0
|
||||
ORDER BY security_id, trade_time DESC
|
||||
LIMIT 1 BY security_id
|
||||
"""
|
||||
szse_data = ch_client.execute(szse_stats_query)
|
||||
|
||||
for row in szse_data:
|
||||
last_price = float(row[1])
|
||||
prev_close = float(row[2])
|
||||
upper_limit = float(row[3]) if row[3] else None
|
||||
lower_limit = float(row[4]) if row[4] else None
|
||||
amount = float(row[5]) if row[5] else 0
|
||||
|
||||
change_pct = (last_price - prev_close) / prev_close * 100
|
||||
|
||||
# 统计涨跌
|
||||
if change_pct > 0.01:
|
||||
result['data']['rising_count'] += 1
|
||||
elif change_pct < -0.01:
|
||||
result['data']['falling_count'] += 1
|
||||
else:
|
||||
result['data']['flat_count'] += 1
|
||||
|
||||
# 判断涨停/跌停
|
||||
if upper_limit and abs(last_price - upper_limit) < 0.01:
|
||||
result['data']['limit_up_count'] += 1
|
||||
elif lower_limit and abs(last_price - lower_limit) < 0.01:
|
||||
result['data']['limit_down_count'] += 1
|
||||
|
||||
result['data']['total_amount'] += amount
|
||||
|
||||
except Exception as e:
|
||||
app.logger.warning(f"统计深交所数据失败: {e}")
|
||||
|
||||
# 3. 统计上交所股票涨跌情况
|
||||
try:
|
||||
sse_stats_query = """
|
||||
SELECT
|
||||
security_id,
|
||||
last_price,
|
||||
prev_close,
|
||||
upper_limit_price,
|
||||
lower_limit_price,
|
||||
amount
|
||||
FROM stock.sse_stock_realtime
|
||||
WHERE trade_date = today()
|
||||
AND last_price > 0
|
||||
AND prev_close > 0
|
||||
ORDER BY security_id, trade_time DESC
|
||||
LIMIT 1 BY security_id
|
||||
"""
|
||||
sse_data = ch_client.execute(sse_stats_query)
|
||||
|
||||
for row in sse_data:
|
||||
last_price = float(row[1])
|
||||
prev_close = float(row[2])
|
||||
upper_limit = float(row[3]) if row[3] else None
|
||||
lower_limit = float(row[4]) if row[4] else None
|
||||
amount = float(row[5]) if row[5] else 0
|
||||
|
||||
change_pct = (last_price - prev_close) / prev_close * 100
|
||||
|
||||
if change_pct > 0.01:
|
||||
result['data']['rising_count'] += 1
|
||||
elif change_pct < -0.01:
|
||||
result['data']['falling_count'] += 1
|
||||
else:
|
||||
result['data']['flat_count'] += 1
|
||||
|
||||
if upper_limit and abs(last_price - upper_limit) < 0.01:
|
||||
result['data']['limit_up_count'] += 1
|
||||
elif lower_limit and abs(last_price - lower_limit) < 0.01:
|
||||
result['data']['limit_down_count'] += 1
|
||||
|
||||
result['data']['total_amount'] += amount
|
||||
|
||||
except Exception as e:
|
||||
app.logger.warning(f"统计上交所数据失败: {e}")
|
||||
|
||||
# 4. 尝试获取上证指数(补充)
|
||||
try:
|
||||
sh_index_query = """
|
||||
SELECT
|
||||
seccode,
|
||||
close as current_price,
|
||||
pre_close,
|
||||
open,
|
||||
high,
|
||||
low,
|
||||
amount,
|
||||
tradetime
|
||||
FROM stock.index_minute
|
||||
WHERE tradetime >= today()
|
||||
AND seccode = '000001.SH'
|
||||
ORDER BY tradetime DESC
|
||||
LIMIT 1
|
||||
"""
|
||||
sh_data = ch_client.execute(sh_index_query)
|
||||
if sh_data:
|
||||
row = sh_data[0]
|
||||
prev_close = float(row[2]) if row[2] else 0
|
||||
current = float(row[1]) if row[1] else 0
|
||||
change_pct = ((current - prev_close) / prev_close * 100) if prev_close else 0
|
||||
result['data']['index'] = {
|
||||
'code': '000001.SH',
|
||||
'name': '上证指数',
|
||||
'current': current,
|
||||
'prev_close': prev_close,
|
||||
'change_pct': round(change_pct, 2),
|
||||
'open': float(row[3]) if row[3] else 0,
|
||||
'high': float(row[4]) if row[4] else 0,
|
||||
'low': float(row[5]) if row[5] else 0,
|
||||
}
|
||||
if row[7]:
|
||||
result['data']['update_time'] = str(row[7])
|
||||
except Exception as e:
|
||||
app.logger.warning(f"获取上证指数失败: {e}")
|
||||
|
||||
return jsonify(result)
|
||||
|
||||
except Exception as e:
|
||||
app.logger.error(f"获取实时市场统计失败: {e}")
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
@app.route('/api/market/statistics', methods=['GET'])
|
||||
def get_market_statistics():
|
||||
"""获取市场统计数据(从ea_blocktrading表)"""
|
||||
|
||||
Reference in New Issue
Block a user