community增加事件详情

This commit is contained in:
2026-01-08 17:45:28 +08:00
parent e3b13324a3
commit 46b1f2452f
2 changed files with 544 additions and 0 deletions

182
app.py
View File

@@ -10998,6 +10998,188 @@ def get_zt_theme_scatter():
}), 500
@app.route('/api/v1/events/effectiveness-stats', methods=['GET'])
def get_events_effectiveness_stats():
"""获取事件有效性统计数据
按交易日统计事件数据,展示事件预测的有效性
参数:
date: 指定日期YYYY-MM-DD格式可选默认今天
days: 统计天数默认7天
返回:
{
success: true,
data: {
currentDate: "2026-01-08",
summary: {
totalEvents: 150, // 总事件数
avgChg: 2.35, // 平均涨幅
maxChg: 15.8, // 最大涨幅
positiveRate: 68.5, // 正收益率
avgInvestScore: 65, // 平均投资评分
avgSurpriseScore: 58 // 平均超预期得分
},
dailyStats: [
{
date: "2026-01-08",
eventCount: 25,
avgChg: 1.85,
maxChg: 8.5,
positiveCount: 18,
topEvents: [...] // 当日表现最好的事件
},
...
],
topPerformers: [...] // 近期表现最好的事件
}
}
"""
try:
date_str = request.args.get('date', '')
days = request.args.get('days', 7, type=int)
days = min(max(days, 1), 30) # 限制1-30天
# 确定查询日期范围
if date_str:
try:
end_date = datetime.strptime(date_str, '%Y-%m-%d')
except ValueError:
end_date = datetime.now()
else:
end_date = datetime.now()
start_date = end_date - timedelta(days=days)
# 查询事件数据
events_query = db.session.query(Event).filter(
Event.created_at >= start_date,
Event.created_at <= end_date + timedelta(days=1),
Event.status == 'active'
).order_by(Event.created_at.desc()).all()
if not events_query:
return jsonify({
'success': True,
'data': {
'currentDate': end_date.strftime('%Y-%m-%d'),
'summary': {
'totalEvents': 0,
'avgChg': 0,
'maxChg': 0,
'positiveRate': 0,
'avgInvestScore': 0,
'avgSurpriseScore': 0
},
'dailyStats': [],
'topPerformers': []
}
})
# 计算汇总统计
total_events = len(events_query)
avg_chg_list = [e.related_avg_chg for e in events_query if e.related_avg_chg is not None]
max_chg_list = [e.related_max_chg for e in events_query if e.related_max_chg is not None]
invest_scores = [e.invest_score for e in events_query if e.invest_score is not None]
surprise_scores = [e.expectation_surprise_score for e in events_query if e.expectation_surprise_score is not None]
positive_count = sum(1 for chg in avg_chg_list if chg > 0)
summary = {
'totalEvents': total_events,
'avgChg': round(sum(avg_chg_list) / len(avg_chg_list), 2) if avg_chg_list else 0,
'maxChg': round(max(max_chg_list), 2) if max_chg_list else 0,
'positiveRate': round(positive_count / len(avg_chg_list) * 100, 1) if avg_chg_list else 0,
'avgInvestScore': round(sum(invest_scores) / len(invest_scores)) if invest_scores else 0,
'avgSurpriseScore': round(sum(surprise_scores) / len(surprise_scores)) if surprise_scores else 0
}
# 按日期分组统计
daily_data = {}
for event in events_query:
date_key = event.created_at.strftime('%Y-%m-%d')
if date_key not in daily_data:
daily_data[date_key] = {
'date': date_key,
'events': [],
'avgChgList': [],
'maxChgList': []
}
daily_data[date_key]['events'].append({
'id': event.id,
'title': event.title[:50] if event.title else '',
'eventType': event.event_type,
'avgChg': event.related_avg_chg,
'maxChg': event.related_max_chg,
'investScore': event.invest_score,
'surpriseScore': event.expectation_surprise_score,
'indType': event.ind_type,
})
if event.related_avg_chg is not None:
daily_data[date_key]['avgChgList'].append(event.related_avg_chg)
if event.related_max_chg is not None:
daily_data[date_key]['maxChgList'].append(event.related_max_chg)
# 处理每日统计
daily_stats = []
for date_key in sorted(daily_data.keys(), reverse=True):
day = daily_data[date_key]
avg_list = day['avgChgList']
max_list = day['maxChgList']
# 找出当日表现最好的事件(按最大涨幅排序)
top_events = sorted(day['events'], key=lambda x: x['maxChg'] or 0, reverse=True)[:3]
daily_stats.append({
'date': date_key,
'eventCount': len(day['events']),
'avgChg': round(sum(avg_list) / len(avg_list), 2) if avg_list else 0,
'maxChg': round(max(max_list), 2) if max_list else 0,
'positiveCount': sum(1 for chg in avg_list if chg > 0),
'topEvents': top_events
})
# 找出表现最好的事件(全局)
top_performers = sorted(
[e for e in events_query if e.related_max_chg is not None],
key=lambda x: x.related_max_chg,
reverse=True
)[:10]
top_performers_list = [{
'id': e.id,
'title': e.title[:60] if e.title else '',
'eventType': e.event_type,
'avgChg': e.related_avg_chg,
'maxChg': e.related_max_chg,
'investScore': e.invest_score,
'surpriseScore': e.expectation_surprise_score,
'indType': e.ind_type,
'createdAt': e.created_at.strftime('%Y-%m-%d %H:%M') if e.created_at else '',
} for e in top_performers]
return jsonify({
'success': True,
'data': {
'currentDate': end_date.strftime('%Y-%m-%d'),
'summary': summary,
'dailyStats': daily_stats,
'topPerformers': top_performers_list
}
})
except Exception as e:
import traceback
traceback.print_exc()
return jsonify({
'success': False,
'error': str(e)
}), 500
@app.route('/api/v1/calendar/events', methods=['GET'])
def get_calendar_events():
"""获取指定日期的事件列表"""