import { useEffect, useState } from 'react'; import type { ActivationConfig } from '../../lib/types'; import { useActivationSettings, useUpdateActivationSettings } from '../../hooks/useAdmin'; import { SkeletonTable } from '../ui/Skeleton'; const DEFAULTS: ActivationConfig = { min_expected_value: 0.15, min_rr: 1.2, min_confidence: 55, min_target_probability: 0, require_high_conviction: false, exclude_conflicts: false, }; export function ActivationSettings() { const { data, isLoading, isError, error } = useActivationSettings(); const update = useUpdateActivationSettings(); const [form, setForm] = useState(DEFAULTS); useEffect(() => { if (data) setForm(data); }, [data]); const onSave = () => { update.mutate(form); }; const onReset = () => { setForm(DEFAULTS); update.mutate(DEFAULTS); }; if (isLoading) return ; if (isError) return

{(error as Error)?.message || 'Failed to load activation thresholds'}

; return (

Activation Gate

What counts as a signal worth acting on. Drives the Dashboard's "Qualified" metric, the Signals "Qualified only" view, and the Track Record's qualified stats. The core test is expected value — probability-weighted asymmetry — so R:R and target probability no longer fight each other. All setups are still evaluated regardless; tune the EV floor against the Track Record's EV sweep to see what actually wins.

Optional tighteners

Off by default — turn on to be more selective on top of the EV gate.

); }