Files
vf_react/change_pct_fix.py
2025-11-13 07:40:46 +08:00

98 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 这是要替换的涨跌幅计算逻辑第3729-3738行
# 计算基于事件时间的涨跌幅(参考 app.py /api/stock/quotes 的实现)
change_pct = None
change_amount = None
current_price = None
try:
# 获取事件时间和当前时间
evt_time = event.start_time if event.start_time else event.created_at
cur_time = datetime.now()
# 获取交易日和时间范围
evt_date = evt_time.date()
evt_time_only = evt_time.time()
market_open = dt_time(9, 30)
market_close = dt_time(15, 0)
# 检查是否是交易日
is_trading_day_result = db.session.execute(text("""
SELECT 1 FROM trading_days WHERE EXCHANGE_DATE = :date
"""), {"date": evt_date}).fetchone()
trading_day = None
start_time = None
end_time = None
if is_trading_day_result:
# 是交易日
if evt_time_only < market_open:
# 盘前 - 使用当日开盘
trading_day, start_time, end_time = evt_date, market_open, market_close
elif evt_time_only > market_close:
# 盘后 - 使用下一交易日
next_day_result = db.session.execute(text("""
SELECT EXCHANGE_DATE FROM trading_days
WHERE EXCHANGE_DATE > :date ORDER BY EXCHANGE_DATE LIMIT 1
"""), {"date": evt_date}).fetchone()
if next_day_result:
trading_day, start_time, end_time = next_day_result[0].date(), market_open, market_close
else:
# 盘中 - 从事件时间到收盘
trading_day, start_time, end_time = evt_date, evt_time_only, market_close
else:
# 非交易日 - 获取下一交易日
next_day_result = db.session.execute(text("""
SELECT EXCHANGE_DATE FROM trading_days
WHERE EXCHANGE_DATE > :date ORDER BY EXCHANGE_DATE LIMIT 1
"""), {"date": evt_date}).fetchone()
if next_day_result:
trading_day, start_time, end_time = next_day_result[0].date(), market_open, market_close
# 如果有有效的交易日且不在未来,查询涨跌幅
if trading_day and trading_day <= cur_time.date():
start_dt = datetime.combine(trading_day, start_time)
end_dt = datetime.combine(trading_day, end_time)
# 查询第一个bar和最后一个bar的价格
price_data = client.execute("""
WITH first_price AS (
SELECT close FROM stock_minute
WHERE code = %(code)s AND timestamp >= %(start)s AND timestamp <= %(end)s
ORDER BY timestamp LIMIT 1
),
last_price AS (
SELECT close FROM stock_minute
WHERE code = %(code)s AND timestamp >= %(start)s AND timestamp <= %(end)s
ORDER BY timestamp DESC LIMIT 1
)
SELECT first_price.close as first_price,
last_price.close as last_price,
(last_price.close - first_price.close) / first_price.close * 100 as change_pct
FROM last_price CROSS JOIN first_price
WHERE EXISTS (SELECT 1 FROM first_price) AND EXISTS (SELECT 1 FROM last_price)
""", {'code': stock.stock_code, 'start': start_dt, 'end': end_dt})
if price_data and price_data[0] and price_data[0][0] is not None:
first_price = float(price_data[0][0])
current_price = float(price_data[0][1])
change_pct = float(price_data[0][2])
change_amount = current_price - first_price
except Exception as e:
print(f"计算事件涨跌幅失败 {stock.stock_code}: {e}")
# 如果ClickHouse没有数据fallback到原来的逻辑
if change_pct is None:
if latest_trade and prev_trade:
if prev_trade.F007N and prev_trade.F007N != 0:
change_amount = float(latest_trade.F007N) - float(prev_trade.F007N)
change_pct = (change_amount / float(prev_trade.F007N)) * 100
elif latest_trade and latest_trade.F010N:
change_pct = float(latest_trade.F010N)
change_amount = float(latest_trade.F009N) if latest_trade.F009N else None
# 如果还没有当前价格使用latest_trade
if current_price is None and latest_trade and latest_trade.F007N:
current_price = float(latest_trade.F007N)