Files
autofirmer-expanded/lib/trading-logic.ts
T
SenofyandClaude Sonnet 4.6 b2a1bdd1c3 Add auto-trade scheduler with batch locking, commission gross-up, and sync gate
- Auto-trade scheduler fires every 60s; uses Promise.allSettled batch so no new trades fire while any position from the current batch is open
- Commission gross-up: read entryCommission from cash.realizedPnL after fill (fallback 2.5×contracts), grossTarget = target + 2×entryCommission
- Sync gate: TradovateClient.syncComplete flag; scheduler skips tick until every client finishes initial position/balance sync
- Contracts formula changed to Math.ceil so $1500 target = 2 contracts
- Removed all fee caching (perContractFees, recentFills, fillFee handler) from tradovate-class.ts
- Removed firm_fees table, getFirmFees, upsertFirmFee from db.ts
- Deleted instrument-configs API routes; removed Fees UI from firm settings page
- /api/instruments returns full {symbol, enabled}[] objects; dashboard filters to enabled-only for trade selector
- Added auto-trade, debug, orders, settings, and trade API routes
- Instrument selector on dashboard now driven by enabled instruments from DB

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 03:31:47 -05:00

48 lines
1.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/** Dollar-per-point value for common futures products. */
export const POINT_VALUES: { [symbol: string]: number } = {
NQ: 20, MNQ: 2, ES: 50, MES: 5,
YM: 5, MYM: 0.5, RTY: 50, M2K: 10,
GC: 100, MGC: 10, SI: 50, CL: 1000,
MCL: 100, NG: 10000, ZB: 1000, ZN: 1000,
ZF: 1000, '6E': 125000, '6J': 12500000, '6B': 62500,
};
/**
* Compute the next trading day's profit target for an account.
*
* Path 1 No positive trading days yet:
* target = profitTarget × consistency
*
* Path 2 At least one positive day exists:
* maxDay = highest single-day P&L so far
* realTarget = maxDay / consistency (the total profit at which maxDay ≤ consistency% of total)
* needed = realTarget totalProfit
*
* if needed > maxDay → target maxDay (still a long way from the real target; trade a normal day)
* else → target needed (close to the real target; aim for exactly what's left)
*/
export function computeDailyTarget(
profitTarget: number,
consistency: number,
totalProfit: number,
dailyPnL: { date: string; pnl: number }[]
): { amount: number; path: 'first_day' | 'normal_day' | 'reduced_day' } {
const positiveDays = dailyPnL.filter((d) => d.pnl > 0);
if (positiveDays.length === 0) {
return {
amount: Math.round(profitTarget * consistency * 100) / 100,
path: 'first_day',
};
}
const maxDay = Math.max(...positiveDays.map((d) => d.pnl));
const realTarget = maxDay / consistency;
const needed = realTarget - totalProfit;
if (needed > maxDay) {
return { amount: Math.round(maxDay * 100) / 100, path: 'normal_day' };
}
return { amount: Math.round(Math.max(0, needed) * 100) / 100, path: 'reduced_day' };
}