Skip to content

Fix IBKR sync timezone handling and protect existing history - #24

Merged
ChristopherDownie merged 1 commit into
mainfrom
fix/ibkr-sync-timezone
Sep 27, 2026
Merged

ChristopherDownie merged 1 commit into
mainfrom
fix/ibkr-sync-timezone

Conversation

@ChristopherDownie

@ChristopherDownie ChristopherDownie commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Use the published @luxalgo/broker-sdk 0.5.1 patch, following Fix IBKR statement timezone conversion (0.5.1) broker-sdk#17. This includes all 22 already-public brokers, including the six integrations added after the journal's previous 0.3.0 dependency.
  • Read Default import timezone once at the start of IBKR sync and pass it to the SDK. Reuse the existing setting, explain its IBKR scope, and show it on the connection form. Display timezone remains independent.
  • Add nullable accounts.ibkrSyncTimeZone via the existing additive database upgrade. Existing rows remain unknown; no timestamps or annotations are rewritten.
  • Reject legacy synced history or a changed statement timezone before writing. Recheck the account after fetching; provenance, executions, trade rebuild and sync status commit in one immediate SQLite transaction.
  • Preserve provenance on transfers, reject unknown/incompatible synced histories and moves into another broker connection, and prevent changing the broker to bypass the guard. Empty accounts can adopt a timezone; same-zone retries keep existing deduplication.
  • Report unusable timestamps in existing skipped-record warnings, including the initial connection. Keep optional SDK credential fields optional and surface transfer failures in the account UI.
  • Document backup, separate-account recovery and comparison of execution times/counts/fees/P&L. Keep original notes and trades. Archiving alone does not remove old trades from All accounts.

Related to #16. PR #7's CSV/MT5 behavior remains intact. The confirmed defect is IBKR broker sync; the reporter's "XML import" wording has not been clarified. Direct Flex XML upload remains unsupported, so the issue must remain open pending that clarification; this PR only resolves the proven broker-sync defect.

Verification

  • First tested with the locally packed SDK, then switched to the exact published 0.5.1 release and lockfile. The downloaded npm tarball is byte-for-byte identical to the tested artifact (103 files), and npm gitHead matches the SDK merge. The existing pnpm release-age allowlist gets only this verified version.
  • 500 journal tests pass. New coverage uses mocked IBKR HTTP through actual SDK connect() → syncAccount() → temporary SQLite → trade-detail and analytics APIs.
  • The reported New York 08:59:05 / 10:08:30 values persist as 12:59:05Z / 14:08:30Z and display as 14:59:05 / 16:08:30 in Rome.
  • Coverage includes timezone boundaries, offsets, bad dates/zones, DST gaps/repeats, alias equivalence, zero-write rejected syncs/transfers, concurrent conflicting syncs, rollback, migration, repeat deduplication, Questrade credential rotation and non-IBKR timestamps, plus existing IBKR CSV/MT5 tests.
  • All 22 credential forms render and submit with mocked responses. The real browser shows the 22-entry roster, IBKR effective timezone, corrected execution table, existing settings help, and actionable legacy-history warning against an isolated synthetic database.
  • Format, typecheck, full tests, dependency license gate, package builds and production build verified. One local production build hit the previously observed SQLite startup lock; the no-change rerun passed.
  • Transfer rejection is covered through integration/API tests. The in-app browser cannot open the existing native prompt() used to choose a transfer destination, so that browser interaction was not claimed as verified.
  • No live broker credentials or customer history were used. No automatic repair, annotation migration, XML upload or general deduplication redesign.

Recovery behavior

Users with existing IBKR synced executions must back up their full data directory, verify the statement timezone, connect a separate journal account and compare the source report. The original account remains available for notes and comparison. Fresh accounts and repeated syncs under the recorded timezone continue normally.

Signed-off-by: Christopher Downie <Cnicholasdownieyt@gmail.com>
@ChristopherDownie
ChristopherDownie merged commit a7980bf into main Sep 27, 2026
1 check passed
@ChristopherDownie ChristopherDownie self-assigned this Sep 27, 2026
@frakton

frakton commented Sep 28, 2026

Copy link
Copy Markdown

Hello Christopher, thank you for the detailed breakdown of the 0.5.1 patch.

Following your notes, I performed a complete fresh test: I wiped the database entirely to start from a clean state (brand new SQLite database, clean install of version 0.5.1, and creating a brand new account), but unfortunately, the execution timestamps for IBKR Flex remain completely unchanged regardless of the default import timezone chosen.

Since the fix doesn't seem to alter the resulting execution times even on a completely fresh environment, could you please advise what additional troubleshooting steps we should take, or if there is a specific configuration we might be missing to force the timezone offset application? Thank you!

@ChristopherDownie

Copy link
Copy Markdown
Contributor Author

Your original report mentions importing and re-importing a Flex XML file. Could you confirm the exact screen or steps you use to bring that data into the Journal? The fix applies to Import → Broker sync → Interactive Brokers, so I want to make sure we’re investigating the same path.

Could you also share the Trade Journal commit or Docker image tag you’re running? Version 0.5.1 is the broker SDK release; the Journal-side update in this PR is also needed to pass the selected timezone through.

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants