@@ -106,14 +115,15 @@ export function PerformanceSettings() {
saveBook.mutate({ enabled: e.target.checked })}
+ onChange={(e) => setBook({ ...book, enabled: e.target.checked })}
className="mt-0.5"
/>
Shadow book enabled
- Starts opening real paper positions automatically on the next near-close scan. Verify its
- first selections match a backtest of that day's cross-section before trusting the curve.
+ Starts opening real paper positions automatically on the next near-close scan — takes
+ effect when you Save. Verify its first selections match the top-ranked qualified setups
+ before trusting the curve.
@@ -127,7 +137,6 @@ export function PerformanceSettings() {
max={100}
value={book.capacity}
onChange={(e) => setBook({ ...book, capacity: Number(e.target.value) })}
- onBlur={() => saveBook.mutate({ capacity: book.capacity })}
className="input-glass w-full px-3 py-2 text-sm"
/>
@@ -140,7 +149,6 @@ export function PerformanceSettings() {
max={10}
value={book.risk_pct}
onChange={(e) => setBook({ ...book, risk_pct: Number(e.target.value) })}
- onBlur={() => saveBook.mutate({ risk_pct: book.risk_pct })}
className="input-glass w-full px-3 py-2 text-sm"
/>
@@ -152,7 +160,6 @@ export function PerformanceSettings() {
step={1000}
value={book.start_equity}
onChange={(e) => setBook({ ...book, start_equity: Number(e.target.value) })}
- onBlur={() => saveBook.mutate({ start_equity: book.start_equity })}
className="input-glass w-full px-3 py-2 text-sm"
/>
@@ -161,6 +168,20 @@ export function PerformanceSettings() {
Defaults match the validated configuration: 10 positions, 1% fixed-fractional risk. Start
equity is only a sizing base — the books are compared in R-multiples, not currency.
+
+
+
+ {bookDirty && !saveBook.isPending && (
+ Unsaved changes
+ )}
+