feat: override trade tab — manual order entry with auto-registration

Backend:
- OverrideOrderRequest/Response Pydantic models with ticker, quantity, price validators
- POST /api/trading/override/order endpoint (enqueue to Redis broker queue)
- auto_register_symbol() module for untracked ticker registration via Symbol Registry
- Unit tests (17) and property-based tests (3 x 100 examples)

Frontend:
- OverrideTradePanel component (order form + positions display)
- Override tab in TradingEngine page with URL search param navigation
- Override Trade button on Trading Controls page
- useSubmitOverrideOrder mutation hook
- MSW handler and 13 component/integration tests

Steering:
- Updated steering docs for Ubuntu dev machine with nvm/Node 24
This commit is contained in:
Celes Renata
2026-04-17 07:02:30 +00:00
parent 7f67725ec8
commit 913fe8b0b3
18 changed files with 3074 additions and 17 deletions
+36
View File
@@ -336,3 +336,39 @@ export function useUpdateNotificationConfig() {
onSuccess: () => qc.invalidateQueries({ queryKey: ['notification-config'] }),
});
}
// ---------------------------------------------------------------------------
// Override Order (manual trade submission)
// ---------------------------------------------------------------------------
export interface OverrideOrderRequest {
ticker: string;
side: 'buy' | 'sell';
quantity: number;
order_type: 'market' | 'limit' | 'stop' | 'stop_limit';
limit_price?: number;
stop_price?: number;
}
export interface OverrideOrderResponse {
job_id: string;
status: string;
ticker: string;
side: string;
quantity: number;
auto_registered: boolean;
}
/** Submit a manual override order to the trading engine. */
export function useSubmitOverrideOrder() {
const qc = useQueryClient();
return useMutation({
mutationFn: (body: OverrideOrderRequest) =>
apiPost<OverrideOrderResponse>('trading', '/api/trading/override/order', body),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['orders'] });
qc.invalidateQueries({ queryKey: ['positions'] });
qc.invalidateQueries({ queryKey: ['companies'] });
},
});
}