Commit Graph
13 Commits
Author SHA1 Message Date
Brandon LiandClaude Sonnet 4.6 6d960ceb7b Reset days traded counter from last fund transaction date
Tracks Fund Transaction entries in the Cash History report to find the
most recent account funding/reset date. Only trading days on or after
that date count toward daysTraded and the daily target calculation.
The last fund date is persisted in SQLite so it survives beyond the
28-day Tradovate report window.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 04:10:02 -05:00
Brandon LiandClaude Sonnet 4.6 6b299f5359 Persist daily P&L beyond 28-day Tradovate window
Adds a daily_pnl SQLite table that accumulates trade history indefinitely.
On each hourly fetch, fresh API data is upserted (not replaced) so entries
older than Tradovate's 28-day limit are preserved. Cache is loaded at startup
and used as fallback when both report requests fail.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 03:40:37 -05:00
Brandon Li 131c9bca9f Use resolved active contracts for orders 2026-03-18 00:52:25 -05:00
SenofyandClaude Sonnet 4.6 15ef2d7adc Auto-reconnect on WebSocket disconnect
- Extract connection logic into connectAndAuth() so it can be called
  on both initial connect and reconnect
- Add ws.onclose handler: if not an intentional disconnect, clear stale
  intervals and retry connectAndAuth() after 5 seconds
- Track sync, heartbeat, and tokenRenewal interval handles so they are
  cleared and recreated cleanly on each reconnect
- Reset syncComplete = false on reconnect so the scheduler waits for
  a fresh sync before trading
- disconnect() sets intentionalDisconnect = true and clears all intervals
  to prevent reconnect loops when a client is removed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 23:21:03 -05:00
SenofyandClaude Sonnet 4.6 d0065ab047 Refresh dailyPnL on a fixed hourly interval instead of throttling
- Replace the reactive throttle with a proactive setInterval in requestSync
  that fires fetchDaysTraded exactly once per hour per client
- Remove post-fill fetchDaysTraded calls from auto-trade.ts — no longer
  needed and were causing bursts of report API requests on simultaneous fills
- Guard against duplicate intervals if requestSync fires more than once

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 20:41:56 -05:00
SenofyandClaude Sonnet 4.6 92b929f4ce Throttle fetchDaysTraded to once per hour per client
Multiple simultaneous fills were triggering concurrent report API calls
to Tradovate for every account in the firm, causing rate limiting.
Added a 1-hour cooldown — the first call always runs (lastDaysFetch=0),
subsequent calls within the same hour are no-ops.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 20:40:17 -05:00
SenofyandClaude Sonnet 4.6 d945e0038f Add volume-based contract auto-resolver and CLAUDE.md
- New lib/contract-resolver.ts: picks the best contract month for each
  symbol by comparing Yahoo Finance volume between the front month
  (Tradovate suggest API) and the roll target (rollcontract API)
- lib/clients.ts: auto-resolves all enabled instruments 15s after startup
  and again daily at midnight via a setInterval check
- lib/tradovate-class.ts: findFrontMonthContract checks resolver cache
  first before falling back to the suggest API
- app/api/instruments/contracts/route.ts: GET returns cached contracts,
  POST triggers a fresh resolve
- app/settings/page.tsx: shows active contract + rolled badge per symbol;
  auto-resolves on load if cache is empty; removed manual Resolve button
- app/api/debug/route.ts: include entity data in recentEntityEvents
- CLAUDE.md: instructs Claude to always work on main

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 03:17:09 -05:00
SenofyandClaude Sonnet 4.6 8848f90b11 Use Cash History report for true after-fee daily P&L, Fills FIFO as fallback
- Primary: Cash History report sums non-Fund-Transaction Deltas per day,
  capturing broker platform fees not present in the Fills report
- Fallback: Fills + FIFO used when Cash History 404s (passed/completed accounts)
- Extracts requestReport() as shared helper to reduce duplication
- debug PATCH endpoint now accepts optional `name` param to test any report

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 20:37:05 -05:00
SenofyandClaude Sonnet 4.6 570a54fe60 Fix fetchDaysTraded to use reports API with bearer auth and correct daysTraded counting
- Replace fill/ldeps and fill/list approaches with Tradovate reports API
- Add bearer auth to getreport polling (root cause of prior 404s)
- Use endDate = tomorrow to ensure current-session fills are included
- Count all traded days when minDayPnL is 0, otherwise count days >= minDayPnL
- Add PATCH /api/debug endpoint for proxying raw Tradovate API calls

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 18:57:12 -05:00
SenofyandClaude Sonnet 4.6 68075059d0 Fix min-day target for 0% consistency accounts + daysTraded consistency
trading-logic: when baseAmount=0 (consistency=0%), target cappedByFuture
directly instead of collapsing to minDayPnL. For a $4000 target with $150
min-day and 5 days, day 1 now correctly targets $3400 ($4000 - 4×$150)
then $150 for each remaining mandatory day.

tradovate-class: make fetchDaysTraded() public so auto-trade can call it
immediately after a trade exits. Fix daysTraded to count only positive-P&L
days from the FIFO results, consistent with computeDailyTarget's
positiveDays.length — previously counted all raw fill dates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 17:33:55 -05:00
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
SenofyandClaude Sonnet 4.6 dd18f91584 Add full Next.js autotrader app with SQLite persistence and live Tradovate data
- SQLite DB (better-sqlite3) with firms, account_configs, firm_fees, instruments tables
- REST API routes: firms CRUD, account configs CRUD, state, accounts, instruments
- Live Tradovate WebSocket client: login, sync, positions, auto-liq thresholds
- Dashboard (app/page.tsx): per-firm account list with balance, day P&L, days traded,
  target progress, and Dead/Inactive/Flat status based on Tradovate auto-liq floors
- Account detail page: objectives progress, daily P&L chart, consistency tracking
- Per-firm settings page: account configs and instrument fee management
- Dead detection uses trailingMaxDrawdownLimit - trailingMaxDrawdown from
  userAccountAutoLiqs; filters Tradovate sentinel value (999999999 = no limit)
- FIFO P&L engine with commission accounting for daily P&L history
- Removed manual maxLoss fallback in favour of live Tradovate auto-liq data

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 15:03:21 -05:00
Senofy a9b6acd479 Initial Commit 2026-03-07 22:07:02 -06:00