Add max_position_size to account configs
- DB migration: ALTER TABLE account_configs ADD COLUMN max_position_size INTEGER NOT NULL DEFAULT 0 - Added max_position_size to AccountConfigRow, createAccountConfig, updateAccountConfig in lib/db.ts - Added maxPositionSize to AccountConfig type in types.ts (0 = no limit) - GET /api/firms/[id] now returns maxPositionSize per account - POST /api/firms/[id]/accounts and PUT /api/account-configs/[id] accept maxPositionSize - Firm settings page: new Max Contracts column (blank = no limit) - auto-trade: contracts capped at maxPositionSize when > 0 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
b2a1bdd1c3
commit
49580c6bb4
+3
-1
@@ -41,6 +41,7 @@ function mapFirmConfig(firm: FirmWithAccounts): FirmConfig {
|
||||
minTradingDays: a.min_trading_days,
|
||||
accountSize: a.account_size,
|
||||
maxLoss: a.max_loss,
|
||||
maxPositionSize: a.max_position_size,
|
||||
})),
|
||||
};
|
||||
}
|
||||
@@ -124,7 +125,8 @@ export async function runTrade(action: 'Buy' | 'Sell', symbol: string) {
|
||||
const totalProfit = dailyPnL.reduce((sum, d) => sum + d.pnl, 0);
|
||||
const target = computeDailyTarget(cfg.profitTarget, cfg.consistency, totalProfit, dailyPnL);
|
||||
|
||||
const contracts = Math.max(1, Math.ceil(target.amount / 1000));
|
||||
const rawContracts = Math.max(1, Math.ceil(target.amount / 1000));
|
||||
const contracts = cfg.maxPositionSize > 0 ? Math.min(rawContracts, cfg.maxPositionSize) : rawContracts;
|
||||
const fill = await client.sendOrder(acc.id, contract.name, contracts, action, 'Market');
|
||||
|
||||
// Wait briefly for the cash balance WebSocket update to reflect entry commission
|
||||
|
||||
@@ -43,6 +43,13 @@ try {
|
||||
// Column already exists
|
||||
}
|
||||
|
||||
// Migration: add max_position_size column (0 = no limit)
|
||||
try {
|
||||
db.exec('ALTER TABLE account_configs ADD COLUMN max_position_size INTEGER NOT NULL DEFAULT 0');
|
||||
} catch {
|
||||
// Column already exists
|
||||
}
|
||||
|
||||
// Seed default firms if empty
|
||||
const firmCount = (db.prepare('SELECT COUNT(*) as count FROM firms').get() as { count: number }).count;
|
||||
if (firmCount === 0) {
|
||||
@@ -77,6 +84,7 @@ export interface AccountConfigRow {
|
||||
min_trading_days: number;
|
||||
account_size: number;
|
||||
max_loss: number;
|
||||
max_position_size: number;
|
||||
}
|
||||
|
||||
export interface FirmRow {
|
||||
@@ -129,11 +137,12 @@ export function createAccountConfig(firmId: number, data: {
|
||||
minTradingDays: number;
|
||||
accountSize: number;
|
||||
maxLoss: number;
|
||||
maxPositionSize: number;
|
||||
}): AccountConfigRow {
|
||||
const stmt = db.prepare(
|
||||
'INSERT INTO account_configs (firm_id, prefix, profit_target, consistency, min_day_pnl, min_trading_days, account_size, max_loss) VALUES (?, ?, ?, ?, ?, ?, ?, ?)'
|
||||
'INSERT INTO account_configs (firm_id, prefix, profit_target, consistency, min_day_pnl, min_trading_days, account_size, max_loss, max_position_size) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)'
|
||||
);
|
||||
const result = stmt.run(firmId, data.prefix, data.profitTarget, data.consistency, data.minDayPnL, data.minTradingDays, data.accountSize, data.maxLoss);
|
||||
const result = stmt.run(firmId, data.prefix, data.profitTarget, data.consistency, data.minDayPnL, data.minTradingDays, data.accountSize, data.maxLoss, data.maxPositionSize);
|
||||
return db.prepare('SELECT * FROM account_configs WHERE id = ?').get(result.lastInsertRowid) as AccountConfigRow;
|
||||
}
|
||||
|
||||
@@ -150,12 +159,13 @@ export function updateAccountConfig(id: number, data: {
|
||||
minTradingDays: number;
|
||||
accountSize: number;
|
||||
maxLoss: number;
|
||||
maxPositionSize: number;
|
||||
}): boolean {
|
||||
const result = db.prepare(`
|
||||
UPDATE account_configs
|
||||
SET prefix = ?, profit_target = ?, consistency = ?, min_day_pnl = ?, min_trading_days = ?, account_size = ?, max_loss = ?
|
||||
SET prefix = ?, profit_target = ?, consistency = ?, min_day_pnl = ?, min_trading_days = ?, account_size = ?, max_loss = ?, max_position_size = ?
|
||||
WHERE id = ?
|
||||
`).run(data.prefix, data.profitTarget, data.consistency, data.minDayPnL, data.minTradingDays, data.accountSize, data.maxLoss, id);
|
||||
`).run(data.prefix, data.profitTarget, data.consistency, data.minDayPnL, data.minTradingDays, data.accountSize, data.maxLoss, data.maxPositionSize, id);
|
||||
return result.changes > 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user