feat: risk tier selector on Trading page + confidence filter on Recommendations
- Trading page: added conservative/moderate/aggressive selector that updates the trading engine config via PUT /api/trading/config - Recommendations page: added risk tier dropdown that defaults to the engine's current tier and filters recs by the tier's min_confidence - Backend: added min_confidence query param to GET /api/recommendations - Risk tier thresholds: conservative ≥0.75, moderate ≥0.55, aggressive ≥0.40
This commit is contained in:
@@ -10,7 +10,7 @@ import {
|
||||
useCompetitiveStatus,
|
||||
useToggleCompetitive,
|
||||
} from '../api/hooks';
|
||||
import { useResetPaperTrading } from '../api/tradingHooks';
|
||||
import { useResetPaperTrading, useTradingStatus, useUpdateTradingConfig } from '../api/tradingHooks';
|
||||
import { StatusBadge, LoadingSpinner, Card } from '../components/ui';
|
||||
|
||||
export function TradingPage() {
|
||||
@@ -21,6 +21,8 @@ export function TradingPage() {
|
||||
const { data: competitiveStatus } = useCompetitiveStatus();
|
||||
const setMode = useSetTradingMode();
|
||||
const resetTrading = useResetPaperTrading();
|
||||
const { data: tradingStatus } = useTradingStatus();
|
||||
const updateConfig = useUpdateTradingConfig();
|
||||
const reviewApproval = useReviewApproval();
|
||||
const toggleMacro = useToggleMacro();
|
||||
const toggleCompetitive = useToggleCompetitive();
|
||||
@@ -95,6 +97,41 @@ export function TradingPage() {
|
||||
isResetting={resetTrading.isPending}
|
||||
/>
|
||||
|
||||
{/* Risk Tier */}
|
||||
<Card>
|
||||
<h2 className="mb-3 text-sm font-medium text-gray-400">Risk Tier</h2>
|
||||
<p className="mb-3 text-[10px] text-gray-600">
|
||||
Controls confidence gates, position sizing, and portfolio heat limits for the trading engine.
|
||||
</p>
|
||||
<div className="flex items-center gap-3">
|
||||
{(['conservative', 'moderate', 'aggressive'] as const).map((tier) => {
|
||||
const currentTier = tradingStatus?.risk_tier ?? 'moderate';
|
||||
const descriptions: Record<string, string> = {
|
||||
conservative: 'Min confidence 0.75, max 5% position, 10% heat',
|
||||
moderate: 'Min confidence 0.55, max 10% position, 20% heat',
|
||||
aggressive: 'Min confidence 0.40, max 15% position, 30% heat',
|
||||
};
|
||||
return (
|
||||
<button
|
||||
key={tier}
|
||||
onClick={() => {
|
||||
if (tier !== currentTier) updateConfig.mutate({ risk_tier: tier });
|
||||
}}
|
||||
className={`rounded-md px-4 py-2 text-sm font-medium capitalize transition-colors ${
|
||||
currentTier === tier
|
||||
? 'bg-brand-600 text-white'
|
||||
: 'border border-surface-700 bg-surface-900 text-gray-400 hover:bg-surface-800'
|
||||
}`}
|
||||
aria-pressed={currentTier === tier}
|
||||
title={descriptions[tier]}
|
||||
>
|
||||
{tier}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* Macro Signal Layer Toggle */}
|
||||
<Card>
|
||||
<h2 className="mb-3 text-sm font-medium text-gray-400">Macro Signal Layer</h2>
|
||||
|
||||
Reference in New Issue
Block a user