Syntrex commited on
Commit
6028d62
·
verified ·
1 Parent(s): 919c034

Create edge_strip.py

Browse files
Files changed (1) hide show
  1. visualization/edge_strip.py +103 -0
visualization/edge_strip.py ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ import streamlit as st
6
+
7
+
8
+ def _fmt_odds(value: Any) -> str:
9
+ if value is None:
10
+ return "—"
11
+ try:
12
+ iv = int(value)
13
+ return f"+{iv}" if iv > 0 else str(iv)
14
+ except Exception:
15
+ return str(value)
16
+
17
+
18
+ def _fmt_edge(value: Any) -> str:
19
+ try:
20
+ return f"{float(value):+.1%}"
21
+ except Exception:
22
+ return "—"
23
+
24
+
25
+ def render_live_edge_strip(edge: dict[str, Any]) -> None:
26
+ batter_name = edge.get("batter_name", "") or "Current Batter"
27
+
28
+ st.markdown(
29
+ f"""
30
+ <div style="
31
+ margin-top:-4px;
32
+ margin-bottom:14px;
33
+ background: rgba(255,255,255,0.03);
34
+ border: 1px solid rgba(148,163,184,0.14);
35
+ border-radius: 16px;
36
+ padding: 12px;
37
+ ">
38
+ <div style="color:#94a3b8;font-size:12px;font-weight:700;margin-bottom:8px;">
39
+ LIVE EDGE STRIP • {batter_name}
40
+ </div>
41
+
42
+ <div style="
43
+ display:grid;
44
+ grid-template-columns: 1.2fr 0.8fr 0.8fr 0.7fr;
45
+ gap:8px;
46
+ color:#94a3b8;
47
+ font-size:11px;
48
+ font-weight:700;
49
+ margin-bottom:6px;
50
+ ">
51
+ <div>MARKET</div>
52
+ <div>FAIR</div>
53
+ <div>BOOK</div>
54
+ <div>EDGE</div>
55
+ </div>
56
+
57
+ <div style="
58
+ display:grid;
59
+ grid-template-columns: 1.2fr 0.8fr 0.8fr 0.7fr;
60
+ gap:8px;
61
+ color:#e2e8f0;
62
+ font-size:13px;
63
+ font-weight:700;
64
+ margin-bottom:4px;
65
+ ">
66
+ <div>Hit</div>
67
+ <div>{_fmt_odds(edge.get("fair_hit_odds"))}</div>
68
+ <div>{_fmt_odds(edge.get("book_hit_odds"))}</div>
69
+ <div>{_fmt_edge(edge.get("hit_edge"))}</div>
70
+ </div>
71
+
72
+ <div style="
73
+ display:grid;
74
+ grid-template-columns: 1.2fr 0.8fr 0.8fr 0.7fr;
75
+ gap:8px;
76
+ color:#e2e8f0;
77
+ font-size:13px;
78
+ font-weight:700;
79
+ margin-bottom:4px;
80
+ ">
81
+ <div>HR</div>
82
+ <div>{_fmt_odds(edge.get("fair_hr_odds"))}</div>
83
+ <div>{_fmt_odds(edge.get("book_hr_odds"))}</div>
84
+ <div>{_fmt_edge(edge.get("hr_edge"))}</div>
85
+ </div>
86
+
87
+ <div style="
88
+ display:grid;
89
+ grid-template-columns: 1.2fr 0.8fr 0.8fr 0.7fr;
90
+ gap:8px;
91
+ color:#e2e8f0;
92
+ font-size:13px;
93
+ font-weight:700;
94
+ ">
95
+ <div>2+ TB</div>
96
+ <div>{_fmt_odds(edge.get("fair_tb2p_odds"))}</div>
97
+ <div>{_fmt_odds(edge.get("book_tb2p_odds"))}</div>
98
+ <div>{_fmt_edge(edge.get("tb2p_edge"))}</div>
99
+ </div>
100
+ </div>
101
+ """,
102
+ unsafe_allow_html=True,
103
+ )