add track-record reset; drop dead distance_penalty_factor knob
Track Record: new "Reset" action (POST /admin/track-record/reset) deletes all trade setups so stats start fresh after material scoring/setup changes — live setups regenerate on the next scan. Guarded by a confirm dialog. Recommendation config: remove distance_penalty_factor, which was exposed in the admin UI but consumed nowhere (the touch-probability model superseded it). A knob that silently does nothing is worse than no knob. Remaining defaults are left as-is — they're reasonable, and the honest way to tune them is backtesting against accumulated outcomes, not invented "researched" numbers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -180,3 +180,10 @@ export function cleanupData(olderThanDays: number) {
|
||||
})
|
||||
.then((r) => r.data);
|
||||
}
|
||||
|
||||
// Track record
|
||||
export function resetTrackRecord() {
|
||||
return apiClient
|
||||
.post<{ trade_setups: number }>('admin/track-record/reset')
|
||||
.then((r) => r.data);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ const DEFAULTS: RecommendationConfig = {
|
||||
confidence_diff_threshold: 20,
|
||||
signal_alignment_weight: 0.15,
|
||||
sr_strength_weight: 0.2,
|
||||
distance_penalty_factor: 0.1,
|
||||
momentum_technical_divergence_threshold: 30,
|
||||
fundamental_technical_divergence_threshold: 40,
|
||||
};
|
||||
@@ -82,7 +81,6 @@ export function RecommendationSettings() {
|
||||
|
||||
<NumberInput label="Signal Alignment Weight" value={form.signal_alignment_weight} min={0} max={1} step={0.01} onChange={(v) => setField('signal_alignment_weight', v)} />
|
||||
<NumberInput label="S/R Strength Weight" value={form.sr_strength_weight} min={0} max={1} step={0.01} onChange={(v) => setField('sr_strength_weight', v)} />
|
||||
<NumberInput label="Distance Penalty Factor" value={form.distance_penalty_factor} min={0} max={1} step={0.01} onChange={(v) => setField('distance_penalty_factor', v)} />
|
||||
|
||||
<NumberInput label="Momentum-Technical Divergence Threshold" value={form.momentum_technical_divergence_threshold} min={0} max={100} onChange={(v) => setField('momentum_technical_divergence_threshold', v)} />
|
||||
<NumberInput label="Fundamental-Technical Divergence Threshold" value={form.fundamental_technical_divergence_threshold} min={0} max={100} onChange={(v) => setField('fundamental_technical_divergence_threshold', v)} />
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { useActivation } from '../../hooks/useActivation';
|
||||
import { activationSummary } from '../../lib/qualification';
|
||||
import { usePerformance } from '../../hooks/usePerformance';
|
||||
import { triggerJob } from '../../api/admin';
|
||||
import { triggerJob, resetTrackRecord } from '../../api/admin';
|
||||
import { Button } from '../ui/Button';
|
||||
import { Callout } from '../ui/Callout';
|
||||
import { Disclosure } from '../ui/Disclosure';
|
||||
@@ -112,6 +112,29 @@ export function TrackRecordPanel() {
|
||||
},
|
||||
});
|
||||
|
||||
const resetMutation = useMutation({
|
||||
mutationFn: () => resetTrackRecord(),
|
||||
onSuccess: (data) => {
|
||||
toast.addToast('success', `Track record reset — ${data.trade_setups} setups cleared. Run the scanner to rebuild.`);
|
||||
queryClient.invalidateQueries({ queryKey: ['performance'] });
|
||||
queryClient.invalidateQueries({ queryKey: ['trades'] });
|
||||
},
|
||||
onError: () => {
|
||||
toast.addToast('error', 'Failed to reset track record');
|
||||
},
|
||||
});
|
||||
|
||||
const onReset = () => {
|
||||
if (
|
||||
window.confirm(
|
||||
'Reset the track record? This permanently deletes ALL trade setups and their outcomes. ' +
|
||||
'Live setups will regenerate on the next R:R scan. This cannot be undone.',
|
||||
)
|
||||
) {
|
||||
resetMutation.mutate();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="glass-sm flex flex-wrap items-center justify-between gap-3 px-4 py-3">
|
||||
@@ -145,9 +168,14 @@ export function TrackRecordPanel() {
|
||||
evaluator runs nightly after OHLCV collection.
|
||||
</p>
|
||||
</Disclosure>
|
||||
<Button onClick={() => evaluateMutation.mutate()} loading={evaluateMutation.isPending} className="shrink-0">
|
||||
{evaluateMutation.isPending ? 'Evaluating…' : 'Evaluate Now'}
|
||||
</Button>
|
||||
<div className="flex shrink-0 items-center gap-2">
|
||||
<Button onClick={() => evaluateMutation.mutate()} loading={evaluateMutation.isPending}>
|
||||
{evaluateMutation.isPending ? 'Evaluating…' : 'Evaluate Now'}
|
||||
</Button>
|
||||
<Button variant="danger" onClick={onReset} loading={resetMutation.isPending}>
|
||||
{resetMutation.isPending ? 'Resetting…' : 'Reset'}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isLoading && (
|
||||
|
||||
@@ -307,7 +307,6 @@ export interface RecommendationConfig {
|
||||
confidence_diff_threshold: number;
|
||||
signal_alignment_weight: number;
|
||||
sr_strength_weight: number;
|
||||
distance_penalty_factor: number;
|
||||
momentum_technical_divergence_threshold: number;
|
||||
fundamental_technical_divergence_threshold: number;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user