diff --git a/backend_api_python/app/data_sources/polymarket.py b/backend_api_python/app/data_sources/polymarket.py index 4eac4c6..3f2a64e 100644 --- a/backend_api_python/app/data_sources/polymarket.py +++ b/backend_api_python/app/data_sources/polymarket.py @@ -262,18 +262,26 @@ class PolymarketDataSource: cur.close() if rows: - return [{ - "market_id": str(row.get('market_id') or ''), - "question": row.get('question') or '', - "category": row.get('category') or 'other', - "current_probability": float(row.get('current_probability') or 0), - "volume_24h": float(row.get('volume_24h') or 0), - "liquidity": float(row.get('liquidity') or 0), - "end_date_iso": row.get('end_date_iso'), - "status": row.get('status') or 'active', - "outcome_tokens": row.get('outcome_tokens') if row.get('outcome_tokens') else {}, - "polymarket_url": f"https://polymarket.com/event/{row.get('market_id') or ''}" - } for row in rows] + result = [] + for row in rows: + market_id = str(row.get('market_id') or '') + slug = row.get('slug') + # 确保使用正确的URL构建方法 + polymarket_url = self._build_polymarket_url(slug, market_id) + result.append({ + "market_id": market_id, + "question": row.get('question') or '', + "category": row.get('category') or 'other', + "current_probability": float(row.get('current_probability') or 0), + "volume_24h": float(row.get('volume_24h') or 0), + "liquidity": float(row.get('liquidity') or 0), + "end_date_iso": row.get('end_date_iso'), + "status": row.get('status') or 'active', + "outcome_tokens": row.get('outcome_tokens') if row.get('outcome_tokens') else {}, + "polymarket_url": polymarket_url, + "slug": slug if slug and not str(slug).isdigit() else None + }) + return result return None except Exception as e: diff --git a/backend_api_python/app/routes/polymarket.py b/backend_api_python/app/routes/polymarket.py index c8952e4..341f3b4 100644 --- a/backend_api_python/app/routes/polymarket.py +++ b/backend_api_python/app/routes/polymarket.py @@ -160,13 +160,20 @@ def get_markets(): opportunity_markets = markets[:min(limit, len(markets))] # 排序和筛选 + # 辅助函数:安全获取 ai_analysis 数据(处理 None 情况) + def safe_get_ai_analysis(market, key, default=0): + ai_analysis = market.get('ai_analysis') + if ai_analysis is None: + return default + return ai_analysis.get(key, default) or default + if sort_by == "ai_score": # 按AI机会评分排序(高概率/高回报比优先) opportunity_markets.sort( key=lambda x: ( - x.get('ai_analysis', {}).get('opportunity_score', 0) or 0, - abs(x.get('ai_analysis', {}).get('divergence', 0) or 0), # 差异越大越好 - x.get('ai_analysis', {}).get('confidence_score', 0) or 0 # 置信度越高越好 + safe_get_ai_analysis(x, 'opportunity_score', 0), + abs(safe_get_ai_analysis(x, 'divergence', 0)), # 差异越大越好 + safe_get_ai_analysis(x, 'confidence_score', 0) # 置信度越高越好 ), reverse=True ) @@ -174,8 +181,8 @@ def get_markets(): # 高概率机会:AI预测概率 > 市场概率 + 10% opportunity_markets.sort( key=lambda x: ( - x.get('ai_analysis', {}).get('ai_predicted_probability', 0) or 0, - x.get('ai_analysis', {}).get('confidence_score', 0) or 0 + safe_get_ai_analysis(x, 'ai_predicted_probability', 0), + safe_get_ai_analysis(x, 'confidence_score', 0) ), reverse=True ) @@ -183,9 +190,9 @@ def get_markets(): # 高回报比机会:AI与市场差异大且置信度高 opportunity_markets.sort( key=lambda x: ( - abs(x.get('ai_analysis', {}).get('divergence', 0) or 0) * - (x.get('ai_analysis', {}).get('confidence_score', 0) or 0) / 100, - x.get('ai_analysis', {}).get('opportunity_score', 0) or 0 + abs(safe_get_ai_analysis(x, 'divergence', 0)) * + safe_get_ai_analysis(x, 'confidence_score', 0) / 100, + safe_get_ai_analysis(x, 'opportunity_score', 0) ), reverse=True ) diff --git a/backend_api_python/app/services/market_data_collector.py b/backend_api_python/app/services/market_data_collector.py index 094cd97..3f55ec6 100644 --- a/backend_api_python/app/services/market_data_collector.py +++ b/backend_api_python/app/services/market_data_collector.py @@ -1242,6 +1242,18 @@ class MarketDataCollector: market_id = market_data.get('market_id') if market_id and market_id not in seen: seen.add(market_id) + # 构建正确的 Polymarket URL + # 优先使用已有的 polymarket_url,如果没有则根据 slug 或 market_id 构建 + polymarket_url = market_data.get('polymarket_url') + if not polymarket_url: + slug = market_data.get('slug') + if slug and not str(slug).isdigit() and ('-' in str(slug) or any(c.isalpha() for c in str(slug))): + # 使用有效的 slug + polymarket_url = f"https://polymarket.com/event/{slug}" + else: + # 使用 markets 端点(更可靠) + polymarket_url = f"https://polymarket.com/markets/{market_id}" + result.append({ "market_id": market_id, "question": market_data.get('question', ''), @@ -1249,7 +1261,7 @@ class MarketDataCollector: "volume_24h": market_data.get('volume_24h', 0), "liquidity": market_data.get('liquidity', 0), "category": market_data.get('category', 'other'), - "polymarket_url": market_data.get('polymarket_url', f"https://polymarket.com/event/{market_id}") + "polymarket_url": polymarket_url }) logger.info(f"Total {len(result)} unique Polymarket events found for {symbol}")