Session D (night2): Phase 2.5 — intraday refresh + directional movement
Odds-only refresh every 20 min during slate hours (noon–midnight ET), in-process (INTRADAY_REFRESH=0 kill switch; skips full-snapshot slots): - signed delta RELATIVE TO THE GRADED SIDE; direction is the signal. - WITH the grade → STEAM badge, never a re-grade. - AGAINST >=1.0 → re-grade THAT PROP ONLY at the real current line: holds/refuses → VALUE (better entry, same read); drops → PUBLIC revision (grade updates, revised_from_grade preserves the ORIGINAL forever, UI strikethrough on slate strips + ledger cards). - Every run recaptures closing_line/odds → the close is now refresh- fidelity; SYNC goes live by dropping SNAPSHOT_EXPECTED_INTERVAL to 1200. - Ticker MOVE events feed from the refresh (>=1.0 moves). - QUOTA MATH: 36 runs/day/sport x 4 sports <= 144 PropLine calls/day vs 9,000/day free capacity (3 keys x 3,000). Re-grades are internal compute. - POST /api/internal/refresh/all for manual runs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,28 @@ export interface StripProp {
|
||||
awaiting?: boolean; // not yet graded by a snapshot → "Awaiting next scan"
|
||||
// Session 55 — settled outcome from the self-learning loop (once the game is final).
|
||||
outcome?: { result: 'hit' | 'miss' | 'push' | string; actual?: number | null } | null;
|
||||
// Session 60 (Phase 2.5) — intraday movement + public revision.
|
||||
movement?: { kind: 'steam' | 'value' | 'against' | 'revised' | string; delta: number; currentLine: number } | null;
|
||||
revisedFrom?: string | null;
|
||||
}
|
||||
|
||||
/** Phase 2.5 movement chip: STEAM ▲ (market chasing), VALUE ▲ (better
|
||||
* entry, read holds). Revisions render on the grade itself. */
|
||||
function MovementChip({ p }: { p: StripProp }) {
|
||||
const m = p.movement;
|
||||
if (!m || (m.kind !== 'steam' && m.kind !== 'value')) return null;
|
||||
const steam = m.kind === 'steam';
|
||||
return (
|
||||
<span
|
||||
className="mono"
|
||||
title={steam ? 'Market moved toward the graded side since lock' : 'Line moved against the grade — re-graded and the read holds: better entry'}
|
||||
style={{ fontSize: 9.5, fontWeight: 800, letterSpacing: '0.06em', padding: '1px 5px', borderRadius: 3,
|
||||
color: steam ? 'var(--amber, #FFB347)' : 'var(--g-a, #00D4A0)',
|
||||
border: `1px solid ${steam ? 'rgba(255,179,71,.4)' : 'rgba(0,212,160,.4)'}` }}
|
||||
>
|
||||
{steam ? `STEAM ▲ ${m.delta > 0 ? '+' : ''}${m.delta}` : 'VALUE ▲ better entry'}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
export interface StripArchetype {
|
||||
primary: string;
|
||||
@@ -232,7 +254,12 @@ export default function StatStrip({
|
||||
<div key={i} style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
||||
<div className="mono" style={{ display: 'inline-flex', alignItems: 'center', gap: 7, fontSize: 12, color: '#B8BCC8' }}>
|
||||
<span style={{ color: '#fff' }}>{p.stat} {p.side}{p.line}</span>
|
||||
{/* Phase 2.5 — a revised grade is PUBLIC: original struck through. */}
|
||||
{p.revisedFrom && (
|
||||
<span className="mono" title="Grade revised after the line moved against the read — original preserved" style={{ fontSize: 10.5, color: 'var(--text-2)', textDecoration: 'line-through' }}>{p.revisedFrom}</span>
|
||||
)}
|
||||
{p.grade && <GradeBadge grade={p.grade} size="sm" />}
|
||||
<MovementChip p={p} />
|
||||
<OutcomeChip p={p} />
|
||||
{!p.outcome && <ParlayBtn p={p} />}
|
||||
{!p.outcome && <BookItTeaser p={p} />}
|
||||
|
||||
Reference in New Issue
Block a user