gg
This commit is contained in:
@@ -1,145 +0,0 @@
|
||||
"""
|
||||
Diagnostic Backtest - Hangi Pazar Kanıyor?
|
||||
===========================================
|
||||
Analyses the 500 matches to see WHICH markets are losing money.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import time
|
||||
import psycopg2
|
||||
from psycopg2.extras import RealDictCursor
|
||||
from collections import defaultdict
|
||||
|
||||
AI_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
ROOT_DIR = os.path.dirname(AI_DIR)
|
||||
sys.path.insert(0, ROOT_DIR)
|
||||
if "scripts" in os.path.basename(AI_DIR):
|
||||
ROOT_DIR = os.path.dirname(ROOT_DIR)
|
||||
|
||||
from services.single_match_orchestrator import get_single_match_orchestrator
|
||||
|
||||
def get_clean_dsn() -> str:
|
||||
return "postgresql://suggestbet:SuGGesT2026SecuRe@localhost:15432/boilerplate_db"
|
||||
|
||||
def run_diagnostic():
|
||||
print("🔍 TANI BACKTESTİ: NEREDE KAYBETTİK?")
|
||||
print("="*60)
|
||||
|
||||
leagues_path = os.path.join(ROOT_DIR, "top_leagues.json")
|
||||
with open(leagues_path, 'r') as f:
|
||||
top_leagues = json.load(f)
|
||||
league_ids = tuple(str(lid) for lid in top_leagues)
|
||||
|
||||
dsn = get_clean_dsn()
|
||||
conn = psycopg2.connect(dsn)
|
||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||
|
||||
cur.execute("""
|
||||
SELECT m.id, m.match_name, m.home_team_id, m.away_team_id,
|
||||
m.score_home, m.score_away, m.league_id,
|
||||
t1.name as home_team, t2.name as away_team
|
||||
FROM matches m
|
||||
LEFT JOIN teams t1 ON m.home_team_id = t1.id
|
||||
LEFT JOIN teams t2 ON m.away_team_id = t2.id
|
||||
WHERE m.league_id IN %s
|
||||
AND m.status = 'FT'
|
||||
AND m.score_home IS NOT NULL
|
||||
AND EXISTS (SELECT 1 FROM odd_categories oc WHERE oc.match_id = m.id)
|
||||
ORDER BY m.mst_utc DESC
|
||||
LIMIT 500
|
||||
""", (league_ids,))
|
||||
|
||||
rows = cur.fetchall()
|
||||
print(f"📊 {len(rows)} maç analiz ediliyor...\n")
|
||||
|
||||
try: orchestrator = get_single_match_orchestrator()
|
||||
except Exception as e:
|
||||
print(f"❌ AI Hatası: {e}")
|
||||
return
|
||||
|
||||
# Market Stats: { "MS": {"won": 10, "lost": 20, "profit": -5.0}, ... }
|
||||
market_stats = defaultdict(lambda: {"won": 0, "lost": 0, "profit": 0.0, "total": 0})
|
||||
|
||||
for i, row in enumerate(rows):
|
||||
match_id = str(row['id'])
|
||||
h_score = row['score_home'] or 0
|
||||
a_score = row['score_away'] or 0
|
||||
|
||||
try:
|
||||
pred = orchestrator.analyze_match(match_id)
|
||||
if not pred: continue
|
||||
|
||||
candidates = []
|
||||
if pred.get("expert_recommendation"):
|
||||
rec = pred["expert_recommendation"]
|
||||
if rec.get("main_pick"): candidates.append(rec["main_pick"])
|
||||
if rec.get("value_picks"): candidates.extend(rec["value_picks"])
|
||||
elif pred.get("main_pick"):
|
||||
candidates.append(pred["main_pick"])
|
||||
|
||||
played_this = False
|
||||
for c in candidates:
|
||||
if not c: continue
|
||||
conf = c.get("confidence", 0)
|
||||
odds = c.get("odds", 0)
|
||||
pick = str(c.get("pick")).upper()
|
||||
market_type = c.get("market_type", "Unknown")
|
||||
|
||||
# Criteria
|
||||
if conf >= 60 and odds > 1.10:
|
||||
implied = 1.0 / odds
|
||||
edge = ((conf/100) - implied) * 100
|
||||
if edge > -2.0:
|
||||
# Resolve
|
||||
won = False
|
||||
if pick in ["1", "MS 1"] and h_score > a_score: won = True
|
||||
elif pick in ["X", "MS X"] and h_score == a_score: won = True
|
||||
elif pick in ["2", "MS 2"] and a_score > h_score: won = True
|
||||
elif pick in ["1X", "X2"]:
|
||||
if "1X" in pick and h_score >= a_score: won = True
|
||||
elif "X2" in pick and a_score >= h_score: won = True
|
||||
elif pick == "12" and h_score != a_score: won = True
|
||||
elif "ÜST" in pick or "OVER" in pick:
|
||||
line = 2.5
|
||||
if "1.5" in pick: line = 1.5
|
||||
elif "3.5" in pick: line = 3.5
|
||||
if (h_score + a_score) > line: won = True
|
||||
elif "ALT" in pick or "UNDER" in pick:
|
||||
line = 2.5
|
||||
if "1.5" in pick: line = 1.5
|
||||
elif "3.5" in pick: line = 3.5
|
||||
if (h_score + a_score) < line: won = True
|
||||
elif "VAR" in pick and h_score > 0 and a_score > 0: won = True
|
||||
elif "YOK" in pick and (h_score == 0 or a_score == 0): won = True
|
||||
|
||||
market_stats[market_type]["total"] += 1
|
||||
if won:
|
||||
market_stats[market_type]["won"] += 1
|
||||
market_stats[market_type]["profit"] += (odds - 1.0)
|
||||
else:
|
||||
market_stats[market_type]["lost"] += 1
|
||||
market_stats[market_type]["profit"] -= 1.0
|
||||
|
||||
played_this = True
|
||||
break # Only one bet per match
|
||||
|
||||
except: pass
|
||||
|
||||
# Print Results
|
||||
print("\n" + "="*60)
|
||||
print("📊 PAZAR BAZLI KAR/ZARAR TABLOSU")
|
||||
print("="*60)
|
||||
print(f"{'Market':<15} {'Oynanan':<10} {'Kazanılan':<10} {'Win%':<8} {'Kâr':<10}")
|
||||
print("-" * 60)
|
||||
|
||||
for mkt, stats in sorted(market_stats.items(), key=lambda x: x[1]["profit"], reverse=True):
|
||||
wr = (stats["won"] / stats["total"] * 100) if stats["total"] > 0 else 0
|
||||
print(f"{mkt:<15} {stats['total']:<10} {stats['won']:<10} {wr:.1f}% {stats['profit']:+.2f} Units")
|
||||
|
||||
cur.close()
|
||||
conn.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
run_diagnostic()
|
||||
Reference in New Issue
Block a user