All pastes #7BMCECEe3L Raw Edit

python paste

public python v1 · immutable
#7BMCECEe3L ·published 2026-09-11 04:51 UTC ·by bbin123
rendered paste body
        # ---- 数据完整性检查:如果排名缺失,尝试AI补全 ----        if home_rank is None or away_rank is None:            if AI_COMPLETE_MISSING_RANK:                print(f"  🔄 {match.get('match_num', '')} {match.get('home_team', '')} vs {match.get('away_team', '')} 排名缺失,尝试AI补全...")                                ai_data = ai_complete_missing_data(                    match,                    match.get('home_team', ''),                    match.get('away_team', ''),                    league                )                                if ai_data:                    home_rank = ai_data['home_rank']                    away_rank = ai_data['away_rank']                    home_strength = ai_data['home_strength']                    away_strength = ai_data['away_strength']                    ai_completed = True                    print(f"  ✅ AI补全完成: 主{home_rank}位({home_strength:.1f}),客{away_rank}位({away_strength:.1f}),置信度:{ai_data.get('confidence', '未知')}")                else:                    print(f"  ⏭️ AI补全失败,跳过该场")                    continue            else:                print(f"  ⏭️ {match.get('match_num', '')} {match.get('home_team', '')} vs {match.get('away_team', '')} 排名缺失(AI补全已关闭),跳过")                continue        else:            # 排名存在,正常计算            home_rank = int(home_rank)            away_rank = int(away_rank)            # 正常计算实力分            home_strength = calculate_strength(home_preview, True, league_params)            away_strength = calculate_strength(away_preview, False, league_params)            ai_completed = False        # 确保实力分有值        if home_strength is None or away_strength is None:            print(f"  ⚠️ 实力分缺失,跳过")            continue        # ---- 计算预期进球(新增这一行) ----        home_xg, away_xg = expected_goals(home_strength, away_strength, league_params)        result = {            'match_num': match['match_num'],            'ai_completed': ai_completed,            'home_team': match['home_team'],            'away_team': match['away_team'],            'league': league,            'strength': {'home': home_strength, 'away': away_strength},            'rank': {'home': home_rank, 'away': away_rank},            'expected_goals': {'home': round(home_xg, 2), 'away': round(away_xg, 2)},            'odds': {                'spf': match.get('spf', []),                'rqspf': match.get('rqspf', []),                'total_goals': match.get('total_goals', []),                'score': match.get('score', []),                'half_full': match.get('half_full', [])            },            'handicap': match.get('handicap', '0'),            'recommendations': [],            'trial_recommendations': [],            'ai_analysis': None,            'comparison': None        }                # ---- 各玩法分析 ----        bias_signals = []        trial_signals = []        skip_ai = False        spf_result = analyze_spf(home_strength, away_strength, match.get('spf', []), league_params)        if spf_result:            if 'reverse' in spf_result:                rev = spf_result['reverse']                bias_signals.append({                    'play': 'SPF',                    'option': rev['recommend'],                    'bias': rev['recommend_bias'],                    'signal_type': '反向挖掘',                    'match_id': mid                })            else:                max_key = max(spf_result['bias'], key=lambda k: abs(spf_result['bias'][k]))                if abs(spf_result['bias'][max_key]) > 0.08 and spf_result['bias'][max_key] > 0:                    bias_signals.append({                        'play': 'SPF',                        'option': max_key,                        'bias': spf_result['bias'][max_key],                        'signal_type': '正向偏差',                        'match_id': mid                    })                rqspf_result = analyze_rqspf(home_strength, away_strength, match.get('rqspf', []), match.get('handicap', '0'), league_params)        if rqspf_result:            if 'reverse' in rqspf_result:                rev = rqspf_result['reverse']                bias_signals.append({                    'play': 'RQSPF',                    'option': rev['recommend'],                    'bias': rev['recommend_bias'],                    'signal_type': '反向挖掘',                    'match_id': mid                })            else:                max_key = max(rqspf_result['bias'], key=lambda k: abs(rqspf_result['bias'][k]))                if abs(rqspf_result['bias'][max_key]) > 0.08 and rqspf_result['bias'][max_key] > 0:                    bias_signals.append({                        'play': 'RQSPF',                        'option': max_key,                        'bias': rqspf_result['bias'][max_key],                        'signal_type': '正向偏差',                        'match_id': mid                    })                tg_result = analyze_total_goals(home_xg, away_xg, match.get('total_goals', []))        if tg_result and tg_result['max_bias'] > 0.15:            bias_signals.append({                'play': '总进球',                'option': TOTAL_GOALS_LABELS[tg_result['max_index']],                'bias': tg_result['max_bias'],                'signal_type': '正向偏差',                'match_id': mid            })                # ---- 平局推荐约束:只在实力接近时推荐 ----        strength_diff = abs(home_strength - away_strength)        before_count = len(bias_signals)        bias_signals = [            s for s in bias_signals             if not (s.get('option') in ['draw', '平局'] and strength_diff >= 20)        ]        if before_count > len(bias_signals):            print(f"  ⚠️ 平局信号被过滤(实力分差{strength_diff:.1f} ≥ 20)")        # ---- 试推演:半全场和比分(仅观察,不进入正式推荐) ----        trial_signals = []                # 半全场试推演        try:            hf_result = analyze_half_full(home_strength, away_strength, match.get('half_full', []), league_params)            if hf_result and hf_result.get('max_bias') is not None:                if abs(hf_result['max_bias']) > 0.05:  # 试推演阈值放宽到5%                    trial_signals.append({                        'play': '半全场',                        'option': hf_result['recommend'],                        'bias': hf_result['max_bias'],                        'signal_type': '试推演',                        'match_id': mid                    })        except Exception as e:            print(f"  ⚠️ 半全场试推演失败: {e}")                # 比分试推演        try:            score_result = analyze_score(home_xg, away_xg, match.get('score', []))            if score_result and score_result.get('max_bias') is not None:                if abs(score_result['max_bias']) > 0.03:  # 试推演阈值放宽到3%                    trial_signals.append({                        'play': '比分',                        'option': score_result['recommend'],                        'bias': score_result['max_bias'],                        'signal_type': '试推演',                        'match_id': mid                    })        except Exception as e:            print(f"  ⚠️ 比分试推演失败: {e}")                # ---- 信心赋值(先赋值,再过滤) ----        for s in bias_signals:            s['confidence'] = '' if abs(s['bias']) > 0.12 else ''                # ---- 只保留高信心信号 ----        bias_signals = [s for s in bias_signals if s['confidence'] == '']        # ---- 🆕 加载历史记录并对比 ----        if mid:            history = load_history_for_match(mid)            if history and len(history) > 0:                prev_record = history[-1]                prev_signals = prev_record.get('recommendations', [])                                # ---- 检查当前信号与历史是否完全相同 ----                if bias_signals and prev_signals and signals_are_identical(bias_signals, prev_signals):                    # 完全一样:直接沿用历史,跳过AI分析                    bias_signals = prev_signals.copy()                    for s in bias_signals:                        s['match_id'] = mid                        if 'signal_type' not in s:                            s['signal_type'] = '历史沿用(无变化)'                    print(f"  ⏭️ 偏差与历史完全相同,直接沿用 ({len(bias_signals)} 条),跳过AI")                    skip_ai = True                    result['comparison'] = {                        'previous_time': prev_record.get('generated_at', '未知'),                        'changes': None,                        'market_analysis': {'recommendation': '无变化,沿用历史'}                    }                else:                    # 有变化或新比赛:正常走对比                    changes = compare_odds_changes(result, prev_record)                    if changes:                        comparison_count += 1                        market_analysis = analyze_market_impact(changes, bias_signals)                        result['comparison'] = {                            'previous_time': prev_record.get('generated_at', '未知'),                            'changes': changes,                            'market_analysis': market_analysis                        }                    else:                        result['comparison'] = {                            'previous_time': prev_record.get('generated_at', '未知'),                            'changes': None,                            'market_analysis': {'recommendation': '无赔率变化'}                        }                                # ---- 当前无信号但有历史推荐,则沿用 ----                if not bias_signals and prev_signals:                    bias_signals = prev_signals.copy()                    for s in bias_signals:                        s['match_id'] = mid                        if 'signal_type' not in s:                            s['signal_type'] = '历史沿用'                    print(f"  📋 沿用历史推荐 ({len(bias_signals)} 条)")                    skip_ai = True            else:                # 没有历史记录                skip_ai = False        else:            skip_ai = False                # ---- AI 分析(如果 skip_ai 为 True,则跳过) ----        if not skip_ai:            need_ai = any(abs(s['bias']) > 0.08 for s in bias_signals)            if need_ai:                ai_output = ai_analyze_match(match, home_strength, away_strength, home_rank, away_rank, bias_signals)                result['ai_analysis'] = ai_output                ai_usage_count += 1                if ai_output.get('修正建议') == '放弃':                    bias_signals = []                elif ai_output.get('修正建议') == '降低信心':                    for s in bias_signals:                        s['confidence'] = ''        else:            # 直接沿用历史,无需AI分析            pass        result['recommendations'] = bias_signals        result['trial_recommendations'] = trial_signals                # ---- 保存历史记录 ----        if mid:            history_record = {                'generated_at': datetime.now().isoformat(),                'match_num': match['match_num'],                'odds': result['odds'],                'handicap': result['handicap'],                'strength': result['strength'],                'recommendations': result['recommendations']            }            save_history_for_match(mid, history_record)        # ---- 生成详细推演分析 ----        detailed = generate_detailed_analysis(match, bias_signals, result.get('comparison'))        result['detailed_analysis'] = detailed                match_results.append(result)                # ---- 终端输出 ----        print(f"【{result['match_num']}{result['home_team']} vs {result['away_team']} ({result['league']})")        print(f"  实力: {home_strength} - {away_strength} (排名:{home_rank} vs {away_rank})")        print(f"  预期进球: {home_xg:.2f} - {away_xg:.2f}")                if result.get('comparison'):            changes = result['comparison'].get('changes')            if changes and isinstance(changes, dict) and len(changes) > 0:                print(f"  📊 赔率变化: 与 {result['comparison']['previous_time'][:16]} 对比")                for key, change in changes.items():                    if isinstance(change, dict) and 'direction' in change:                        print(f"    {key}: {change['from']}{change['to']} ({change['direction']})")            else:                print(f"  📊 赔率变化: 无变化(与 {result['comparison']['previous_time'][:16]} 对比)")                        if result['comparison'].get('market_analysis'):                ma = result['comparison']['market_analysis']                print(f"  📈 市场分析: {ma.get('recommendation', '无变化')}")                for s in ma.get('summary', [])[:3]:                    print(f"    {s}")        if bias_signals:            for s in bias_signals:                print(f"  → {s['play']}: {s['option']} (偏差{s['bias']:+.0%}, 信心:{s.get('confidence', '')})")            print("  " + "-"*40)            for line in detailed.split('\n'):                if line.strip():                    print(f"  {line}")            print("  " + "-"*40)        # ---- 试推演输出(仅观察) ----        if trial_signals:            print(f"  📝 试推演(仅供观察,不投注):")            for t in trial_signals:                print(f"    {t['play']}: {t['option']} (偏差{t['bias']:+.0%})")            if result.get('ai_analysis'):            print(f"  💬 {result['ai_analysis'].get('说明', '')[:60]}")        print()        time.sleep(0.1)        if new_leagues:        print(f"📌 发现 {len(new_leagues)} 个新联赛,已自动生成参数")        # ---- 保存报告(带时间戳,不覆盖) ----    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')        report = {        'generated_at': datetime.now().isoformat(),        'total_matches': len(matches),        'ai_analyzed': ai_usage_count,        'compared_matches': comparison_count,        'new_leagues': new_leagues,        'matches': match_results    }        json_file = os.path.join(DAILY_DIR, f"report_{timestamp}.json")    with open(json_file, 'w', encoding='utf-8') as f:        json.dump(report, f, ensure_ascii=False, indent=2)    print(f"✅ 完整报告已保存: {json_file}")        # ---- 文本摘要 ----    txt_file = os.path.join(SUMMARY_DIR, f"summary_{timestamp}.txt")    with open(txt_file, 'w', encoding='utf-8') as f:        f.write(f"足球预测推演报告 (动态追踪版) - {datetime.now().strftime('%Y-%m-%d %H:%M')}\n")        f.write("=" * 60 + "\n\n")        f.write(f"总场次: {len(matches)}, AI分析: {ai_usage_count}, 赔率对比: {comparison_count}\n\n")        for r in match_results:            f.write(f"【{r['match_num']}{r['home_team']} vs {r['away_team']} ({r['league']})\n")            if r.get('comparison'):                ma = r['comparison'].get('market_analysis', {})                f.write(f"  市场分析: {ma.get('recommendation', '无变化')}\n")            if r['recommendations']:                for s in r['recommendations']:                    f.write(f"  → {s['play']}: {s['option']} (偏差{s['bias']:+.0%})\n")            if r.get('trial_recommendations'):                f.write("  📝 试推演(仅观察):\n")                for t in r['trial_recommendations']:                    f.write(f"    {t['play']}: {t['option']} (偏差{t['bias']:+.0%})\n")            else:                f.write(f"  → 无推荐\n")            if r.get('ai_analysis'):                f.write(f"  💬 {r['ai_analysis'].get('说明', '')}\n")            # ✅ 新增:写入详细推演分析            if r.get('detailed_analysis'):                f.write(r['detailed_analysis'] + "\n")            f.write("\n")    print(f"✅ 文本摘要已保存: {txt_file}")    print(f"📊 共 {len(matches)} 场比赛,AI分析 {ai_usage_count} 场,赔率对比 {comparison_count} 场")if __name__ == '__main__':    main()