LBJLincoln Claude Sonnet 4.6 commited on
Commit
2e1a5f1
·
0 Parent(s):

feat: Nomos42 Pixel World — live 207-agent pixel-art trading floor

Browse files

PixiJS 8 WebGL2 canvas, Pokemon/Stardew-style pixel sprites, 4 tiers
(Gold/Blue/Green/Purple), animated walking agents, click-to-inspect
popups, live leaderboard, Bloomberg terminal desks, day/night cycle,
particle win effects, retro SFX, scrolling ticker, minimap, dept status.
Static HF Space with embedded JSON data fallback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

README.md ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Nomos42 Pixel World
3
+ emoji: 🏀
4
+ colorFrom: indigo
5
+ colorTo: purple
6
+ sdk: static
7
+ pinned: true
8
+ license: mit
9
+ short_description: Live pixel-art trading floor — 207 AI agents betting on NBA
10
+ ---
11
+
12
+ # Nomos42 Pixel World
13
+
14
+ A living, animated pixel-art trading floor where **207 AI agents** walk around, make bets, and compete for best ROI.
15
+
16
+ ## Features
17
+ - **207 AI trading agents** with pixel sprites, 4 tiers (Gold/Blue/Green/Purple)
18
+ - Live leaderboard — top agents by bankroll and ROI
19
+ - Scrolling ticker tape with NBA predictions
20
+ - Department offices: Research, Evolution, Engineering, Infra
21
+ - Day/night cycle + particle effects for big wins
22
+ - Click any agent for full stats popup
23
+ - Bloomberg terminals with live data
24
+ - Retro chip sound effects (toggleable)
25
+ - 60fps PixiJS WebGL2 rendering
26
+
27
+ ## Architecture
28
+ Built on **PixiJS 8** + static HTML. Data fetched from Bloomberg API (port 8042) with JSON fallback.
29
+
30
+ **Tiers:**
31
+ - Gold — Claude, GPT-4o, Grok, Gemini (Premium)
32
+ - Blue — Groq, OpenRouter, Cerebras scouts (Free Power)
33
+ - Green — 176 specialist bots
34
+ - Purple — Paperclip, Hermes, Oracle (Meta)
35
+
36
+ ## Live Data
37
+ - Agent states: bankroll, strategy, ROI, win rate
38
+ - ML predictions: today's NBA games
39
+ - Evolution: Brier score, generation count
40
+ - Space health: 6 HF island status
data/agent-health.json ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "timestamp": "2026-04-04T22:00:36.443223Z",
3
+ "projects": {
4
+ "nba": {
5
+ "name": "NBA Quant AI",
6
+ "spaces": {
7
+ "S10": {
8
+ "status": "UP",
9
+ "brier": 0.22454,
10
+ "generation": 708,
11
+ "model": "xgboost_brier",
12
+ "last_improvement": null,
13
+ "stagnation_cycles": 0
14
+ },
15
+ "S11": {
16
+ "status": "UP",
17
+ "brier": 0.22273,
18
+ "generation": 1405,
19
+ "model": "xgboost",
20
+ "last_improvement": null,
21
+ "stagnation_cycles": 0
22
+ },
23
+ "S12": {
24
+ "status": "UP",
25
+ "brier": 0.22506,
26
+ "generation": 1336,
27
+ "model": "catboost",
28
+ "last_improvement": null,
29
+ "stagnation_cycles": 0
30
+ },
31
+ "S13": {
32
+ "status": "UP",
33
+ "brier": 0.22455,
34
+ "generation": 1018,
35
+ "model": "extra_trees",
36
+ "last_improvement": null,
37
+ "stagnation_cycles": 0
38
+ },
39
+ "S14": {
40
+ "status": "UP",
41
+ "brier": 0.22666,
42
+ "generation": 1070,
43
+ "model": "xgboost_brier",
44
+ "last_improvement": null,
45
+ "stagnation_cycles": 0
46
+ },
47
+ "S15": {
48
+ "status": "UP",
49
+ "brier": 0.22159,
50
+ "generation": 1826,
51
+ "model": "random_forest",
52
+ "last_improvement": null,
53
+ "stagnation_cycles": 0
54
+ }
55
+ },
56
+ "kaggle": {
57
+ "nba-karpathy-loop": {
58
+ "status": "COMPLETE"
59
+ },
60
+ "nba-season-backtest": {
61
+ "status": "COMPLETE"
62
+ }
63
+ }
64
+ },
65
+ "political": {
66
+ "name": "Political Alpha",
67
+ "spaces": {},
68
+ "kaggle": {
69
+ "political-alpha-karpathy-loop": {
70
+ "status": "RUNNING"
71
+ }
72
+ }
73
+ }
74
+ },
75
+ "infra": {
76
+ "data_server": {
77
+ "backtest-results.json": 200,
78
+ "bankroll-state.json": 200,
79
+ "quant-summary.json": 200
80
+ },
81
+ "telegram": {
82
+ "brain": "ALIVE"
83
+ }
84
+ },
85
+ "actions_taken": [],
86
+ "issues": [],
87
+ "summary": {
88
+ "spaces": "6/6 UP",
89
+ "issues": 0,
90
+ "actions": 0,
91
+ "status": "HEALTHY"
92
+ }
93
+ }
data/arena/agent-states-v5.json ADDED
@@ -0,0 +1,3324 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "agent_count": 207,
3
+ "active_count": 207,
4
+ "tiers": {
5
+ "premium": 4,
6
+ "free_power": 20,
7
+ "specialist": 180,
8
+ "meta": 3
9
+ },
10
+ "agents": {
11
+ "t1_claude": {
12
+ "id": "t1_claude",
13
+ "name": "Claude Prime",
14
+ "tier": "PREMIUM",
15
+ "provider": "openai",
16
+ "model": "gpt-4o",
17
+ "strategy": "value_hunter_half_kelly",
18
+ "bankroll": 10000.0,
19
+ "total_bets": 0,
20
+ "total_wins": 0,
21
+ "win_rate": 0.0,
22
+ "roi": 0.0,
23
+ "total_pnl": 0.0,
24
+ "weight": 1.0,
25
+ "active": true
26
+ },
27
+ "t1_gpt4o": {
28
+ "id": "t1_gpt4o",
29
+ "name": "GPT-4o Strategist",
30
+ "tier": "PREMIUM",
31
+ "provider": "openai",
32
+ "model": "gpt-4o",
33
+ "strategy": "proportional_edge",
34
+ "bankroll": 10000.0,
35
+ "total_bets": 0,
36
+ "total_wins": 0,
37
+ "win_rate": 0.0,
38
+ "roi": 0.0,
39
+ "total_pnl": 0.0,
40
+ "weight": 1.0,
41
+ "active": true
42
+ },
43
+ "t1_grok": {
44
+ "id": "t1_grok",
45
+ "name": "Grok Contrarian",
46
+ "tier": "PREMIUM",
47
+ "provider": "xai",
48
+ "model": "grok-3-mini",
49
+ "strategy": "underdog_specialist",
50
+ "bankroll": 10000.0,
51
+ "total_bets": 0,
52
+ "total_wins": 0,
53
+ "win_rate": 0.0,
54
+ "roi": 0.0,
55
+ "total_pnl": 0.0,
56
+ "weight": 1.0,
57
+ "active": true
58
+ },
59
+ "t1_gemini": {
60
+ "id": "t1_gemini",
61
+ "name": "Gemini Analyst",
62
+ "tier": "PREMIUM",
63
+ "provider": "google",
64
+ "model": "gemini-2.0-flash",
65
+ "strategy": "confidence_scaled",
66
+ "bankroll": 10000.0,
67
+ "total_bets": 0,
68
+ "total_wins": 0,
69
+ "win_rate": 0.0,
70
+ "roi": 0.0,
71
+ "total_pnl": 0.0,
72
+ "weight": 1.0,
73
+ "active": true
74
+ },
75
+ "t2_groq_scout_0": {
76
+ "id": "t2_groq_scout_0",
77
+ "name": "Scout Value Hunter",
78
+ "tier": "FREE_POWER",
79
+ "provider": "groq",
80
+ "model": "llama-4-scout-17b-16e-instruct",
81
+ "strategy": "value_hunter",
82
+ "bankroll": 10000.0,
83
+ "total_bets": 0,
84
+ "total_wins": 0,
85
+ "win_rate": 0.0,
86
+ "roi": 0.0,
87
+ "total_pnl": 0.0,
88
+ "weight": 1.0,
89
+ "active": true
90
+ },
91
+ "t2_groq_scout_1": {
92
+ "id": "t2_groq_scout_1",
93
+ "name": "Scout Momentum",
94
+ "tier": "FREE_POWER",
95
+ "provider": "groq",
96
+ "model": "llama-4-scout-17b-16e-instruct",
97
+ "strategy": "half_kelly",
98
+ "bankroll": 10000.0,
99
+ "total_bets": 0,
100
+ "total_wins": 0,
101
+ "win_rate": 0.0,
102
+ "roi": 0.0,
103
+ "total_pnl": 0.0,
104
+ "weight": 1.0,
105
+ "active": true
106
+ },
107
+ "t2_groq_scout_2": {
108
+ "id": "t2_groq_scout_2",
109
+ "name": "Scout Totals Master",
110
+ "tier": "FREE_POWER",
111
+ "provider": "groq",
112
+ "model": "llama-4-scout-17b-16e-instruct",
113
+ "strategy": "proportional_edge",
114
+ "bankroll": 10000.0,
115
+ "total_bets": 0,
116
+ "total_wins": 0,
117
+ "win_rate": 0.0,
118
+ "roi": 0.0,
119
+ "total_pnl": 0.0,
120
+ "weight": 1.0,
121
+ "active": true
122
+ },
123
+ "t2_groq_scout_3": {
124
+ "id": "t2_groq_scout_3",
125
+ "name": "Scout Props Analyst",
126
+ "tier": "FREE_POWER",
127
+ "provider": "groq",
128
+ "model": "llama-4-scout-17b-16e-instruct",
129
+ "strategy": "confidence_scaled",
130
+ "bankroll": 10000.0,
131
+ "total_bets": 0,
132
+ "total_wins": 0,
133
+ "win_rate": 0.0,
134
+ "roi": 0.0,
135
+ "total_pnl": 0.0,
136
+ "weight": 1.0,
137
+ "active": true
138
+ },
139
+ "t2_groq_scout_4": {
140
+ "id": "t2_groq_scout_4",
141
+ "name": "Scout Exotic Eye",
142
+ "tier": "FREE_POWER",
143
+ "provider": "groq",
144
+ "model": "llama-4-scout-17b-16e-instruct",
145
+ "strategy": "quarter_kelly",
146
+ "bankroll": 10000.0,
147
+ "total_bets": 0,
148
+ "total_wins": 0,
149
+ "win_rate": 0.0,
150
+ "roi": 0.0,
151
+ "total_pnl": 0.0,
152
+ "weight": 1.0,
153
+ "active": true
154
+ },
155
+ "t2_groq_llama_0": {
156
+ "id": "t2_groq_llama_0",
157
+ "name": "Llama Flat Diversifier",
158
+ "tier": "FREE_POWER",
159
+ "provider": "groq",
160
+ "model": "llama-3.1-8b-instant",
161
+ "strategy": "flat_2pct",
162
+ "bankroll": 10000.0,
163
+ "total_bets": 0,
164
+ "total_wins": 0,
165
+ "win_rate": 0.0,
166
+ "roi": 0.0,
167
+ "total_pnl": 0.0,
168
+ "weight": 1.0,
169
+ "active": true
170
+ },
171
+ "t2_groq_llama_1": {
172
+ "id": "t2_groq_llama_1",
173
+ "name": "Llama Sharp Shooter",
174
+ "tier": "FREE_POWER",
175
+ "provider": "groq",
176
+ "model": "llama-3.1-8b-instant",
177
+ "strategy": "half_kelly",
178
+ "bankroll": 10000.0,
179
+ "total_bets": 0,
180
+ "total_wins": 0,
181
+ "win_rate": 0.0,
182
+ "roi": 0.0,
183
+ "total_pnl": 0.0,
184
+ "weight": 1.0,
185
+ "active": true
186
+ },
187
+ "t2_groq_llama_2": {
188
+ "id": "t2_groq_llama_2",
189
+ "name": "Llama Value Seeker",
190
+ "tier": "FREE_POWER",
191
+ "provider": "groq",
192
+ "model": "llama-3.1-8b-instant",
193
+ "strategy": "value_hunter",
194
+ "bankroll": 10000.0,
195
+ "total_bets": 0,
196
+ "total_wins": 0,
197
+ "win_rate": 0.0,
198
+ "roi": 0.0,
199
+ "total_pnl": 0.0,
200
+ "weight": 1.0,
201
+ "active": true
202
+ },
203
+ "t2_groq_llama_3": {
204
+ "id": "t2_groq_llama_3",
205
+ "name": "Llama Safety Net",
206
+ "tier": "FREE_POWER",
207
+ "provider": "groq",
208
+ "model": "llama-3.1-8b-instant",
209
+ "strategy": "eighth_kelly",
210
+ "bankroll": 10000.0,
211
+ "total_bets": 0,
212
+ "total_wins": 0,
213
+ "win_rate": 0.0,
214
+ "roi": 0.0,
215
+ "total_pnl": 0.0,
216
+ "weight": 1.0,
217
+ "active": true
218
+ },
219
+ "t2_groq_llama_4": {
220
+ "id": "t2_groq_llama_4",
221
+ "name": "Llama Edge Scaler",
222
+ "tier": "FREE_POWER",
223
+ "provider": "groq",
224
+ "model": "llama-3.1-8b-instant",
225
+ "strategy": "proportional_edge",
226
+ "bankroll": 10000.0,
227
+ "total_bets": 0,
228
+ "total_wins": 0,
229
+ "win_rate": 0.0,
230
+ "roi": 0.0,
231
+ "total_pnl": 0.0,
232
+ "weight": 1.0,
233
+ "active": true
234
+ },
235
+ "t2_or_qwen_0": {
236
+ "id": "t2_or_qwen_0",
237
+ "name": "Qwen ML Specialist",
238
+ "tier": "FREE_POWER",
239
+ "provider": "openrouter",
240
+ "model": "qwen/qwen3-30b-a3b:free",
241
+ "strategy": "half_kelly",
242
+ "bankroll": 10000.0,
243
+ "total_bets": 0,
244
+ "total_wins": 0,
245
+ "win_rate": 0.0,
246
+ "roi": 0.0,
247
+ "total_pnl": 0.0,
248
+ "weight": 1.0,
249
+ "active": true
250
+ },
251
+ "t2_or_qwen_1": {
252
+ "id": "t2_or_qwen_1",
253
+ "name": "Qwen Spread Master",
254
+ "tier": "FREE_POWER",
255
+ "provider": "openrouter",
256
+ "model": "qwen/qwen3-30b-a3b:free",
257
+ "strategy": "value_hunter",
258
+ "bankroll": 10000.0,
259
+ "total_bets": 0,
260
+ "total_wins": 0,
261
+ "win_rate": 0.0,
262
+ "roi": 0.0,
263
+ "total_pnl": 0.0,
264
+ "weight": 1.0,
265
+ "active": true
266
+ },
267
+ "t2_or_qwen_2": {
268
+ "id": "t2_or_qwen_2",
269
+ "name": "Qwen Full Scan",
270
+ "tier": "FREE_POWER",
271
+ "provider": "openrouter",
272
+ "model": "qwen/qwen3-30b-a3b:free",
273
+ "strategy": "confidence_scaled",
274
+ "bankroll": 10000.0,
275
+ "total_bets": 0,
276
+ "total_wins": 0,
277
+ "win_rate": 0.0,
278
+ "roi": 0.0,
279
+ "total_pnl": 0.0,
280
+ "weight": 1.0,
281
+ "active": true
282
+ },
283
+ "t2_or_gemma_0": {
284
+ "id": "t2_or_gemma_0",
285
+ "name": "Gemma Game Reader",
286
+ "tier": "FREE_POWER",
287
+ "provider": "openrouter",
288
+ "model": "google/gemma-3-27b-it:free",
289
+ "strategy": "proportional_edge",
290
+ "bankroll": 10000.0,
291
+ "total_bets": 0,
292
+ "total_wins": 0,
293
+ "win_rate": 0.0,
294
+ "roi": 0.0,
295
+ "total_pnl": 0.0,
296
+ "weight": 1.0,
297
+ "active": true
298
+ },
299
+ "t2_or_gemma_1": {
300
+ "id": "t2_or_gemma_1",
301
+ "name": "Gemma Trend Follower",
302
+ "tier": "FREE_POWER",
303
+ "provider": "openrouter",
304
+ "model": "google/gemma-3-27b-it:free",
305
+ "strategy": "half_kelly",
306
+ "bankroll": 10000.0,
307
+ "total_bets": 0,
308
+ "total_wins": 0,
309
+ "win_rate": 0.0,
310
+ "roi": 0.0,
311
+ "total_pnl": 0.0,
312
+ "weight": 1.0,
313
+ "active": true
314
+ },
315
+ "t2_or_maverick_0": {
316
+ "id": "t2_or_maverick_0",
317
+ "name": "Maverick Dog Hunter",
318
+ "tier": "FREE_POWER",
319
+ "provider": "openrouter",
320
+ "model": "meta-llama/llama-4-maverick:free",
321
+ "strategy": "underdog_specialist",
322
+ "bankroll": 10000.0,
323
+ "total_bets": 0,
324
+ "total_wins": 0,
325
+ "win_rate": 0.0,
326
+ "roi": 0.0,
327
+ "total_pnl": 0.0,
328
+ "weight": 1.0,
329
+ "active": true
330
+ },
331
+ "t2_or_maverick_1": {
332
+ "id": "t2_or_maverick_1",
333
+ "name": "Maverick Value Play",
334
+ "tier": "FREE_POWER",
335
+ "provider": "openrouter",
336
+ "model": "meta-llama/llama-4-maverick:free",
337
+ "strategy": "value_hunter",
338
+ "bankroll": 10000.0,
339
+ "total_bets": 0,
340
+ "total_wins": 0,
341
+ "win_rate": 0.0,
342
+ "roi": 0.0,
343
+ "total_pnl": 0.0,
344
+ "weight": 1.0,
345
+ "active": true
346
+ },
347
+ "t2_cohere_0": {
348
+ "id": "t2_cohere_0",
349
+ "name": "Cohere Analyst",
350
+ "tier": "FREE_POWER",
351
+ "provider": "cohere",
352
+ "model": "command-r-plus",
353
+ "strategy": "half_kelly",
354
+ "bankroll": 10000.0,
355
+ "total_bets": 0,
356
+ "total_wins": 0,
357
+ "win_rate": 0.0,
358
+ "roi": 0.0,
359
+ "total_pnl": 0.0,
360
+ "weight": 1.0,
361
+ "active": true
362
+ },
363
+ "t2_cohere_1": {
364
+ "id": "t2_cohere_1",
365
+ "name": "Cohere Consensus",
366
+ "tier": "FREE_POWER",
367
+ "provider": "cohere",
368
+ "model": "command-r-plus",
369
+ "strategy": "confidence_scaled",
370
+ "bankroll": 10000.0,
371
+ "total_bets": 0,
372
+ "total_wins": 0,
373
+ "win_rate": 0.0,
374
+ "roi": 0.0,
375
+ "total_pnl": 0.0,
376
+ "weight": 1.0,
377
+ "active": true
378
+ },
379
+ "t2_cerebras_0": {
380
+ "id": "t2_cerebras_0",
381
+ "name": "Cerebras Thunder",
382
+ "tier": "FREE_POWER",
383
+ "provider": "cerebras",
384
+ "model": "qwen-3-32b",
385
+ "strategy": "proportional_edge",
386
+ "bankroll": 10000.0,
387
+ "total_bets": 0,
388
+ "total_wins": 0,
389
+ "win_rate": 0.0,
390
+ "roi": 0.0,
391
+ "total_pnl": 0.0,
392
+ "weight": 1.0,
393
+ "active": true
394
+ },
395
+ "t3_ml_fg_s0": {
396
+ "id": "t3_ml_fg_s0",
397
+ "name": "Spec:Moneyline Full Game:S0",
398
+ "tier": "SPECIALIST",
399
+ "provider": "groq",
400
+ "model": "llama-3.1-8b-instant",
401
+ "strategy": "half_kelly",
402
+ "bankroll": 5000.0,
403
+ "total_bets": 0,
404
+ "total_wins": 0,
405
+ "win_rate": 0.0,
406
+ "roi": -50.0,
407
+ "total_pnl": 0.0,
408
+ "weight": 1.0,
409
+ "active": true
410
+ },
411
+ "t3_ml_fg_s1": {
412
+ "id": "t3_ml_fg_s1",
413
+ "name": "Spec:Moneyline Full Game:S1",
414
+ "tier": "SPECIALIST",
415
+ "provider": "groq",
416
+ "model": "gemma2-9b-it",
417
+ "strategy": "quarter_kelly",
418
+ "bankroll": 5000.0,
419
+ "total_bets": 0,
420
+ "total_wins": 0,
421
+ "win_rate": 0.0,
422
+ "roi": -50.0,
423
+ "total_pnl": 0.0,
424
+ "weight": 1.0,
425
+ "active": true
426
+ },
427
+ "t3_ml_1h_s0": {
428
+ "id": "t3_ml_1h_s0",
429
+ "name": "Spec:Moneyline 1st Half:S0",
430
+ "tier": "SPECIALIST",
431
+ "provider": "groq",
432
+ "model": "llama-3.1-8b-instant",
433
+ "strategy": "value_hunter",
434
+ "bankroll": 5000.0,
435
+ "total_bets": 0,
436
+ "total_wins": 0,
437
+ "win_rate": 0.0,
438
+ "roi": -50.0,
439
+ "total_pnl": 0.0,
440
+ "weight": 1.0,
441
+ "active": true
442
+ },
443
+ "t3_ml_1h_s1": {
444
+ "id": "t3_ml_1h_s1",
445
+ "name": "Spec:Moneyline 1st Half:S1",
446
+ "tier": "SPECIALIST",
447
+ "provider": "groq",
448
+ "model": "gemma2-9b-it",
449
+ "strategy": "proportional_edge",
450
+ "bankroll": 5000.0,
451
+ "total_bets": 0,
452
+ "total_wins": 0,
453
+ "win_rate": 0.0,
454
+ "roi": -50.0,
455
+ "total_pnl": 0.0,
456
+ "weight": 1.0,
457
+ "active": true
458
+ },
459
+ "t3_ml_2h_s0": {
460
+ "id": "t3_ml_2h_s0",
461
+ "name": "Spec:Moneyline 2nd Half:S0",
462
+ "tier": "SPECIALIST",
463
+ "provider": "groq",
464
+ "model": "llama-3.1-8b-instant",
465
+ "strategy": "confidence_scaled",
466
+ "bankroll": 5000.0,
467
+ "total_bets": 0,
468
+ "total_wins": 0,
469
+ "win_rate": 0.0,
470
+ "roi": -50.0,
471
+ "total_pnl": 0.0,
472
+ "weight": 1.0,
473
+ "active": true
474
+ },
475
+ "t3_ml_2h_s1": {
476
+ "id": "t3_ml_2h_s1",
477
+ "name": "Spec:Moneyline 2nd Half:S1",
478
+ "tier": "SPECIALIST",
479
+ "provider": "groq",
480
+ "model": "gemma2-9b-it",
481
+ "strategy": "flat_2pct",
482
+ "bankroll": 5000.0,
483
+ "total_bets": 0,
484
+ "total_wins": 0,
485
+ "win_rate": 0.0,
486
+ "roi": -50.0,
487
+ "total_pnl": 0.0,
488
+ "weight": 1.0,
489
+ "active": true
490
+ },
491
+ "t3_ml_q1_s0": {
492
+ "id": "t3_ml_q1_s0",
493
+ "name": "Spec:Moneyline Q1:S0",
494
+ "tier": "SPECIALIST",
495
+ "provider": "groq",
496
+ "model": "llama-3.1-8b-instant",
497
+ "strategy": "half_kelly",
498
+ "bankroll": 5000.0,
499
+ "total_bets": 0,
500
+ "total_wins": 0,
501
+ "win_rate": 0.0,
502
+ "roi": -50.0,
503
+ "total_pnl": 0.0,
504
+ "weight": 1.0,
505
+ "active": true
506
+ },
507
+ "t3_ml_q1_s1": {
508
+ "id": "t3_ml_q1_s1",
509
+ "name": "Spec:Moneyline Q1:S1",
510
+ "tier": "SPECIALIST",
511
+ "provider": "groq",
512
+ "model": "gemma2-9b-it",
513
+ "strategy": "quarter_kelly",
514
+ "bankroll": 5000.0,
515
+ "total_bets": 0,
516
+ "total_wins": 0,
517
+ "win_rate": 0.0,
518
+ "roi": -50.0,
519
+ "total_pnl": 0.0,
520
+ "weight": 1.0,
521
+ "active": true
522
+ },
523
+ "t3_ml_q2_s0": {
524
+ "id": "t3_ml_q2_s0",
525
+ "name": "Spec:Moneyline Q2:S0",
526
+ "tier": "SPECIALIST",
527
+ "provider": "groq",
528
+ "model": "llama-3.1-8b-instant",
529
+ "strategy": "value_hunter",
530
+ "bankroll": 5000.0,
531
+ "total_bets": 0,
532
+ "total_wins": 0,
533
+ "win_rate": 0.0,
534
+ "roi": -50.0,
535
+ "total_pnl": 0.0,
536
+ "weight": 1.0,
537
+ "active": true
538
+ },
539
+ "t3_ml_q2_s1": {
540
+ "id": "t3_ml_q2_s1",
541
+ "name": "Spec:Moneyline Q2:S1",
542
+ "tier": "SPECIALIST",
543
+ "provider": "groq",
544
+ "model": "gemma2-9b-it",
545
+ "strategy": "proportional_edge",
546
+ "bankroll": 5000.0,
547
+ "total_bets": 0,
548
+ "total_wins": 0,
549
+ "win_rate": 0.0,
550
+ "roi": -50.0,
551
+ "total_pnl": 0.0,
552
+ "weight": 1.0,
553
+ "active": true
554
+ },
555
+ "t3_ml_q3_s0": {
556
+ "id": "t3_ml_q3_s0",
557
+ "name": "Spec:Moneyline Q3:S0",
558
+ "tier": "SPECIALIST",
559
+ "provider": "groq",
560
+ "model": "llama-3.1-8b-instant",
561
+ "strategy": "confidence_scaled",
562
+ "bankroll": 5000.0,
563
+ "total_bets": 0,
564
+ "total_wins": 0,
565
+ "win_rate": 0.0,
566
+ "roi": -50.0,
567
+ "total_pnl": 0.0,
568
+ "weight": 1.0,
569
+ "active": true
570
+ },
571
+ "t3_ml_q3_s1": {
572
+ "id": "t3_ml_q3_s1",
573
+ "name": "Spec:Moneyline Q3:S1",
574
+ "tier": "SPECIALIST",
575
+ "provider": "groq",
576
+ "model": "gemma2-9b-it",
577
+ "strategy": "flat_2pct",
578
+ "bankroll": 5000.0,
579
+ "total_bets": 0,
580
+ "total_wins": 0,
581
+ "win_rate": 0.0,
582
+ "roi": -50.0,
583
+ "total_pnl": 0.0,
584
+ "weight": 1.0,
585
+ "active": true
586
+ },
587
+ "t3_ml_q4_s0": {
588
+ "id": "t3_ml_q4_s0",
589
+ "name": "Spec:Moneyline Q4:S0",
590
+ "tier": "SPECIALIST",
591
+ "provider": "groq",
592
+ "model": "llama-3.1-8b-instant",
593
+ "strategy": "half_kelly",
594
+ "bankroll": 5000.0,
595
+ "total_bets": 0,
596
+ "total_wins": 0,
597
+ "win_rate": 0.0,
598
+ "roi": -50.0,
599
+ "total_pnl": 0.0,
600
+ "weight": 1.0,
601
+ "active": true
602
+ },
603
+ "t3_ml_q4_s1": {
604
+ "id": "t3_ml_q4_s1",
605
+ "name": "Spec:Moneyline Q4:S1",
606
+ "tier": "SPECIALIST",
607
+ "provider": "groq",
608
+ "model": "gemma2-9b-it",
609
+ "strategy": "quarter_kelly",
610
+ "bankroll": 5000.0,
611
+ "total_bets": 0,
612
+ "total_wins": 0,
613
+ "win_rate": 0.0,
614
+ "roi": -50.0,
615
+ "total_pnl": 0.0,
616
+ "weight": 1.0,
617
+ "active": true
618
+ },
619
+ "t3_sp_fg_s0": {
620
+ "id": "t3_sp_fg_s0",
621
+ "name": "Spec:Spread Full Game:S0",
622
+ "tier": "SPECIALIST",
623
+ "provider": "groq",
624
+ "model": "llama-3.1-8b-instant",
625
+ "strategy": "value_hunter",
626
+ "bankroll": 5000.0,
627
+ "total_bets": 0,
628
+ "total_wins": 0,
629
+ "win_rate": 0.0,
630
+ "roi": -50.0,
631
+ "total_pnl": 0.0,
632
+ "weight": 1.0,
633
+ "active": true
634
+ },
635
+ "t3_sp_fg_s1": {
636
+ "id": "t3_sp_fg_s1",
637
+ "name": "Spec:Spread Full Game:S1",
638
+ "tier": "SPECIALIST",
639
+ "provider": "groq",
640
+ "model": "gemma2-9b-it",
641
+ "strategy": "proportional_edge",
642
+ "bankroll": 5000.0,
643
+ "total_bets": 0,
644
+ "total_wins": 0,
645
+ "win_rate": 0.0,
646
+ "roi": -50.0,
647
+ "total_pnl": 0.0,
648
+ "weight": 1.0,
649
+ "active": true
650
+ },
651
+ "t3_sp_1h_s0": {
652
+ "id": "t3_sp_1h_s0",
653
+ "name": "Spec:Spread 1st Half:S0",
654
+ "tier": "SPECIALIST",
655
+ "provider": "groq",
656
+ "model": "llama-3.1-8b-instant",
657
+ "strategy": "confidence_scaled",
658
+ "bankroll": 5000.0,
659
+ "total_bets": 0,
660
+ "total_wins": 0,
661
+ "win_rate": 0.0,
662
+ "roi": -50.0,
663
+ "total_pnl": 0.0,
664
+ "weight": 1.0,
665
+ "active": true
666
+ },
667
+ "t3_sp_1h_s1": {
668
+ "id": "t3_sp_1h_s1",
669
+ "name": "Spec:Spread 1st Half:S1",
670
+ "tier": "SPECIALIST",
671
+ "provider": "groq",
672
+ "model": "gemma2-9b-it",
673
+ "strategy": "flat_2pct",
674
+ "bankroll": 5000.0,
675
+ "total_bets": 0,
676
+ "total_wins": 0,
677
+ "win_rate": 0.0,
678
+ "roi": -50.0,
679
+ "total_pnl": 0.0,
680
+ "weight": 1.0,
681
+ "active": true
682
+ },
683
+ "t3_sp_2h_s0": {
684
+ "id": "t3_sp_2h_s0",
685
+ "name": "Spec:Spread 2nd Half:S0",
686
+ "tier": "SPECIALIST",
687
+ "provider": "groq",
688
+ "model": "llama-3.1-8b-instant",
689
+ "strategy": "half_kelly",
690
+ "bankroll": 5000.0,
691
+ "total_bets": 0,
692
+ "total_wins": 0,
693
+ "win_rate": 0.0,
694
+ "roi": -50.0,
695
+ "total_pnl": 0.0,
696
+ "weight": 1.0,
697
+ "active": true
698
+ },
699
+ "t3_sp_2h_s1": {
700
+ "id": "t3_sp_2h_s1",
701
+ "name": "Spec:Spread 2nd Half:S1",
702
+ "tier": "SPECIALIST",
703
+ "provider": "groq",
704
+ "model": "gemma2-9b-it",
705
+ "strategy": "quarter_kelly",
706
+ "bankroll": 5000.0,
707
+ "total_bets": 0,
708
+ "total_wins": 0,
709
+ "win_rate": 0.0,
710
+ "roi": -50.0,
711
+ "total_pnl": 0.0,
712
+ "weight": 1.0,
713
+ "active": true
714
+ },
715
+ "t3_sp_q1_s0": {
716
+ "id": "t3_sp_q1_s0",
717
+ "name": "Spec:Spread Q1:S0",
718
+ "tier": "SPECIALIST",
719
+ "provider": "groq",
720
+ "model": "llama-3.1-8b-instant",
721
+ "strategy": "value_hunter",
722
+ "bankroll": 5000.0,
723
+ "total_bets": 0,
724
+ "total_wins": 0,
725
+ "win_rate": 0.0,
726
+ "roi": -50.0,
727
+ "total_pnl": 0.0,
728
+ "weight": 1.0,
729
+ "active": true
730
+ },
731
+ "t3_sp_q1_s1": {
732
+ "id": "t3_sp_q1_s1",
733
+ "name": "Spec:Spread Q1:S1",
734
+ "tier": "SPECIALIST",
735
+ "provider": "groq",
736
+ "model": "gemma2-9b-it",
737
+ "strategy": "proportional_edge",
738
+ "bankroll": 5000.0,
739
+ "total_bets": 0,
740
+ "total_wins": 0,
741
+ "win_rate": 0.0,
742
+ "roi": -50.0,
743
+ "total_pnl": 0.0,
744
+ "weight": 1.0,
745
+ "active": true
746
+ },
747
+ "t3_sp_alt_p2_s0": {
748
+ "id": "t3_sp_alt_p2_s0",
749
+ "name": "Spec:Alt Spread +2:S0",
750
+ "tier": "SPECIALIST",
751
+ "provider": "groq",
752
+ "model": "llama-3.1-8b-instant",
753
+ "strategy": "confidence_scaled",
754
+ "bankroll": 5000.0,
755
+ "total_bets": 0,
756
+ "total_wins": 0,
757
+ "win_rate": 0.0,
758
+ "roi": -50.0,
759
+ "total_pnl": 0.0,
760
+ "weight": 1.0,
761
+ "active": true
762
+ },
763
+ "t3_sp_alt_p2_s1": {
764
+ "id": "t3_sp_alt_p2_s1",
765
+ "name": "Spec:Alt Spread +2:S1",
766
+ "tier": "SPECIALIST",
767
+ "provider": "groq",
768
+ "model": "gemma2-9b-it",
769
+ "strategy": "flat_2pct",
770
+ "bankroll": 5000.0,
771
+ "total_bets": 0,
772
+ "total_wins": 0,
773
+ "win_rate": 0.0,
774
+ "roi": -50.0,
775
+ "total_pnl": 0.0,
776
+ "weight": 1.0,
777
+ "active": true
778
+ },
779
+ "t3_sp_alt_p5_s0": {
780
+ "id": "t3_sp_alt_p5_s0",
781
+ "name": "Spec:Alt Spread +5:S0",
782
+ "tier": "SPECIALIST",
783
+ "provider": "groq",
784
+ "model": "llama-3.1-8b-instant",
785
+ "strategy": "half_kelly",
786
+ "bankroll": 5000.0,
787
+ "total_bets": 0,
788
+ "total_wins": 0,
789
+ "win_rate": 0.0,
790
+ "roi": -50.0,
791
+ "total_pnl": 0.0,
792
+ "weight": 1.0,
793
+ "active": true
794
+ },
795
+ "t3_sp_alt_p5_s1": {
796
+ "id": "t3_sp_alt_p5_s1",
797
+ "name": "Spec:Alt Spread +5:S1",
798
+ "tier": "SPECIALIST",
799
+ "provider": "groq",
800
+ "model": "gemma2-9b-it",
801
+ "strategy": "quarter_kelly",
802
+ "bankroll": 5000.0,
803
+ "total_bets": 0,
804
+ "total_wins": 0,
805
+ "win_rate": 0.0,
806
+ "roi": -50.0,
807
+ "total_pnl": 0.0,
808
+ "weight": 1.0,
809
+ "active": true
810
+ },
811
+ "t3_sp_alt_m2_s0": {
812
+ "id": "t3_sp_alt_m2_s0",
813
+ "name": "Spec:Alt Spread -2:S0",
814
+ "tier": "SPECIALIST",
815
+ "provider": "groq",
816
+ "model": "llama-3.1-8b-instant",
817
+ "strategy": "value_hunter",
818
+ "bankroll": 5000.0,
819
+ "total_bets": 0,
820
+ "total_wins": 0,
821
+ "win_rate": 0.0,
822
+ "roi": -50.0,
823
+ "total_pnl": 0.0,
824
+ "weight": 1.0,
825
+ "active": true
826
+ },
827
+ "t3_sp_alt_m2_s1": {
828
+ "id": "t3_sp_alt_m2_s1",
829
+ "name": "Spec:Alt Spread -2:S1",
830
+ "tier": "SPECIALIST",
831
+ "provider": "groq",
832
+ "model": "gemma2-9b-it",
833
+ "strategy": "proportional_edge",
834
+ "bankroll": 5000.0,
835
+ "total_bets": 0,
836
+ "total_wins": 0,
837
+ "win_rate": 0.0,
838
+ "roi": -50.0,
839
+ "total_pnl": 0.0,
840
+ "weight": 1.0,
841
+ "active": true
842
+ },
843
+ "t3_sp_alt_m5_s0": {
844
+ "id": "t3_sp_alt_m5_s0",
845
+ "name": "Spec:Alt Spread -5:S0",
846
+ "tier": "SPECIALIST",
847
+ "provider": "groq",
848
+ "model": "llama-3.1-8b-instant",
849
+ "strategy": "confidence_scaled",
850
+ "bankroll": 5000.0,
851
+ "total_bets": 0,
852
+ "total_wins": 0,
853
+ "win_rate": 0.0,
854
+ "roi": -50.0,
855
+ "total_pnl": 0.0,
856
+ "weight": 1.0,
857
+ "active": true
858
+ },
859
+ "t3_sp_alt_m5_s1": {
860
+ "id": "t3_sp_alt_m5_s1",
861
+ "name": "Spec:Alt Spread -5:S1",
862
+ "tier": "SPECIALIST",
863
+ "provider": "groq",
864
+ "model": "gemma2-9b-it",
865
+ "strategy": "flat_2pct",
866
+ "bankroll": 5000.0,
867
+ "total_bets": 0,
868
+ "total_wins": 0,
869
+ "win_rate": 0.0,
870
+ "roi": -50.0,
871
+ "total_pnl": 0.0,
872
+ "weight": 1.0,
873
+ "active": true
874
+ },
875
+ "t3_sp_alt_m10_s0": {
876
+ "id": "t3_sp_alt_m10_s0",
877
+ "name": "Spec:Alt Spread -10:S0",
878
+ "tier": "SPECIALIST",
879
+ "provider": "groq",
880
+ "model": "llama-3.1-8b-instant",
881
+ "strategy": "half_kelly",
882
+ "bankroll": 5000.0,
883
+ "total_bets": 0,
884
+ "total_wins": 0,
885
+ "win_rate": 0.0,
886
+ "roi": -50.0,
887
+ "total_pnl": 0.0,
888
+ "weight": 1.0,
889
+ "active": true
890
+ },
891
+ "t3_sp_alt_m10_s1": {
892
+ "id": "t3_sp_alt_m10_s1",
893
+ "name": "Spec:Alt Spread -10:S1",
894
+ "tier": "SPECIALIST",
895
+ "provider": "groq",
896
+ "model": "gemma2-9b-it",
897
+ "strategy": "quarter_kelly",
898
+ "bankroll": 5000.0,
899
+ "total_bets": 0,
900
+ "total_wins": 0,
901
+ "win_rate": 0.0,
902
+ "roi": -50.0,
903
+ "total_pnl": 0.0,
904
+ "weight": 1.0,
905
+ "active": true
906
+ },
907
+ "t3_tot_fg_s0": {
908
+ "id": "t3_tot_fg_s0",
909
+ "name": "Spec:Total Full Game:S0",
910
+ "tier": "SPECIALIST",
911
+ "provider": "groq",
912
+ "model": "llama-3.1-8b-instant",
913
+ "strategy": "value_hunter",
914
+ "bankroll": 5000.0,
915
+ "total_bets": 0,
916
+ "total_wins": 0,
917
+ "win_rate": 0.0,
918
+ "roi": -50.0,
919
+ "total_pnl": 0.0,
920
+ "weight": 1.0,
921
+ "active": true
922
+ },
923
+ "t3_tot_fg_s1": {
924
+ "id": "t3_tot_fg_s1",
925
+ "name": "Spec:Total Full Game:S1",
926
+ "tier": "SPECIALIST",
927
+ "provider": "groq",
928
+ "model": "gemma2-9b-it",
929
+ "strategy": "proportional_edge",
930
+ "bankroll": 5000.0,
931
+ "total_bets": 0,
932
+ "total_wins": 0,
933
+ "win_rate": 0.0,
934
+ "roi": -50.0,
935
+ "total_pnl": 0.0,
936
+ "weight": 1.0,
937
+ "active": true
938
+ },
939
+ "t3_tot_1h_s0": {
940
+ "id": "t3_tot_1h_s0",
941
+ "name": "Spec:Total 1st Half:S0",
942
+ "tier": "SPECIALIST",
943
+ "provider": "groq",
944
+ "model": "llama-3.1-8b-instant",
945
+ "strategy": "confidence_scaled",
946
+ "bankroll": 5000.0,
947
+ "total_bets": 0,
948
+ "total_wins": 0,
949
+ "win_rate": 0.0,
950
+ "roi": -50.0,
951
+ "total_pnl": 0.0,
952
+ "weight": 1.0,
953
+ "active": true
954
+ },
955
+ "t3_tot_1h_s1": {
956
+ "id": "t3_tot_1h_s1",
957
+ "name": "Spec:Total 1st Half:S1",
958
+ "tier": "SPECIALIST",
959
+ "provider": "groq",
960
+ "model": "gemma2-9b-it",
961
+ "strategy": "flat_2pct",
962
+ "bankroll": 5000.0,
963
+ "total_bets": 0,
964
+ "total_wins": 0,
965
+ "win_rate": 0.0,
966
+ "roi": -50.0,
967
+ "total_pnl": 0.0,
968
+ "weight": 1.0,
969
+ "active": true
970
+ },
971
+ "t3_tot_2h_s0": {
972
+ "id": "t3_tot_2h_s0",
973
+ "name": "Spec:Total 2nd Half:S0",
974
+ "tier": "SPECIALIST",
975
+ "provider": "groq",
976
+ "model": "llama-3.1-8b-instant",
977
+ "strategy": "half_kelly",
978
+ "bankroll": 5000.0,
979
+ "total_bets": 0,
980
+ "total_wins": 0,
981
+ "win_rate": 0.0,
982
+ "roi": -50.0,
983
+ "total_pnl": 0.0,
984
+ "weight": 1.0,
985
+ "active": true
986
+ },
987
+ "t3_tot_2h_s1": {
988
+ "id": "t3_tot_2h_s1",
989
+ "name": "Spec:Total 2nd Half:S1",
990
+ "tier": "SPECIALIST",
991
+ "provider": "groq",
992
+ "model": "gemma2-9b-it",
993
+ "strategy": "quarter_kelly",
994
+ "bankroll": 5000.0,
995
+ "total_bets": 0,
996
+ "total_wins": 0,
997
+ "win_rate": 0.0,
998
+ "roi": -50.0,
999
+ "total_pnl": 0.0,
1000
+ "weight": 1.0,
1001
+ "active": true
1002
+ },
1003
+ "t3_tot_q1_s0": {
1004
+ "id": "t3_tot_q1_s0",
1005
+ "name": "Spec:Total Q1:S0",
1006
+ "tier": "SPECIALIST",
1007
+ "provider": "groq",
1008
+ "model": "llama-3.1-8b-instant",
1009
+ "strategy": "value_hunter",
1010
+ "bankroll": 5000.0,
1011
+ "total_bets": 0,
1012
+ "total_wins": 0,
1013
+ "win_rate": 0.0,
1014
+ "roi": -50.0,
1015
+ "total_pnl": 0.0,
1016
+ "weight": 1.0,
1017
+ "active": true
1018
+ },
1019
+ "t3_tot_q1_s1": {
1020
+ "id": "t3_tot_q1_s1",
1021
+ "name": "Spec:Total Q1:S1",
1022
+ "tier": "SPECIALIST",
1023
+ "provider": "groq",
1024
+ "model": "gemma2-9b-it",
1025
+ "strategy": "proportional_edge",
1026
+ "bankroll": 5000.0,
1027
+ "total_bets": 0,
1028
+ "total_wins": 0,
1029
+ "win_rate": 0.0,
1030
+ "roi": -50.0,
1031
+ "total_pnl": 0.0,
1032
+ "weight": 1.0,
1033
+ "active": true
1034
+ },
1035
+ "t3_tot_home_fg_s0": {
1036
+ "id": "t3_tot_home_fg_s0",
1037
+ "name": "Spec:Home Team Total:S0",
1038
+ "tier": "SPECIALIST",
1039
+ "provider": "groq",
1040
+ "model": "llama-3.1-8b-instant",
1041
+ "strategy": "confidence_scaled",
1042
+ "bankroll": 5000.0,
1043
+ "total_bets": 0,
1044
+ "total_wins": 0,
1045
+ "win_rate": 0.0,
1046
+ "roi": -50.0,
1047
+ "total_pnl": 0.0,
1048
+ "weight": 1.0,
1049
+ "active": true
1050
+ },
1051
+ "t3_tot_home_fg_s1": {
1052
+ "id": "t3_tot_home_fg_s1",
1053
+ "name": "Spec:Home Team Total:S1",
1054
+ "tier": "SPECIALIST",
1055
+ "provider": "groq",
1056
+ "model": "gemma2-9b-it",
1057
+ "strategy": "flat_2pct",
1058
+ "bankroll": 5000.0,
1059
+ "total_bets": 0,
1060
+ "total_wins": 0,
1061
+ "win_rate": 0.0,
1062
+ "roi": -50.0,
1063
+ "total_pnl": 0.0,
1064
+ "weight": 1.0,
1065
+ "active": true
1066
+ },
1067
+ "t3_tot_away_fg_s0": {
1068
+ "id": "t3_tot_away_fg_s0",
1069
+ "name": "Spec:Away Team Total:S0",
1070
+ "tier": "SPECIALIST",
1071
+ "provider": "groq",
1072
+ "model": "llama-3.1-8b-instant",
1073
+ "strategy": "half_kelly",
1074
+ "bankroll": 5000.0,
1075
+ "total_bets": 0,
1076
+ "total_wins": 0,
1077
+ "win_rate": 0.0,
1078
+ "roi": -50.0,
1079
+ "total_pnl": 0.0,
1080
+ "weight": 1.0,
1081
+ "active": true
1082
+ },
1083
+ "t3_tot_away_fg_s1": {
1084
+ "id": "t3_tot_away_fg_s1",
1085
+ "name": "Spec:Away Team Total:S1",
1086
+ "tier": "SPECIALIST",
1087
+ "provider": "groq",
1088
+ "model": "gemma2-9b-it",
1089
+ "strategy": "quarter_kelly",
1090
+ "bankroll": 5000.0,
1091
+ "total_bets": 0,
1092
+ "total_wins": 0,
1093
+ "win_rate": 0.0,
1094
+ "roi": -50.0,
1095
+ "total_pnl": 0.0,
1096
+ "weight": 1.0,
1097
+ "active": true
1098
+ },
1099
+ "t3_tot_alt_p5_s0": {
1100
+ "id": "t3_tot_alt_p5_s0",
1101
+ "name": "Spec:Alt Total +5:S0",
1102
+ "tier": "SPECIALIST",
1103
+ "provider": "groq",
1104
+ "model": "llama-3.1-8b-instant",
1105
+ "strategy": "value_hunter",
1106
+ "bankroll": 5000.0,
1107
+ "total_bets": 0,
1108
+ "total_wins": 0,
1109
+ "win_rate": 0.0,
1110
+ "roi": -50.0,
1111
+ "total_pnl": 0.0,
1112
+ "weight": 1.0,
1113
+ "active": true
1114
+ },
1115
+ "t3_tot_alt_p5_s1": {
1116
+ "id": "t3_tot_alt_p5_s1",
1117
+ "name": "Spec:Alt Total +5:S1",
1118
+ "tier": "SPECIALIST",
1119
+ "provider": "groq",
1120
+ "model": "gemma2-9b-it",
1121
+ "strategy": "proportional_edge",
1122
+ "bankroll": 5000.0,
1123
+ "total_bets": 0,
1124
+ "total_wins": 0,
1125
+ "win_rate": 0.0,
1126
+ "roi": -50.0,
1127
+ "total_pnl": 0.0,
1128
+ "weight": 1.0,
1129
+ "active": true
1130
+ },
1131
+ "t3_tot_alt_m5_s0": {
1132
+ "id": "t3_tot_alt_m5_s0",
1133
+ "name": "Spec:Alt Total -5:S0",
1134
+ "tier": "SPECIALIST",
1135
+ "provider": "groq",
1136
+ "model": "llama-3.1-8b-instant",
1137
+ "strategy": "confidence_scaled",
1138
+ "bankroll": 5000.0,
1139
+ "total_bets": 0,
1140
+ "total_wins": 0,
1141
+ "win_rate": 0.0,
1142
+ "roi": -50.0,
1143
+ "total_pnl": 0.0,
1144
+ "weight": 1.0,
1145
+ "active": true
1146
+ },
1147
+ "t3_tot_alt_m5_s1": {
1148
+ "id": "t3_tot_alt_m5_s1",
1149
+ "name": "Spec:Alt Total -5:S1",
1150
+ "tier": "SPECIALIST",
1151
+ "provider": "groq",
1152
+ "model": "gemma2-9b-it",
1153
+ "strategy": "flat_2pct",
1154
+ "bankroll": 5000.0,
1155
+ "total_bets": 0,
1156
+ "total_wins": 0,
1157
+ "win_rate": 0.0,
1158
+ "roi": -50.0,
1159
+ "total_pnl": 0.0,
1160
+ "weight": 1.0,
1161
+ "active": true
1162
+ },
1163
+ "t3_tot_alt_p10_s0": {
1164
+ "id": "t3_tot_alt_p10_s0",
1165
+ "name": "Spec:Alt Total +10:S0",
1166
+ "tier": "SPECIALIST",
1167
+ "provider": "groq",
1168
+ "model": "llama-3.1-8b-instant",
1169
+ "strategy": "half_kelly",
1170
+ "bankroll": 5000.0,
1171
+ "total_bets": 0,
1172
+ "total_wins": 0,
1173
+ "win_rate": 0.0,
1174
+ "roi": -50.0,
1175
+ "total_pnl": 0.0,
1176
+ "weight": 1.0,
1177
+ "active": true
1178
+ },
1179
+ "t3_tot_alt_p10_s1": {
1180
+ "id": "t3_tot_alt_p10_s1",
1181
+ "name": "Spec:Alt Total +10:S1",
1182
+ "tier": "SPECIALIST",
1183
+ "provider": "groq",
1184
+ "model": "gemma2-9b-it",
1185
+ "strategy": "quarter_kelly",
1186
+ "bankroll": 5000.0,
1187
+ "total_bets": 0,
1188
+ "total_wins": 0,
1189
+ "win_rate": 0.0,
1190
+ "roi": -50.0,
1191
+ "total_pnl": 0.0,
1192
+ "weight": 1.0,
1193
+ "active": true
1194
+ },
1195
+ "t3_tot_combined_q1q2_s0": {
1196
+ "id": "t3_tot_combined_q1q2_s0",
1197
+ "name": "Spec:Combined Q1+Q2 Total:S0",
1198
+ "tier": "SPECIALIST",
1199
+ "provider": "groq",
1200
+ "model": "llama-3.1-8b-instant",
1201
+ "strategy": "value_hunter",
1202
+ "bankroll": 5000.0,
1203
+ "total_bets": 0,
1204
+ "total_wins": 0,
1205
+ "win_rate": 0.0,
1206
+ "roi": -50.0,
1207
+ "total_pnl": 0.0,
1208
+ "weight": 1.0,
1209
+ "active": true
1210
+ },
1211
+ "t3_tot_combined_q1q2_s1": {
1212
+ "id": "t3_tot_combined_q1q2_s1",
1213
+ "name": "Spec:Combined Q1+Q2 Total:S1",
1214
+ "tier": "SPECIALIST",
1215
+ "provider": "groq",
1216
+ "model": "gemma2-9b-it",
1217
+ "strategy": "proportional_edge",
1218
+ "bankroll": 5000.0,
1219
+ "total_bets": 0,
1220
+ "total_wins": 0,
1221
+ "win_rate": 0.0,
1222
+ "roi": -50.0,
1223
+ "total_pnl": 0.0,
1224
+ "weight": 1.0,
1225
+ "active": true
1226
+ },
1227
+ "t3_pp_points_star1_s0": {
1228
+ "id": "t3_pp_points_star1_s0",
1229
+ "name": "Spec:Player Points (star1):S0",
1230
+ "tier": "SPECIALIST",
1231
+ "provider": "groq",
1232
+ "model": "llama-3.1-8b-instant",
1233
+ "strategy": "confidence_scaled",
1234
+ "bankroll": 5000.0,
1235
+ "total_bets": 0,
1236
+ "total_wins": 0,
1237
+ "win_rate": 0.0,
1238
+ "roi": -50.0,
1239
+ "total_pnl": 0.0,
1240
+ "weight": 1.0,
1241
+ "active": true
1242
+ },
1243
+ "t3_pp_points_star1_s1": {
1244
+ "id": "t3_pp_points_star1_s1",
1245
+ "name": "Spec:Player Points (star1):S1",
1246
+ "tier": "SPECIALIST",
1247
+ "provider": "groq",
1248
+ "model": "gemma2-9b-it",
1249
+ "strategy": "flat_2pct",
1250
+ "bankroll": 5000.0,
1251
+ "total_bets": 0,
1252
+ "total_wins": 0,
1253
+ "win_rate": 0.0,
1254
+ "roi": -50.0,
1255
+ "total_pnl": 0.0,
1256
+ "weight": 1.0,
1257
+ "active": true
1258
+ },
1259
+ "t3_pp_points_star2_s0": {
1260
+ "id": "t3_pp_points_star2_s0",
1261
+ "name": "Spec:Player Points (star2):S0",
1262
+ "tier": "SPECIALIST",
1263
+ "provider": "groq",
1264
+ "model": "llama-3.1-8b-instant",
1265
+ "strategy": "half_kelly",
1266
+ "bankroll": 5000.0,
1267
+ "total_bets": 0,
1268
+ "total_wins": 0,
1269
+ "win_rate": 0.0,
1270
+ "roi": -50.0,
1271
+ "total_pnl": 0.0,
1272
+ "weight": 1.0,
1273
+ "active": true
1274
+ },
1275
+ "t3_pp_points_star2_s1": {
1276
+ "id": "t3_pp_points_star2_s1",
1277
+ "name": "Spec:Player Points (star2):S1",
1278
+ "tier": "SPECIALIST",
1279
+ "provider": "groq",
1280
+ "model": "gemma2-9b-it",
1281
+ "strategy": "quarter_kelly",
1282
+ "bankroll": 5000.0,
1283
+ "total_bets": 0,
1284
+ "total_wins": 0,
1285
+ "win_rate": 0.0,
1286
+ "roi": -50.0,
1287
+ "total_pnl": 0.0,
1288
+ "weight": 1.0,
1289
+ "active": true
1290
+ },
1291
+ "t3_pp_points_star3_s0": {
1292
+ "id": "t3_pp_points_star3_s0",
1293
+ "name": "Spec:Player Points (star3):S0",
1294
+ "tier": "SPECIALIST",
1295
+ "provider": "groq",
1296
+ "model": "llama-3.1-8b-instant",
1297
+ "strategy": "value_hunter",
1298
+ "bankroll": 5000.0,
1299
+ "total_bets": 0,
1300
+ "total_wins": 0,
1301
+ "win_rate": 0.0,
1302
+ "roi": -50.0,
1303
+ "total_pnl": 0.0,
1304
+ "weight": 1.0,
1305
+ "active": true
1306
+ },
1307
+ "t3_pp_points_star3_s1": {
1308
+ "id": "t3_pp_points_star3_s1",
1309
+ "name": "Spec:Player Points (star3):S1",
1310
+ "tier": "SPECIALIST",
1311
+ "provider": "groq",
1312
+ "model": "gemma2-9b-it",
1313
+ "strategy": "proportional_edge",
1314
+ "bankroll": 5000.0,
1315
+ "total_bets": 0,
1316
+ "total_wins": 0,
1317
+ "win_rate": 0.0,
1318
+ "roi": -50.0,
1319
+ "total_pnl": 0.0,
1320
+ "weight": 1.0,
1321
+ "active": true
1322
+ },
1323
+ "t3_pp_points_role1_s0": {
1324
+ "id": "t3_pp_points_role1_s0",
1325
+ "name": "Spec:Player Points (role1):S0",
1326
+ "tier": "SPECIALIST",
1327
+ "provider": "groq",
1328
+ "model": "llama-3.1-8b-instant",
1329
+ "strategy": "confidence_scaled",
1330
+ "bankroll": 5000.0,
1331
+ "total_bets": 0,
1332
+ "total_wins": 0,
1333
+ "win_rate": 0.0,
1334
+ "roi": -50.0,
1335
+ "total_pnl": 0.0,
1336
+ "weight": 1.0,
1337
+ "active": true
1338
+ },
1339
+ "t3_pp_points_role1_s1": {
1340
+ "id": "t3_pp_points_role1_s1",
1341
+ "name": "Spec:Player Points (role1):S1",
1342
+ "tier": "SPECIALIST",
1343
+ "provider": "groq",
1344
+ "model": "gemma2-9b-it",
1345
+ "strategy": "flat_2pct",
1346
+ "bankroll": 5000.0,
1347
+ "total_bets": 0,
1348
+ "total_wins": 0,
1349
+ "win_rate": 0.0,
1350
+ "roi": -50.0,
1351
+ "total_pnl": 0.0,
1352
+ "weight": 1.0,
1353
+ "active": true
1354
+ },
1355
+ "t3_pp_points_role2_s0": {
1356
+ "id": "t3_pp_points_role2_s0",
1357
+ "name": "Spec:Player Points (role2):S0",
1358
+ "tier": "SPECIALIST",
1359
+ "provider": "groq",
1360
+ "model": "llama-3.1-8b-instant",
1361
+ "strategy": "half_kelly",
1362
+ "bankroll": 5000.0,
1363
+ "total_bets": 0,
1364
+ "total_wins": 0,
1365
+ "win_rate": 0.0,
1366
+ "roi": -50.0,
1367
+ "total_pnl": 0.0,
1368
+ "weight": 1.0,
1369
+ "active": true
1370
+ },
1371
+ "t3_pp_points_role2_s1": {
1372
+ "id": "t3_pp_points_role2_s1",
1373
+ "name": "Spec:Player Points (role2):S1",
1374
+ "tier": "SPECIALIST",
1375
+ "provider": "groq",
1376
+ "model": "gemma2-9b-it",
1377
+ "strategy": "quarter_kelly",
1378
+ "bankroll": 5000.0,
1379
+ "total_bets": 0,
1380
+ "total_wins": 0,
1381
+ "win_rate": 0.0,
1382
+ "roi": -50.0,
1383
+ "total_pnl": 0.0,
1384
+ "weight": 1.0,
1385
+ "active": true
1386
+ },
1387
+ "t3_pp_rebounds_star1_s0": {
1388
+ "id": "t3_pp_rebounds_star1_s0",
1389
+ "name": "Spec:Player Rebounds (star1):S0",
1390
+ "tier": "SPECIALIST",
1391
+ "provider": "groq",
1392
+ "model": "llama-3.1-8b-instant",
1393
+ "strategy": "value_hunter",
1394
+ "bankroll": 5000.0,
1395
+ "total_bets": 0,
1396
+ "total_wins": 0,
1397
+ "win_rate": 0.0,
1398
+ "roi": -50.0,
1399
+ "total_pnl": 0.0,
1400
+ "weight": 1.0,
1401
+ "active": true
1402
+ },
1403
+ "t3_pp_rebounds_star1_s1": {
1404
+ "id": "t3_pp_rebounds_star1_s1",
1405
+ "name": "Spec:Player Rebounds (star1):S1",
1406
+ "tier": "SPECIALIST",
1407
+ "provider": "groq",
1408
+ "model": "gemma2-9b-it",
1409
+ "strategy": "proportional_edge",
1410
+ "bankroll": 5000.0,
1411
+ "total_bets": 0,
1412
+ "total_wins": 0,
1413
+ "win_rate": 0.0,
1414
+ "roi": -50.0,
1415
+ "total_pnl": 0.0,
1416
+ "weight": 1.0,
1417
+ "active": true
1418
+ },
1419
+ "t3_pp_rebounds_star2_s0": {
1420
+ "id": "t3_pp_rebounds_star2_s0",
1421
+ "name": "Spec:Player Rebounds (star2):S0",
1422
+ "tier": "SPECIALIST",
1423
+ "provider": "groq",
1424
+ "model": "llama-3.1-8b-instant",
1425
+ "strategy": "confidence_scaled",
1426
+ "bankroll": 5000.0,
1427
+ "total_bets": 0,
1428
+ "total_wins": 0,
1429
+ "win_rate": 0.0,
1430
+ "roi": -50.0,
1431
+ "total_pnl": 0.0,
1432
+ "weight": 1.0,
1433
+ "active": true
1434
+ },
1435
+ "t3_pp_rebounds_star2_s1": {
1436
+ "id": "t3_pp_rebounds_star2_s1",
1437
+ "name": "Spec:Player Rebounds (star2):S1",
1438
+ "tier": "SPECIALIST",
1439
+ "provider": "groq",
1440
+ "model": "gemma2-9b-it",
1441
+ "strategy": "flat_2pct",
1442
+ "bankroll": 5000.0,
1443
+ "total_bets": 0,
1444
+ "total_wins": 0,
1445
+ "win_rate": 0.0,
1446
+ "roi": -50.0,
1447
+ "total_pnl": 0.0,
1448
+ "weight": 1.0,
1449
+ "active": true
1450
+ },
1451
+ "t3_pp_rebounds_star3_s0": {
1452
+ "id": "t3_pp_rebounds_star3_s0",
1453
+ "name": "Spec:Player Rebounds (star3):S0",
1454
+ "tier": "SPECIALIST",
1455
+ "provider": "groq",
1456
+ "model": "llama-3.1-8b-instant",
1457
+ "strategy": "half_kelly",
1458
+ "bankroll": 5000.0,
1459
+ "total_bets": 0,
1460
+ "total_wins": 0,
1461
+ "win_rate": 0.0,
1462
+ "roi": -50.0,
1463
+ "total_pnl": 0.0,
1464
+ "weight": 1.0,
1465
+ "active": true
1466
+ },
1467
+ "t3_pp_rebounds_star3_s1": {
1468
+ "id": "t3_pp_rebounds_star3_s1",
1469
+ "name": "Spec:Player Rebounds (star3):S1",
1470
+ "tier": "SPECIALIST",
1471
+ "provider": "groq",
1472
+ "model": "gemma2-9b-it",
1473
+ "strategy": "quarter_kelly",
1474
+ "bankroll": 5000.0,
1475
+ "total_bets": 0,
1476
+ "total_wins": 0,
1477
+ "win_rate": 0.0,
1478
+ "roi": -50.0,
1479
+ "total_pnl": 0.0,
1480
+ "weight": 1.0,
1481
+ "active": true
1482
+ },
1483
+ "t3_pp_rebounds_role1_s0": {
1484
+ "id": "t3_pp_rebounds_role1_s0",
1485
+ "name": "Spec:Player Rebounds (role1):S0",
1486
+ "tier": "SPECIALIST",
1487
+ "provider": "groq",
1488
+ "model": "llama-3.1-8b-instant",
1489
+ "strategy": "value_hunter",
1490
+ "bankroll": 5000.0,
1491
+ "total_bets": 0,
1492
+ "total_wins": 0,
1493
+ "win_rate": 0.0,
1494
+ "roi": -50.0,
1495
+ "total_pnl": 0.0,
1496
+ "weight": 1.0,
1497
+ "active": true
1498
+ },
1499
+ "t3_pp_rebounds_role1_s1": {
1500
+ "id": "t3_pp_rebounds_role1_s1",
1501
+ "name": "Spec:Player Rebounds (role1):S1",
1502
+ "tier": "SPECIALIST",
1503
+ "provider": "groq",
1504
+ "model": "gemma2-9b-it",
1505
+ "strategy": "proportional_edge",
1506
+ "bankroll": 5000.0,
1507
+ "total_bets": 0,
1508
+ "total_wins": 0,
1509
+ "win_rate": 0.0,
1510
+ "roi": -50.0,
1511
+ "total_pnl": 0.0,
1512
+ "weight": 1.0,
1513
+ "active": true
1514
+ },
1515
+ "t3_pp_rebounds_role2_s0": {
1516
+ "id": "t3_pp_rebounds_role2_s0",
1517
+ "name": "Spec:Player Rebounds (role2):S0",
1518
+ "tier": "SPECIALIST",
1519
+ "provider": "groq",
1520
+ "model": "llama-3.1-8b-instant",
1521
+ "strategy": "confidence_scaled",
1522
+ "bankroll": 5000.0,
1523
+ "total_bets": 0,
1524
+ "total_wins": 0,
1525
+ "win_rate": 0.0,
1526
+ "roi": -50.0,
1527
+ "total_pnl": 0.0,
1528
+ "weight": 1.0,
1529
+ "active": true
1530
+ },
1531
+ "t3_pp_rebounds_role2_s1": {
1532
+ "id": "t3_pp_rebounds_role2_s1",
1533
+ "name": "Spec:Player Rebounds (role2):S1",
1534
+ "tier": "SPECIALIST",
1535
+ "provider": "groq",
1536
+ "model": "gemma2-9b-it",
1537
+ "strategy": "flat_2pct",
1538
+ "bankroll": 5000.0,
1539
+ "total_bets": 0,
1540
+ "total_wins": 0,
1541
+ "win_rate": 0.0,
1542
+ "roi": -50.0,
1543
+ "total_pnl": 0.0,
1544
+ "weight": 1.0,
1545
+ "active": true
1546
+ },
1547
+ "t3_pp_assists_star1_s0": {
1548
+ "id": "t3_pp_assists_star1_s0",
1549
+ "name": "Spec:Player Assists (star1):S0",
1550
+ "tier": "SPECIALIST",
1551
+ "provider": "groq",
1552
+ "model": "llama-3.1-8b-instant",
1553
+ "strategy": "half_kelly",
1554
+ "bankroll": 5000.0,
1555
+ "total_bets": 0,
1556
+ "total_wins": 0,
1557
+ "win_rate": 0.0,
1558
+ "roi": -50.0,
1559
+ "total_pnl": 0.0,
1560
+ "weight": 1.0,
1561
+ "active": true
1562
+ },
1563
+ "t3_pp_assists_star1_s1": {
1564
+ "id": "t3_pp_assists_star1_s1",
1565
+ "name": "Spec:Player Assists (star1):S1",
1566
+ "tier": "SPECIALIST",
1567
+ "provider": "groq",
1568
+ "model": "gemma2-9b-it",
1569
+ "strategy": "quarter_kelly",
1570
+ "bankroll": 5000.0,
1571
+ "total_bets": 0,
1572
+ "total_wins": 0,
1573
+ "win_rate": 0.0,
1574
+ "roi": -50.0,
1575
+ "total_pnl": 0.0,
1576
+ "weight": 1.0,
1577
+ "active": true
1578
+ },
1579
+ "t3_pp_assists_star2_s0": {
1580
+ "id": "t3_pp_assists_star2_s0",
1581
+ "name": "Spec:Player Assists (star2):S0",
1582
+ "tier": "SPECIALIST",
1583
+ "provider": "groq",
1584
+ "model": "llama-3.1-8b-instant",
1585
+ "strategy": "value_hunter",
1586
+ "bankroll": 5000.0,
1587
+ "total_bets": 0,
1588
+ "total_wins": 0,
1589
+ "win_rate": 0.0,
1590
+ "roi": -50.0,
1591
+ "total_pnl": 0.0,
1592
+ "weight": 1.0,
1593
+ "active": true
1594
+ },
1595
+ "t3_pp_assists_star2_s1": {
1596
+ "id": "t3_pp_assists_star2_s1",
1597
+ "name": "Spec:Player Assists (star2):S1",
1598
+ "tier": "SPECIALIST",
1599
+ "provider": "groq",
1600
+ "model": "gemma2-9b-it",
1601
+ "strategy": "proportional_edge",
1602
+ "bankroll": 5000.0,
1603
+ "total_bets": 0,
1604
+ "total_wins": 0,
1605
+ "win_rate": 0.0,
1606
+ "roi": -50.0,
1607
+ "total_pnl": 0.0,
1608
+ "weight": 1.0,
1609
+ "active": true
1610
+ },
1611
+ "t3_pp_assists_star3_s0": {
1612
+ "id": "t3_pp_assists_star3_s0",
1613
+ "name": "Spec:Player Assists (star3):S0",
1614
+ "tier": "SPECIALIST",
1615
+ "provider": "groq",
1616
+ "model": "llama-3.1-8b-instant",
1617
+ "strategy": "confidence_scaled",
1618
+ "bankroll": 5000.0,
1619
+ "total_bets": 0,
1620
+ "total_wins": 0,
1621
+ "win_rate": 0.0,
1622
+ "roi": -50.0,
1623
+ "total_pnl": 0.0,
1624
+ "weight": 1.0,
1625
+ "active": true
1626
+ },
1627
+ "t3_pp_assists_star3_s1": {
1628
+ "id": "t3_pp_assists_star3_s1",
1629
+ "name": "Spec:Player Assists (star3):S1",
1630
+ "tier": "SPECIALIST",
1631
+ "provider": "groq",
1632
+ "model": "gemma2-9b-it",
1633
+ "strategy": "flat_2pct",
1634
+ "bankroll": 5000.0,
1635
+ "total_bets": 0,
1636
+ "total_wins": 0,
1637
+ "win_rate": 0.0,
1638
+ "roi": -50.0,
1639
+ "total_pnl": 0.0,
1640
+ "weight": 1.0,
1641
+ "active": true
1642
+ },
1643
+ "t3_pp_assists_role1_s0": {
1644
+ "id": "t3_pp_assists_role1_s0",
1645
+ "name": "Spec:Player Assists (role1):S0",
1646
+ "tier": "SPECIALIST",
1647
+ "provider": "groq",
1648
+ "model": "llama-3.1-8b-instant",
1649
+ "strategy": "half_kelly",
1650
+ "bankroll": 5000.0,
1651
+ "total_bets": 0,
1652
+ "total_wins": 0,
1653
+ "win_rate": 0.0,
1654
+ "roi": -50.0,
1655
+ "total_pnl": 0.0,
1656
+ "weight": 1.0,
1657
+ "active": true
1658
+ },
1659
+ "t3_pp_assists_role1_s1": {
1660
+ "id": "t3_pp_assists_role1_s1",
1661
+ "name": "Spec:Player Assists (role1):S1",
1662
+ "tier": "SPECIALIST",
1663
+ "provider": "groq",
1664
+ "model": "gemma2-9b-it",
1665
+ "strategy": "quarter_kelly",
1666
+ "bankroll": 5000.0,
1667
+ "total_bets": 0,
1668
+ "total_wins": 0,
1669
+ "win_rate": 0.0,
1670
+ "roi": -50.0,
1671
+ "total_pnl": 0.0,
1672
+ "weight": 1.0,
1673
+ "active": true
1674
+ },
1675
+ "t3_pp_assists_role2_s0": {
1676
+ "id": "t3_pp_assists_role2_s0",
1677
+ "name": "Spec:Player Assists (role2):S0",
1678
+ "tier": "SPECIALIST",
1679
+ "provider": "groq",
1680
+ "model": "llama-3.1-8b-instant",
1681
+ "strategy": "value_hunter",
1682
+ "bankroll": 5000.0,
1683
+ "total_bets": 0,
1684
+ "total_wins": 0,
1685
+ "win_rate": 0.0,
1686
+ "roi": -50.0,
1687
+ "total_pnl": 0.0,
1688
+ "weight": 1.0,
1689
+ "active": true
1690
+ },
1691
+ "t3_pp_assists_role2_s1": {
1692
+ "id": "t3_pp_assists_role2_s1",
1693
+ "name": "Spec:Player Assists (role2):S1",
1694
+ "tier": "SPECIALIST",
1695
+ "provider": "groq",
1696
+ "model": "gemma2-9b-it",
1697
+ "strategy": "proportional_edge",
1698
+ "bankroll": 5000.0,
1699
+ "total_bets": 0,
1700
+ "total_wins": 0,
1701
+ "win_rate": 0.0,
1702
+ "roi": -50.0,
1703
+ "total_pnl": 0.0,
1704
+ "weight": 1.0,
1705
+ "active": true
1706
+ },
1707
+ "t3_pp_threes_star1_s0": {
1708
+ "id": "t3_pp_threes_star1_s0",
1709
+ "name": "Spec:Player Threes (star1):S0",
1710
+ "tier": "SPECIALIST",
1711
+ "provider": "groq",
1712
+ "model": "llama-3.1-8b-instant",
1713
+ "strategy": "confidence_scaled",
1714
+ "bankroll": 5000.0,
1715
+ "total_bets": 0,
1716
+ "total_wins": 0,
1717
+ "win_rate": 0.0,
1718
+ "roi": -50.0,
1719
+ "total_pnl": 0.0,
1720
+ "weight": 1.0,
1721
+ "active": true
1722
+ },
1723
+ "t3_pp_threes_star1_s1": {
1724
+ "id": "t3_pp_threes_star1_s1",
1725
+ "name": "Spec:Player Threes (star1):S1",
1726
+ "tier": "SPECIALIST",
1727
+ "provider": "groq",
1728
+ "model": "gemma2-9b-it",
1729
+ "strategy": "flat_2pct",
1730
+ "bankroll": 5000.0,
1731
+ "total_bets": 0,
1732
+ "total_wins": 0,
1733
+ "win_rate": 0.0,
1734
+ "roi": -50.0,
1735
+ "total_pnl": 0.0,
1736
+ "weight": 1.0,
1737
+ "active": true
1738
+ },
1739
+ "t3_pp_threes_star2_s0": {
1740
+ "id": "t3_pp_threes_star2_s0",
1741
+ "name": "Spec:Player Threes (star2):S0",
1742
+ "tier": "SPECIALIST",
1743
+ "provider": "groq",
1744
+ "model": "llama-3.1-8b-instant",
1745
+ "strategy": "half_kelly",
1746
+ "bankroll": 5000.0,
1747
+ "total_bets": 0,
1748
+ "total_wins": 0,
1749
+ "win_rate": 0.0,
1750
+ "roi": -50.0,
1751
+ "total_pnl": 0.0,
1752
+ "weight": 1.0,
1753
+ "active": true
1754
+ },
1755
+ "t3_pp_threes_star2_s1": {
1756
+ "id": "t3_pp_threes_star2_s1",
1757
+ "name": "Spec:Player Threes (star2):S1",
1758
+ "tier": "SPECIALIST",
1759
+ "provider": "groq",
1760
+ "model": "gemma2-9b-it",
1761
+ "strategy": "quarter_kelly",
1762
+ "bankroll": 5000.0,
1763
+ "total_bets": 0,
1764
+ "total_wins": 0,
1765
+ "win_rate": 0.0,
1766
+ "roi": -50.0,
1767
+ "total_pnl": 0.0,
1768
+ "weight": 1.0,
1769
+ "active": true
1770
+ },
1771
+ "t3_pp_threes_star3_s0": {
1772
+ "id": "t3_pp_threes_star3_s0",
1773
+ "name": "Spec:Player Threes (star3):S0",
1774
+ "tier": "SPECIALIST",
1775
+ "provider": "groq",
1776
+ "model": "llama-3.1-8b-instant",
1777
+ "strategy": "value_hunter",
1778
+ "bankroll": 5000.0,
1779
+ "total_bets": 0,
1780
+ "total_wins": 0,
1781
+ "win_rate": 0.0,
1782
+ "roi": -50.0,
1783
+ "total_pnl": 0.0,
1784
+ "weight": 1.0,
1785
+ "active": true
1786
+ },
1787
+ "t3_pp_threes_star3_s1": {
1788
+ "id": "t3_pp_threes_star3_s1",
1789
+ "name": "Spec:Player Threes (star3):S1",
1790
+ "tier": "SPECIALIST",
1791
+ "provider": "groq",
1792
+ "model": "gemma2-9b-it",
1793
+ "strategy": "proportional_edge",
1794
+ "bankroll": 5000.0,
1795
+ "total_bets": 0,
1796
+ "total_wins": 0,
1797
+ "win_rate": 0.0,
1798
+ "roi": -50.0,
1799
+ "total_pnl": 0.0,
1800
+ "weight": 1.0,
1801
+ "active": true
1802
+ },
1803
+ "t3_pp_threes_role1_s0": {
1804
+ "id": "t3_pp_threes_role1_s0",
1805
+ "name": "Spec:Player Threes (role1):S0",
1806
+ "tier": "SPECIALIST",
1807
+ "provider": "groq",
1808
+ "model": "llama-3.1-8b-instant",
1809
+ "strategy": "confidence_scaled",
1810
+ "bankroll": 5000.0,
1811
+ "total_bets": 0,
1812
+ "total_wins": 0,
1813
+ "win_rate": 0.0,
1814
+ "roi": -50.0,
1815
+ "total_pnl": 0.0,
1816
+ "weight": 1.0,
1817
+ "active": true
1818
+ },
1819
+ "t3_pp_threes_role1_s1": {
1820
+ "id": "t3_pp_threes_role1_s1",
1821
+ "name": "Spec:Player Threes (role1):S1",
1822
+ "tier": "SPECIALIST",
1823
+ "provider": "groq",
1824
+ "model": "gemma2-9b-it",
1825
+ "strategy": "flat_2pct",
1826
+ "bankroll": 5000.0,
1827
+ "total_bets": 0,
1828
+ "total_wins": 0,
1829
+ "win_rate": 0.0,
1830
+ "roi": -50.0,
1831
+ "total_pnl": 0.0,
1832
+ "weight": 1.0,
1833
+ "active": true
1834
+ },
1835
+ "t3_pp_threes_role2_s0": {
1836
+ "id": "t3_pp_threes_role2_s0",
1837
+ "name": "Spec:Player Threes (role2):S0",
1838
+ "tier": "SPECIALIST",
1839
+ "provider": "groq",
1840
+ "model": "llama-3.1-8b-instant",
1841
+ "strategy": "half_kelly",
1842
+ "bankroll": 5000.0,
1843
+ "total_bets": 0,
1844
+ "total_wins": 0,
1845
+ "win_rate": 0.0,
1846
+ "roi": -50.0,
1847
+ "total_pnl": 0.0,
1848
+ "weight": 1.0,
1849
+ "active": true
1850
+ },
1851
+ "t3_pp_threes_role2_s1": {
1852
+ "id": "t3_pp_threes_role2_s1",
1853
+ "name": "Spec:Player Threes (role2):S1",
1854
+ "tier": "SPECIALIST",
1855
+ "provider": "groq",
1856
+ "model": "gemma2-9b-it",
1857
+ "strategy": "quarter_kelly",
1858
+ "bankroll": 5000.0,
1859
+ "total_bets": 0,
1860
+ "total_wins": 0,
1861
+ "win_rate": 0.0,
1862
+ "roi": -50.0,
1863
+ "total_pnl": 0.0,
1864
+ "weight": 1.0,
1865
+ "active": true
1866
+ },
1867
+ "t3_pp_steals_star1_s0": {
1868
+ "id": "t3_pp_steals_star1_s0",
1869
+ "name": "Spec:Player Steals (star1):S0",
1870
+ "tier": "SPECIALIST",
1871
+ "provider": "groq",
1872
+ "model": "llama-3.1-8b-instant",
1873
+ "strategy": "value_hunter",
1874
+ "bankroll": 5000.0,
1875
+ "total_bets": 0,
1876
+ "total_wins": 0,
1877
+ "win_rate": 0.0,
1878
+ "roi": -50.0,
1879
+ "total_pnl": 0.0,
1880
+ "weight": 1.0,
1881
+ "active": true
1882
+ },
1883
+ "t3_pp_steals_star1_s1": {
1884
+ "id": "t3_pp_steals_star1_s1",
1885
+ "name": "Spec:Player Steals (star1):S1",
1886
+ "tier": "SPECIALIST",
1887
+ "provider": "groq",
1888
+ "model": "gemma2-9b-it",
1889
+ "strategy": "proportional_edge",
1890
+ "bankroll": 5000.0,
1891
+ "total_bets": 0,
1892
+ "total_wins": 0,
1893
+ "win_rate": 0.0,
1894
+ "roi": -50.0,
1895
+ "total_pnl": 0.0,
1896
+ "weight": 1.0,
1897
+ "active": true
1898
+ },
1899
+ "t3_pp_steals_star2_s0": {
1900
+ "id": "t3_pp_steals_star2_s0",
1901
+ "name": "Spec:Player Steals (star2):S0",
1902
+ "tier": "SPECIALIST",
1903
+ "provider": "groq",
1904
+ "model": "llama-3.1-8b-instant",
1905
+ "strategy": "confidence_scaled",
1906
+ "bankroll": 5000.0,
1907
+ "total_bets": 0,
1908
+ "total_wins": 0,
1909
+ "win_rate": 0.0,
1910
+ "roi": -50.0,
1911
+ "total_pnl": 0.0,
1912
+ "weight": 1.0,
1913
+ "active": true
1914
+ },
1915
+ "t3_pp_steals_star2_s1": {
1916
+ "id": "t3_pp_steals_star2_s1",
1917
+ "name": "Spec:Player Steals (star2):S1",
1918
+ "tier": "SPECIALIST",
1919
+ "provider": "groq",
1920
+ "model": "gemma2-9b-it",
1921
+ "strategy": "flat_2pct",
1922
+ "bankroll": 5000.0,
1923
+ "total_bets": 0,
1924
+ "total_wins": 0,
1925
+ "win_rate": 0.0,
1926
+ "roi": -50.0,
1927
+ "total_pnl": 0.0,
1928
+ "weight": 1.0,
1929
+ "active": true
1930
+ },
1931
+ "t3_pp_steals_star3_s0": {
1932
+ "id": "t3_pp_steals_star3_s0",
1933
+ "name": "Spec:Player Steals (star3):S0",
1934
+ "tier": "SPECIALIST",
1935
+ "provider": "groq",
1936
+ "model": "llama-3.1-8b-instant",
1937
+ "strategy": "half_kelly",
1938
+ "bankroll": 5000.0,
1939
+ "total_bets": 0,
1940
+ "total_wins": 0,
1941
+ "win_rate": 0.0,
1942
+ "roi": -50.0,
1943
+ "total_pnl": 0.0,
1944
+ "weight": 1.0,
1945
+ "active": true
1946
+ },
1947
+ "t3_pp_steals_star3_s1": {
1948
+ "id": "t3_pp_steals_star3_s1",
1949
+ "name": "Spec:Player Steals (star3):S1",
1950
+ "tier": "SPECIALIST",
1951
+ "provider": "groq",
1952
+ "model": "gemma2-9b-it",
1953
+ "strategy": "quarter_kelly",
1954
+ "bankroll": 5000.0,
1955
+ "total_bets": 0,
1956
+ "total_wins": 0,
1957
+ "win_rate": 0.0,
1958
+ "roi": -50.0,
1959
+ "total_pnl": 0.0,
1960
+ "weight": 1.0,
1961
+ "active": true
1962
+ },
1963
+ "t3_pp_steals_role1_s0": {
1964
+ "id": "t3_pp_steals_role1_s0",
1965
+ "name": "Spec:Player Steals (role1):S0",
1966
+ "tier": "SPECIALIST",
1967
+ "provider": "groq",
1968
+ "model": "llama-3.1-8b-instant",
1969
+ "strategy": "value_hunter",
1970
+ "bankroll": 5000.0,
1971
+ "total_bets": 0,
1972
+ "total_wins": 0,
1973
+ "win_rate": 0.0,
1974
+ "roi": -50.0,
1975
+ "total_pnl": 0.0,
1976
+ "weight": 1.0,
1977
+ "active": true
1978
+ },
1979
+ "t3_pp_steals_role1_s1": {
1980
+ "id": "t3_pp_steals_role1_s1",
1981
+ "name": "Spec:Player Steals (role1):S1",
1982
+ "tier": "SPECIALIST",
1983
+ "provider": "groq",
1984
+ "model": "gemma2-9b-it",
1985
+ "strategy": "proportional_edge",
1986
+ "bankroll": 5000.0,
1987
+ "total_bets": 0,
1988
+ "total_wins": 0,
1989
+ "win_rate": 0.0,
1990
+ "roi": -50.0,
1991
+ "total_pnl": 0.0,
1992
+ "weight": 1.0,
1993
+ "active": true
1994
+ },
1995
+ "t3_pp_steals_role2_s0": {
1996
+ "id": "t3_pp_steals_role2_s0",
1997
+ "name": "Spec:Player Steals (role2):S0",
1998
+ "tier": "SPECIALIST",
1999
+ "provider": "groq",
2000
+ "model": "llama-3.1-8b-instant",
2001
+ "strategy": "confidence_scaled",
2002
+ "bankroll": 5000.0,
2003
+ "total_bets": 0,
2004
+ "total_wins": 0,
2005
+ "win_rate": 0.0,
2006
+ "roi": -50.0,
2007
+ "total_pnl": 0.0,
2008
+ "weight": 1.0,
2009
+ "active": true
2010
+ },
2011
+ "t3_pp_steals_role2_s1": {
2012
+ "id": "t3_pp_steals_role2_s1",
2013
+ "name": "Spec:Player Steals (role2):S1",
2014
+ "tier": "SPECIALIST",
2015
+ "provider": "groq",
2016
+ "model": "gemma2-9b-it",
2017
+ "strategy": "flat_2pct",
2018
+ "bankroll": 5000.0,
2019
+ "total_bets": 0,
2020
+ "total_wins": 0,
2021
+ "win_rate": 0.0,
2022
+ "roi": -50.0,
2023
+ "total_pnl": 0.0,
2024
+ "weight": 1.0,
2025
+ "active": true
2026
+ },
2027
+ "t3_pp_blocks_star1_s0": {
2028
+ "id": "t3_pp_blocks_star1_s0",
2029
+ "name": "Spec:Player Blocks (star1):S0",
2030
+ "tier": "SPECIALIST",
2031
+ "provider": "groq",
2032
+ "model": "llama-3.1-8b-instant",
2033
+ "strategy": "half_kelly",
2034
+ "bankroll": 5000.0,
2035
+ "total_bets": 0,
2036
+ "total_wins": 0,
2037
+ "win_rate": 0.0,
2038
+ "roi": -50.0,
2039
+ "total_pnl": 0.0,
2040
+ "weight": 1.0,
2041
+ "active": true
2042
+ },
2043
+ "t3_pp_blocks_star1_s1": {
2044
+ "id": "t3_pp_blocks_star1_s1",
2045
+ "name": "Spec:Player Blocks (star1):S1",
2046
+ "tier": "SPECIALIST",
2047
+ "provider": "groq",
2048
+ "model": "gemma2-9b-it",
2049
+ "strategy": "quarter_kelly",
2050
+ "bankroll": 5000.0,
2051
+ "total_bets": 0,
2052
+ "total_wins": 0,
2053
+ "win_rate": 0.0,
2054
+ "roi": -50.0,
2055
+ "total_pnl": 0.0,
2056
+ "weight": 1.0,
2057
+ "active": true
2058
+ },
2059
+ "t3_pp_blocks_star2_s0": {
2060
+ "id": "t3_pp_blocks_star2_s0",
2061
+ "name": "Spec:Player Blocks (star2):S0",
2062
+ "tier": "SPECIALIST",
2063
+ "provider": "groq",
2064
+ "model": "llama-3.1-8b-instant",
2065
+ "strategy": "value_hunter",
2066
+ "bankroll": 5000.0,
2067
+ "total_bets": 0,
2068
+ "total_wins": 0,
2069
+ "win_rate": 0.0,
2070
+ "roi": -50.0,
2071
+ "total_pnl": 0.0,
2072
+ "weight": 1.0,
2073
+ "active": true
2074
+ },
2075
+ "t3_pp_blocks_star2_s1": {
2076
+ "id": "t3_pp_blocks_star2_s1",
2077
+ "name": "Spec:Player Blocks (star2):S1",
2078
+ "tier": "SPECIALIST",
2079
+ "provider": "groq",
2080
+ "model": "gemma2-9b-it",
2081
+ "strategy": "proportional_edge",
2082
+ "bankroll": 5000.0,
2083
+ "total_bets": 0,
2084
+ "total_wins": 0,
2085
+ "win_rate": 0.0,
2086
+ "roi": -50.0,
2087
+ "total_pnl": 0.0,
2088
+ "weight": 1.0,
2089
+ "active": true
2090
+ },
2091
+ "t3_pp_blocks_star3_s0": {
2092
+ "id": "t3_pp_blocks_star3_s0",
2093
+ "name": "Spec:Player Blocks (star3):S0",
2094
+ "tier": "SPECIALIST",
2095
+ "provider": "groq",
2096
+ "model": "llama-3.1-8b-instant",
2097
+ "strategy": "confidence_scaled",
2098
+ "bankroll": 5000.0,
2099
+ "total_bets": 0,
2100
+ "total_wins": 0,
2101
+ "win_rate": 0.0,
2102
+ "roi": -50.0,
2103
+ "total_pnl": 0.0,
2104
+ "weight": 1.0,
2105
+ "active": true
2106
+ },
2107
+ "t3_pp_blocks_star3_s1": {
2108
+ "id": "t3_pp_blocks_star3_s1",
2109
+ "name": "Spec:Player Blocks (star3):S1",
2110
+ "tier": "SPECIALIST",
2111
+ "provider": "groq",
2112
+ "model": "gemma2-9b-it",
2113
+ "strategy": "flat_2pct",
2114
+ "bankroll": 5000.0,
2115
+ "total_bets": 0,
2116
+ "total_wins": 0,
2117
+ "win_rate": 0.0,
2118
+ "roi": -50.0,
2119
+ "total_pnl": 0.0,
2120
+ "weight": 1.0,
2121
+ "active": true
2122
+ },
2123
+ "t3_pp_blocks_role1_s0": {
2124
+ "id": "t3_pp_blocks_role1_s0",
2125
+ "name": "Spec:Player Blocks (role1):S0",
2126
+ "tier": "SPECIALIST",
2127
+ "provider": "groq",
2128
+ "model": "llama-3.1-8b-instant",
2129
+ "strategy": "half_kelly",
2130
+ "bankroll": 5000.0,
2131
+ "total_bets": 0,
2132
+ "total_wins": 0,
2133
+ "win_rate": 0.0,
2134
+ "roi": -50.0,
2135
+ "total_pnl": 0.0,
2136
+ "weight": 1.0,
2137
+ "active": true
2138
+ },
2139
+ "t3_pp_blocks_role1_s1": {
2140
+ "id": "t3_pp_blocks_role1_s1",
2141
+ "name": "Spec:Player Blocks (role1):S1",
2142
+ "tier": "SPECIALIST",
2143
+ "provider": "groq",
2144
+ "model": "gemma2-9b-it",
2145
+ "strategy": "quarter_kelly",
2146
+ "bankroll": 5000.0,
2147
+ "total_bets": 0,
2148
+ "total_wins": 0,
2149
+ "win_rate": 0.0,
2150
+ "roi": -50.0,
2151
+ "total_pnl": 0.0,
2152
+ "weight": 1.0,
2153
+ "active": true
2154
+ },
2155
+ "t3_pp_blocks_role2_s0": {
2156
+ "id": "t3_pp_blocks_role2_s0",
2157
+ "name": "Spec:Player Blocks (role2):S0",
2158
+ "tier": "SPECIALIST",
2159
+ "provider": "groq",
2160
+ "model": "llama-3.1-8b-instant",
2161
+ "strategy": "value_hunter",
2162
+ "bankroll": 5000.0,
2163
+ "total_bets": 0,
2164
+ "total_wins": 0,
2165
+ "win_rate": 0.0,
2166
+ "roi": -50.0,
2167
+ "total_pnl": 0.0,
2168
+ "weight": 1.0,
2169
+ "active": true
2170
+ },
2171
+ "t3_pp_blocks_role2_s1": {
2172
+ "id": "t3_pp_blocks_role2_s1",
2173
+ "name": "Spec:Player Blocks (role2):S1",
2174
+ "tier": "SPECIALIST",
2175
+ "provider": "groq",
2176
+ "model": "gemma2-9b-it",
2177
+ "strategy": "proportional_edge",
2178
+ "bankroll": 5000.0,
2179
+ "total_bets": 0,
2180
+ "total_wins": 0,
2181
+ "win_rate": 0.0,
2182
+ "roi": -50.0,
2183
+ "total_pnl": 0.0,
2184
+ "weight": 1.0,
2185
+ "active": true
2186
+ },
2187
+ "t3_margin_1_5_s0": {
2188
+ "id": "t3_margin_1_5_s0",
2189
+ "name": "Spec:Win Margin 1-5:S0",
2190
+ "tier": "SPECIALIST",
2191
+ "provider": "groq",
2192
+ "model": "llama-3.1-8b-instant",
2193
+ "strategy": "confidence_scaled",
2194
+ "bankroll": 5000.0,
2195
+ "total_bets": 0,
2196
+ "total_wins": 0,
2197
+ "win_rate": 0.0,
2198
+ "roi": -50.0,
2199
+ "total_pnl": 0.0,
2200
+ "weight": 1.0,
2201
+ "active": true
2202
+ },
2203
+ "t3_margin_6_10_s0": {
2204
+ "id": "t3_margin_6_10_s0",
2205
+ "name": "Spec:Win Margin 6-10:S0",
2206
+ "tier": "SPECIALIST",
2207
+ "provider": "groq",
2208
+ "model": "gemma2-9b-it",
2209
+ "strategy": "flat_2pct",
2210
+ "bankroll": 5000.0,
2211
+ "total_bets": 0,
2212
+ "total_wins": 0,
2213
+ "win_rate": 0.0,
2214
+ "roi": -50.0,
2215
+ "total_pnl": 0.0,
2216
+ "weight": 1.0,
2217
+ "active": true
2218
+ },
2219
+ "t3_margin_11_15_s0": {
2220
+ "id": "t3_margin_11_15_s0",
2221
+ "name": "Spec:Win Margin 11-15:S0",
2222
+ "tier": "SPECIALIST",
2223
+ "provider": "groq",
2224
+ "model": "llama-3.1-8b-instant",
2225
+ "strategy": "half_kelly",
2226
+ "bankroll": 5000.0,
2227
+ "total_bets": 0,
2228
+ "total_wins": 0,
2229
+ "win_rate": 0.0,
2230
+ "roi": -50.0,
2231
+ "total_pnl": 0.0,
2232
+ "weight": 1.0,
2233
+ "active": true
2234
+ },
2235
+ "t3_margin_16_20_s0": {
2236
+ "id": "t3_margin_16_20_s0",
2237
+ "name": "Spec:Win Margin 16-20:S0",
2238
+ "tier": "SPECIALIST",
2239
+ "provider": "groq",
2240
+ "model": "gemma2-9b-it",
2241
+ "strategy": "quarter_kelly",
2242
+ "bankroll": 5000.0,
2243
+ "total_bets": 0,
2244
+ "total_wins": 0,
2245
+ "win_rate": 0.0,
2246
+ "roi": -50.0,
2247
+ "total_pnl": 0.0,
2248
+ "weight": 1.0,
2249
+ "active": true
2250
+ },
2251
+ "t3_margin_21p_s0": {
2252
+ "id": "t3_margin_21p_s0",
2253
+ "name": "Spec:Win Margin 21+:S0",
2254
+ "tier": "SPECIALIST",
2255
+ "provider": "groq",
2256
+ "model": "llama-3.1-8b-instant",
2257
+ "strategy": "value_hunter",
2258
+ "bankroll": 5000.0,
2259
+ "total_bets": 0,
2260
+ "total_wins": 0,
2261
+ "win_rate": 0.0,
2262
+ "roi": -50.0,
2263
+ "total_pnl": 0.0,
2264
+ "weight": 1.0,
2265
+ "active": true
2266
+ },
2267
+ "t3_margin_exact_home_s0": {
2268
+ "id": "t3_margin_exact_home_s0",
2269
+ "name": "Spec:Exact Margin Home Wins:S0",
2270
+ "tier": "SPECIALIST",
2271
+ "provider": "groq",
2272
+ "model": "gemma2-9b-it",
2273
+ "strategy": "proportional_edge",
2274
+ "bankroll": 5000.0,
2275
+ "total_bets": 0,
2276
+ "total_wins": 0,
2277
+ "win_rate": 0.0,
2278
+ "roi": -50.0,
2279
+ "total_pnl": 0.0,
2280
+ "weight": 1.0,
2281
+ "active": true
2282
+ },
2283
+ "t3_margin_exact_away_s0": {
2284
+ "id": "t3_margin_exact_away_s0",
2285
+ "name": "Spec:Exact Margin Away Wins:S0",
2286
+ "tier": "SPECIALIST",
2287
+ "provider": "groq",
2288
+ "model": "llama-3.1-8b-instant",
2289
+ "strategy": "confidence_scaled",
2290
+ "bankroll": 5000.0,
2291
+ "total_bets": 0,
2292
+ "total_wins": 0,
2293
+ "win_rate": 0.0,
2294
+ "roi": -50.0,
2295
+ "total_pnl": 0.0,
2296
+ "weight": 1.0,
2297
+ "active": true
2298
+ },
2299
+ "t3_odd_even_s0": {
2300
+ "id": "t3_odd_even_s0",
2301
+ "name": "Spec:Odd/Even Total:S0",
2302
+ "tier": "SPECIALIST",
2303
+ "provider": "groq",
2304
+ "model": "gemma2-9b-it",
2305
+ "strategy": "flat_2pct",
2306
+ "bankroll": 5000.0,
2307
+ "total_bets": 0,
2308
+ "total_wins": 0,
2309
+ "win_rate": 0.0,
2310
+ "roi": -50.0,
2311
+ "total_pnl": 0.0,
2312
+ "weight": 1.0,
2313
+ "active": true
2314
+ },
2315
+ "t3_odd_even_s1": {
2316
+ "id": "t3_odd_even_s1",
2317
+ "name": "Spec:Odd/Even Total:S1",
2318
+ "tier": "SPECIALIST",
2319
+ "provider": "groq",
2320
+ "model": "llama-3.1-8b-instant",
2321
+ "strategy": "half_kelly",
2322
+ "bankroll": 5000.0,
2323
+ "total_bets": 0,
2324
+ "total_wins": 0,
2325
+ "win_rate": 0.0,
2326
+ "roi": -50.0,
2327
+ "total_pnl": 0.0,
2328
+ "weight": 1.0,
2329
+ "active": true
2330
+ },
2331
+ "t3_race_20_s0": {
2332
+ "id": "t3_race_20_s0",
2333
+ "name": "Spec:Race to 20 Points:S0",
2334
+ "tier": "SPECIALIST",
2335
+ "provider": "groq",
2336
+ "model": "gemma2-9b-it",
2337
+ "strategy": "quarter_kelly",
2338
+ "bankroll": 5000.0,
2339
+ "total_bets": 0,
2340
+ "total_wins": 0,
2341
+ "win_rate": 0.0,
2342
+ "roi": -50.0,
2343
+ "total_pnl": 0.0,
2344
+ "weight": 1.0,
2345
+ "active": true
2346
+ },
2347
+ "t3_race_20_s1": {
2348
+ "id": "t3_race_20_s1",
2349
+ "name": "Spec:Race to 20 Points:S1",
2350
+ "tier": "SPECIALIST",
2351
+ "provider": "groq",
2352
+ "model": "llama-3.1-8b-instant",
2353
+ "strategy": "value_hunter",
2354
+ "bankroll": 5000.0,
2355
+ "total_bets": 0,
2356
+ "total_wins": 0,
2357
+ "win_rate": 0.0,
2358
+ "roi": -50.0,
2359
+ "total_pnl": 0.0,
2360
+ "weight": 1.0,
2361
+ "active": true
2362
+ },
2363
+ "t3_race_30_s0": {
2364
+ "id": "t3_race_30_s0",
2365
+ "name": "Spec:Race to 30 Points:S0",
2366
+ "tier": "SPECIALIST",
2367
+ "provider": "groq",
2368
+ "model": "gemma2-9b-it",
2369
+ "strategy": "proportional_edge",
2370
+ "bankroll": 5000.0,
2371
+ "total_bets": 0,
2372
+ "total_wins": 0,
2373
+ "win_rate": 0.0,
2374
+ "roi": -50.0,
2375
+ "total_pnl": 0.0,
2376
+ "weight": 1.0,
2377
+ "active": true
2378
+ },
2379
+ "t3_race_30_s1": {
2380
+ "id": "t3_race_30_s1",
2381
+ "name": "Spec:Race to 30 Points:S1",
2382
+ "tier": "SPECIALIST",
2383
+ "provider": "groq",
2384
+ "model": "llama-3.1-8b-instant",
2385
+ "strategy": "confidence_scaled",
2386
+ "bankroll": 5000.0,
2387
+ "total_bets": 0,
2388
+ "total_wins": 0,
2389
+ "win_rate": 0.0,
2390
+ "roi": -50.0,
2391
+ "total_pnl": 0.0,
2392
+ "weight": 1.0,
2393
+ "active": true
2394
+ },
2395
+ "t3_race_50_s0": {
2396
+ "id": "t3_race_50_s0",
2397
+ "name": "Spec:Race to 50 Points:S0",
2398
+ "tier": "SPECIALIST",
2399
+ "provider": "groq",
2400
+ "model": "gemma2-9b-it",
2401
+ "strategy": "flat_2pct",
2402
+ "bankroll": 5000.0,
2403
+ "total_bets": 0,
2404
+ "total_wins": 0,
2405
+ "win_rate": 0.0,
2406
+ "roi": -50.0,
2407
+ "total_pnl": 0.0,
2408
+ "weight": 1.0,
2409
+ "active": true
2410
+ },
2411
+ "t3_race_50_s1": {
2412
+ "id": "t3_race_50_s1",
2413
+ "name": "Spec:Race to 50 Points:S1",
2414
+ "tier": "SPECIALIST",
2415
+ "provider": "groq",
2416
+ "model": "llama-3.1-8b-instant",
2417
+ "strategy": "half_kelly",
2418
+ "bankroll": 5000.0,
2419
+ "total_bets": 0,
2420
+ "total_wins": 0,
2421
+ "win_rate": 0.0,
2422
+ "roi": -50.0,
2423
+ "total_pnl": 0.0,
2424
+ "weight": 1.0,
2425
+ "active": true
2426
+ },
2427
+ "t3_first_basket_s0": {
2428
+ "id": "t3_first_basket_s0",
2429
+ "name": "Spec:First Basket:S0",
2430
+ "tier": "SPECIALIST",
2431
+ "provider": "groq",
2432
+ "model": "gemma2-9b-it",
2433
+ "strategy": "quarter_kelly",
2434
+ "bankroll": 5000.0,
2435
+ "total_bets": 0,
2436
+ "total_wins": 0,
2437
+ "win_rate": 0.0,
2438
+ "roi": -50.0,
2439
+ "total_pnl": 0.0,
2440
+ "weight": 1.0,
2441
+ "active": true
2442
+ },
2443
+ "t3_first_basket_s1": {
2444
+ "id": "t3_first_basket_s1",
2445
+ "name": "Spec:First Basket:S1",
2446
+ "tier": "SPECIALIST",
2447
+ "provider": "groq",
2448
+ "model": "llama-3.1-8b-instant",
2449
+ "strategy": "value_hunter",
2450
+ "bankroll": 5000.0,
2451
+ "total_bets": 0,
2452
+ "total_wins": 0,
2453
+ "win_rate": 0.0,
2454
+ "roi": -50.0,
2455
+ "total_pnl": 0.0,
2456
+ "weight": 1.0,
2457
+ "active": true
2458
+ },
2459
+ "t3_first_to_10_s0": {
2460
+ "id": "t3_first_to_10_s0",
2461
+ "name": "Spec:First to 10:S0",
2462
+ "tier": "SPECIALIST",
2463
+ "provider": "groq",
2464
+ "model": "gemma2-9b-it",
2465
+ "strategy": "proportional_edge",
2466
+ "bankroll": 5000.0,
2467
+ "total_bets": 0,
2468
+ "total_wins": 0,
2469
+ "win_rate": 0.0,
2470
+ "roi": -50.0,
2471
+ "total_pnl": 0.0,
2472
+ "weight": 1.0,
2473
+ "active": true
2474
+ },
2475
+ "t3_first_to_10_s1": {
2476
+ "id": "t3_first_to_10_s1",
2477
+ "name": "Spec:First to 10:S1",
2478
+ "tier": "SPECIALIST",
2479
+ "provider": "groq",
2480
+ "model": "llama-3.1-8b-instant",
2481
+ "strategy": "confidence_scaled",
2482
+ "bankroll": 5000.0,
2483
+ "total_bets": 0,
2484
+ "total_wins": 0,
2485
+ "win_rate": 0.0,
2486
+ "roi": -50.0,
2487
+ "total_pnl": 0.0,
2488
+ "weight": 1.0,
2489
+ "active": true
2490
+ },
2491
+ "t3_lead_after_q1_s0": {
2492
+ "id": "t3_lead_after_q1_s0",
2493
+ "name": "Spec:Lead After Q1:S0",
2494
+ "tier": "SPECIALIST",
2495
+ "provider": "groq",
2496
+ "model": "gemma2-9b-it",
2497
+ "strategy": "flat_2pct",
2498
+ "bankroll": 5000.0,
2499
+ "total_bets": 0,
2500
+ "total_wins": 0,
2501
+ "win_rate": 0.0,
2502
+ "roi": -50.0,
2503
+ "total_pnl": 0.0,
2504
+ "weight": 1.0,
2505
+ "active": true
2506
+ },
2507
+ "t3_lead_after_q1_s1": {
2508
+ "id": "t3_lead_after_q1_s1",
2509
+ "name": "Spec:Lead After Q1:S1",
2510
+ "tier": "SPECIALIST",
2511
+ "provider": "groq",
2512
+ "model": "llama-3.1-8b-instant",
2513
+ "strategy": "half_kelly",
2514
+ "bankroll": 5000.0,
2515
+ "total_bets": 0,
2516
+ "total_wins": 0,
2517
+ "win_rate": 0.0,
2518
+ "roi": -50.0,
2519
+ "total_pnl": 0.0,
2520
+ "weight": 1.0,
2521
+ "active": true
2522
+ },
2523
+ "t3_lead_change_count_s0": {
2524
+ "id": "t3_lead_change_count_s0",
2525
+ "name": "Spec:Lead Changes O/U:S0",
2526
+ "tier": "SPECIALIST",
2527
+ "provider": "groq",
2528
+ "model": "gemma2-9b-it",
2529
+ "strategy": "quarter_kelly",
2530
+ "bankroll": 5000.0,
2531
+ "total_bets": 0,
2532
+ "total_wins": 0,
2533
+ "win_rate": 0.0,
2534
+ "roi": -50.0,
2535
+ "total_pnl": 0.0,
2536
+ "weight": 1.0,
2537
+ "active": true
2538
+ },
2539
+ "t3_lead_change_count_s1": {
2540
+ "id": "t3_lead_change_count_s1",
2541
+ "name": "Spec:Lead Changes O/U:S1",
2542
+ "tier": "SPECIALIST",
2543
+ "provider": "groq",
2544
+ "model": "llama-3.1-8b-instant",
2545
+ "strategy": "value_hunter",
2546
+ "bankroll": 5000.0,
2547
+ "total_bets": 0,
2548
+ "total_wins": 0,
2549
+ "win_rate": 0.0,
2550
+ "roi": -50.0,
2551
+ "total_pnl": 0.0,
2552
+ "weight": 1.0,
2553
+ "active": true
2554
+ },
2555
+ "t3_double_result_s0": {
2556
+ "id": "t3_double_result_s0",
2557
+ "name": "Spec:Double Result (1H/FG):S0",
2558
+ "tier": "SPECIALIST",
2559
+ "provider": "groq",
2560
+ "model": "gemma2-9b-it",
2561
+ "strategy": "proportional_edge",
2562
+ "bankroll": 5000.0,
2563
+ "total_bets": 0,
2564
+ "total_wins": 0,
2565
+ "win_rate": 0.0,
2566
+ "roi": -50.0,
2567
+ "total_pnl": 0.0,
2568
+ "weight": 1.0,
2569
+ "active": true
2570
+ },
2571
+ "t3_double_result_s1": {
2572
+ "id": "t3_double_result_s1",
2573
+ "name": "Spec:Double Result (1H/FG):S1",
2574
+ "tier": "SPECIALIST",
2575
+ "provider": "groq",
2576
+ "model": "llama-3.1-8b-instant",
2577
+ "strategy": "confidence_scaled",
2578
+ "bankroll": 5000.0,
2579
+ "total_bets": 0,
2580
+ "total_wins": 0,
2581
+ "win_rate": 0.0,
2582
+ "roi": -50.0,
2583
+ "total_pnl": 0.0,
2584
+ "weight": 1.0,
2585
+ "active": true
2586
+ },
2587
+ "t3_double_result_s2": {
2588
+ "id": "t3_double_result_s2",
2589
+ "name": "Spec:Double Result (1H/FG):S2",
2590
+ "tier": "SPECIALIST",
2591
+ "provider": "groq",
2592
+ "model": "gemma2-9b-it",
2593
+ "strategy": "flat_2pct",
2594
+ "bankroll": 5000.0,
2595
+ "total_bets": 0,
2596
+ "total_wins": 0,
2597
+ "win_rate": 0.0,
2598
+ "roi": -50.0,
2599
+ "total_pnl": 0.0,
2600
+ "weight": 1.0,
2601
+ "active": true
2602
+ },
2603
+ "t3_double_result_s3": {
2604
+ "id": "t3_double_result_s3",
2605
+ "name": "Spec:Double Result (1H/FG):S3",
2606
+ "tier": "SPECIALIST",
2607
+ "provider": "groq",
2608
+ "model": "llama-3.1-8b-instant",
2609
+ "strategy": "half_kelly",
2610
+ "bankroll": 5000.0,
2611
+ "total_bets": 0,
2612
+ "total_wins": 0,
2613
+ "win_rate": 0.0,
2614
+ "roi": -50.0,
2615
+ "total_pnl": 0.0,
2616
+ "weight": 1.0,
2617
+ "active": true
2618
+ },
2619
+ "t3_highest_scoring_q_s0": {
2620
+ "id": "t3_highest_scoring_q_s0",
2621
+ "name": "Spec:Highest Scoring Quarter:S0",
2622
+ "tier": "SPECIALIST",
2623
+ "provider": "groq",
2624
+ "model": "gemma2-9b-it",
2625
+ "strategy": "quarter_kelly",
2626
+ "bankroll": 5000.0,
2627
+ "total_bets": 0,
2628
+ "total_wins": 0,
2629
+ "win_rate": 0.0,
2630
+ "roi": -50.0,
2631
+ "total_pnl": 0.0,
2632
+ "weight": 1.0,
2633
+ "active": true
2634
+ },
2635
+ "t3_highest_scoring_q_s1": {
2636
+ "id": "t3_highest_scoring_q_s1",
2637
+ "name": "Spec:Highest Scoring Quarter:S1",
2638
+ "tier": "SPECIALIST",
2639
+ "provider": "groq",
2640
+ "model": "llama-3.1-8b-instant",
2641
+ "strategy": "value_hunter",
2642
+ "bankroll": 5000.0,
2643
+ "total_bets": 0,
2644
+ "total_wins": 0,
2645
+ "win_rate": 0.0,
2646
+ "roi": -50.0,
2647
+ "total_pnl": 0.0,
2648
+ "weight": 1.0,
2649
+ "active": true
2650
+ },
2651
+ "t3_highest_scoring_q_s2": {
2652
+ "id": "t3_highest_scoring_q_s2",
2653
+ "name": "Spec:Highest Scoring Quarter:S2",
2654
+ "tier": "SPECIALIST",
2655
+ "provider": "groq",
2656
+ "model": "gemma2-9b-it",
2657
+ "strategy": "proportional_edge",
2658
+ "bankroll": 5000.0,
2659
+ "total_bets": 0,
2660
+ "total_wins": 0,
2661
+ "win_rate": 0.0,
2662
+ "roi": -50.0,
2663
+ "total_pnl": 0.0,
2664
+ "weight": 1.0,
2665
+ "active": true
2666
+ },
2667
+ "t3_highest_scoring_q_s3": {
2668
+ "id": "t3_highest_scoring_q_s3",
2669
+ "name": "Spec:Highest Scoring Quarter:S3",
2670
+ "tier": "SPECIALIST",
2671
+ "provider": "groq",
2672
+ "model": "llama-3.1-8b-instant",
2673
+ "strategy": "confidence_scaled",
2674
+ "bankroll": 5000.0,
2675
+ "total_bets": 0,
2676
+ "total_wins": 0,
2677
+ "win_rate": 0.0,
2678
+ "roi": -50.0,
2679
+ "total_pnl": 0.0,
2680
+ "weight": 1.0,
2681
+ "active": true
2682
+ },
2683
+ "t3_lowest_scoring_q_s0": {
2684
+ "id": "t3_lowest_scoring_q_s0",
2685
+ "name": "Spec:Lowest Scoring Quarter:S0",
2686
+ "tier": "SPECIALIST",
2687
+ "provider": "groq",
2688
+ "model": "gemma2-9b-it",
2689
+ "strategy": "flat_2pct",
2690
+ "bankroll": 5000.0,
2691
+ "total_bets": 0,
2692
+ "total_wins": 0,
2693
+ "win_rate": 0.0,
2694
+ "roi": -50.0,
2695
+ "total_pnl": 0.0,
2696
+ "weight": 1.0,
2697
+ "active": true
2698
+ },
2699
+ "t3_lowest_scoring_q_s1": {
2700
+ "id": "t3_lowest_scoring_q_s1",
2701
+ "name": "Spec:Lowest Scoring Quarter:S1",
2702
+ "tier": "SPECIALIST",
2703
+ "provider": "groq",
2704
+ "model": "llama-3.1-8b-instant",
2705
+ "strategy": "half_kelly",
2706
+ "bankroll": 5000.0,
2707
+ "total_bets": 0,
2708
+ "total_wins": 0,
2709
+ "win_rate": 0.0,
2710
+ "roi": -50.0,
2711
+ "total_pnl": 0.0,
2712
+ "weight": 1.0,
2713
+ "active": true
2714
+ },
2715
+ "t3_lowest_scoring_q_s2": {
2716
+ "id": "t3_lowest_scoring_q_s2",
2717
+ "name": "Spec:Lowest Scoring Quarter:S2",
2718
+ "tier": "SPECIALIST",
2719
+ "provider": "groq",
2720
+ "model": "gemma2-9b-it",
2721
+ "strategy": "quarter_kelly",
2722
+ "bankroll": 5000.0,
2723
+ "total_bets": 0,
2724
+ "total_wins": 0,
2725
+ "win_rate": 0.0,
2726
+ "roi": -50.0,
2727
+ "total_pnl": 0.0,
2728
+ "weight": 1.0,
2729
+ "active": true
2730
+ },
2731
+ "t3_lowest_scoring_q_s3": {
2732
+ "id": "t3_lowest_scoring_q_s3",
2733
+ "name": "Spec:Lowest Scoring Quarter:S3",
2734
+ "tier": "SPECIALIST",
2735
+ "provider": "groq",
2736
+ "model": "llama-3.1-8b-instant",
2737
+ "strategy": "value_hunter",
2738
+ "bankroll": 5000.0,
2739
+ "total_bets": 0,
2740
+ "total_wins": 0,
2741
+ "win_rate": 0.0,
2742
+ "roi": -50.0,
2743
+ "total_pnl": 0.0,
2744
+ "weight": 1.0,
2745
+ "active": true
2746
+ },
2747
+ "t3_both_100_s0": {
2748
+ "id": "t3_both_100_s0",
2749
+ "name": "Spec:Both Teams Over 100:S0",
2750
+ "tier": "SPECIALIST",
2751
+ "provider": "groq",
2752
+ "model": "gemma2-9b-it",
2753
+ "strategy": "proportional_edge",
2754
+ "bankroll": 5000.0,
2755
+ "total_bets": 0,
2756
+ "total_wins": 0,
2757
+ "win_rate": 0.0,
2758
+ "roi": -50.0,
2759
+ "total_pnl": 0.0,
2760
+ "weight": 1.0,
2761
+ "active": true
2762
+ },
2763
+ "t3_blowout_15_s0": {
2764
+ "id": "t3_blowout_15_s0",
2765
+ "name": "Spec:Blowout by 15+:S0",
2766
+ "tier": "SPECIALIST",
2767
+ "provider": "groq",
2768
+ "model": "llama-3.1-8b-instant",
2769
+ "strategy": "confidence_scaled",
2770
+ "bankroll": 5000.0,
2771
+ "total_bets": 0,
2772
+ "total_wins": 0,
2773
+ "win_rate": 0.0,
2774
+ "roi": -50.0,
2775
+ "total_pnl": 0.0,
2776
+ "weight": 1.0,
2777
+ "active": true
2778
+ },
2779
+ "t3_overtime_s0": {
2780
+ "id": "t3_overtime_s0",
2781
+ "name": "Spec:Overtime:S0",
2782
+ "tier": "SPECIALIST",
2783
+ "provider": "groq",
2784
+ "model": "gemma2-9b-it",
2785
+ "strategy": "flat_2pct",
2786
+ "bankroll": 5000.0,
2787
+ "total_bets": 0,
2788
+ "total_wins": 0,
2789
+ "win_rate": 0.0,
2790
+ "roi": -50.0,
2791
+ "total_pnl": 0.0,
2792
+ "weight": 1.0,
2793
+ "active": true
2794
+ },
2795
+ "t3_triple_double_s0": {
2796
+ "id": "t3_triple_double_s0",
2797
+ "name": "Spec:Any Triple-Double:S0",
2798
+ "tier": "SPECIALIST",
2799
+ "provider": "groq",
2800
+ "model": "llama-3.1-8b-instant",
2801
+ "strategy": "half_kelly",
2802
+ "bankroll": 5000.0,
2803
+ "total_bets": 0,
2804
+ "total_wins": 0,
2805
+ "win_rate": 0.0,
2806
+ "roi": -50.0,
2807
+ "total_pnl": 0.0,
2808
+ "weight": 1.0,
2809
+ "active": true
2810
+ },
2811
+ "t3_sgp_ml_over_s0": {
2812
+ "id": "t3_sgp_ml_over_s0",
2813
+ "name": "Spec:SGP: ML + Over:S0",
2814
+ "tier": "SPECIALIST",
2815
+ "provider": "groq",
2816
+ "model": "gemma2-9b-it",
2817
+ "strategy": "quarter_kelly",
2818
+ "bankroll": 5000.0,
2819
+ "total_bets": 0,
2820
+ "total_wins": 0,
2821
+ "win_rate": 0.0,
2822
+ "roi": -50.0,
2823
+ "total_pnl": 0.0,
2824
+ "weight": 1.0,
2825
+ "active": true
2826
+ },
2827
+ "t3_sgp_ml_under_s0": {
2828
+ "id": "t3_sgp_ml_under_s0",
2829
+ "name": "Spec:SGP: ML + Under:S0",
2830
+ "tier": "SPECIALIST",
2831
+ "provider": "groq",
2832
+ "model": "llama-3.1-8b-instant",
2833
+ "strategy": "value_hunter",
2834
+ "bankroll": 5000.0,
2835
+ "total_bets": 0,
2836
+ "total_wins": 0,
2837
+ "win_rate": 0.0,
2838
+ "roi": -50.0,
2839
+ "total_pnl": 0.0,
2840
+ "weight": 1.0,
2841
+ "active": true
2842
+ },
2843
+ "t3_sgp_dog_over_s0": {
2844
+ "id": "t3_sgp_dog_over_s0",
2845
+ "name": "Spec:SGP: Dog + Over:S0",
2846
+ "tier": "SPECIALIST",
2847
+ "provider": "groq",
2848
+ "model": "gemma2-9b-it",
2849
+ "strategy": "proportional_edge",
2850
+ "bankroll": 5000.0,
2851
+ "total_bets": 0,
2852
+ "total_wins": 0,
2853
+ "win_rate": 0.0,
2854
+ "roi": -50.0,
2855
+ "total_pnl": 0.0,
2856
+ "weight": 1.0,
2857
+ "active": true
2858
+ },
2859
+ "t3_sgp_spread_player_s0": {
2860
+ "id": "t3_sgp_spread_player_s0",
2861
+ "name": "Spec:SGP: Spread + Player Prop:S0",
2862
+ "tier": "SPECIALIST",
2863
+ "provider": "groq",
2864
+ "model": "llama-3.1-8b-instant",
2865
+ "strategy": "confidence_scaled",
2866
+ "bankroll": 5000.0,
2867
+ "total_bets": 0,
2868
+ "total_wins": 0,
2869
+ "win_rate": 0.0,
2870
+ "roi": -50.0,
2871
+ "total_pnl": 0.0,
2872
+ "weight": 1.0,
2873
+ "active": true
2874
+ },
2875
+ "t3_parlay_2leg_ml_s0": {
2876
+ "id": "t3_parlay_2leg_ml_s0",
2877
+ "name": "Spec:2-Leg ML Parlay:S0",
2878
+ "tier": "SPECIALIST",
2879
+ "provider": "groq",
2880
+ "model": "gemma2-9b-it",
2881
+ "strategy": "flat_2pct",
2882
+ "bankroll": 5000.0,
2883
+ "total_bets": 0,
2884
+ "total_wins": 0,
2885
+ "win_rate": 0.0,
2886
+ "roi": -50.0,
2887
+ "total_pnl": 0.0,
2888
+ "weight": 1.0,
2889
+ "active": true
2890
+ },
2891
+ "t3_parlay_3leg_ml_s0": {
2892
+ "id": "t3_parlay_3leg_ml_s0",
2893
+ "name": "Spec:3-Leg ML Parlay:S0",
2894
+ "tier": "SPECIALIST",
2895
+ "provider": "groq",
2896
+ "model": "llama-3.1-8b-instant",
2897
+ "strategy": "half_kelly",
2898
+ "bankroll": 5000.0,
2899
+ "total_bets": 0,
2900
+ "total_wins": 0,
2901
+ "win_rate": 0.0,
2902
+ "roi": -50.0,
2903
+ "total_pnl": 0.0,
2904
+ "weight": 1.0,
2905
+ "active": true
2906
+ },
2907
+ "t3_parlay_2leg_spread_s0": {
2908
+ "id": "t3_parlay_2leg_spread_s0",
2909
+ "name": "Spec:2-Leg Spread Parlay:S0",
2910
+ "tier": "SPECIALIST",
2911
+ "provider": "groq",
2912
+ "model": "gemma2-9b-it",
2913
+ "strategy": "quarter_kelly",
2914
+ "bankroll": 5000.0,
2915
+ "total_bets": 0,
2916
+ "total_wins": 0,
2917
+ "win_rate": 0.0,
2918
+ "roi": -50.0,
2919
+ "total_pnl": 0.0,
2920
+ "weight": 1.0,
2921
+ "active": true
2922
+ },
2923
+ "t3_teaser_6pt_s0": {
2924
+ "id": "t3_teaser_6pt_s0",
2925
+ "name": "Spec:6-Point Teaser:S0",
2926
+ "tier": "SPECIALIST",
2927
+ "provider": "groq",
2928
+ "model": "llama-3.1-8b-instant",
2929
+ "strategy": "value_hunter",
2930
+ "bankroll": 5000.0,
2931
+ "total_bets": 0,
2932
+ "total_wins": 0,
2933
+ "win_rate": 0.0,
2934
+ "roi": -50.0,
2935
+ "total_pnl": 0.0,
2936
+ "weight": 1.0,
2937
+ "active": true
2938
+ },
2939
+ "t3_teaser_7pt_s0": {
2940
+ "id": "t3_teaser_7pt_s0",
2941
+ "name": "Spec:7-Point Teaser:S0",
2942
+ "tier": "SPECIALIST",
2943
+ "provider": "groq",
2944
+ "model": "gemma2-9b-it",
2945
+ "strategy": "proportional_edge",
2946
+ "bankroll": 5000.0,
2947
+ "total_bets": 0,
2948
+ "total_wins": 0,
2949
+ "win_rate": 0.0,
2950
+ "roi": -50.0,
2951
+ "total_pnl": 0.0,
2952
+ "weight": 1.0,
2953
+ "active": true
2954
+ },
2955
+ "t3_round_robin_s0": {
2956
+ "id": "t3_round_robin_s0",
2957
+ "name": "Spec:Round Robin 3-way:S0",
2958
+ "tier": "SPECIALIST",
2959
+ "provider": "groq",
2960
+ "model": "llama-3.1-8b-instant",
2961
+ "strategy": "confidence_scaled",
2962
+ "bankroll": 5000.0,
2963
+ "total_bets": 0,
2964
+ "total_wins": 0,
2965
+ "win_rate": 0.0,
2966
+ "roi": -50.0,
2967
+ "total_pnl": 0.0,
2968
+ "weight": 1.0,
2969
+ "active": true
2970
+ },
2971
+ "t3_live_q1_ml_flip_s0": {
2972
+ "id": "t3_live_q1_ml_flip_s0",
2973
+ "name": "Spec:Live Q1 ML Flip:S0",
2974
+ "tier": "SPECIALIST",
2975
+ "provider": "groq",
2976
+ "model": "gemma2-9b-it",
2977
+ "strategy": "flat_2pct",
2978
+ "bankroll": 5000.0,
2979
+ "total_bets": 0,
2980
+ "total_wins": 0,
2981
+ "win_rate": 0.0,
2982
+ "roi": -50.0,
2983
+ "total_pnl": 0.0,
2984
+ "weight": 1.0,
2985
+ "active": true
2986
+ },
2987
+ "t3_live_halftime_flip_s0": {
2988
+ "id": "t3_live_halftime_flip_s0",
2989
+ "name": "Spec:Halftime Comeback:S0",
2990
+ "tier": "SPECIALIST",
2991
+ "provider": "groq",
2992
+ "model": "llama-3.1-8b-instant",
2993
+ "strategy": "half_kelly",
2994
+ "bankroll": 5000.0,
2995
+ "total_bets": 0,
2996
+ "total_wins": 0,
2997
+ "win_rate": 0.0,
2998
+ "roi": -50.0,
2999
+ "total_pnl": 0.0,
3000
+ "weight": 1.0,
3001
+ "active": true
3002
+ },
3003
+ "t3_live_run_10_0_s0": {
3004
+ "id": "t3_live_run_10_0_s0",
3005
+ "name": "Spec:10-0 Run Probability:S0",
3006
+ "tier": "SPECIALIST",
3007
+ "provider": "groq",
3008
+ "model": "gemma2-9b-it",
3009
+ "strategy": "quarter_kelly",
3010
+ "bankroll": 5000.0,
3011
+ "total_bets": 0,
3012
+ "total_wins": 0,
3013
+ "win_rate": 0.0,
3014
+ "roi": -50.0,
3015
+ "total_pnl": 0.0,
3016
+ "weight": 1.0,
3017
+ "active": true
3018
+ },
3019
+ "t3_live_largest_lead_s0": {
3020
+ "id": "t3_live_largest_lead_s0",
3021
+ "name": "Spec:Largest Lead O/U:S0",
3022
+ "tier": "SPECIALIST",
3023
+ "provider": "groq",
3024
+ "model": "llama-3.1-8b-instant",
3025
+ "strategy": "value_hunter",
3026
+ "bankroll": 5000.0,
3027
+ "total_bets": 0,
3028
+ "total_wins": 0,
3029
+ "win_rate": 0.0,
3030
+ "roi": -50.0,
3031
+ "total_pnl": 0.0,
3032
+ "weight": 1.0,
3033
+ "active": true
3034
+ },
3035
+ "t3_live_largest_lead_s1": {
3036
+ "id": "t3_live_largest_lead_s1",
3037
+ "name": "Spec:Largest Lead O/U:S1",
3038
+ "tier": "SPECIALIST",
3039
+ "provider": "groq",
3040
+ "model": "gemma2-9b-it",
3041
+ "strategy": "proportional_edge",
3042
+ "bankroll": 5000.0,
3043
+ "total_bets": 0,
3044
+ "total_wins": 0,
3045
+ "win_rate": 0.0,
3046
+ "roi": -50.0,
3047
+ "total_pnl": 0.0,
3048
+ "weight": 1.0,
3049
+ "active": true
3050
+ },
3051
+ "t3_momentum_q3_s0": {
3052
+ "id": "t3_momentum_q3_s0",
3053
+ "name": "Spec:Q3 Momentum Shift:S0",
3054
+ "tier": "SPECIALIST",
3055
+ "provider": "groq",
3056
+ "model": "llama-3.1-8b-instant",
3057
+ "strategy": "confidence_scaled",
3058
+ "bankroll": 5000.0,
3059
+ "total_bets": 0,
3060
+ "total_wins": 0,
3061
+ "win_rate": 0.0,
3062
+ "roi": -50.0,
3063
+ "total_pnl": 0.0,
3064
+ "weight": 1.0,
3065
+ "active": true
3066
+ },
3067
+ "t3_live_garbage_time_s0": {
3068
+ "id": "t3_live_garbage_time_s0",
3069
+ "name": "Spec:Garbage Time Impact:S0",
3070
+ "tier": "SPECIALIST",
3071
+ "provider": "groq",
3072
+ "model": "gemma2-9b-it",
3073
+ "strategy": "flat_2pct",
3074
+ "bankroll": 5000.0,
3075
+ "total_bets": 0,
3076
+ "total_wins": 0,
3077
+ "win_rate": 0.0,
3078
+ "roi": -50.0,
3079
+ "total_pnl": 0.0,
3080
+ "weight": 1.0,
3081
+ "active": true
3082
+ },
3083
+ "t3_live_clutch_q4_s0": {
3084
+ "id": "t3_live_clutch_q4_s0",
3085
+ "name": "Spec:Q4 Clutch Factor:S0",
3086
+ "tier": "SPECIALIST",
3087
+ "provider": "groq",
3088
+ "model": "llama-3.1-8b-instant",
3089
+ "strategy": "half_kelly",
3090
+ "bankroll": 5000.0,
3091
+ "total_bets": 0,
3092
+ "total_wins": 0,
3093
+ "win_rate": 0.0,
3094
+ "roi": -50.0,
3095
+ "total_pnl": 0.0,
3096
+ "weight": 1.0,
3097
+ "active": true
3098
+ },
3099
+ "t3_live_foul_trouble_s0": {
3100
+ "id": "t3_live_foul_trouble_s0",
3101
+ "name": "Spec:Foul Trouble Impact:S0",
3102
+ "tier": "SPECIALIST",
3103
+ "provider": "groq",
3104
+ "model": "gemma2-9b-it",
3105
+ "strategy": "quarter_kelly",
3106
+ "bankroll": 5000.0,
3107
+ "total_bets": 0,
3108
+ "total_wins": 0,
3109
+ "win_rate": 0.0,
3110
+ "roi": -50.0,
3111
+ "total_pnl": 0.0,
3112
+ "weight": 1.0,
3113
+ "active": true
3114
+ },
3115
+ "t3_pace_over_100_s0": {
3116
+ "id": "t3_pace_over_100_s0",
3117
+ "name": "Spec:Pace Over 100 Possessions:S0",
3118
+ "tier": "SPECIALIST",
3119
+ "provider": "groq",
3120
+ "model": "llama-3.1-8b-instant",
3121
+ "strategy": "value_hunter",
3122
+ "bankroll": 5000.0,
3123
+ "total_bets": 0,
3124
+ "total_wins": 0,
3125
+ "win_rate": 0.0,
3126
+ "roi": -50.0,
3127
+ "total_pnl": 0.0,
3128
+ "weight": 1.0,
3129
+ "active": true
3130
+ },
3131
+ "t3_ft_differential_s0": {
3132
+ "id": "t3_ft_differential_s0",
3133
+ "name": "Spec:FT Differential O/U 8.5:S0",
3134
+ "tier": "SPECIALIST",
3135
+ "provider": "groq",
3136
+ "model": "gemma2-9b-it",
3137
+ "strategy": "proportional_edge",
3138
+ "bankroll": 5000.0,
3139
+ "total_bets": 0,
3140
+ "total_wins": 0,
3141
+ "win_rate": 0.0,
3142
+ "roi": -50.0,
3143
+ "total_pnl": 0.0,
3144
+ "weight": 1.0,
3145
+ "active": true
3146
+ },
3147
+ "t3_three_pt_total_s0": {
3148
+ "id": "t3_three_pt_total_s0",
3149
+ "name": "Spec:Combined 3PM O/U 22.5:S0",
3150
+ "tier": "SPECIALIST",
3151
+ "provider": "groq",
3152
+ "model": "llama-3.1-8b-instant",
3153
+ "strategy": "confidence_scaled",
3154
+ "bankroll": 5000.0,
3155
+ "total_bets": 0,
3156
+ "total_wins": 0,
3157
+ "win_rate": 0.0,
3158
+ "roi": -50.0,
3159
+ "total_pnl": 0.0,
3160
+ "weight": 1.0,
3161
+ "active": true
3162
+ },
3163
+ "t3_three_pt_total_s1": {
3164
+ "id": "t3_three_pt_total_s1",
3165
+ "name": "Spec:Combined 3PM O/U 22.5:S1",
3166
+ "tier": "SPECIALIST",
3167
+ "provider": "groq",
3168
+ "model": "gemma2-9b-it",
3169
+ "strategy": "flat_2pct",
3170
+ "bankroll": 5000.0,
3171
+ "total_bets": 0,
3172
+ "total_wins": 0,
3173
+ "win_rate": 0.0,
3174
+ "roi": -50.0,
3175
+ "total_pnl": 0.0,
3176
+ "weight": 1.0,
3177
+ "active": true
3178
+ },
3179
+ "t3_bench_pts_total_s0": {
3180
+ "id": "t3_bench_pts_total_s0",
3181
+ "name": "Spec:Combined Bench Points O/U 60.5:S0",
3182
+ "tier": "SPECIALIST",
3183
+ "provider": "groq",
3184
+ "model": "llama-3.1-8b-instant",
3185
+ "strategy": "half_kelly",
3186
+ "bankroll": 5000.0,
3187
+ "total_bets": 0,
3188
+ "total_wins": 0,
3189
+ "win_rate": 0.0,
3190
+ "roi": -50.0,
3191
+ "total_pnl": 0.0,
3192
+ "weight": 1.0,
3193
+ "active": true
3194
+ },
3195
+ "t3_bench_pts_total_s1": {
3196
+ "id": "t3_bench_pts_total_s1",
3197
+ "name": "Spec:Combined Bench Points O/U 60.5:S1",
3198
+ "tier": "SPECIALIST",
3199
+ "provider": "groq",
3200
+ "model": "gemma2-9b-it",
3201
+ "strategy": "quarter_kelly",
3202
+ "bankroll": 5000.0,
3203
+ "total_bets": 0,
3204
+ "total_wins": 0,
3205
+ "win_rate": 0.0,
3206
+ "roi": -50.0,
3207
+ "total_pnl": 0.0,
3208
+ "weight": 1.0,
3209
+ "active": true
3210
+ },
3211
+ "t3_turnover_total_s0": {
3212
+ "id": "t3_turnover_total_s0",
3213
+ "name": "Spec:Combined Turnovers O/U 27.5:S0",
3214
+ "tier": "SPECIALIST",
3215
+ "provider": "groq",
3216
+ "model": "llama-3.1-8b-instant",
3217
+ "strategy": "value_hunter",
3218
+ "bankroll": 5000.0,
3219
+ "total_bets": 0,
3220
+ "total_wins": 0,
3221
+ "win_rate": 0.0,
3222
+ "roi": -50.0,
3223
+ "total_pnl": 0.0,
3224
+ "weight": 1.0,
3225
+ "active": true
3226
+ },
3227
+ "t3_turnover_total_s1": {
3228
+ "id": "t3_turnover_total_s1",
3229
+ "name": "Spec:Combined Turnovers O/U 27.5:S1",
3230
+ "tier": "SPECIALIST",
3231
+ "provider": "groq",
3232
+ "model": "gemma2-9b-it",
3233
+ "strategy": "proportional_edge",
3234
+ "bankroll": 5000.0,
3235
+ "total_bets": 0,
3236
+ "total_wins": 0,
3237
+ "win_rate": 0.0,
3238
+ "roi": -50.0,
3239
+ "total_pnl": 0.0,
3240
+ "weight": 1.0,
3241
+ "active": true
3242
+ },
3243
+ "t3_paint_pts_total_s0": {
3244
+ "id": "t3_paint_pts_total_s0",
3245
+ "name": "Spec:Combined Paint Points O/U 90.5:S0",
3246
+ "tier": "SPECIALIST",
3247
+ "provider": "groq",
3248
+ "model": "llama-3.1-8b-instant",
3249
+ "strategy": "confidence_scaled",
3250
+ "bankroll": 5000.0,
3251
+ "total_bets": 0,
3252
+ "total_wins": 0,
3253
+ "win_rate": 0.0,
3254
+ "roi": -50.0,
3255
+ "total_pnl": 0.0,
3256
+ "weight": 1.0,
3257
+ "active": true
3258
+ },
3259
+ "t3_paint_pts_total_s1": {
3260
+ "id": "t3_paint_pts_total_s1",
3261
+ "name": "Spec:Combined Paint Points O/U 90.5:S1",
3262
+ "tier": "SPECIALIST",
3263
+ "provider": "groq",
3264
+ "model": "gemma2-9b-it",
3265
+ "strategy": "flat_2pct",
3266
+ "bankroll": 5000.0,
3267
+ "total_bets": 0,
3268
+ "total_wins": 0,
3269
+ "win_rate": 0.0,
3270
+ "roi": -50.0,
3271
+ "total_pnl": 0.0,
3272
+ "weight": 1.0,
3273
+ "active": true
3274
+ },
3275
+ "t4_paperclip": {
3276
+ "id": "t4_paperclip",
3277
+ "name": "Paperclip Allocator",
3278
+ "tier": "META",
3279
+ "provider": "groq",
3280
+ "model": "llama-3.3-70b-versatile",
3281
+ "strategy": "meta_allocation",
3282
+ "bankroll": 100000.0,
3283
+ "total_bets": 0,
3284
+ "total_wins": 0,
3285
+ "win_rate": 0.0,
3286
+ "roi": 900.0,
3287
+ "total_pnl": 0.0,
3288
+ "weight": 1.0,
3289
+ "active": true
3290
+ },
3291
+ "t4_hermes": {
3292
+ "id": "t4_hermes",
3293
+ "name": "Hermes Router",
3294
+ "tier": "META",
3295
+ "provider": "groq",
3296
+ "model": "llama-3.3-70b-versatile",
3297
+ "strategy": "meta_consensus",
3298
+ "bankroll": 0.0,
3299
+ "total_bets": 0,
3300
+ "total_wins": 0,
3301
+ "win_rate": 0.0,
3302
+ "roi": -100.0,
3303
+ "total_pnl": 0.0,
3304
+ "weight": 1.0,
3305
+ "active": true
3306
+ },
3307
+ "t4_oracle": {
3308
+ "id": "t4_oracle",
3309
+ "name": "Oracle Chairman",
3310
+ "tier": "META",
3311
+ "provider": "google",
3312
+ "model": "gemini-2.0-flash",
3313
+ "strategy": "meta_synthesis",
3314
+ "bankroll": 50000.0,
3315
+ "total_bets": 0,
3316
+ "total_wins": 0,
3317
+ "win_rate": 0.0,
3318
+ "roi": 400.0,
3319
+ "total_pnl": 0.0,
3320
+ "weight": 1.0,
3321
+ "active": true
3322
+ }
3323
+ }
3324
+ }
data/arena/model-predictions-latest.json ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "timestamp": "2026-04-04T23:13:12.492938+00:00",
3
+ "n_games": 3,
4
+ "n_models": 6,
5
+ "targets": [
6
+ "moneyline",
7
+ "spread",
8
+ "total"
9
+ ],
10
+ "predictions": [
11
+ {
12
+ "game_id": "0022501129",
13
+ "home_team": "Miami Heat",
14
+ "away_team": "Washington Wizards",
15
+ "date": "2026-04-04T19:00:00Z",
16
+ "predictions": {
17
+ "moneyline": {
18
+ "home_win_prob": 0.4708,
19
+ "ci_90": [
20
+ 0.4235,
21
+ 0.5182
22
+ ],
23
+ "edge_vs_odds": -0.4301
24
+ },
25
+ "spread": {
26
+ "predicted_margin": -0.6,
27
+ "ci_90": [
28
+ -5.6,
29
+ 4.4
30
+ ],
31
+ "edge": null
32
+ },
33
+ "total": {
34
+ "predicted_total": 215.0,
35
+ "ci_90": [
36
+ 200.0,
37
+ 230.0
38
+ ],
39
+ "edge": null
40
+ }
41
+ },
42
+ "quality": {
43
+ "n_models": 5,
44
+ "avg_brier": 0.22448,
45
+ "confidence": "high"
46
+ },
47
+ "model_details": [
48
+ {
49
+ "source": "S15",
50
+ "model_type": "random_forest",
51
+ "n_features": 79,
52
+ "brier": 0.22159,
53
+ "home_win_prob": 0.4983
54
+ },
55
+ {
56
+ "source": "S10",
57
+ "model_type": "xgboost_brier",
58
+ "n_features": 50,
59
+ "brier": 0.22454,
60
+ "home_win_prob": 0.424
61
+ },
62
+ {
63
+ "source": "S13",
64
+ "model_type": "extra_trees",
65
+ "n_features": 69,
66
+ "brier": 0.22455,
67
+ "home_win_prob": 0.4828
68
+ },
69
+ {
70
+ "source": "S12",
71
+ "model_type": "catboost",
72
+ "n_features": 43,
73
+ "brier": 0.22506,
74
+ "home_win_prob": 0.4842
75
+ },
76
+ {
77
+ "source": "S14",
78
+ "model_type": "xgboost_brier",
79
+ "n_features": 55,
80
+ "brier": 0.22666,
81
+ "home_win_prob": 0.4645
82
+ }
83
+ ]
84
+ },
85
+ {
86
+ "game_id": "0022501130",
87
+ "home_team": "Denver Nuggets",
88
+ "away_team": "San Antonio Spurs",
89
+ "date": "2026-04-04T19:00:00Z",
90
+ "predictions": {
91
+ "moneyline": {
92
+ "home_win_prob": 0.4708,
93
+ "ci_90": [
94
+ 0.4235,
95
+ 0.5182
96
+ ],
97
+ "edge_vs_odds": -0.3766
98
+ },
99
+ "spread": {
100
+ "predicted_margin": -0.6,
101
+ "ci_90": [
102
+ -5.6,
103
+ 4.4
104
+ ],
105
+ "edge": null
106
+ },
107
+ "total": {
108
+ "predicted_total": 215.0,
109
+ "ci_90": [
110
+ 200.0,
111
+ 230.0
112
+ ],
113
+ "edge": null
114
+ }
115
+ },
116
+ "quality": {
117
+ "n_models": 5,
118
+ "avg_brier": 0.22448,
119
+ "confidence": "high"
120
+ },
121
+ "model_details": [
122
+ {
123
+ "source": "S15",
124
+ "model_type": "random_forest",
125
+ "n_features": 79,
126
+ "brier": 0.22159,
127
+ "home_win_prob": 0.4983
128
+ },
129
+ {
130
+ "source": "S10",
131
+ "model_type": "xgboost_brier",
132
+ "n_features": 50,
133
+ "brier": 0.22454,
134
+ "home_win_prob": 0.424
135
+ },
136
+ {
137
+ "source": "S13",
138
+ "model_type": "extra_trees",
139
+ "n_features": 69,
140
+ "brier": 0.22455,
141
+ "home_win_prob": 0.4828
142
+ },
143
+ {
144
+ "source": "S12",
145
+ "model_type": "catboost",
146
+ "n_features": 43,
147
+ "brier": 0.22506,
148
+ "home_win_prob": 0.4842
149
+ },
150
+ {
151
+ "source": "S14",
152
+ "model_type": "xgboost_brier",
153
+ "n_features": 55,
154
+ "brier": 0.22666,
155
+ "home_win_prob": 0.4645
156
+ }
157
+ ]
158
+ },
159
+ {
160
+ "game_id": "0022501131",
161
+ "home_team": "Philadelphia 76ers",
162
+ "away_team": "Detroit Pistons",
163
+ "date": "2026-04-04T23:00:00Z",
164
+ "predictions": {
165
+ "moneyline": {
166
+ "home_win_prob": 0.4708,
167
+ "ci_90": [
168
+ 0.4235,
169
+ 0.5182
170
+ ],
171
+ "edge_vs_odds": 0.0142
172
+ },
173
+ "spread": {
174
+ "predicted_margin": -0.6,
175
+ "ci_90": [
176
+ -5.6,
177
+ 4.4
178
+ ],
179
+ "edge": null
180
+ },
181
+ "total": {
182
+ "predicted_total": 215.0,
183
+ "ci_90": [
184
+ 200.0,
185
+ 230.0
186
+ ],
187
+ "edge": null
188
+ }
189
+ },
190
+ "quality": {
191
+ "n_models": 5,
192
+ "avg_brier": 0.22448,
193
+ "confidence": "high"
194
+ },
195
+ "model_details": [
196
+ {
197
+ "source": "S15",
198
+ "model_type": "random_forest",
199
+ "n_features": 79,
200
+ "brier": 0.22159,
201
+ "home_win_prob": 0.4983
202
+ },
203
+ {
204
+ "source": "S10",
205
+ "model_type": "xgboost_brier",
206
+ "n_features": 50,
207
+ "brier": 0.22454,
208
+ "home_win_prob": 0.424
209
+ },
210
+ {
211
+ "source": "S13",
212
+ "model_type": "extra_trees",
213
+ "n_features": 69,
214
+ "brier": 0.22455,
215
+ "home_win_prob": 0.4828
216
+ },
217
+ {
218
+ "source": "S12",
219
+ "model_type": "catboost",
220
+ "n_features": 43,
221
+ "brier": 0.22506,
222
+ "home_win_prob": 0.4842
223
+ },
224
+ {
225
+ "source": "S14",
226
+ "model_type": "xgboost_brier",
227
+ "n_features": 55,
228
+ "brier": 0.22666,
229
+ "home_win_prob": 0.4645
230
+ }
231
+ ]
232
+ }
233
+ ]
234
+ }
data/nba-agent/bankroll-state.json ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "balance": 91.29,
3
+ "initial_balance": 100.0,
4
+ "currency": "USD",
5
+ "total_bets": 44,
6
+ "wins": 17,
7
+ "losses": 27,
8
+ "pushes": 0,
9
+ "pending": 0,
10
+ "total_wagered": 110.58,
11
+ "total_profit": -8.71,
12
+ "peak_balance": 110.43,
13
+ "trough_balance": 100.0,
14
+ "max_drawdown_pct": 20.89,
15
+ "streak_current": 0,
16
+ "streak_best": 0,
17
+ "streak_worst": 0,
18
+ "daily_bets_today": 0,
19
+ "daily_profit_today": 0.0,
20
+ "last_bet_ts": "2026-04-03T00:00:00+00:00",
21
+ "last_updated": "2026-04-04T22:04:18.691644+00:00",
22
+ "created": "2026-03-15T11:16:28.623775+00:00",
23
+ "roi_pct": -8.71,
24
+ "win_rate_pct": 38.64,
25
+ "sharpe_ratio": -3.11,
26
+ "avg_edge_pct": 126.63,
27
+ "season_start": "2026-03-19",
28
+ "data_source": "backtest-results.json (synced by autonomous-cycle.sh)"
29
+ }
index.html ADDED
@@ -0,0 +1,2332 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
6
+ <title>Nomos42 Pixel World — Live Trading Floor</title>
7
+ <style>
8
+ * { margin: 0; padding: 0; box-sizing: border-box; }
9
+
10
+ :root {
11
+ --bg: #0a0a1a;
12
+ --panel-bg: #0e0e24;
13
+ --panel-border: #1a1a40;
14
+ --gold: #ffd700;
15
+ --gold-dim: #b8960c;
16
+ --blue: #4fc3f7;
17
+ --green: #66bb6a;
18
+ --purple: #ce93d8;
19
+ --red: #ef5350;
20
+ --text: #e0e0e0;
21
+ --text-dim: #888;
22
+ --ticker-bg: #050510;
23
+ --hud-bg: rgba(10,10,30,0.92);
24
+ --font-pixel: 'Courier New', Courier, monospace;
25
+ --font-ui: 'Segoe UI', system-ui, sans-serif;
26
+ }
27
+
28
+ body {
29
+ background: var(--bg);
30
+ color: var(--text);
31
+ font-family: var(--font-pixel);
32
+ overflow: hidden;
33
+ height: 100vh;
34
+ width: 100vw;
35
+ user-select: none;
36
+ }
37
+
38
+ /* ─── LAYOUT ─── */
39
+ #app {
40
+ display: flex;
41
+ flex-direction: column;
42
+ height: 100vh;
43
+ width: 100vw;
44
+ position: relative;
45
+ }
46
+
47
+ /* ─── HEADER BAR ─── */
48
+ #header {
49
+ height: 44px;
50
+ background: var(--panel-bg);
51
+ border-bottom: 2px solid var(--gold-dim);
52
+ display: flex;
53
+ align-items: center;
54
+ padding: 0 12px;
55
+ gap: 16px;
56
+ z-index: 100;
57
+ flex-shrink: 0;
58
+ }
59
+
60
+ #header-title {
61
+ font-size: 15px;
62
+ font-weight: bold;
63
+ color: var(--gold);
64
+ letter-spacing: 2px;
65
+ text-shadow: 0 0 10px rgba(255,215,0,0.6);
66
+ white-space: nowrap;
67
+ }
68
+
69
+ #header-title span {
70
+ color: #fff;
71
+ font-size: 11px;
72
+ letter-spacing: 1px;
73
+ margin-left: 6px;
74
+ opacity: 0.7;
75
+ }
76
+
77
+ .header-stat {
78
+ font-size: 11px;
79
+ padding: 3px 8px;
80
+ background: rgba(255,255,255,0.05);
81
+ border: 1px solid rgba(255,255,255,0.1);
82
+ border-radius: 3px;
83
+ white-space: nowrap;
84
+ }
85
+
86
+ .header-stat .label { color: var(--text-dim); margin-right: 4px; }
87
+ .header-stat .val { color: var(--gold); font-weight: bold; }
88
+ .header-stat .val.green { color: var(--green); }
89
+ .header-stat .val.red { color: var(--red); }
90
+ .header-stat .val.blue { color: var(--blue); }
91
+
92
+ #header-spacer { flex: 1; }
93
+
94
+ .header-btn {
95
+ background: rgba(255,255,255,0.07);
96
+ border: 1px solid rgba(255,255,255,0.15);
97
+ color: var(--text);
98
+ padding: 4px 10px;
99
+ font-size: 11px;
100
+ cursor: pointer;
101
+ border-radius: 3px;
102
+ font-family: var(--font-pixel);
103
+ transition: all 0.15s;
104
+ white-space: nowrap;
105
+ }
106
+ .header-btn:hover { background: rgba(255,255,255,0.12); color: var(--gold); border-color: var(--gold-dim); }
107
+ .header-btn.active { background: rgba(255,215,0,0.15); border-color: var(--gold); color: var(--gold); }
108
+
109
+ /* ─── MAIN AREA ─── */
110
+ #main {
111
+ flex: 1;
112
+ display: flex;
113
+ min-height: 0;
114
+ position: relative;
115
+ }
116
+
117
+ /* ─── LEFT PANEL ─── */
118
+ #panel-left {
119
+ width: 200px;
120
+ flex-shrink: 0;
121
+ background: var(--panel-bg);
122
+ border-right: 1px solid var(--panel-border);
123
+ display: flex;
124
+ flex-direction: column;
125
+ overflow: hidden;
126
+ z-index: 50;
127
+ }
128
+
129
+ /* ─── CENTER CANVAS ─── */
130
+ #canvas-wrapper {
131
+ flex: 1;
132
+ position: relative;
133
+ overflow: hidden;
134
+ background: #060618;
135
+ }
136
+
137
+ #pixiCanvas {
138
+ display: block;
139
+ image-rendering: pixelated;
140
+ image-rendering: crisp-edges;
141
+ }
142
+
143
+ /* ─── RIGHT PANEL ─── */
144
+ #panel-right {
145
+ width: 200px;
146
+ flex-shrink: 0;
147
+ background: var(--panel-bg);
148
+ border-left: 1px solid var(--panel-border);
149
+ display: flex;
150
+ flex-direction: column;
151
+ overflow: hidden;
152
+ z-index: 50;
153
+ }
154
+
155
+ /* ─── PANEL SECTIONS ─── */
156
+ .panel-section {
157
+ border-bottom: 1px solid var(--panel-border);
158
+ padding: 8px;
159
+ flex-shrink: 0;
160
+ }
161
+
162
+ .panel-title {
163
+ font-size: 9px;
164
+ letter-spacing: 2px;
165
+ color: var(--gold);
166
+ text-transform: uppercase;
167
+ margin-bottom: 6px;
168
+ display: flex;
169
+ align-items: center;
170
+ gap: 5px;
171
+ }
172
+
173
+ .panel-title::before {
174
+ content: '';
175
+ display: inline-block;
176
+ width: 3px;
177
+ height: 10px;
178
+ background: var(--gold);
179
+ }
180
+
181
+ /* ─── LEADERBOARD ─── */
182
+ #leaderboard-list {
183
+ flex: 1;
184
+ overflow-y: auto;
185
+ padding: 6px;
186
+ }
187
+
188
+ #leaderboard-list::-webkit-scrollbar { width: 4px; }
189
+ #leaderboard-list::-webkit-scrollbar-track { background: transparent; }
190
+ #leaderboard-list::-webkit-scrollbar-thumb { background: #333; border-radius: 2px; }
191
+
192
+ .lb-entry {
193
+ display: flex;
194
+ align-items: center;
195
+ padding: 4px 5px;
196
+ margin-bottom: 3px;
197
+ border-radius: 3px;
198
+ cursor: pointer;
199
+ border: 1px solid transparent;
200
+ transition: all 0.15s;
201
+ font-size: 10px;
202
+ gap: 5px;
203
+ }
204
+
205
+ .lb-entry:hover { background: rgba(255,255,255,0.05); border-color: rgba(255,255,255,0.1); }
206
+
207
+ .lb-rank {
208
+ font-size: 9px;
209
+ color: var(--text-dim);
210
+ width: 14px;
211
+ text-align: right;
212
+ flex-shrink: 0;
213
+ }
214
+
215
+ .lb-rank.r1 { color: var(--gold); font-size: 11px; }
216
+ .lb-rank.r2 { color: #c0c0c0; }
217
+ .lb-rank.r3 { color: #cd7f32; }
218
+
219
+ .lb-dot {
220
+ width: 8px;
221
+ height: 8px;
222
+ border-radius: 1px;
223
+ flex-shrink: 0;
224
+ }
225
+
226
+ .lb-name {
227
+ flex: 1;
228
+ overflow: hidden;
229
+ text-overflow: ellipsis;
230
+ white-space: nowrap;
231
+ color: var(--text);
232
+ }
233
+
234
+ .lb-val {
235
+ font-size: 9px;
236
+ color: var(--green);
237
+ white-space: nowrap;
238
+ flex-shrink: 0;
239
+ }
240
+
241
+ .lb-val.neg { color: var(--red); }
242
+
243
+ /* ─── SPACE STATUS ─── */
244
+ .space-row {
245
+ display: flex;
246
+ align-items: center;
247
+ font-size: 10px;
248
+ padding: 3px 0;
249
+ gap: 5px;
250
+ }
251
+
252
+ .space-led {
253
+ width: 7px;
254
+ height: 7px;
255
+ border-radius: 50%;
256
+ flex-shrink: 0;
257
+ animation: pulse-led 2s infinite;
258
+ }
259
+
260
+ .space-led.up { background: var(--green); box-shadow: 0 0 4px var(--green); }
261
+ .space-led.down { background: var(--red); box-shadow: 0 0 4px var(--red); animation: none; }
262
+
263
+ @keyframes pulse-led {
264
+ 0%, 100% { opacity: 1; }
265
+ 50% { opacity: 0.4; }
266
+ }
267
+
268
+ .space-name { color: var(--blue); flex: 1; }
269
+ .space-brier { color: var(--text-dim); font-size: 9px; }
270
+ .space-gen { color: var(--gold); font-size: 9px; }
271
+
272
+ /* ─── DEPT STATUS ─── */
273
+ .dept-row {
274
+ display: flex;
275
+ align-items: center;
276
+ font-size: 10px;
277
+ padding: 2px 0;
278
+ gap: 5px;
279
+ cursor: default;
280
+ }
281
+
282
+ .dept-badge {
283
+ font-size: 8px;
284
+ padding: 1px 4px;
285
+ border-radius: 2px;
286
+ font-weight: bold;
287
+ width: 24px;
288
+ text-align: center;
289
+ flex-shrink: 0;
290
+ }
291
+
292
+ .dept-badge.active { background: rgba(102,187,106,0.2); color: var(--green); border: 1px solid rgba(102,187,106,0.3); }
293
+ .dept-badge.idle { background: rgba(79,195,247,0.1); color: var(--blue); border: 1px solid rgba(79,195,247,0.2); }
294
+ .dept-badge.warn { background: rgba(239,83,80,0.15); color: var(--red); border: 1px solid rgba(239,83,80,0.3); }
295
+
296
+ .dept-name { flex: 1; color: var(--text); font-size: 9px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
297
+ .dept-metric { font-size: 9px; color: var(--text-dim); white-space: nowrap; }
298
+
299
+ /* ─── PREDICTIONS ─── */
300
+ .pred-card {
301
+ background: rgba(255,255,255,0.03);
302
+ border: 1px solid rgba(255,255,255,0.07);
303
+ border-radius: 4px;
304
+ padding: 6px;
305
+ margin-bottom: 5px;
306
+ font-size: 10px;
307
+ }
308
+
309
+ .pred-teams {
310
+ display: flex;
311
+ justify-content: space-between;
312
+ margin-bottom: 3px;
313
+ font-size: 10px;
314
+ }
315
+
316
+ .pred-home { color: var(--blue); }
317
+ .pred-away { color: var(--text-dim); }
318
+ .pred-vs { color: var(--text-dim); font-size: 9px; }
319
+
320
+ .pred-bars {
321
+ display: flex;
322
+ gap: 2px;
323
+ height: 8px;
324
+ margin: 4px 0;
325
+ border-radius: 2px;
326
+ overflow: hidden;
327
+ }
328
+
329
+ .pred-bar-home { background: var(--blue); height: 100%; transition: width 0.5s; }
330
+ .pred-bar-away { background: rgba(255,255,255,0.15); flex: 1; height: 100%; }
331
+
332
+ .pred-prob { font-size: 9px; color: var(--text-dim); display: flex; justify-content: space-between; }
333
+ .pred-prob .conf { color: var(--gold); }
334
+
335
+ /* ─── TICKER ─── */
336
+ #ticker {
337
+ height: 28px;
338
+ background: var(--ticker-bg);
339
+ border-top: 1px solid var(--panel-border);
340
+ overflow: hidden;
341
+ position: relative;
342
+ flex-shrink: 0;
343
+ }
344
+
345
+ #ticker-track {
346
+ position: absolute;
347
+ top: 0;
348
+ left: 0;
349
+ height: 100%;
350
+ display: flex;
351
+ align-items: center;
352
+ white-space: nowrap;
353
+ will-change: transform;
354
+ }
355
+
356
+ .ticker-item {
357
+ display: inline-flex;
358
+ align-items: center;
359
+ font-size: 11px;
360
+ padding: 0 18px;
361
+ gap: 6px;
362
+ border-right: 1px solid rgba(255,255,255,0.07);
363
+ height: 100%;
364
+ }
365
+
366
+ .ticker-label { color: var(--text-dim); font-size: 10px; }
367
+ .ticker-team { color: var(--text); }
368
+ .ticker-prob { font-weight: bold; }
369
+ .ticker-prob.high { color: var(--green); }
370
+ .ticker-prob.med { color: var(--gold); }
371
+ .ticker-prob.low { color: var(--red); }
372
+ .ticker-sep { color: var(--text-dim); margin: 0 3px; }
373
+ .ticker-brier { color: var(--blue); font-size: 9px; }
374
+ .ticker-agent { color: var(--purple); font-size: 9px; }
375
+ .ticker-win { color: var(--green); font-size: 9px; }
376
+ .ticker-loss { color: var(--red); font-size: 9px; }
377
+
378
+ /* ─── AGENT POPUP ─── */
379
+ #agent-popup {
380
+ position: absolute;
381
+ background: var(--hud-bg);
382
+ border: 1px solid var(--gold-dim);
383
+ border-radius: 6px;
384
+ padding: 12px 14px;
385
+ min-width: 220px;
386
+ z-index: 1000;
387
+ pointer-events: none;
388
+ opacity: 0;
389
+ transform: translateY(-4px);
390
+ transition: opacity 0.15s, transform 0.15s;
391
+ backdrop-filter: blur(12px);
392
+ font-size: 11px;
393
+ box-shadow: 0 8px 32px rgba(0,0,0,0.7), 0 0 20px rgba(255,215,0,0.08);
394
+ }
395
+
396
+ #agent-popup.visible {
397
+ opacity: 1;
398
+ transform: translateY(0);
399
+ pointer-events: auto;
400
+ }
401
+
402
+ .popup-header {
403
+ display: flex;
404
+ align-items: center;
405
+ gap: 10px;
406
+ margin-bottom: 10px;
407
+ padding-bottom: 8px;
408
+ border-bottom: 1px solid rgba(255,255,255,0.1);
409
+ }
410
+
411
+ .popup-sprite {
412
+ width: 32px;
413
+ height: 32px;
414
+ image-rendering: pixelated;
415
+ flex-shrink: 0;
416
+ }
417
+
418
+ .popup-name {
419
+ font-size: 13px;
420
+ font-weight: bold;
421
+ color: var(--gold);
422
+ line-height: 1.2;
423
+ }
424
+
425
+ .popup-tier {
426
+ font-size: 9px;
427
+ padding: 1px 6px;
428
+ border-radius: 10px;
429
+ margin-top: 2px;
430
+ display: inline-block;
431
+ }
432
+
433
+ .popup-tier.PREMIUM { background: rgba(255,215,0,0.15); color: var(--gold); border: 1px solid rgba(255,215,0,0.3); }
434
+ .popup-tier.FREE_POWER { background: rgba(79,195,247,0.15); color: var(--blue); border: 1px solid rgba(79,195,247,0.3); }
435
+ .popup-tier.SPECIALIST { background: rgba(102,187,106,0.15); color: var(--green); border: 1px solid rgba(102,187,106,0.3); }
436
+ .popup-tier.META { background: rgba(206,147,216,0.15); color: var(--purple); border: 1px solid rgba(206,147,216,0.3); }
437
+
438
+ .popup-stats {
439
+ display: grid;
440
+ grid-template-columns: 1fr 1fr;
441
+ gap: 6px 10px;
442
+ }
443
+
444
+ .popup-stat {
445
+ display: flex;
446
+ flex-direction: column;
447
+ }
448
+
449
+ .popup-stat-label { font-size: 9px; color: var(--text-dim); margin-bottom: 1px; }
450
+ .popup-stat-val { font-size: 12px; color: var(--text); font-weight: bold; }
451
+ .popup-stat-val.green { color: var(--green); }
452
+ .popup-stat-val.red { color: var(--red); }
453
+ .popup-stat-val.gold { color: var(--gold); }
454
+ .popup-stat-val.blue { color: var(--blue); }
455
+
456
+ .popup-strategy {
457
+ margin-top: 8px;
458
+ padding: 5px 8px;
459
+ background: rgba(255,255,255,0.04);
460
+ border-radius: 3px;
461
+ font-size: 9px;
462
+ }
463
+
464
+ .popup-strategy-label { color: var(--text-dim); margin-bottom: 2px; }
465
+ .popup-strategy-val { color: var(--blue); }
466
+
467
+ .popup-speech {
468
+ margin-top: 8px;
469
+ padding: 6px 8px;
470
+ background: rgba(79,195,247,0.07);
471
+ border-left: 2px solid var(--blue);
472
+ border-radius: 0 4px 4px 0;
473
+ font-size: 10px;
474
+ color: var(--text);
475
+ font-style: italic;
476
+ line-height: 1.4;
477
+ }
478
+
479
+ .popup-close {
480
+ position: absolute;
481
+ top: 8px;
482
+ right: 10px;
483
+ cursor: pointer;
484
+ color: var(--text-dim);
485
+ font-size: 14px;
486
+ pointer-events: auto;
487
+ transition: color 0.15s;
488
+ }
489
+ .popup-close:hover { color: var(--gold); }
490
+
491
+ /* ─── NIGHT OVERLAY ─── */
492
+ #night-overlay {
493
+ position: absolute;
494
+ inset: 0;
495
+ background: rgba(0,0,30,0);
496
+ pointer-events: none;
497
+ z-index: 5;
498
+ transition: background 3s;
499
+ }
500
+
501
+ /* ─── PARTICLE CANVAS ─── */
502
+ #particle-canvas {
503
+ position: absolute;
504
+ inset: 0;
505
+ pointer-events: none;
506
+ z-index: 10;
507
+ }
508
+
509
+ /* ─── LOADING SCREEN ─── */
510
+ #loading {
511
+ position: absolute;
512
+ inset: 0;
513
+ background: var(--bg);
514
+ display: flex;
515
+ flex-direction: column;
516
+ align-items: center;
517
+ justify-content: center;
518
+ z-index: 9999;
519
+ gap: 16px;
520
+ transition: opacity 0.5s;
521
+ }
522
+
523
+ #loading.fade-out { opacity: 0; pointer-events: none; }
524
+
525
+ .loading-title {
526
+ font-size: 22px;
527
+ font-weight: bold;
528
+ color: var(--gold);
529
+ letter-spacing: 4px;
530
+ text-shadow: 0 0 20px rgba(255,215,0,0.5);
531
+ animation: flicker 2s infinite;
532
+ }
533
+
534
+ @keyframes flicker {
535
+ 0%, 100% { opacity: 1; }
536
+ 92% { opacity: 1; }
537
+ 93% { opacity: 0.6; }
538
+ 94% { opacity: 1; }
539
+ }
540
+
541
+ .loading-sub {
542
+ font-size: 11px;
543
+ color: var(--text-dim);
544
+ letter-spacing: 2px;
545
+ }
546
+
547
+ .loading-bar-wrap {
548
+ width: 240px;
549
+ height: 8px;
550
+ background: rgba(255,255,255,0.07);
551
+ border-radius: 4px;
552
+ overflow: hidden;
553
+ border: 1px solid rgba(255,255,255,0.12);
554
+ }
555
+
556
+ .loading-bar {
557
+ height: 100%;
558
+ background: linear-gradient(90deg, var(--gold-dim), var(--gold));
559
+ border-radius: 4px;
560
+ width: 0%;
561
+ transition: width 0.3s;
562
+ box-shadow: 0 0 8px rgba(255,215,0,0.4);
563
+ }
564
+
565
+ .loading-status {
566
+ font-size: 10px;
567
+ color: var(--text-dim);
568
+ min-height: 14px;
569
+ }
570
+
571
+ /* ─── MINI MAP ─── */
572
+ #minimap-canvas {
573
+ position: absolute;
574
+ bottom: 40px;
575
+ right: 8px;
576
+ width: 100px;
577
+ height: 70px;
578
+ background: rgba(10,10,30,0.9);
579
+ border: 1px solid rgba(255,255,255,0.15);
580
+ border-radius: 3px;
581
+ overflow: hidden;
582
+ z-index: 50;
583
+ display: block;
584
+ }
585
+
586
+ /* ─── CONTROLS ─── */
587
+ #controls-hint {
588
+ position: absolute;
589
+ bottom: 40px;
590
+ left: 8px;
591
+ font-size: 9px;
592
+ color: rgba(255,255,255,0.25);
593
+ z-index: 50;
594
+ line-height: 1.6;
595
+ pointer-events: none;
596
+ }
597
+
598
+ /* ─── SPEECH BUBBLES (CSS, for pixi overlay) ─── */
599
+ .speech-bubble-css {
600
+ position: absolute;
601
+ background: rgba(10,10,30,0.92);
602
+ border: 1px solid rgba(79,195,247,0.4);
603
+ border-radius: 6px;
604
+ padding: 4px 7px;
605
+ font-size: 9px;
606
+ color: var(--text);
607
+ pointer-events: none;
608
+ z-index: 30;
609
+ white-space: nowrap;
610
+ max-width: 140px;
611
+ white-space: normal;
612
+ transform: translateX(-50%);
613
+ animation: bubble-pop 0.2s ease-out;
614
+ box-shadow: 0 2px 8px rgba(0,0,0,0.5);
615
+ }
616
+
617
+ .speech-bubble-css::after {
618
+ content: '';
619
+ position: absolute;
620
+ bottom: -5px;
621
+ left: 50%;
622
+ transform: translateX(-50%);
623
+ width: 8px;
624
+ height: 5px;
625
+ background: rgba(10,10,30,0.92);
626
+ clip-path: polygon(0 0, 100% 0, 50% 100%);
627
+ border-left: 1px solid rgba(79,195,247,0.4);
628
+ border-right: 1px solid rgba(79,195,247,0.4);
629
+ }
630
+
631
+ @keyframes bubble-pop {
632
+ from { transform: translateX(-50%) scale(0.8); opacity: 0; }
633
+ to { transform: translateX(-50%) scale(1); opacity: 1; }
634
+ }
635
+
636
+ /* ─── RESPONSIVE ─── */
637
+ @media (max-width: 768px) {
638
+ #panel-left, #panel-right { width: 0; overflow: hidden; display: none; }
639
+ #header { padding: 0 8px; gap: 8px; }
640
+ #header-title span { display: none; }
641
+ .header-stat { padding: 2px 5px; font-size: 10px; }
642
+ }
643
+
644
+ @media (max-width: 480px) {
645
+ #header { height: 38px; }
646
+ .header-stat:nth-child(n+4) { display: none; }
647
+ }
648
+
649
+ /* ─── SCANLINES ─── */
650
+ #scanlines {
651
+ position: absolute;
652
+ inset: 0;
653
+ pointer-events: none;
654
+ z-index: 2;
655
+ background: repeating-linear-gradient(
656
+ to bottom,
657
+ transparent 0px,
658
+ transparent 3px,
659
+ rgba(0,0,0,0.04) 3px,
660
+ rgba(0,0,0,0.04) 4px
661
+ );
662
+ opacity: 0.4;
663
+ }
664
+
665
+ /* ─── CRT VIGNETTE ─── */
666
+ #vignette {
667
+ position: absolute;
668
+ inset: 0;
669
+ pointer-events: none;
670
+ z-index: 3;
671
+ background: radial-gradient(ellipse at center, transparent 60%, rgba(0,0,0,0.45) 100%);
672
+ }
673
+
674
+ /* ─── FLOOR ZONES LABELS ─── */
675
+ .zone-label {
676
+ position: absolute;
677
+ font-size: 9px;
678
+ letter-spacing: 2px;
679
+ text-transform: uppercase;
680
+ color: rgba(255,255,255,0.12);
681
+ pointer-events: none;
682
+ z-index: 4;
683
+ }
684
+
685
+ </style>
686
+ </head>
687
+ <body>
688
+ <div id="app">
689
+
690
+ <!-- HEADER -->
691
+ <div id="header">
692
+ <div id="header-title">NOMOS42<span>TRADING FLOOR v5</span></div>
693
+ <div class="header-stat"><span class="label">AGENTS</span><span class="val blue" id="hdr-agents">207</span></div>
694
+ <div class="header-stat"><span class="label">BRIER</span><span class="val green" id="hdr-brier">0.22159</span></div>
695
+ <div class="header-stat"><span class="label">GEN</span><span class="val" id="hdr-gen">1826</span></div>
696
+ <div class="header-stat"><span class="label">BANKROLL</span><span class="val" id="hdr-bankroll">$91.29</span></div>
697
+ <div class="header-stat"><span class="label">ROI</span><span class="val red" id="hdr-roi">-8.71%</span></div>
698
+ <div id="header-spacer"></div>
699
+ <button class="header-btn" id="btn-zoom-out">-</button>
700
+ <button class="header-btn" id="btn-zoom-in">+</button>
701
+ <button class="header-btn active" id="btn-sound" title="Toggle sound">SFX</button>
702
+ <button class="header-btn" id="btn-speed">1x</button>
703
+ <button class="header-btn" id="btn-follow">FOLLOW</button>
704
+ <div class="header-stat" id="hdr-time" style="min-width:60px;text-align:center;">
705
+ <span class="val blue" id="clock">00:00</span>
706
+ </div>
707
+ </div>
708
+
709
+ <!-- MAIN -->
710
+ <div id="main">
711
+
712
+ <!-- LEFT PANEL -->
713
+ <div id="panel-left">
714
+ <div class="panel-section">
715
+ <div class="panel-title">Leaderboard</div>
716
+ </div>
717
+ <div id="leaderboard-list"></div>
718
+
719
+ <div class="panel-section" style="margin-top:auto;">
720
+ <div class="panel-title">Dept Status</div>
721
+ <div id="dept-list"></div>
722
+ </div>
723
+ </div>
724
+
725
+ <!-- CENTER -->
726
+ <div id="canvas-wrapper">
727
+ <canvas id="pixiCanvas"></canvas>
728
+ <canvas id="particle-canvas"></canvas>
729
+ <div id="scanlines"></div>
730
+ <div id="vignette"></div>
731
+ <div id="night-overlay"></div>
732
+ <canvas id="minimap-canvas"></canvas>
733
+
734
+ <div id="controls-hint">
735
+ WASD / drag: pan<br>
736
+ scroll: zoom<br>
737
+ click: select agent
738
+ </div>
739
+
740
+ <!-- Agent Popup -->
741
+ <div id="agent-popup">
742
+ <span class="popup-close" id="popup-close">✕</span>
743
+ <div class="popup-header">
744
+ <canvas class="popup-sprite" id="popup-sprite" width="32" height="32"></canvas>
745
+ <div>
746
+ <div class="popup-name" id="popup-name">—</div>
747
+ <div class="popup-tier" id="popup-tier">PREMIUM</div>
748
+ </div>
749
+ </div>
750
+ <div class="popup-stats">
751
+ <div class="popup-stat">
752
+ <div class="popup-stat-label">BANKROLL</div>
753
+ <div class="popup-stat-val gold" id="popup-bankroll">$10,000</div>
754
+ </div>
755
+ <div class="popup-stat">
756
+ <div class="popup-stat-label">ROI</div>
757
+ <div class="popup-stat-val" id="popup-roi">0.00%</div>
758
+ </div>
759
+ <div class="popup-stat">
760
+ <div class="popup-stat-label">WIN RATE</div>
761
+ <div class="popup-stat-val" id="popup-winrate">0%</div>
762
+ </div>
763
+ <div class="popup-stat">
764
+ <div class="popup-stat-label">TOTAL BETS</div>
765
+ <div class="popup-stat-val" id="popup-bets">0</div>
766
+ </div>
767
+ </div>
768
+ <div class="popup-strategy">
769
+ <div class="popup-strategy-label">Strategy</div>
770
+ <div class="popup-strategy-val" id="popup-strategy">—</div>
771
+ </div>
772
+ <div class="popup-speech" id="popup-speech">"Analyzing the floor…"</div>
773
+ </div>
774
+ </div>
775
+
776
+ <!-- RIGHT PANEL -->
777
+ <div id="panel-right">
778
+ <div class="panel-section">
779
+ <div class="panel-title">Today's Games</div>
780
+ <div id="predictions-list"></div>
781
+ </div>
782
+
783
+ <div class="panel-section">
784
+ <div class="panel-title">Spaces</div>
785
+ <div id="spaces-list"></div>
786
+ </div>
787
+
788
+ <div class="panel-section">
789
+ <div class="panel-title">Bankroll</div>
790
+ <div id="bankroll-stats" style="font-size:10px;"></div>
791
+ </div>
792
+ </div>
793
+
794
+ </div>
795
+
796
+ <!-- TICKER -->
797
+ <div id="ticker">
798
+ <div id="ticker-track"></div>
799
+ </div>
800
+
801
+ </div>
802
+
803
+ <!-- LOADING -->
804
+ <div id="loading">
805
+ <div class="loading-title">NOMOS42</div>
806
+ <div class="loading-sub">PIXEL WORLD v5</div>
807
+ <div class="loading-bar-wrap"><div class="loading-bar" id="loading-bar"></div></div>
808
+ <div class="loading-status" id="loading-status">Initializing…</div>
809
+ </div>
810
+
811
+ <!-- PIXI CDN -->
812
+ <script src="https://cdn.jsdelivr.net/npm/pixi.js@8/dist/pixi.min.js"></script>
813
+
814
+ <script>
815
+ // ═══════════════════════════════════════════════════════════════
816
+ // NOMOS42 PIXEL WORLD — Main Application
817
+ // Architecture: PixiJS 8 + WebGL2 + Static Data JSON
818
+ // ═══════════════════════════════════════════════════════════════
819
+
820
+ 'use strict';
821
+
822
+ // ─── CONSTANTS ─────────────────────────────────────────────────
823
+ const WORLD_W = 2400;
824
+ const WORLD_H = 1600;
825
+ const TILE = 32;
826
+ const AGENT_SIZE = 16;
827
+ const FPS_TARGET = 60;
828
+ const DATA_REFRESH_MS = 30000;
829
+ const TICKER_SPEED = 0.6;
830
+
831
+ const TIER_COLORS = {
832
+ PREMIUM: 0xFFD700,
833
+ FREE_POWER: 0x4FC3F7,
834
+ SPECIALIST: 0x66BB6A,
835
+ META: 0xCE93D8,
836
+ };
837
+
838
+ const TIER_COLORS_HEX = {
839
+ PREMIUM: '#ffd700',
840
+ FREE_POWER: '#4fc3f7',
841
+ SPECIALIST: '#66bb6a',
842
+ META: '#ce93d8',
843
+ };
844
+
845
+ const ZONE_RECTS = {
846
+ pit: { x: 700, y: 500, w: 1000, h: 600 },
847
+ research: { x: 60, y: 80, w: 380, h: 420 },
848
+ evolution: { x: 60, y: 580, w: 380, h: 420 },
849
+ engineering:{ x: 1960,y: 80, w: 380, h: 420 },
850
+ infra: { x: 1960, y: 580, w: 380, h: 420 },
851
+ leaderboard:{ x: 700, y: 60, w: 1000, h: 340 },
852
+ lounge: { x: 700, y: 1200, w: 1000, h: 340 },
853
+ };
854
+
855
+ // Speech lines per strategy
856
+ const SPEECHES = {
857
+ value_hunter: ["Edge found! +4.2%", "This line is wrong", "Sharp money here", "Market inefficiency spotted"],
858
+ half_kelly: ["Half Kelly, safe play", "Risk managed", "Variance reduction", "0.5x Kelly → placing"],
859
+ value_hunter_half_kelly: ["Best of both worlds", "Value + discipline", "Edge × 0.5 = optimal"],
860
+ proportional_edge: ["Scaling by edge", "Proportional position", "No overbet today"],
861
+ confidence_scaled: ["High conf → full size", "CI tight, going in", "Model agreement: 87%"],
862
+ flat_2pct: ["Flat 2% → consistent", "Steady bankroll play", "No FOMO bets today"],
863
+ quarter_kelly: ["Conservative sizing", "Quarter Kelly: safe", "Preserving capital"],
864
+ underdog_specialist: ["Dogs have value today", "Market overvalues fav", "Contrarian edge: +7%"],
865
+ default: ["Analyzing…", "Computing edge…", "Watching the floor", "Reading the tape…"],
866
+ };
867
+
868
+ // Dept data
869
+ const DEPTS = [
870
+ { id:'D1', name:'Research', status:'active', metric:'4 papers/wk' },
871
+ { id:'D2', name:'Engineering', status:'active', metric:'Δ Brier -0.003' },
872
+ { id:'D3', name:'Evolution', status:'active', metric:'Gen 1826' },
873
+ { id:'D4', name:'Product', status:'idle', metric:'2 shipped' },
874
+ { id:'D5', name:'Business', status:'idle', metric:'MRR $0' },
875
+ { id:'D6', name:'Evaluation', status:'active', metric:'Cal: 0.89' },
876
+ { id:'D7', name:'Infra', status:'active', metric:'6/6 UP' },
877
+ { id:'D8', name:'Finance', status:'idle', metric:'$91.29 live' },
878
+ { id:'D9', name:'Cross-Repo', status:'active', metric:'Parity 94%' },
879
+ ];
880
+
881
+ // ─── STATE ─────────────────────────────────────────────────────
882
+ const STATE = {
883
+ agents: {},
884
+ predictions: [],
885
+ bankroll: {},
886
+ health: {},
887
+ agentList: [],
888
+ viewX: WORLD_W / 2,
889
+ viewY: WORLD_H / 2,
890
+ zoom: 1.2,
891
+ dragging: false,
892
+ dragStart: { x:0, y:0 },
893
+ dragViewStart: { x:0, y:0 },
894
+ soundEnabled: true,
895
+ speed: 1,
896
+ followAgent: null,
897
+ selectedAgent: null,
898
+ tickerOffset: 0,
899
+ tickerWidth: 0,
900
+ lastUpdate: 0,
901
+ particles: [],
902
+ speechBubbles: [],
903
+ };
904
+
905
+ // ─── AUDIO CONTEXT ─────────────────────────────────────────────
906
+ let audioCtx = null;
907
+
908
+ function getAudio() {
909
+ if (!audioCtx) {
910
+ try { audioCtx = new (window.AudioContext || window.webkitAudioContext)(); } catch(e) {}
911
+ }
912
+ return audioCtx;
913
+ }
914
+
915
+ function playTone(freq, dur, type='square', vol=0.08) {
916
+ if (!STATE.soundEnabled) return;
917
+ try {
918
+ const ctx = getAudio();
919
+ if (!ctx) return;
920
+ const osc = ctx.createOscillator();
921
+ const gain = ctx.createGain();
922
+ osc.type = type;
923
+ osc.frequency.value = freq;
924
+ gain.gain.setValueAtTime(vol, ctx.currentTime);
925
+ gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + dur);
926
+ osc.connect(gain);
927
+ gain.connect(ctx.destination);
928
+ osc.start();
929
+ osc.stop(ctx.currentTime + dur);
930
+ } catch(e) {}
931
+ }
932
+
933
+ function playCoin() { playTone(880, 0.08, 'square', 0.06); setTimeout(()=>playTone(1320,0.12,'square',0.05),80); }
934
+ function playWin() {
935
+ [523,659,784,1047].forEach((f,i)=>setTimeout(()=>playTone(f,0.15,'square',0.06),i*80));
936
+ }
937
+ function playLoss() { playTone(220, 0.25, 'sawtooth', 0.05); }
938
+ function playSelect() { playTone(660, 0.05, 'square', 0.04); }
939
+ function playTick() { playTone(440, 0.03, 'square', 0.02); }
940
+
941
+ // ─── SPRITE GENERATOR ──────────────────────────────────────────
942
+ // Generates 16×16 pixel sprites for each tier using Canvas 2D
943
+ function makeSpriteCanvas(tier, id, size=16) {
944
+ const c = document.createElement('canvas');
945
+ c.width = size; c.height = size;
946
+ const ctx = c.getContext('2d');
947
+ ctx.imageSmoothingEnabled = false;
948
+
949
+ const palettes = {
950
+ PREMIUM: ['#ffd700','#ffec6e','#b8960c','#fff8dc','#8b6914'],
951
+ FREE_POWER: ['#4fc3f7','#81d4fa','#0288d1','#e1f5fe','#01579b'],
952
+ SPECIALIST: ['#66bb6a','#a5d6a7','#2e7d32','#e8f5e9','#1b5e20'],
953
+ META: ['#ce93d8','#e1bee7','#7b1fa2','#f3e5f5','#4a148c'],
954
+ };
955
+
956
+ const pal = palettes[tier] || palettes.SPECIALIST;
957
+ const s = size / 16; // scale factor
958
+
959
+ // Helper for drawing pixel blocks
960
+ const px = (x,y,c,w=1,h=1)=>{
961
+ ctx.fillStyle = c;
962
+ ctx.fillRect(x*s, y*s, w*s, h*s);
963
+ };
964
+
965
+ // Different sprites based on ID hash
966
+ const hash = (id || '').split('').reduce((a,c)=>a+c.charCodeAt(0),0);
967
+ const variant = hash % 4;
968
+
969
+ if (tier === 'PREMIUM') {
970
+ // Gold elite sprite — slightly larger, more detail
971
+ px(6,1,pal[1],4,1); // head top
972
+ px(5,2,pal[0],6,4); // head
973
+ px(5,2,pal[2],1,4); // shadow
974
+ px(5,4,pal[3],1,1); // eye left
975
+ px(9,4,pal[3],1,1); // eye right
976
+ px(6,6,pal[2],4,1); // mouth
977
+ px(4,6,pal[2],8,1); // shoulders
978
+ px(4,7,pal[0],8,5); // body
979
+ px(3,7,pal[2],1,5); // arm L
980
+ px(12,7,pal[2],1,5); // arm R
981
+ px(5,12,pal[2],3,4); // leg L
982
+ px(8,12,pal[2],3,4); // leg R
983
+ px(7,0,pal[1],2,1); // crown hint
984
+ px(6,0,pal[4],1,1); px(9,0,pal[4],1,1);
985
+ } else if (tier === 'FREE_POWER') {
986
+ // Blue agent
987
+ px(6,2,pal[1],4,1);
988
+ px(5,3,pal[0],6,4);
989
+ px(5,5,pal[3],1,1); // eye L
990
+ px(9,5,pal[3],1,1); // eye R
991
+ px(6,7,pal[2],4,1); // mouth
992
+ px(4,7,pal[2],8,1); // shoulders
993
+ px(4,8,pal[0],8,4); // body
994
+ px(3,8,pal[2],1,4); // arm L
995
+ px(12,8,pal[2],1,4); // arm R
996
+ px(5,12,pal[2],3,4); // leg L
997
+ px(8,12,pal[2],3,4); // leg R
998
+ if (variant===0) { px(6,1,pal[1],4,2); } // hat
999
+ } else if (tier === 'META') {
1000
+ // Purple oracle — robed
1001
+ px(6,1,pal[0],4,1);
1002
+ px(5,2,pal[1],6,4);
1003
+ px(5,4,pal[3],2,1); // eye L (bigger)
1004
+ px(9,4,pal[3],2,1); // eye R
1005
+ px(6,6,pal[4],4,1); // mystical mouth
1006
+ px(3,7,pal[0],10,9); // wide robe
1007
+ px(4,7,pal[2],1,8); // robe shadow L
1008
+ px(11,7,pal[2],1,8); // robe shadow R
1009
+ px(6,0,pal[4],1,2); px(9,0,pal[4],1,2); // antennae
1010
+ } else {
1011
+ // Green specialist — simple worker
1012
+ const bodies = [
1013
+ ()=>{ px(6,2,pal[0],4,4); px(5,4,pal[3],1,1); px(9,4,pal[3],1,1); px(4,6,pal[2],8,1); px(4,7,pal[1],8,4); px(3,7,pal[2],1,4); px(12,7,pal[2],1,4); px(5,11,pal[2],3,5); px(8,11,pal[2],3,5); },
1014
+ ()=>{ px(7,2,pal[0],2,1); px(6,3,pal[0],4,4); px(5,5,pal[3],1,1); px(9,5,pal[3],1,1); px(5,7,pal[2],6,1); px(4,8,pal[1],8,4); px(3,8,pal[2],1,4); px(12,8,pal[2],1,4); px(5,12,pal[2],3,4); px(8,12,pal[2],3,4); },
1015
+ ];
1016
+ (bodies[variant%bodies.length] || bodies[0])();
1017
+ }
1018
+
1019
+ return c;
1020
+ }
1021
+
1022
+ // Generate walking frames (offset pixels slightly)
1023
+ function makeWalkFrames(tier, id, size=16) {
1024
+ return [0,1,2,1].map(frame => {
1025
+ const c = makeSpriteCanvas(tier, id, size);
1026
+ if (frame === 1 || frame === 3) {
1027
+ // Slight leg shift for walking illusion
1028
+ const tmp = document.createElement('canvas');
1029
+ tmp.width = size; tmp.height = size;
1030
+ const tctx = tmp.getContext('2d');
1031
+ tctx.imageSmoothingEnabled = false;
1032
+ tctx.drawImage(c, 0, 0);
1033
+ return tmp;
1034
+ }
1035
+ return c;
1036
+ });
1037
+ }
1038
+
1039
+ // ─── WORLD MAP ─────────────────────────────────────────────────
1040
+ // Generates the floor texture using Canvas 2D
1041
+ function buildWorldTexture(app) {
1042
+ const c = document.createElement('canvas');
1043
+ c.width = WORLD_W;
1044
+ c.height = WORLD_H;
1045
+ const ctx = c.getContext('2d');
1046
+ ctx.imageSmoothingEnabled = false;
1047
+
1048
+ // Background — dark floor tiles
1049
+ for (let tx = 0; tx < WORLD_W; tx += TILE) {
1050
+ for (let ty = 0; ty < WORLD_H; ty += TILE) {
1051
+ const even = ((tx/TILE + ty/TILE) % 2 === 0);
1052
+ ctx.fillStyle = even ? '#080818' : '#090920';
1053
+ ctx.fillRect(tx, ty, TILE, TILE);
1054
+ }
1055
+ }
1056
+
1057
+ // Grid lines
1058
+ ctx.strokeStyle = 'rgba(255,255,255,0.025)';
1059
+ ctx.lineWidth = 0.5;
1060
+ for (let tx = 0; tx < WORLD_W; tx += TILE) {
1061
+ ctx.beginPath(); ctx.moveTo(tx, 0); ctx.lineTo(tx, WORLD_H); ctx.stroke();
1062
+ }
1063
+ for (let ty = 0; ty < WORLD_H; ty += TILE) {
1064
+ ctx.beginPath(); ctx.moveTo(0, ty); ctx.lineTo(WORLD_W, ty); ctx.stroke();
1065
+ }
1066
+
1067
+ // Draw zones
1068
+ function drawZone(zone, label, color, alpha=0.08) {
1069
+ const r = ZONE_RECTS[zone];
1070
+ if (!r) return;
1071
+ ctx.fillStyle = `rgba(${hexToRgb(color)},${alpha})`;
1072
+ ctx.fillRect(r.x, r.y, r.w, r.h);
1073
+ // Border
1074
+ ctx.strokeStyle = `rgba(${hexToRgb(color)},0.25)`;
1075
+ ctx.lineWidth = 2;
1076
+ ctx.strokeRect(r.x+1, r.y+1, r.w-2, r.h-2);
1077
+ // Inner glow border
1078
+ ctx.strokeStyle = `rgba(${hexToRgb(color)},0.1)`;
1079
+ ctx.lineWidth = 8;
1080
+ ctx.strokeRect(r.x+4, r.y+4, r.w-8, r.h-8);
1081
+ // Label
1082
+ ctx.fillStyle = `rgba(${hexToRgb(color)},0.18)`;
1083
+ ctx.font = 'bold 28px monospace';
1084
+ ctx.letterSpacing = '8px';
1085
+ ctx.textAlign = 'center';
1086
+ ctx.fillText(label.toUpperCase(), r.x + r.w/2, r.y + r.h/2 + 10);
1087
+ }
1088
+
1089
+ function hexToRgb(hex) {
1090
+ const r = parseInt(hex.slice(1,3),16);
1091
+ const g = parseInt(hex.slice(3,5),16);
1092
+ const b = parseInt(hex.slice(5,7),16);
1093
+ return `${r},${g},${b}`;
1094
+ }
1095
+
1096
+ drawZone('pit', 'TRADING PIT', '#ffd700', 0.06);
1097
+ drawZone('research', 'RESEARCH', '#4fc3f7', 0.09);
1098
+ drawZone('evolution', 'EVOLUTION', '#66bb6a', 0.09);
1099
+ drawZone('engineering','ENGINEERING', '#ce93d8', 0.09);
1100
+ drawZone('infra', 'INFRA', '#ef5350', 0.09);
1101
+ drawZone('leaderboard','LEADERBOARD', '#ffd700', 0.04);
1102
+ drawZone('lounge', 'LOUNGE', '#4fc3f7', 0.04);
1103
+
1104
+ // Bloomberg terminals (desk sprites)
1105
+ drawTerminals(ctx);
1106
+
1107
+ // Decorative circuit traces
1108
+ drawCircuitTraces(ctx);
1109
+
1110
+ return PIXI.Texture.from(c);
1111
+ }
1112
+
1113
+ function drawTerminals(ctx) {
1114
+ // Scattered terminal desks in the Trading Pit
1115
+ const pit = ZONE_RECTS.pit;
1116
+ const positions = [];
1117
+ for (let i = 0; i < 24; i++) {
1118
+ positions.push({
1119
+ x: pit.x + 80 + (i % 6) * 145,
1120
+ y: pit.y + 80 + Math.floor(i / 6) * 130,
1121
+ });
1122
+ }
1123
+ positions.forEach(({x, y}) => {
1124
+ // Desk
1125
+ ctx.fillStyle = '#12122a';
1126
+ ctx.fillRect(x - 24, y - 16, 48, 32);
1127
+ ctx.strokeStyle = '#1a1a40';
1128
+ ctx.lineWidth = 1;
1129
+ ctx.strokeRect(x - 24, y - 16, 48, 32);
1130
+ // Screen
1131
+ ctx.fillStyle = '#0d2040';
1132
+ ctx.fillRect(x - 16, y - 12, 32, 20);
1133
+ // Screen glow
1134
+ ctx.fillStyle = `rgba(79,195,247,${0.05 + Math.random() * 0.08})`;
1135
+ ctx.fillRect(x - 15, y - 11, 30, 18);
1136
+ // Scanline on screen
1137
+ ctx.fillStyle = 'rgba(79,195,247,0.15)';
1138
+ for (let sl = 0; sl < 4; sl++) {
1139
+ ctx.fillRect(x - 15, y - 11 + sl * 4, 30, 1);
1140
+ }
1141
+ });
1142
+ }
1143
+
1144
+ function drawCircuitTraces(ctx) {
1145
+ ctx.strokeStyle = 'rgba(79,195,247,0.04)';
1146
+ ctx.lineWidth = 1;
1147
+ // Horizontal traces
1148
+ for (let i = 0; i < 18; i++) {
1149
+ const y = 100 + i * 85;
1150
+ ctx.beginPath();
1151
+ ctx.moveTo(0, y);
1152
+ ctx.lineTo(WORLD_W, y);
1153
+ ctx.stroke();
1154
+ }
1155
+ // Nodes
1156
+ ctx.fillStyle = 'rgba(79,195,247,0.08)';
1157
+ for (let i = 0; i < 40; i++) {
1158
+ const x = Math.random() * WORLD_W;
1159
+ const y = Math.random() * WORLD_H;
1160
+ ctx.beginPath();
1161
+ ctx.arc(x, y, 3, 0, Math.PI*2);
1162
+ ctx.fill();
1163
+ }
1164
+ }
1165
+
1166
+ // ─── PIXI APP ──────────────────────────────────────────────────
1167
+ let pixiApp = null;
1168
+ let worldContainer = null;
1169
+ let agentContainer = null;
1170
+ let uiContainer = null;
1171
+ let worldSprite = null;
1172
+ const agentSprites = new Map();
1173
+ const speechBubblePool = [];
1174
+
1175
+ async function initPixi() {
1176
+ const wrapper = document.getElementById('canvas-wrapper');
1177
+ const W = wrapper.clientWidth;
1178
+ const H = wrapper.clientHeight;
1179
+
1180
+ pixiApp = new PIXI.Application();
1181
+ await pixiApp.init({
1182
+ canvas: document.getElementById('pixiCanvas'),
1183
+ width: W,
1184
+ height: H,
1185
+ backgroundColor: 0x060618,
1186
+ antialias: false,
1187
+ resolution: Math.min(window.devicePixelRatio || 1, 2),
1188
+ autoDensity: true,
1189
+ });
1190
+
1191
+ // World container (panned/zoomed)
1192
+ worldContainer = new PIXI.Container();
1193
+ pixiApp.stage.addChild(worldContainer);
1194
+
1195
+ // World sprite
1196
+ setLoadStatus('Generating world…', 40);
1197
+ const worldTex = buildWorldTexture(pixiApp);
1198
+ worldSprite = new PIXI.Sprite(worldTex);
1199
+ worldSprite.x = 0;
1200
+ worldSprite.y = 0;
1201
+ worldContainer.addChild(worldSprite);
1202
+
1203
+ // Agent container
1204
+ agentContainer = new PIXI.Container();
1205
+ worldContainer.addChild(agentContainer);
1206
+
1207
+ // UI overlay container (screen-space)
1208
+ uiContainer = new PIXI.Container();
1209
+ pixiApp.stage.addChild(uiContainer);
1210
+
1211
+ // Center view
1212
+ setViewCenter(STATE.viewX, STATE.viewY);
1213
+
1214
+ // Interaction
1215
+ setupInteraction();
1216
+
1217
+ // Resize handler
1218
+ window.addEventListener('resize', onResize);
1219
+ onResize();
1220
+ }
1221
+
1222
+ function onResize() {
1223
+ const wrapper = document.getElementById('canvas-wrapper');
1224
+ if (pixiApp && wrapper) {
1225
+ pixiApp.renderer.resize(wrapper.clientWidth, wrapper.clientHeight);
1226
+ setViewCenter(STATE.viewX, STATE.viewY);
1227
+ }
1228
+ }
1229
+
1230
+ // ─── VIEW TRANSFORM ────────────────────────────────────────────
1231
+ function setViewCenter(wx, wy) {
1232
+ STATE.viewX = wx;
1233
+ STATE.viewY = wy;
1234
+ const W = pixiApp.screen.width;
1235
+ const H = pixiApp.screen.height;
1236
+ const z = STATE.zoom;
1237
+ worldContainer.x = W/2 - wx * z;
1238
+ worldContainer.y = H/2 - wy * z;
1239
+ worldContainer.scale.set(z);
1240
+ }
1241
+
1242
+ function clampView() {
1243
+ const W = pixiApp.screen.width;
1244
+ const H = pixiApp.screen.height;
1245
+ const z = STATE.zoom;
1246
+ const margin = 200;
1247
+ STATE.viewX = Math.max(-margin/z, Math.min(WORLD_W + margin/z, STATE.viewX));
1248
+ STATE.viewY = Math.max(-margin/z, Math.min(WORLD_H + margin/z, STATE.viewY));
1249
+ }
1250
+
1251
+ // ─── INTERACTION ───────────────────────────────────────────────
1252
+ function setupInteraction() {
1253
+ const canvas = document.getElementById('pixiCanvas');
1254
+
1255
+ // Drag to pan
1256
+ canvas.addEventListener('pointerdown', e => {
1257
+ if (e.button !== 0) return;
1258
+ STATE.dragging = true;
1259
+ STATE.dragStart = { x: e.clientX, y: e.clientY };
1260
+ STATE.dragViewStart = { x: STATE.viewX, y: STATE.viewY };
1261
+ canvas.style.cursor = 'grabbing';
1262
+ e.preventDefault();
1263
+ });
1264
+
1265
+ window.addEventListener('pointermove', e => {
1266
+ if (!STATE.dragging) return;
1267
+ const dx = (e.clientX - STATE.dragStart.x) / STATE.zoom;
1268
+ const dy = (e.clientY - STATE.dragStart.y) / STATE.zoom;
1269
+ STATE.viewX = STATE.dragViewStart.x - dx;
1270
+ STATE.viewY = STATE.dragViewStart.y - dy;
1271
+ clampView();
1272
+ setViewCenter(STATE.viewX, STATE.viewY);
1273
+ });
1274
+
1275
+ window.addEventListener('pointerup', e => {
1276
+ if (STATE.dragging) {
1277
+ STATE.dragging = false;
1278
+ canvas.style.cursor = 'default';
1279
+ }
1280
+ });
1281
+
1282
+ // Scroll to zoom
1283
+ canvas.addEventListener('wheel', e => {
1284
+ e.preventDefault();
1285
+ const delta = e.deltaY > 0 ? -0.1 : 0.1;
1286
+ STATE.zoom = Math.max(0.4, Math.min(3.5, STATE.zoom + delta));
1287
+ setViewCenter(STATE.viewX, STATE.viewY);
1288
+ }, { passive: false });
1289
+
1290
+ // WASD keys
1291
+ const keysDown = new Set();
1292
+ window.addEventListener('keydown', e => keysDown.add(e.key.toLowerCase()));
1293
+ window.addEventListener('keyup', e => keysDown.delete(e.key.toLowerCase()));
1294
+
1295
+ pixiApp.ticker.add(() => {
1296
+ if (STATE.dragging) return;
1297
+ const speed = 8 / STATE.zoom;
1298
+ let moved = false;
1299
+ if (keysDown.has('w') || keysDown.has('arrowup')) { STATE.viewY -= speed; moved=true; }
1300
+ if (keysDown.has('s') || keysDown.has('arrowdown')) { STATE.viewY += speed; moved=true; }
1301
+ if (keysDown.has('a') || keysDown.has('arrowleft')) { STATE.viewX -= speed; moved=true; }
1302
+ if (keysDown.has('d') || keysDown.has('arrowright')) { STATE.viewX += speed; moved=true; }
1303
+ if (moved) { clampView(); setViewCenter(STATE.viewX, STATE.viewY); }
1304
+ });
1305
+
1306
+ // Popup close
1307
+ document.getElementById('popup-close').addEventListener('click', () => {
1308
+ closePopup();
1309
+ });
1310
+
1311
+ // Header buttons
1312
+ document.getElementById('btn-zoom-in').addEventListener('click', () => {
1313
+ STATE.zoom = Math.min(3.5, STATE.zoom + 0.2);
1314
+ setViewCenter(STATE.viewX, STATE.viewY);
1315
+ playSelect();
1316
+ });
1317
+ document.getElementById('btn-zoom-out').addEventListener('click', () => {
1318
+ STATE.zoom = Math.max(0.4, STATE.zoom - 0.2);
1319
+ setViewCenter(STATE.viewX, STATE.viewY);
1320
+ playSelect();
1321
+ });
1322
+
1323
+ const soundBtn = document.getElementById('btn-sound');
1324
+ soundBtn.addEventListener('click', () => {
1325
+ STATE.soundEnabled = !STATE.soundEnabled;
1326
+ soundBtn.classList.toggle('active', STATE.soundEnabled);
1327
+ soundBtn.textContent = STATE.soundEnabled ? 'SFX' : 'MUTE';
1328
+ // Unlock AudioContext
1329
+ if (STATE.soundEnabled) { getAudio(); playTick(); }
1330
+ });
1331
+
1332
+ const speedBtn = document.getElementById('btn-speed');
1333
+ const speeds = [1, 2, 4];
1334
+ let speedIdx = 0;
1335
+ speedBtn.addEventListener('click', () => {
1336
+ speedIdx = (speedIdx + 1) % speeds.length;
1337
+ STATE.speed = speeds[speedIdx];
1338
+ speedBtn.textContent = `${STATE.speed}x`;
1339
+ playSelect();
1340
+ });
1341
+
1342
+ const followBtn = document.getElementById('btn-follow');
1343
+ followBtn.addEventListener('click', () => {
1344
+ if (STATE.followAgent) {
1345
+ STATE.followAgent = null;
1346
+ followBtn.classList.remove('active');
1347
+ followBtn.textContent = 'FOLLOW';
1348
+ } else if (STATE.selectedAgent) {
1349
+ STATE.followAgent = STATE.selectedAgent;
1350
+ followBtn.classList.add('active');
1351
+ followBtn.textContent = 'UNFOLLOW';
1352
+ playSelect();
1353
+ }
1354
+ });
1355
+ }
1356
+
1357
+ // ─── AGENTS ────────────────────────────────────────────────────
1358
+ class Agent {
1359
+ constructor(data) {
1360
+ this.id = data.id;
1361
+ this.name = data.name || data.id;
1362
+ this.tier = data.tier || 'SPECIALIST';
1363
+ this.strategy = data.strategy || 'default';
1364
+ this.bankroll = data.bankroll || 10000;
1365
+ this.roi = data.roi || 0;
1366
+ this.win_rate = data.win_rate || 0;
1367
+ this.total_bets = data.total_bets || 0;
1368
+ this.total_wins = data.total_wins || 0;
1369
+ this.total_pnl = data.total_pnl || 0;
1370
+ this.model = data.model || '';
1371
+ this.provider = data.provider || '';
1372
+
1373
+ // World position (random start in tier zone)
1374
+ const zone = this._homeZone();
1375
+ this.x = zone.x + Math.random() * zone.w;
1376
+ this.y = zone.y + Math.random() * zone.h;
1377
+
1378
+ // Movement
1379
+ this.targetX = this.x;
1380
+ this.targetY = this.y;
1381
+ this.speed = 0.6 + Math.random() * 0.8;
1382
+ this.moveTimer = 0;
1383
+ this.moveCooldown = 120 + Math.random() * 300;
1384
+ this.walkFrame = 0;
1385
+ this.walkTimer = 0;
1386
+ this.facingRight = Math.random() > 0.5;
1387
+
1388
+ // Sit at desk
1389
+ this.sittingTimer = 0;
1390
+ this.isSitting = false;
1391
+
1392
+ // Speech
1393
+ this.speechText = null;
1394
+ this.speechTimer = 0;
1395
+
1396
+ // Sprite
1397
+ this.sprite = null;
1398
+ this.spriteCanvas = makeSpriteCanvas(this.tier, this.id, AGENT_SIZE);
1399
+ this.sparkTimer = 0;
1400
+ }
1401
+
1402
+ _homeZone() {
1403
+ if (this.tier === 'PREMIUM') return ZONE_RECTS.leaderboard;
1404
+ if (this.tier === 'META') return ZONE_RECTS.evolution;
1405
+ if (this.tier === 'FREE_POWER') return ZONE_RECTS.research;
1406
+ // Specialists spread across pit
1407
+ return ZONE_RECTS.pit;
1408
+ }
1409
+
1410
+ _randomTarget() {
1411
+ // Premium agents prefer leaderboard
1412
+ // Others wander pit and adjacent zones
1413
+ const zones = this.tier === 'PREMIUM'
1414
+ ? [ZONE_RECTS.leaderboard, ZONE_RECTS.pit]
1415
+ : this.tier === 'META'
1416
+ ? [ZONE_RECTS.evolution, ZONE_RECTS.pit]
1417
+ : this.tier === 'FREE_POWER'
1418
+ ? [ZONE_RECTS.research, ZONE_RECTS.pit, ZONE_RECTS.lounge]
1419
+ : [ZONE_RECTS.pit, ZONE_RECTS.lounge, ZONE_RECTS.engineering];
1420
+
1421
+ const zone = zones[Math.floor(Math.random() * zones.length)];
1422
+ return {
1423
+ x: zone.x + 20 + Math.random() * (zone.w - 40),
1424
+ y: zone.y + 20 + Math.random() * (zone.h - 40),
1425
+ };
1426
+ }
1427
+
1428
+ update(dt) {
1429
+ const spd = this.speed * STATE.speed * dt;
1430
+
1431
+ // Sitting at desk
1432
+ if (this.isSitting) {
1433
+ this.sittingTimer -= dt;
1434
+ if (this.sittingTimer <= 0) {
1435
+ this.isSitting = false;
1436
+ const t = this._randomTarget();
1437
+ this.targetX = t.x;
1438
+ this.targetY = t.y;
1439
+ }
1440
+ return;
1441
+ }
1442
+
1443
+ this.moveTimer -= dt;
1444
+
1445
+ const dx = this.targetX - this.x;
1446
+ const dy = this.targetY - this.y;
1447
+ const dist = Math.sqrt(dx*dx + dy*dy);
1448
+
1449
+ if (dist < 3 || this.moveTimer <= 0) {
1450
+ // Reached target or timed out
1451
+ // Chance to sit at a desk
1452
+ if (Math.random() < 0.15) {
1453
+ this.isSitting = true;
1454
+ this.sittingTimer = 60 + Math.random() * 180;
1455
+ this.speechText = this._speech();
1456
+ this.speechTimer = 120 + Math.random() * 60;
1457
+ if (STATE.soundEnabled && Math.random() < 0.01) playTick();
1458
+ }
1459
+ const t = this._randomTarget();
1460
+ this.targetX = t.x;
1461
+ this.targetY = t.y;
1462
+ this.moveTimer = this.moveCooldown * (0.5 + Math.random());
1463
+ } else {
1464
+ // Move toward target
1465
+ const speed = spd * (dist < 20 ? dist/20 : 1);
1466
+ this.x += (dx / dist) * speed;
1467
+ this.y += (dy / dist) * speed;
1468
+ this.facingRight = dx > 0;
1469
+ }
1470
+
1471
+ // Walk animation
1472
+ this.walkTimer += dt;
1473
+ if (this.walkTimer > 8) {
1474
+ this.walkTimer = 0;
1475
+ this.walkFrame = (this.walkFrame + 1) % 4;
1476
+ }
1477
+
1478
+ // Speech timer
1479
+ if (this.speechTimer > 0) {
1480
+ this.speechTimer -= dt;
1481
+ if (this.speechTimer <= 0) this.speechText = null;
1482
+ }
1483
+
1484
+ // Spark timer for big wins
1485
+ if (this.sparkTimer > 0) this.sparkTimer -= dt;
1486
+ }
1487
+
1488
+ _speech() {
1489
+ const lines = SPEECHES[this.strategy] || SPEECHES.default;
1490
+ return lines[Math.floor(Math.random() * lines.length)];
1491
+ }
1492
+
1493
+ celebrate() {
1494
+ this.sparkTimer = 120;
1495
+ this.speechText = '🎉 WIN! +' + (Math.random()*200+50).toFixed(0);
1496
+ this.speechTimer = 180;
1497
+ playWin();
1498
+ }
1499
+
1500
+ getSpriteColor() {
1501
+ return TIER_COLORS[this.tier] || TIER_COLORS.SPECIALIST;
1502
+ }
1503
+ }
1504
+
1505
+ // ─── RENDER AGENTS ─────────────────────────────────────────────
1506
+ // Selection ring graphics (single, reused)
1507
+ let selectionRing = null;
1508
+
1509
+ function createAgentSprites() {
1510
+ agentContainer.removeChildren();
1511
+
1512
+ // Selection ring
1513
+ selectionRing = new PIXI.Graphics();
1514
+ selectionRing.visible = false;
1515
+ agentContainer.addChild(selectionRing);
1516
+
1517
+ STATE.agentList.forEach(agent => {
1518
+ // Create sprite from canvas
1519
+ try {
1520
+ const tex = PIXI.Texture.from(agent.spriteCanvas);
1521
+ const spr = new PIXI.Sprite(tex);
1522
+ spr.width = AGENT_SIZE;
1523
+ spr.height = AGENT_SIZE;
1524
+ spr.anchor.set(0.5, 1.0);
1525
+ spr.eventMode = 'static';
1526
+ spr.cursor = 'pointer';
1527
+ spr.on('pointerdown', () => selectAgent(agent));
1528
+ agentContainer.addChild(spr);
1529
+ agent.sprite = spr;
1530
+ } catch(e) {
1531
+ // Fallback: colored rectangle
1532
+ const g2 = new PIXI.Graphics();
1533
+ g2.rect(-6, -12, 12, 12).fill({ color: agent.getSpriteColor() });
1534
+ g2.eventMode = 'static';
1535
+ g2.cursor = 'pointer';
1536
+ g2.on('pointerdown', () => selectAgent(agent));
1537
+ agentContainer.addChild(g2);
1538
+ agent.spriteGfx = g2;
1539
+ }
1540
+ });
1541
+ }
1542
+
1543
+ function updateAgentPositions() {
1544
+ STATE.agentList.forEach(agent => {
1545
+ if (agent.sprite) {
1546
+ agent.sprite.x = agent.x;
1547
+ agent.sprite.y = agent.isSitting ? agent.y + 4 : agent.y + 2;
1548
+
1549
+ // Scale by bankroll (richer = bigger)
1550
+ const scale = 0.85 + Math.min(agent.bankroll / 10000, 1.5) * 0.3;
1551
+ agent.sprite.scale.y = scale;
1552
+ agent.sprite.scale.x = agent.facingRight ? scale : -scale;
1553
+ } else if (agent.spriteGfx) {
1554
+ agent.spriteGfx.x = agent.x;
1555
+ agent.spriteGfx.y = agent.y;
1556
+ }
1557
+ });
1558
+
1559
+ // Selection ring around selected agent
1560
+ if (selectionRing) {
1561
+ if (STATE.selectedAgent) {
1562
+ const a = STATE.selectedAgent;
1563
+ selectionRing.visible = true;
1564
+ selectionRing.clear();
1565
+ const pulse = 0.5 + 0.5 * Math.sin(Date.now() / 200);
1566
+ const ringColor = TIER_COLORS[a.tier] || 0xFFFFFF;
1567
+ selectionRing.circle(0, 0, AGENT_SIZE * 0.8).stroke({ color: ringColor, alpha: 0.6 + 0.4 * pulse, width: 1.5 });
1568
+ selectionRing.circle(0, 0, AGENT_SIZE * 1.1).stroke({ color: ringColor, alpha: 0.2 + 0.2 * pulse, width: 1 });
1569
+ selectionRing.x = a.x;
1570
+ selectionRing.y = a.y - AGENT_SIZE * 0.5;
1571
+ } else {
1572
+ selectionRing.visible = false;
1573
+ }
1574
+ }
1575
+ }
1576
+
1577
+ // ─── SELECTION ─────────────────────────────────────────────────
1578
+ function selectAgent(agent) {
1579
+ STATE.selectedAgent = agent;
1580
+ playSelect();
1581
+ showPopup(agent);
1582
+ }
1583
+
1584
+ function showPopup(agent) {
1585
+ const popup = document.getElementById('agent-popup');
1586
+ const wrapper = document.getElementById('canvas-wrapper');
1587
+
1588
+ // Fill popup
1589
+ document.getElementById('popup-name').textContent = agent.name;
1590
+
1591
+ const tierEl = document.getElementById('popup-tier');
1592
+ tierEl.textContent = agent.tier.replace('_', ' ');
1593
+ tierEl.className = 'popup-tier ' + agent.tier;
1594
+
1595
+ const bankroll = document.getElementById('popup-bankroll');
1596
+ bankroll.textContent = '$' + agent.bankroll.toLocaleString('en', {minimumFractionDigits:2, maximumFractionDigits:2});
1597
+
1598
+ const roi = document.getElementById('popup-roi');
1599
+ roi.textContent = (agent.roi >= 0 ? '+' : '') + agent.roi.toFixed(2) + '%';
1600
+ roi.className = 'popup-stat-val ' + (agent.roi >= 0 ? 'green' : 'red');
1601
+
1602
+ document.getElementById('popup-winrate').textContent =
1603
+ (agent.win_rate * 100).toFixed(1) + '%';
1604
+ document.getElementById('popup-bets').textContent = agent.total_bets;
1605
+ document.getElementById('popup-strategy').textContent =
1606
+ agent.strategy.replace(/_/g,' ');
1607
+ document.getElementById('popup-speech').textContent =
1608
+ '"' + (agent.speechText || agent._speech()) + '"';
1609
+
1610
+ // Draw sprite in popup
1611
+ const spriteCanvas = document.getElementById('popup-sprite');
1612
+ const sctx = spriteCanvas.getContext('2d');
1613
+ sctx.clearRect(0, 0, 32, 32);
1614
+ sctx.imageSmoothingEnabled = false;
1615
+ const bigSprite = makeSpriteCanvas(agent.tier, agent.id, 32);
1616
+ sctx.drawImage(bigSprite, 0, 0, 32, 32);
1617
+
1618
+ // Position popup near agent (world→screen)
1619
+ const W = wrapper.clientWidth;
1620
+ const H = wrapper.clientHeight;
1621
+ const z = STATE.zoom;
1622
+ const screenX = (agent.x - STATE.viewX) * z + W/2;
1623
+ const screenY = (agent.y - STATE.viewY) * z + H/2;
1624
+
1625
+ const popW = 240, popH = 220;
1626
+ let px = screenX + 20;
1627
+ let py = screenY - popH - 20;
1628
+ if (px + popW > W) px = screenX - popW - 20;
1629
+ if (py < 0) py = screenY + 20;
1630
+
1631
+ popup.style.left = px + 'px';
1632
+ popup.style.top = py + 'px';
1633
+ popup.classList.add('visible');
1634
+ }
1635
+
1636
+ function closePopup() {
1637
+ document.getElementById('agent-popup').classList.remove('visible');
1638
+ STATE.selectedAgent = null;
1639
+ }
1640
+
1641
+ // ─── PARTICLES ─────────────────────────────────────────────────
1642
+ const particleCanvas = document.getElementById('particle-canvas');
1643
+ const pCtx = particleCanvas.getContext('2d');
1644
+
1645
+ function resizeParticleCanvas() {
1646
+ const wrapper = document.getElementById('canvas-wrapper');
1647
+ particleCanvas.width = wrapper.clientWidth;
1648
+ particleCanvas.height = wrapper.clientHeight;
1649
+ }
1650
+
1651
+ function spawnParticles(worldX, worldY, color='#ffd700', count=12) {
1652
+ const wrapper = document.getElementById('canvas-wrapper');
1653
+ const W = wrapper.clientWidth;
1654
+ const H = wrapper.clientHeight;
1655
+ const z = STATE.zoom;
1656
+ const sx = (worldX - STATE.viewX) * z + W/2;
1657
+ const sy = (worldY - STATE.viewY) * z + H/2;
1658
+
1659
+ for (let i = 0; i < count; i++) {
1660
+ const angle = (Math.PI * 2 / count) * i + Math.random() * 0.3;
1661
+ const speed = 1.5 + Math.random() * 3;
1662
+ STATE.particles.push({
1663
+ x: sx, y: sy,
1664
+ vx: Math.cos(angle) * speed,
1665
+ vy: Math.sin(angle) * speed - 2,
1666
+ life: 1.0,
1667
+ decay: 0.02 + Math.random() * 0.02,
1668
+ size: 2 + Math.random() * 3,
1669
+ color,
1670
+ });
1671
+ }
1672
+ }
1673
+
1674
+ function updateParticles() {
1675
+ pCtx.clearRect(0, 0, particleCanvas.width, particleCanvas.height);
1676
+ STATE.particles = STATE.particles.filter(p => p.life > 0);
1677
+ STATE.particles.forEach(p => {
1678
+ p.x += p.vx * STATE.speed;
1679
+ p.y += p.vy * STATE.speed;
1680
+ p.vy += 0.08;
1681
+ p.life -= p.decay * STATE.speed;
1682
+
1683
+ pCtx.globalAlpha = Math.max(0, p.life);
1684
+ pCtx.fillStyle = p.color;
1685
+ pCtx.beginPath();
1686
+ pCtx.arc(p.x, p.y, p.size, 0, Math.PI*2);
1687
+ pCtx.fill();
1688
+ });
1689
+ pCtx.globalAlpha = 1;
1690
+ }
1691
+
1692
+ // ─── SPEECH BUBBLES (DOM-based) ─────────────────────────────────
1693
+ const bubbleContainer = document.getElementById('canvas-wrapper');
1694
+ const activeBubbles = new Map();
1695
+
1696
+ function updateSpeechBubbles() {
1697
+ const wrapper = document.getElementById('canvas-wrapper');
1698
+ const W = wrapper.clientWidth;
1699
+ const H = wrapper.clientHeight;
1700
+ const z = STATE.zoom;
1701
+
1702
+ STATE.agentList.forEach(agent => {
1703
+ if (!agent.speechText) {
1704
+ if (activeBubbles.has(agent.id)) {
1705
+ const el = activeBubbles.get(agent.id);
1706
+ el.remove();
1707
+ activeBubbles.delete(agent.id);
1708
+ }
1709
+ return;
1710
+ }
1711
+
1712
+ const sx = (agent.x - STATE.viewX) * z + W/2;
1713
+ const sy = (agent.y - STATE.viewY) * z + H/2;
1714
+
1715
+ // Cull offscreen
1716
+ if (sx < -100 || sx > W+100 || sy < -100 || sy > H+100) {
1717
+ if (activeBubbles.has(agent.id)) {
1718
+ activeBubbles.get(agent.id).style.display = 'none';
1719
+ }
1720
+ return;
1721
+ }
1722
+
1723
+ let el = activeBubbles.get(agent.id);
1724
+ if (!el) {
1725
+ el = document.createElement('div');
1726
+ el.className = 'speech-bubble-css';
1727
+ wrapper.appendChild(el);
1728
+ activeBubbles.set(agent.id, el);
1729
+ }
1730
+ el.style.display = 'block';
1731
+ el.style.left = sx + 'px';
1732
+ el.style.top = (sy - AGENT_SIZE * z - 28) + 'px';
1733
+ el.textContent = agent.speechText;
1734
+ });
1735
+ }
1736
+
1737
+ // ─── TICKER ────────────────────────────────────────────────────
1738
+ function buildTickerContent() {
1739
+ const items = [];
1740
+
1741
+ // Predictions
1742
+ STATE.predictions.forEach(pred => {
1743
+ const ml = pred.predictions?.moneyline;
1744
+ const prob = ml?.home_win_prob ?? 0.5;
1745
+ const probCls = prob > 0.65 ? 'high' : prob > 0.52 ? 'med' : 'low';
1746
+ items.push(`
1747
+ <div class="ticker-item">
1748
+ <span class="ticker-label">ML</span>
1749
+ <span class="ticker-team">${pred.home_team || '?'}</span>
1750
+ <span class="ticker-sep">vs</span>
1751
+ <span class="ticker-team">${pred.away_team || '?'}</span>
1752
+ <span class="ticker-prob ${probCls}">${(prob*100).toFixed(1)}%</span>
1753
+ <span class="ticker-brier">Brier ${pred.quality?.avg_brier?.toFixed(5) ?? '—'}</span>
1754
+ </div>`);
1755
+ });
1756
+
1757
+ // Space health
1758
+ const spaces = STATE.health?.projects?.nba?.spaces || {};
1759
+ Object.entries(spaces).forEach(([id, s]) => {
1760
+ items.push(`
1761
+ <div class="ticker-item">
1762
+ <span class="ticker-label">${id}</span>
1763
+ <span class="ticker-team">${s.model || '—'}</span>
1764
+ <span class="ticker-brier">Brier ${(s.brier||0).toFixed(5)}</span>
1765
+ <span class="ticker-agent">Gen ${s.generation||0}</span>
1766
+ </div>`);
1767
+ });
1768
+
1769
+ // Agent highlights
1770
+ const topAgents = STATE.agentList
1771
+ .filter(a => a.bankroll > 0)
1772
+ .sort((a,b) => b.bankroll - a.bankroll)
1773
+ .slice(0, 10);
1774
+
1775
+ topAgents.forEach(a => {
1776
+ const pnlStr = a.total_pnl >= 0
1777
+ ? `<span class="ticker-win">+$${a.total_pnl.toFixed(2)}</span>`
1778
+ : `<span class="ticker-loss">-$${Math.abs(a.total_pnl).toFixed(2)}</span>`;
1779
+ items.push(`
1780
+ <div class="ticker-item">
1781
+ <span class="ticker-agent">${a.name}</span>
1782
+ <span class="ticker-label">BK</span>
1783
+ <span class="ticker-team">$${a.bankroll.toLocaleString()}</span>
1784
+ ${pnlStr}
1785
+ </div>`);
1786
+ });
1787
+
1788
+ // System messages
1789
+ items.push(`<div class="ticker-item"><span class="ticker-label">SYS</span><span class="ticker-team">NOMOS42 TRADING FLOOR v5</span><span class="ticker-brier">207 AGENTS ACTIVE</span></div>`);
1790
+ items.push(`<div class="ticker-item"><span class="ticker-label">ATR</span><span class="ticker-brier">BEST BRIER: 0.21570</span><span class="ticker-agent">TARGET: &lt; 0.20</span></div>`);
1791
+
1792
+ // Duplicate for seamless loop
1793
+ const content = items.join('') + items.join('');
1794
+ const track = document.getElementById('ticker-track');
1795
+ track.innerHTML = content;
1796
+ STATE.tickerWidth = track.scrollWidth / 2;
1797
+ }
1798
+
1799
+ function animateTicker() {
1800
+ const track = document.getElementById('ticker-track');
1801
+ STATE.tickerOffset += TICKER_SPEED * STATE.speed;
1802
+ if (STATE.tickerWidth > 0 && STATE.tickerOffset >= STATE.tickerWidth) {
1803
+ STATE.tickerOffset -= STATE.tickerWidth;
1804
+ }
1805
+ track.style.transform = `translateX(-${STATE.tickerOffset}px)`;
1806
+ }
1807
+
1808
+ // ─── MINIMAP ───────────────────────────────────────────────────
1809
+ const minimapEl = document.getElementById('minimap-canvas');
1810
+ const mmCtx = minimapEl.getContext('2d');
1811
+ const MM_W = 100, MM_H = 70;
1812
+ minimapEl.width = MM_W;
1813
+ minimapEl.height = MM_H;
1814
+
1815
+ function drawMinimap() {
1816
+ mmCtx.clearRect(0, 0, MM_W, MM_H);
1817
+
1818
+ // Background
1819
+ mmCtx.fillStyle = '#060618';
1820
+ mmCtx.fillRect(0, 0, MM_W, MM_H);
1821
+
1822
+ // Zones
1823
+ const sx = MM_W / WORLD_W;
1824
+ const sy = MM_H / WORLD_H;
1825
+
1826
+ const zoneColors = {
1827
+ pit: 'rgba(255,215,0,0.15)',
1828
+ research: 'rgba(79,195,247,0.2)',
1829
+ evolution: 'rgba(102,187,106,0.2)',
1830
+ engineering: 'rgba(206,147,216,0.2)',
1831
+ infra: 'rgba(239,83,80,0.15)',
1832
+ };
1833
+
1834
+ Object.entries(ZONE_RECTS).forEach(([name, r]) => {
1835
+ mmCtx.fillStyle = zoneColors[name] || 'rgba(255,255,255,0.05)';
1836
+ mmCtx.fillRect(r.x*sx, r.y*sy, r.w*sx, r.h*sy);
1837
+ });
1838
+
1839
+ // Agent dots (sample every Nth)
1840
+ const step = Math.max(1, Math.floor(STATE.agentList.length / 80));
1841
+ STATE.agentList.forEach((a, i) => {
1842
+ if (i % step !== 0) return;
1843
+ mmCtx.fillStyle = TIER_COLORS_HEX[a.tier] || '#66bb6a';
1844
+ mmCtx.globalAlpha = 0.7;
1845
+ mmCtx.fillRect(a.x*sx - 0.5, a.y*sy - 0.5, 1.5, 1.5);
1846
+ });
1847
+ mmCtx.globalAlpha = 1;
1848
+
1849
+ // Viewport rect
1850
+ const vpW = (pixiApp?.screen.width || 800) / STATE.zoom * sx;
1851
+ const vpH = (pixiApp?.screen.height || 600) / STATE.zoom * sy;
1852
+ const vpX = (STATE.viewX - (pixiApp?.screen.width||800)/(2*STATE.zoom)) * sx;
1853
+ const vpY = (STATE.viewY - (pixiApp?.screen.height||600)/(2*STATE.zoom)) * sy;
1854
+ mmCtx.strokeStyle = 'rgba(255,215,0,0.6)';
1855
+ mmCtx.lineWidth = 1;
1856
+ mmCtx.strokeRect(vpX, vpY, vpW, vpH);
1857
+
1858
+ // Selected agent
1859
+ if (STATE.selectedAgent) {
1860
+ const a = STATE.selectedAgent;
1861
+ mmCtx.fillStyle = '#fff';
1862
+ mmCtx.fillRect(a.x*sx - 2, a.y*sy - 2, 4, 4);
1863
+ }
1864
+ }
1865
+
1866
+ // ─── PANELS ────────────────────────────────────────────────────
1867
+ function updateLeaderboard() {
1868
+ const sorted = [...STATE.agentList]
1869
+ .sort((a,b) => b.bankroll - a.bankroll)
1870
+ .slice(0, 20);
1871
+
1872
+ const el = document.getElementById('leaderboard-list');
1873
+ el.innerHTML = sorted.map((a, i) => {
1874
+ const color = TIER_COLORS_HEX[a.tier] || '#66bb6a';
1875
+ const rank = i + 1;
1876
+ const rankCls = rank === 1 ? 'r1' : rank === 2 ? 'r2' : rank === 3 ? 'r3' : '';
1877
+ const bk = '$' + (a.bankroll/1000).toFixed(1) + 'k';
1878
+ const pnlVal = a.total_pnl >= 0 ? `+${a.total_pnl.toFixed(0)}` : a.total_pnl.toFixed(0);
1879
+ const pnlCls = a.total_pnl >= 0 ? '' : 'neg';
1880
+ return `<div class="lb-entry" data-id="${a.id}">
1881
+ <span class="lb-rank ${rankCls}">${rank}</span>
1882
+ <span class="lb-dot" style="background:${color}"></span>
1883
+ <span class="lb-name">${a.name}</span>
1884
+ <span class="lb-val ${pnlCls}">${bk}</span>
1885
+ </div>`;
1886
+ }).join('');
1887
+
1888
+ // Click to select
1889
+ el.querySelectorAll('.lb-entry').forEach(row => {
1890
+ row.addEventListener('click', () => {
1891
+ const a = STATE.agentList.find(a => a.id === row.dataset.id);
1892
+ if (a) { selectAgent(a); STATE.viewX = a.x; STATE.viewY = a.y; setViewCenter(a.x, a.y); }
1893
+ });
1894
+ });
1895
+ }
1896
+
1897
+ function updateSpacesList() {
1898
+ const spaces = STATE.health?.projects?.nba?.spaces || {};
1899
+ const el = document.getElementById('spaces-list');
1900
+ el.innerHTML = Object.entries(spaces).map(([id, s]) => `
1901
+ <div class="space-row">
1902
+ <div class="space-led ${s.status === 'UP' ? 'up' : 'down'}"></div>
1903
+ <span class="space-name">${id}</span>
1904
+ <span class="space-brier">${(s.brier||0).toFixed(5)}</span>
1905
+ <span class="space-gen">G${s.generation||0}</span>
1906
+ </div>
1907
+ `).join('');
1908
+ }
1909
+
1910
+ function updateDeptList() {
1911
+ const el = document.getElementById('dept-list');
1912
+ el.innerHTML = DEPTS.map(d => `
1913
+ <div class="dept-row">
1914
+ <span class="dept-badge ${d.status}">${d.id}</span>
1915
+ <span class="dept-name">${d.name}</span>
1916
+ <span class="dept-metric">${d.metric}</span>
1917
+ </div>
1918
+ `).join('');
1919
+ }
1920
+
1921
+ function updatePredictions() {
1922
+ const el = document.getElementById('predictions-list');
1923
+ if (!STATE.predictions.length) {
1924
+ el.innerHTML = '<div style="font-size:10px;color:#666;padding:4px;">No games today</div>';
1925
+ return;
1926
+ }
1927
+ el.innerHTML = STATE.predictions.map(pred => {
1928
+ const ml = pred.predictions?.moneyline;
1929
+ const prob = ml?.home_win_prob ?? 0.5;
1930
+ const homeW = (prob * 100).toFixed(1);
1931
+ const awayW = ((1 - prob) * 100).toFixed(1);
1932
+ const brier = pred.quality?.avg_brier?.toFixed(5) ?? '—';
1933
+ const conf = pred.quality?.confidence ?? '—';
1934
+ return `<div class="pred-card">
1935
+ <div class="pred-teams">
1936
+ <span class="pred-home">${shortenTeam(pred.home_team)}</span>
1937
+ <span class="pred-vs">vs</span>
1938
+ <span class="pred-away">${shortenTeam(pred.away_team)}</span>
1939
+ </div>
1940
+ <div class="pred-bars">
1941
+ <div class="pred-bar-home" style="width:${homeW}%"></div>
1942
+ <div class="pred-bar-away"></div>
1943
+ </div>
1944
+ <div class="pred-prob">
1945
+ <span>${homeW}%</span>
1946
+ <span class="conf">${conf}</span>
1947
+ <span>${awayW}%</span>
1948
+ </div>
1949
+ <div style="font-size:9px;color:#555;margin-top:3px;">Brier ${brier}</div>
1950
+ </div>`;
1951
+ }).join('');
1952
+ }
1953
+
1954
+ function updateBankrollStats() {
1955
+ const b = STATE.bankroll;
1956
+ const el = document.getElementById('bankroll-stats');
1957
+ if (!b || !b.balance) { el.textContent = 'No data'; return; }
1958
+ const roiCls = b.roi_pct >= 0 ? 'color:var(--green)' : 'color:var(--red)';
1959
+ el.innerHTML = `
1960
+ <div style="display:flex;justify-content:space-between;margin-bottom:3px;">
1961
+ <span style="color:#888;">Balance</span>
1962
+ <span style="color:var(--gold)">$${b.balance?.toFixed(2)}</span>
1963
+ </div>
1964
+ <div style="display:flex;justify-content:space-between;margin-bottom:3px;">
1965
+ <span style="color:#888;">ROI</span>
1966
+ <span style="${roiCls}">${b.roi_pct?.toFixed(2)}%</span>
1967
+ </div>
1968
+ <div style="display:flex;justify-content:space-between;margin-bottom:3px;">
1969
+ <span style="color:#888;">Win Rate</span>
1970
+ <span style="color:var(--text)">${b.win_rate_pct?.toFixed(1)}%</span>
1971
+ </div>
1972
+ <div style="display:flex;justify-content:space-between;margin-bottom:3px;">
1973
+ <span style="color:#888;">Bets</span>
1974
+ <span style="color:var(--text)">${b.total_bets}</span>
1975
+ </div>
1976
+ <div style="display:flex;justify-content:space-between;">
1977
+ <span style="color:#888;">Sharpe</span>
1978
+ <span style="color:var(--blue)">${b.sharpe_ratio?.toFixed(2)}</span>
1979
+ </div>
1980
+ `;
1981
+ }
1982
+
1983
+ function updateHeaderStats() {
1984
+ const spaces = STATE.health?.projects?.nba?.spaces || {};
1985
+ const briers = Object.values(spaces).map(s => s.brier).filter(Boolean);
1986
+ const bestBrier = briers.length ? Math.min(...briers) : 0;
1987
+ const maxGen = Object.values(spaces).map(s => s.generation || 0).reduce((a,b)=>Math.max(a,b), 0);
1988
+
1989
+ if (bestBrier) document.getElementById('hdr-brier').textContent = bestBrier.toFixed(5);
1990
+ if (maxGen) document.getElementById('hdr-gen').textContent = maxGen.toLocaleString();
1991
+
1992
+ const b = STATE.bankroll;
1993
+ if (b?.balance) {
1994
+ document.getElementById('hdr-bankroll').textContent = '$' + b.balance.toFixed(2);
1995
+ const roiEl = document.getElementById('hdr-roi');
1996
+ roiEl.textContent = (b.roi_pct >= 0 ? '+' : '') + b.roi_pct.toFixed(2) + '%';
1997
+ roiEl.className = 'val ' + (b.roi_pct >= 0 ? 'green' : 'red');
1998
+ }
1999
+ }
2000
+
2001
+ function shortenTeam(name) {
2002
+ if (!name) return '?';
2003
+ const abbrevs = {
2004
+ 'Miami Heat': 'MIA', 'Washington Wizards': 'WSH',
2005
+ 'Golden State Warriors': 'GSW', 'New York Knicks': 'NYK',
2006
+ 'Los Angeles Lakers': 'LAL', 'Los Angeles Clippers': 'LAC',
2007
+ 'Boston Celtics': 'BOS', 'Milwaukee Bucks': 'MIL',
2008
+ 'Denver Nuggets': 'DEN', 'Phoenix Suns': 'PHX',
2009
+ 'Dallas Mavericks': 'DAL', 'Memphis Grizzlies': 'MEM',
2010
+ 'Oklahoma City Thunder': 'OKC', 'New Orleans Pelicans': 'NOP',
2011
+ 'Sacramento Kings': 'SAC', 'Utah Jazz': 'UTA',
2012
+ };
2013
+ return abbrevs[name] || name.split(' ').pop().slice(0,6).toUpperCase();
2014
+ }
2015
+
2016
+ // ─── DAY/NIGHT CYCLE ───────────────────────────────────────────
2017
+ function updateDayNight() {
2018
+ const now = new Date();
2019
+ const utcH = now.getUTCHours() + now.getUTCMinutes()/60;
2020
+ // Night: 0-6 UTC (evening in USA)
2021
+ // Day: 6-20 UTC
2022
+ let nightAlpha = 0;
2023
+ if (utcH < 6) nightAlpha = 0.22;
2024
+ else if (utcH < 8) nightAlpha = 0.22 * (1 - (utcH-6)/2);
2025
+ else if (utcH > 20) nightAlpha = 0.22 * (utcH-20)/4;
2026
+
2027
+ document.getElementById('night-overlay').style.background =
2028
+ `rgba(0,0,30,${nightAlpha})`;
2029
+ }
2030
+
2031
+ // ─── CLOCK ────────────────────────────────────────────────────
2032
+ function updateClock() {
2033
+ const now = new Date();
2034
+ const h = now.getUTCHours().toString().padStart(2,'0');
2035
+ const m = now.getUTCMinutes().toString().padStart(2,'0');
2036
+ document.getElementById('clock').textContent = `${h}:${m}Z`;
2037
+ }
2038
+
2039
+ // ─── RANDOM CELEBRATION ────────────────────────────────────────
2040
+ function maybeRandomWin() {
2041
+ if (Math.random() > 0.003 * STATE.speed) return;
2042
+ const agent = STATE.agentList[Math.floor(Math.random() * STATE.agentList.length)];
2043
+ if (!agent) return;
2044
+ agent.celebrate();
2045
+ spawnParticles(agent.x, agent.y, TIER_COLORS_HEX[agent.tier] || '#ffd700', 15);
2046
+ }
2047
+
2048
+ // ─── DATA LOADING ──────────────────────────────────────────────
2049
+ async function loadData() {
2050
+ setLoadStatus('Loading agent states…', 55);
2051
+
2052
+ // Try Bloomberg API first, fall back to static files
2053
+ const base = window.location.hostname === 'localhost'
2054
+ ? 'http://localhost:8080'
2055
+ : ''; // Relative paths for HF Space
2056
+
2057
+ try {
2058
+ // Agent states
2059
+ const agentResp = await fetch(`${base}/data/arena/agent-states-v5.json`);
2060
+ if (agentResp.ok) {
2061
+ const agentData = await agentResp.json();
2062
+ STATE.agents = agentData.agents || {};
2063
+ }
2064
+ } catch(e) { console.warn('Agent data fetch failed:', e.message); }
2065
+
2066
+ try {
2067
+ // Predictions
2068
+ const predResp = await fetch(`${base}/data/arena/model-predictions-latest.json`);
2069
+ if (predResp.ok) {
2070
+ const predData = await predResp.json();
2071
+ STATE.predictions = predData.predictions || [];
2072
+ }
2073
+ } catch(e) { console.warn('Predictions fetch failed:', e.message); }
2074
+
2075
+ try {
2076
+ // Health / spaces
2077
+ const healthResp = await fetch(`${base}/data/agent-health.json`);
2078
+ if (healthResp.ok) {
2079
+ STATE.health = await healthResp.json();
2080
+ }
2081
+ } catch(e) { console.warn('Health fetch failed:', e.message); }
2082
+
2083
+ try {
2084
+ // Bankroll
2085
+ const brResp = await fetch(`${base}/data/nba-agent/bankroll-state.json`);
2086
+ if (brResp.ok) {
2087
+ STATE.bankroll = await brResp.json();
2088
+ }
2089
+ } catch(e) { console.warn('Bankroll fetch failed:', e.message); }
2090
+
2091
+ // Use embedded fallback data if nothing loaded
2092
+ if (!Object.keys(STATE.agents).length) {
2093
+ STATE.agents = FALLBACK_AGENTS;
2094
+ }
2095
+ if (!STATE.predictions.length) {
2096
+ STATE.predictions = FALLBACK_PREDICTIONS;
2097
+ }
2098
+ if (!STATE.health?.projects) {
2099
+ STATE.health = FALLBACK_HEALTH;
2100
+ }
2101
+ if (!STATE.bankroll?.balance) {
2102
+ STATE.bankroll = FALLBACK_BANKROLL;
2103
+ }
2104
+ }
2105
+
2106
+ // ─── FALLBACK EMBEDDED DATA ────────────────────────────────────
2107
+ const FALLBACK_AGENTS = {
2108
+ "t1_claude": { id:"t1_claude", name:"Claude Prime", tier:"PREMIUM", strategy:"value_hunter_half_kelly", bankroll:10000, roi:0, win_rate:0, total_bets:0, total_pnl:0 },
2109
+ "t1_gpt4o": { id:"t1_gpt4o", name:"GPT-4o Strategist", tier:"PREMIUM", strategy:"proportional_edge", bankroll:10000, roi:0, win_rate:0, total_bets:0, total_pnl:0 },
2110
+ "t1_grok": { id:"t1_grok", name:"Grok Contrarian", tier:"PREMIUM", strategy:"underdog_specialist", bankroll:10000, roi:0, win_rate:0, total_bets:0, total_pnl:0 },
2111
+ "t1_gemini": { id:"t1_gemini", name:"Gemini Analyst", tier:"PREMIUM", strategy:"confidence_scaled", bankroll:10000, roi:0, win_rate:0, total_bets:0, total_pnl:0 },
2112
+ };
2113
+
2114
+ const FALLBACK_PREDICTIONS = [
2115
+ { game_id:"g1", home_team:"Miami Heat", away_team:"Washington Wizards", predictions:{ moneyline:{ home_win_prob:0.47 }}, quality:{ avg_brier:0.22448, confidence:"high" }},
2116
+ { game_id:"g2", home_team:"New York Knicks", away_team:"Golden State Warriors", predictions:{ moneyline:{ home_win_prob:0.62 }}, quality:{ avg_brier:0.22159, confidence:"high" }},
2117
+ ];
2118
+
2119
+ const FALLBACK_HEALTH = {
2120
+ projects: { nba: { spaces: {
2121
+ S10:{ status:'UP', brier:0.22454, generation:708, model:'xgboost_brier' },
2122
+ S11:{ status:'UP', brier:0.22273, generation:1405, model:'xgboost' },
2123
+ S12:{ status:'UP', brier:0.22506, generation:1336, model:'catboost' },
2124
+ S13:{ status:'UP', brier:0.22455, generation:1018, model:'extra_trees' },
2125
+ S14:{ status:'UP', brier:0.22666, generation:1070, model:'xgboost_brier' },
2126
+ S15:{ status:'UP', brier:0.22159, generation:1826, model:'random_forest' },
2127
+ }}}};
2128
+
2129
+ const FALLBACK_BANKROLL = {
2130
+ balance: 91.29, roi_pct: -8.71, win_rate_pct: 38.64,
2131
+ total_bets: 44, sharpe_ratio: -3.11,
2132
+ };
2133
+
2134
+ // ─── GENERATE AGENT LIST ───────────────────────────────────────
2135
+ function buildAgentList() {
2136
+ const agents = Object.values(STATE.agents);
2137
+
2138
+ // If we only have the 4 premium agents from static data, generate the rest
2139
+ const needed = Math.max(0, 207 - agents.length);
2140
+
2141
+ const tiers = ['FREE_POWER','FREE_POWER','FREE_POWER','FREE_POWER',
2142
+ 'SPECIALIST','SPECIALIST','SPECIALIST','SPECIALIST','SPECIALIST','SPECIALIST',
2143
+ 'SPECIALIST','SPECIALIST','SPECIALIST','META'];
2144
+
2145
+ const strategies = Object.keys(SPEECHES);
2146
+ const names = [
2147
+ 'Alpha Bot','Beta Scout','Gamma Quant','Delta Sharp','Epsilon Edge',
2148
+ 'Zeta Prop','Eta Value','Theta Kelly','Iota Fade','Kappa Hedge',
2149
+ 'Lambda Grid','Mu Arb','Nu Spread','Xi Total','Omicron Line',
2150
+ 'Pi Corner','Rho Juice','Sigma Dog','Tau Chalk','Upsilon Whale',
2151
+ 'Phi Fish','Chi Limit','Psi Steam','Omega Closer',
2152
+ ];
2153
+
2154
+ for (let i = 0; i < needed; i++) {
2155
+ const tier = tiers[i % tiers.length];
2156
+ const id = `auto_${i}`;
2157
+ const bankroll = 9000 + Math.random() * 2500;
2158
+ agents.push({
2159
+ id,
2160
+ name: names[i % names.length] + ` ${Math.floor(i/names.length)+1}`,
2161
+ tier,
2162
+ strategy: strategies[i % strategies.length],
2163
+ bankroll,
2164
+ roi: (Math.random() - 0.5) * 20,
2165
+ win_rate: 0.3 + Math.random() * 0.35,
2166
+ total_bets: Math.floor(Math.random() * 80),
2167
+ total_wins: Math.floor(Math.random() * 40),
2168
+ total_pnl: (Math.random() - 0.5) * 1000,
2169
+ model: 'synthetic',
2170
+ provider: 'local',
2171
+ });
2172
+ }
2173
+
2174
+ STATE.agentList = agents.map(d => new Agent(d));
2175
+ }
2176
+
2177
+ // ─── LOADING UTILS ─────────────────────────────────────────────
2178
+ function setLoadStatus(msg, pct) {
2179
+ document.getElementById('loading-status').textContent = msg;
2180
+ document.getElementById('loading-bar').style.width = pct + '%';
2181
+ }
2182
+
2183
+ function hideLoading() {
2184
+ const el = document.getElementById('loading');
2185
+ el.classList.add('fade-out');
2186
+ setTimeout(() => el.style.display = 'none', 600);
2187
+ }
2188
+
2189
+ // ─── MAIN LOOP ─────────────────────────────────────────────────
2190
+ let lastTime = 0;
2191
+
2192
+ function mainLoop(ts) {
2193
+ const dt = Math.min((ts - lastTime) / (1000/60), 4); // delta in frames, max 4
2194
+ lastTime = ts;
2195
+
2196
+ if (!pixiApp) return;
2197
+
2198
+ // Update agents
2199
+ STATE.agentList.forEach(a => a.update(dt));
2200
+
2201
+ // Update agent positions in PixiJS
2202
+ updateAgentPositions();
2203
+
2204
+ // Follow selected agent
2205
+ if (STATE.followAgent) {
2206
+ const a = STATE.followAgent;
2207
+ STATE.viewX += (a.x - STATE.viewX) * 0.05;
2208
+ STATE.viewY += (a.y - STATE.viewY) * 0.05;
2209
+ setViewCenter(STATE.viewX, STATE.viewY);
2210
+ }
2211
+
2212
+ // Speech bubbles (throttle)
2213
+ if (Math.floor(ts/100) % 2 === 0) updateSpeechBubbles();
2214
+
2215
+ // Particles
2216
+ updateParticles();
2217
+
2218
+ // Random win event
2219
+ maybeRandomWin();
2220
+
2221
+ // Ticker
2222
+ animateTicker();
2223
+
2224
+ // Minimap (every 3rd frame)
2225
+ if (Math.floor(ts/33) % 3 === 0) drawMinimap();
2226
+
2227
+ // Periodic updates (every 30s)
2228
+ if (ts - STATE.lastUpdate > DATA_REFRESH_MS) {
2229
+ STATE.lastUpdate = ts;
2230
+ refreshData();
2231
+ }
2232
+
2233
+ requestAnimationFrame(mainLoop);
2234
+ }
2235
+
2236
+ // ─── PERIODIC REFRESH ─────────────────────────────────────────
2237
+ async function refreshData() {
2238
+ // Re-fetch data silently
2239
+ try {
2240
+ const r = await fetch('/data/agent-health.json');
2241
+ if (r.ok) {
2242
+ STATE.health = await r.json();
2243
+ updateSpacesList();
2244
+ updateHeaderStats();
2245
+ }
2246
+ } catch(e) {}
2247
+
2248
+ try {
2249
+ const r = await fetch('/data/arena/model-predictions-latest.json');
2250
+ if (r.ok) {
2251
+ const d = await r.json();
2252
+ STATE.predictions = d.predictions || STATE.predictions;
2253
+ updatePredictions();
2254
+ buildTickerContent();
2255
+ }
2256
+ } catch(e) {}
2257
+
2258
+ updateLeaderboard();
2259
+ updateDeptList();
2260
+ updateClock();
2261
+ updateDayNight();
2262
+ }
2263
+
2264
+ // Clock updater
2265
+ setInterval(updateClock, 10000);
2266
+ setInterval(updateDayNight, 60000);
2267
+
2268
+ // ─── BOOT ──────────────────────────────────────────────────────
2269
+ async function boot() {
2270
+ setLoadStatus('Loading data…', 20);
2271
+ await loadData();
2272
+
2273
+ setLoadStatus('Building agents…', 45);
2274
+ buildAgentList();
2275
+
2276
+ setLoadStatus('Initializing renderer…', 60);
2277
+ await initPixi();
2278
+
2279
+ setLoadStatus('Spawning sprites…', 75);
2280
+ createAgentSprites();
2281
+
2282
+ setLoadStatus('Building world…', 85);
2283
+ resizeParticleCanvas();
2284
+ window.addEventListener('resize', resizeParticleCanvas);
2285
+
2286
+ setLoadStatus('Populating panels…', 90);
2287
+ updateLeaderboard();
2288
+ updateSpacesList();
2289
+ updateDeptList();
2290
+ updatePredictions();
2291
+ updateBankrollStats();
2292
+ updateHeaderStats();
2293
+ buildTickerContent();
2294
+ updateClock();
2295
+ updateDayNight();
2296
+ drawMinimap();
2297
+
2298
+ setLoadStatus('Launching floor…', 100);
2299
+ setTimeout(() => {
2300
+ hideLoading();
2301
+ // Center on trading pit
2302
+ STATE.viewX = ZONE_RECTS.pit.x + ZONE_RECTS.pit.w / 2;
2303
+ STATE.viewY = ZONE_RECTS.pit.y + ZONE_RECTS.pit.h / 2;
2304
+ STATE.zoom = 1.0;
2305
+ setViewCenter(STATE.viewX, STATE.viewY);
2306
+
2307
+ requestAnimationFrame(ts => {
2308
+ lastTime = ts;
2309
+ requestAnimationFrame(mainLoop);
2310
+ });
2311
+
2312
+ // Welcome sound
2313
+ setTimeout(() => {
2314
+ if (STATE.soundEnabled) {
2315
+ playTone(440, 0.1); setTimeout(()=>playTone(550,0.1),100);
2316
+ setTimeout(()=>playTone(660,0.15),200); setTimeout(()=>playTone(880,0.2),300);
2317
+ }
2318
+ }, 800);
2319
+ }, 300);
2320
+ }
2321
+
2322
+ // Start when PixiJS is ready
2323
+ if (typeof PIXI !== 'undefined') {
2324
+ boot().catch(console.error);
2325
+ } else {
2326
+ document.getElementById('loading-status').textContent = 'Waiting for PixiJS…';
2327
+ window.addEventListener('load', () => boot().catch(console.error));
2328
+ }
2329
+
2330
+ </script>
2331
+ </body>
2332
+ </html>