Add per-firm banned symbols feature
- lib/db.ts: new firm_banned_symbols table with getBannedSymbols, isSymbolBanned, and setBannedSymbol helpers - app/api/firms/[id]/banned-symbols/route.ts: GET lists banned symbols, PATCH toggles a ban for a given symbol - app/api/firms/route.ts: include bannedSymbols[] in firm list response - app/firms/[id]/settings/page.tsx: Instruments section shows all globally-enabled symbols with a red toggle to ban/unban; banned symbols display a "SYMBOL BANNED" pill next to their name - app/page.tsx: FirmRows shows "ES BANNED" (or current symbol) pill next to the firm name when the selected trade symbol is banned for that firm - lib/auto-trade.ts: skip firms entirely when the trade symbol is banned - types.ts: add bannedSymbols field to FirmConfig Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
d945e0038f
commit
6d3e8b6065
+7
-1
@@ -7,7 +7,7 @@
|
||||
* signal but have since exited and are now eligible.
|
||||
*/
|
||||
|
||||
import { getFirms } from './db';
|
||||
import { getFirms, isSymbolBanned } from './db';
|
||||
import { getClients } from './clients';
|
||||
import { computeDailyTarget, POINT_VALUES } from './trading-logic';
|
||||
import { getSetting } from './db';
|
||||
@@ -100,6 +100,12 @@ export async function runTrade(action: 'Buy' | 'Sell' | 'Random', symbol: string
|
||||
const client = clients.get(firm.id);
|
||||
if (!client || client.accountList.length === 0) return;
|
||||
|
||||
// Skip this firm entirely if the symbol is banned for it
|
||||
if (isSymbolBanned(firm.id, symbol)) {
|
||||
console.log(`[auto-trade] ${firm.name}: ${symbol} is banned — skipping firm`);
|
||||
return;
|
||||
}
|
||||
|
||||
const firmConfig = mapFirmConfig(firm);
|
||||
|
||||
const contract = await client.findFrontMonthContract(symbol);
|
||||
|
||||
@@ -196,3 +196,30 @@ export function setInstrumentEnabled(symbol: string, enabled: boolean): boolean
|
||||
const result = db.prepare('UPDATE instruments SET enabled = ? WHERE symbol = ?').run(enabled ? 1 : 0, symbol);
|
||||
return result.changes > 0;
|
||||
}
|
||||
|
||||
// ── Firm banned symbols ───────────────────────────────────────────────────────
|
||||
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS firm_banned_symbols (
|
||||
firm_id INTEGER NOT NULL REFERENCES firms(id) ON DELETE CASCADE,
|
||||
symbol TEXT NOT NULL,
|
||||
PRIMARY KEY (firm_id, symbol)
|
||||
);
|
||||
`);
|
||||
|
||||
export function getBannedSymbols(firmId: number): string[] {
|
||||
return (db.prepare('SELECT symbol FROM firm_banned_symbols WHERE firm_id = ? ORDER BY symbol').all(firmId) as { symbol: string }[])
|
||||
.map((r) => r.symbol);
|
||||
}
|
||||
|
||||
export function isSymbolBanned(firmId: number, symbol: string): boolean {
|
||||
return !!db.prepare('SELECT 1 FROM firm_banned_symbols WHERE firm_id = ? AND symbol = ?').get(firmId, symbol);
|
||||
}
|
||||
|
||||
export function setBannedSymbol(firmId: number, symbol: string, banned: boolean): void {
|
||||
if (banned) {
|
||||
db.prepare('INSERT OR IGNORE INTO firm_banned_symbols (firm_id, symbol) VALUES (?, ?)').run(firmId, symbol);
|
||||
} else {
|
||||
db.prepare('DELETE FROM firm_banned_symbols WHERE firm_id = ? AND symbol = ?').run(firmId, symbol);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user