feat: add max open positions and position cap controls to trading dashboard
ci/woodpecker/push/test Pipeline was successful
ci/woodpecker/push/build-2 Pipeline was successful
ci/woodpecker/push/build-3 Pipeline was successful
ci/woodpecker/push/build-1 Pipeline was successful
ci/woodpecker/push/finalize Pipeline was successful
Build and Push / lint-and-test (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.adapters.broker_adapter name:broker-adapter]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.aggregation.worker name:aggregation]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.extractor.worker name:extractor]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.ingestion.worker name:ingestion]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.lake_publisher.worker name:lake-publisher]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.parser.worker name:parser]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.recommendation.worker name:recommendation]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.scheduler.app name:scheduler]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.api.app:app --host 0.0.0.0 --port 8000 name:query-api]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.risk.app:app --host 0.0.0.0 --port 8000 name:risk]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.symbol_registry.app:app --host 0.0.0.0 --port 8000 name:symbol-registry]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.trading.app:app --host 0.0.0.0 --port 8000 name:trading-engine]) (push) Has been cancelled
Build and Push / build-dashboard (push) Has been cancelled
Build and Push / build-superset (push) Has been cancelled
Build and Push / integration-test (push) Has been cancelled
Build and Push / beta-gate (push) Has been cancelled
ci/woodpecker/push/test Pipeline was successful
ci/woodpecker/push/build-2 Pipeline was successful
ci/woodpecker/push/build-3 Pipeline was successful
ci/woodpecker/push/build-1 Pipeline was successful
ci/woodpecker/push/finalize Pipeline was successful
Build and Push / lint-and-test (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.adapters.broker_adapter name:broker-adapter]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.aggregation.worker name:aggregation]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.extractor.worker name:extractor]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.ingestion.worker name:ingestion]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.lake_publisher.worker name:lake-publisher]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.parser.worker name:parser]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.recommendation.worker name:recommendation]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.scheduler.app name:scheduler]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.api.app:app --host 0.0.0.0 --port 8000 name:query-api]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.risk.app:app --host 0.0.0.0 --port 8000 name:risk]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.symbol_registry.app:app --host 0.0.0.0 --port 8000 name:symbol-registry]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.trading.app:app --host 0.0.0.0 --port 8000 name:trading-engine]) (push) Has been cancelled
Build and Push / build-dashboard (push) Has been cancelled
Build and Push / build-superset (push) Has been cancelled
Build and Push / integration-test (push) Has been cancelled
Build and Push / beta-gate (push) Has been cancelled
This commit is contained in:
@@ -22,6 +22,8 @@ export interface TradingEngineStatus {
|
||||
portfolio_heat: number;
|
||||
portfolio_value: number;
|
||||
open_position_count: number;
|
||||
max_open_positions: number;
|
||||
absolute_position_cap: number;
|
||||
last_decision_at: string | null;
|
||||
micro_trading_enabled: boolean;
|
||||
uptime_seconds: number | null;
|
||||
|
||||
@@ -35,6 +35,8 @@ export function TradingOverview() {
|
||||
const resume = useResumeTradingEngine();
|
||||
const updateConfig = useUpdateTradingConfig();
|
||||
const [selectedTier, setSelectedTier] = useState<string | null>(null);
|
||||
const [maxPositions, setMaxPositions] = useState<number | null>(null);
|
||||
const [positionCap, setPositionCap] = useState<number | null>(null);
|
||||
|
||||
if (isLoading) return <LoadingSpinner />;
|
||||
if (!status) return <p className="text-gray-500">No trading status available</p>;
|
||||
@@ -131,6 +133,68 @@ export function TradingOverview() {
|
||||
<StatCard label="Portfolio Heat" value={fmtPct(status.portfolio_heat)} />
|
||||
</div>
|
||||
|
||||
{/* Position Limits */}
|
||||
<Card>
|
||||
<h2 className="mb-3 text-sm font-medium text-gray-400">Position Limits</h2>
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
<div>
|
||||
<label htmlFor="max-positions" className="block text-xs text-gray-500 mb-1">
|
||||
Max Open Positions
|
||||
</label>
|
||||
<div className="flex items-center gap-2">
|
||||
<input
|
||||
id="max-positions"
|
||||
type="number"
|
||||
min={1}
|
||||
max={50}
|
||||
value={maxPositions ?? status.max_open_positions ?? 10}
|
||||
onChange={(e) => setMaxPositions(Number(e.target.value))}
|
||||
className="w-20 rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none"
|
||||
/>
|
||||
<button
|
||||
onClick={() => {
|
||||
const val = maxPositions ?? status.max_open_positions ?? 10;
|
||||
updateConfig.mutate({ max_open_positions: val });
|
||||
}}
|
||||
disabled={updateConfig.isPending}
|
||||
className="rounded-md bg-brand-700 px-3 py-1.5 text-xs font-medium text-white hover:bg-brand-600 disabled:opacity-50"
|
||||
>
|
||||
Apply
|
||||
</button>
|
||||
<span className="text-xs text-gray-500">
|
||||
Current: {status.open_position_count ?? 0} / {status.max_open_positions ?? 10}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="position-cap" className="block text-xs text-gray-500 mb-1">
|
||||
Absolute Position Cap ($)
|
||||
</label>
|
||||
<div className="flex items-center gap-2">
|
||||
<input
|
||||
id="position-cap"
|
||||
type="number"
|
||||
min={10}
|
||||
step={10}
|
||||
value={positionCap ?? status.absolute_position_cap ?? 50}
|
||||
onChange={(e) => setPositionCap(Number(e.target.value))}
|
||||
className="w-24 rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none"
|
||||
/>
|
||||
<button
|
||||
onClick={() => {
|
||||
const val = positionCap ?? status.absolute_position_cap ?? 50;
|
||||
updateConfig.mutate({ absolute_position_cap: val });
|
||||
}}
|
||||
disabled={updateConfig.isPending}
|
||||
className="rounded-md bg-brand-700 px-3 py-1.5 text-xs font-medium text-white hover:bg-brand-600 disabled:opacity-50"
|
||||
>
|
||||
Apply
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* Portfolio Heat Gauge */}
|
||||
<Card>
|
||||
<h2 className="mb-2 text-sm font-medium text-gray-400">Portfolio Heat</h2>
|
||||
|
||||
@@ -314,6 +314,8 @@ async def trading_status() -> dict[str, Any]:
|
||||
"reserve_pool": reserve_pool,
|
||||
"portfolio_heat": portfolio_heat,
|
||||
"open_positions": open_positions,
|
||||
"max_open_positions": engine.config.max_open_positions,
|
||||
"absolute_position_cap": engine.config.absolute_position_cap,
|
||||
"last_decision_at": None,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user