update pay function
This commit is contained in:
BIN
__pycache__/app_vx.cpython-310.pyc
Normal file
BIN
__pycache__/app_vx.cpython-310.pyc
Normal file
Binary file not shown.
6352
app_vx - 副本.py
Normal file
6352
app_vx - 副本.py
Normal file
File diff suppressed because it is too large
Load Diff
315
app_vx.py
315
app_vx.py
@@ -2497,272 +2497,12 @@ def api_get_events():
|
|||||||
|
|
||||||
paginated = query.paginate(page=page, per_page=per_page, error_out=False)
|
paginated = query.paginate(page=page, per_page=per_page, error_out=False)
|
||||||
|
|
||||||
# ==================== 批量获取股票行情数据(优化版) ====================
|
|
||||||
|
|
||||||
# 1. 收集当前页所有事件的ID
|
|
||||||
event_ids = [event.id for event in paginated.items]
|
|
||||||
|
|
||||||
# 2. 获取所有相关股票
|
|
||||||
all_related_stocks = {}
|
|
||||||
if event_ids:
|
|
||||||
related_stocks = RelatedStock.query.filter(
|
|
||||||
RelatedStock.event_id.in_(event_ids)
|
|
||||||
).all()
|
|
||||||
|
|
||||||
# 按事件ID分组
|
|
||||||
for stock in related_stocks:
|
|
||||||
if stock.event_id not in all_related_stocks:
|
|
||||||
all_related_stocks[stock.event_id] = []
|
|
||||||
all_related_stocks[stock.event_id].append(stock)
|
|
||||||
|
|
||||||
# 3. 收集所有股票代码
|
|
||||||
all_stock_codes = []
|
|
||||||
stock_code_mapping = {} # 清理后的代码 -> 原始代码的映射
|
|
||||||
|
|
||||||
for stocks in all_related_stocks.values():
|
|
||||||
for stock in stocks:
|
|
||||||
clean_code = stock.stock_code.replace('.SH', '').replace('.SZ', '').replace('.BJ', '')
|
|
||||||
all_stock_codes.append(clean_code)
|
|
||||||
stock_code_mapping[clean_code] = stock.stock_code
|
|
||||||
|
|
||||||
# 去重
|
|
||||||
all_stock_codes = list(set(all_stock_codes))
|
|
||||||
|
|
||||||
# 4. 批量查询最近7个交易日的数据(用于计算日涨跌和周涨跌)
|
|
||||||
stock_price_data = {}
|
|
||||||
|
|
||||||
if all_stock_codes:
|
|
||||||
# 构建SQL查询 - 获取最近7个交易日的数据
|
|
||||||
codes_str = "'" + "', '".join(all_stock_codes) + "'"
|
|
||||||
|
|
||||||
# 获取最近7个交易日的数据
|
|
||||||
recent_trades_sql = f"""
|
|
||||||
SELECT
|
|
||||||
SECCODE,
|
|
||||||
SECNAME,
|
|
||||||
F007N as close_price,
|
|
||||||
F010N as daily_change,
|
|
||||||
TRADEDATE,
|
|
||||||
ROW_NUMBER() OVER (PARTITION BY SECCODE ORDER BY TRADEDATE DESC) as rn
|
|
||||||
FROM ea_trade
|
|
||||||
WHERE SECCODE IN ({codes_str})
|
|
||||||
AND F007N IS NOT NULL
|
|
||||||
AND TRADEDATE >= DATE_SUB(CURDATE(), INTERVAL 10 DAY)
|
|
||||||
ORDER BY SECCODE, TRADEDATE DESC
|
|
||||||
"""
|
|
||||||
|
|
||||||
result = db.session.execute(text(recent_trades_sql))
|
|
||||||
|
|
||||||
# 整理数据
|
|
||||||
for row in result.fetchall():
|
|
||||||
sec_code = row[0]
|
|
||||||
if sec_code not in stock_price_data:
|
|
||||||
stock_price_data[sec_code] = {
|
|
||||||
'stock_name': row[1],
|
|
||||||
'prices': []
|
|
||||||
}
|
|
||||||
|
|
||||||
stock_price_data[sec_code]['prices'].append({
|
|
||||||
'close_price': float(row[2]) if row[2] else 0,
|
|
||||||
'daily_change': float(row[3]) if row[3] else 0,
|
|
||||||
'trade_date': row[4],
|
|
||||||
'rank': row[5]
|
|
||||||
})
|
|
||||||
|
|
||||||
# 5. 计算日涨跌和周涨跌
|
|
||||||
stock_changes = {}
|
|
||||||
|
|
||||||
for sec_code, data in stock_price_data.items():
|
|
||||||
prices = data['prices']
|
|
||||||
|
|
||||||
# 最新日涨跌(第1条记录)
|
|
||||||
daily_change = 0
|
|
||||||
if prices and prices[0]['rank'] == 1:
|
|
||||||
daily_change = prices[0]['daily_change']
|
|
||||||
|
|
||||||
# 计算周涨跌(最新价 vs 5个交易日前的价格)
|
|
||||||
week_change = 0
|
|
||||||
if len(prices) >= 2:
|
|
||||||
latest_price = prices[0]['close_price']
|
|
||||||
# 找到第5个交易日的数据(如果有)
|
|
||||||
week_ago_price = None
|
|
||||||
for price_data in prices:
|
|
||||||
if price_data['rank'] >= 5:
|
|
||||||
week_ago_price = price_data['close_price']
|
|
||||||
break
|
|
||||||
|
|
||||||
# 如果没有第5天的数据,使用最早的数据
|
|
||||||
if week_ago_price is None and len(prices) > 1:
|
|
||||||
week_ago_price = prices[-1]['close_price']
|
|
||||||
|
|
||||||
if week_ago_price and week_ago_price > 0:
|
|
||||||
week_change = (latest_price - week_ago_price) / week_ago_price * 100
|
|
||||||
|
|
||||||
stock_changes[sec_code] = {
|
|
||||||
'stock_name': data['stock_name'],
|
|
||||||
'daily_change': daily_change,
|
|
||||||
'week_change': week_change
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==================== 获取整体统计信息(应用所有筛选条件) ====================
|
|
||||||
|
|
||||||
overall_distribution = {
|
|
||||||
'limit_down': 0,
|
|
||||||
'down_over_5': 0,
|
|
||||||
'down_5_to_1': 0,
|
|
||||||
'down_within_1': 0,
|
|
||||||
'flat': 0,
|
|
||||||
'up_within_1': 0,
|
|
||||||
'up_1_to_5': 0,
|
|
||||||
'up_over_5': 0,
|
|
||||||
'limit_up': 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# 使用当前筛选条件的query,但不应用分页限制,获取所有符合条件的事件
|
|
||||||
# 这样统计数据会跟随用户的筛选条件变化
|
|
||||||
all_filtered_events = query.limit(1000).all() # 限制最多1000个事件,避免查询过慢
|
|
||||||
week_event_ids = [e.id for e in all_filtered_events]
|
|
||||||
|
|
||||||
if week_event_ids:
|
|
||||||
# 获取这些事件的所有关联股票
|
|
||||||
week_related_stocks = RelatedStock.query.filter(
|
|
||||||
RelatedStock.event_id.in_(week_event_ids)
|
|
||||||
).all()
|
|
||||||
|
|
||||||
# 按事件ID分组
|
|
||||||
week_stocks_by_event = {}
|
|
||||||
for stock in week_related_stocks:
|
|
||||||
if stock.event_id not in week_stocks_by_event:
|
|
||||||
week_stocks_by_event[stock.event_id] = []
|
|
||||||
week_stocks_by_event[stock.event_id].append(stock)
|
|
||||||
|
|
||||||
# 收集所有股票代码(用于批量查询行情)
|
|
||||||
week_stock_codes = []
|
|
||||||
week_code_mapping = {}
|
|
||||||
for stocks in week_stocks_by_event.values():
|
|
||||||
for stock in stocks:
|
|
||||||
clean_code = stock.stock_code.replace('.SH', '').replace('.SZ', '').replace('.BJ', '')
|
|
||||||
week_stock_codes.append(clean_code)
|
|
||||||
week_code_mapping[clean_code] = stock.stock_code
|
|
||||||
|
|
||||||
week_stock_codes = list(set(week_stock_codes))
|
|
||||||
|
|
||||||
# 批量查询这些股票的最新行情数据
|
|
||||||
week_stock_changes = {}
|
|
||||||
if week_stock_codes:
|
|
||||||
codes_str = "'" + "', '".join(week_stock_codes) + "'"
|
|
||||||
recent_trades_sql = f"""
|
|
||||||
SELECT
|
|
||||||
SECCODE,
|
|
||||||
SECNAME,
|
|
||||||
F010N as daily_change,
|
|
||||||
ROW_NUMBER() OVER (PARTITION BY SECCODE ORDER BY TRADEDATE DESC) as rn
|
|
||||||
FROM ea_trade
|
|
||||||
WHERE SECCODE IN ({codes_str})
|
|
||||||
AND F010N IS NOT NULL
|
|
||||||
AND TRADEDATE >= DATE_SUB(CURDATE(), INTERVAL 3 DAY)
|
|
||||||
ORDER BY SECCODE, TRADEDATE DESC
|
|
||||||
"""
|
|
||||||
|
|
||||||
result = db.session.execute(text(recent_trades_sql))
|
|
||||||
|
|
||||||
for row in result.fetchall():
|
|
||||||
sec_code = row[0]
|
|
||||||
if row[3] == 1: # 只取最新的数据(rn=1)
|
|
||||||
week_stock_changes[sec_code] = {
|
|
||||||
'stock_name': row[1],
|
|
||||||
'daily_change': float(row[2]) if row[2] else 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# 按事件统计平均涨跌幅分布
|
|
||||||
event_avg_changes = {}
|
|
||||||
|
|
||||||
for event in all_filtered_events:
|
|
||||||
event_stocks = week_stocks_by_event.get(event.id, [])
|
|
||||||
if not event_stocks:
|
|
||||||
continue
|
|
||||||
|
|
||||||
total_change = 0
|
|
||||||
valid_count = 0
|
|
||||||
|
|
||||||
for stock in event_stocks:
|
|
||||||
clean_code = stock.stock_code.replace('.SH', '').replace('.SZ', '').replace('.BJ', '')
|
|
||||||
if clean_code in week_stock_changes:
|
|
||||||
daily_change = week_stock_changes[clean_code]['daily_change']
|
|
||||||
total_change += daily_change
|
|
||||||
valid_count += 1
|
|
||||||
|
|
||||||
if valid_count > 0:
|
|
||||||
avg_change = total_change / valid_count
|
|
||||||
event_avg_changes[event.id] = avg_change
|
|
||||||
|
|
||||||
# 统计事件平均涨跌幅的分布
|
|
||||||
for event_id, avg_change in event_avg_changes.items():
|
|
||||||
# 对于事件平均涨幅,不使用涨跌停分类,使用通用分类
|
|
||||||
if avg_change <= -10:
|
|
||||||
overall_distribution['limit_down'] += 1
|
|
||||||
elif avg_change >= 10:
|
|
||||||
overall_distribution['limit_up'] += 1
|
|
||||||
elif avg_change > 5:
|
|
||||||
overall_distribution['up_over_5'] += 1
|
|
||||||
elif avg_change > 1:
|
|
||||||
overall_distribution['up_1_to_5'] += 1
|
|
||||||
elif avg_change > 0.1:
|
|
||||||
overall_distribution['up_within_1'] += 1
|
|
||||||
elif avg_change >= -0.1:
|
|
||||||
overall_distribution['flat'] += 1
|
|
||||||
elif avg_change > -1:
|
|
||||||
overall_distribution['down_within_1'] += 1
|
|
||||||
elif avg_change > -5:
|
|
||||||
overall_distribution['down_5_to_1'] += 1
|
|
||||||
else:
|
|
||||||
overall_distribution['down_over_5'] += 1
|
|
||||||
|
|
||||||
# ==================== 构建响应数据 ====================
|
# ==================== 构建响应数据 ====================
|
||||||
|
|
||||||
events_data = []
|
events_data = []
|
||||||
for event in paginated.items:
|
for event in paginated.items:
|
||||||
event_stocks = all_related_stocks.get(event.id, [])
|
|
||||||
stocks_data = []
|
|
||||||
|
|
||||||
total_daily_change = 0
|
# 构建事件数据(简化版,只包含基本信息和涨跌幅)
|
||||||
max_daily_change = -999
|
|
||||||
total_week_change = 0
|
|
||||||
max_week_change = -999
|
|
||||||
valid_stocks_count = 0
|
|
||||||
|
|
||||||
# 处理每个股票的数据
|
|
||||||
for stock in event_stocks:
|
|
||||||
clean_code = stock.stock_code.replace('.SH', '').replace('.SZ', '').replace('.BJ', '')
|
|
||||||
stock_info = stock_changes.get(clean_code, {})
|
|
||||||
|
|
||||||
daily_change = stock_info.get('daily_change', 0)
|
|
||||||
week_change = stock_info.get('week_change', 0)
|
|
||||||
|
|
||||||
if stock_info:
|
|
||||||
total_daily_change += daily_change
|
|
||||||
max_daily_change = max(max_daily_change, daily_change)
|
|
||||||
total_week_change += week_change
|
|
||||||
max_week_change = max(max_week_change, week_change)
|
|
||||||
valid_stocks_count += 1
|
|
||||||
|
|
||||||
stocks_data.append({
|
|
||||||
"stock_code": stock.stock_code,
|
|
||||||
"stock_name": stock.stock_name,
|
|
||||||
"sector": stock.sector,
|
|
||||||
"week_change": round(week_change, 2),
|
|
||||||
"daily_change": round(daily_change, 2)
|
|
||||||
})
|
|
||||||
|
|
||||||
avg_daily_change = total_daily_change / valid_stocks_count if valid_stocks_count > 0 else 0
|
|
||||||
avg_week_change = total_week_change / valid_stocks_count if valid_stocks_count > 0 else 0
|
|
||||||
|
|
||||||
if max_daily_change == -999:
|
|
||||||
max_daily_change = 0
|
|
||||||
if max_week_change == -999:
|
|
||||||
max_week_change = 0
|
|
||||||
|
|
||||||
# 构建事件数据
|
|
||||||
event_dict = {
|
event_dict = {
|
||||||
'id': event.id,
|
'id': event.id,
|
||||||
'title': event.title,
|
'title': event.title,
|
||||||
@@ -2774,34 +2514,26 @@ def api_get_events():
|
|||||||
'updated_at': event.updated_at.isoformat() if event.updated_at else None,
|
'updated_at': event.updated_at.isoformat() if event.updated_at else None,
|
||||||
'start_time': event.start_time.isoformat() if event.start_time else None,
|
'start_time': event.start_time.isoformat() if event.start_time else None,
|
||||||
'end_time': event.end_time.isoformat() if event.end_time else None,
|
'end_time': event.end_time.isoformat() if event.end_time else None,
|
||||||
'related_stocks': stocks_data,
|
# 涨跌幅数据(从数据库字段直接获取)
|
||||||
'stocks_stats': {
|
'related_avg_chg': event.related_avg_chg, # 平均涨跌幅
|
||||||
'stocks_count': len(event_stocks),
|
'related_max_chg': event.related_max_chg, # 最大涨跌幅
|
||||||
'valid_stocks_count': valid_stocks_count,
|
'related_week_chg': event.related_week_chg, # 周涨跌幅
|
||||||
# 周涨跌统计
|
# 关联股票数量(固定值)
|
||||||
'avg_week_change': round(avg_week_change, 2),
|
'stocks_count': 10
|
||||||
'max_week_change': round(max_week_change, 2),
|
|
||||||
# 日涨跌统计
|
|
||||||
'avg_daily_change': round(avg_daily_change, 2),
|
|
||||||
'max_daily_change': round(max_daily_change, 2)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# 统计信息
|
# 统计信息(可选)
|
||||||
if include_stats:
|
if include_stats:
|
||||||
event_dict.update({
|
event_dict.update({
|
||||||
'hot_score': event.hot_score,
|
'hot_score': event.hot_score,
|
||||||
'view_count': event.view_count,
|
'view_count': event.view_count,
|
||||||
'post_count': event.post_count,
|
'post_count': event.post_count,
|
||||||
'follower_count': event.follower_count,
|
'follower_count': event.follower_count,
|
||||||
'related_avg_chg': event.related_avg_chg,
|
|
||||||
'related_max_chg': event.related_max_chg,
|
|
||||||
'related_week_chg': event.related_week_chg,
|
|
||||||
'invest_score': event.invest_score,
|
'invest_score': event.invest_score,
|
||||||
'trending_score': event.trending_score,
|
'trending_score': event.trending_score,
|
||||||
})
|
})
|
||||||
|
|
||||||
# 创建者信息
|
# 创建者信息(可选)
|
||||||
if include_creator:
|
if include_creator:
|
||||||
event_dict['creator'] = {
|
event_dict['creator'] = {
|
||||||
'id': event.creator.id if event.creator else None,
|
'id': event.creator.id if event.creator else None,
|
||||||
@@ -2815,25 +2547,6 @@ def api_get_events():
|
|||||||
event_dict['keywords'] = event.keywords if isinstance(event.keywords, list) else []
|
event_dict['keywords'] = event.keywords if isinstance(event.keywords, list) else []
|
||||||
event_dict['related_industries'] = event.related_industries
|
event_dict['related_industries'] = event.related_industries
|
||||||
|
|
||||||
# 包含统计信息
|
|
||||||
if include_stats:
|
|
||||||
event_dict['stats'] = {
|
|
||||||
'related_stocks_count': len(event_stocks),
|
|
||||||
'historical_events_count': 0, # 需要额外查询
|
|
||||||
'related_data_count': 0, # 需要额外查询
|
|
||||||
'related_concepts_count': 0 # 需要额外查询
|
|
||||||
}
|
|
||||||
|
|
||||||
# 包含关联数据
|
|
||||||
if include_related_data:
|
|
||||||
event_dict['related_stocks'] = [{
|
|
||||||
'id': stock.id,
|
|
||||||
'stock_code': stock.stock_code,
|
|
||||||
'stock_name': stock.stock_name,
|
|
||||||
'sector': stock.sector,
|
|
||||||
'correlation': float(stock.correlation) if stock.correlation else 0
|
|
||||||
} for stock in event_stocks[:5]] # 限制返回5个
|
|
||||||
|
|
||||||
events_data.append(event_dict)
|
events_data.append(event_dict)
|
||||||
|
|
||||||
# ==================== 构建筛选信息 ====================
|
# ==================== 构建筛选信息 ====================
|
||||||
@@ -2860,7 +2573,7 @@ def api_get_events():
|
|||||||
applied_filters['search_query'] = search_query
|
applied_filters['search_query'] = search_query
|
||||||
applied_filters['search_type'] = search_type
|
applied_filters['search_type'] = search_type
|
||||||
|
|
||||||
# ==================== 返回结果(保持完全兼容) ====================
|
# ==================== 返回结果(简化版) ====================
|
||||||
|
|
||||||
return jsonify({
|
return jsonify({
|
||||||
'success': True,
|
'success': True,
|
||||||
@@ -2884,14 +2597,6 @@ def api_get_events():
|
|||||||
'sort': sort_by,
|
'sort': sort_by,
|
||||||
'order': order
|
'order': order
|
||||||
}
|
}
|
||||||
},
|
|
||||||
# 整体股票涨跌幅分布统计
|
|
||||||
'overall_stats': {
|
|
||||||
'total_stocks': len(all_stocks_for_stats) if 'all_stocks_for_stats' in locals() else 0,
|
|
||||||
'change_distribution': overall_distribution,
|
|
||||||
'change_distribution_percentages': {
|
|
||||||
k: v for k, v in overall_distribution.items()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user