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_momentum_percentile: 80, min_rr: 1.2, min_confidence: 55, require_high_conviction: false, exclude_conflicts: false, exclude_neutral: true, }; 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 selection is residual cross-sectional momentum — the ticker must rank in the top slice of the universe by beta-adjusted 12-1 month momentum, the production signal promoted from the backtest. R:R and confidence stay as floors. Tune the cutoff against the Track Record's momentum sweep to see what actually wins.

Optional tighteners

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

); }