Repository navigation
Let cloud live deploy authorize Interactive Brokers (FIX) - #694
Conversation
- the cli read and authorized an oauth-token module under its lowercased display name, which only matches the api's brokerage name when the two are the same word, as for CharlesSchwab or TradeStation - Interactive Brokers (FIX) is displayed with a space and a suffix but authorizes as interactivebrokers, so its modules json entry needs to name it: an optional auth0-brokerage key on the oauth-token configuration does, and modules without it keep using the display name Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Approving. The whole change is ready, and I set risk:high.
What I checked
configuration.auth0_brokerage or self._display_name.lower()is the only place the authorization name is worked out (lean/models/json_module.py:318). Modules without the key behave exactly as before. In the current hosted json, CharlesSchwab, TradeStation, Alpaca and Tastytrade are the onlyoauth-tokenmodules, and none of them sets the key. Older CLI versions ignore it.modules-1.15.jsonwas first read on master in 874a698, and no release reads it yet (1.0.233 readsmodules-1.14.json). So the description is right: the entry can go into 1.15 with this release, and no CLI already released will show the brokerage without being able to authorize it.- The new test fails without the change (
[mybrokerage-mybrokerage]) and passes with it. The other test covers the display-name fallback. - End to end, I ran it myself with a local modules json holding the entry from the description and an already-linked IB user name:
--helplistsInteractive Brokers (FIX),--ib-fix-user-nameand--ib-fix-account.lean cloud live deploy ... --brokerage "Interactive Brokers (FIX)" --ib-fix-user-name <MixedCase user> --ib-fix-account <account>read the authorization underinteractivebrokersand validated the account against the returned list.- The deployment was accepted, and
lean cloud statusshowed it running withBrokerage: Interactive Brokers (FIX). I stopped it afterwards.
CI
All 12 failing jobs are macos-14. GitHub's annotation on each one says "This job failed because of a scheduled macOS 14 runner image brownout": the runner never ran the tests. The same Python versions pass on macos-15, Ubuntu and Windows. This is not caused by the change. Separately, the macos-14 matrix entry will need moving once that image is retired on November 2.
Before release
- The server-side change this depends on has to be live before the modules json entry is published and before the CLI is released. Without it, the read under
interactivebrokersfails, and the CLI sends the user to authorize and then polls for 7 minutes before failing. - Publishing the entry to
modules-1.15.jsonis a separate manual step. - Still needing an update: QuantConnect/Documentation, the
lean cloud live deployoptions page (--ib-fix-user-name,--ib-fix-account).README.mdregenerates once the entry is published. - The
DUquestion in the description needs a person to decide. It doesn't need a CLI change either way.
Risk: risk:high
Once the entry is published, this adds a user-facing brokerage and options to lean cloud live deploy, and the change as a whole changes how live deployments with real money are accepted. A person should merge it alongside the server-side release and the json publish.
- the server authorizes the Interactive Brokers (FIX) module under `interactivebrokers`, the only name `live/auth0/authorize` accepts for it, while every other oauth module authorizes under its lowercased display name; one exception in the CLI is less to get wrong than a new json key every module publisher has to know - without the key the modules json entry needs no new field, and the entry works the same on older CLI versions that never read it
- the readme is generated from the hosted modules json, which gets the Interactive Brokers (FIX) entry with the release of this change; adding the two options now keeps the readme in step with the entry in the PR description instead of a follow-up commit after the publish - the readme check compares against the hosted json, so it fails until the entry is published
- live/create rejects an Interactive Brokers (FIX) deployment unless the settings carry the linked user name a second time, under `ib-fix-linked-account` ("No linked account user id found for this user"), and the modules json had no way to send one value under two keys
- `alias-of` on an internal-input copies the value of the named configuration at settings time, so the entry declares the second key itself and the CLI keeps no brokerage-specific code for it; older CLI versions ignore the key and send the setting empty
- live/auth0/authorize knows the Interactive Brokers login as `interactivebrokers`, but live/auth0/read keys the stored token by the module id; with one name for both calls the CLI never found the token after the login, polled for 7 minutes and ended with "Authorization failed" - the two names are resolved in one private method on the module, and the helper takes both so it never has to guess one from the other
- the modules json entry moved from after the Interactive Brokers entry to the end of the brokerage list, after ClearStreet, and the readme generator prints the brokerage choice and the options in module order, so the readme follows
- `brokerage_id` is the name live/auth0/authorize opens the login for since the read name became its own parameter; the old wording described both calls at once
- a typo in an `alias-of` value failed inside `get_config_value_from_name` with "not enough values to unpack", with no configuration id in the message, so the json author had nothing to search for - the alias lookup now raises a message with the alias id, the target id and the module id
There was a problem hiding this comment.
Requesting changes. Since my approval, the new commits fix a real bug, but two things block merging: a deploy that fails for mixed-case user names, and CI.
A correction to my earlier review. I wrote that the read under interactivebrokers worked end to end. That was wrong: live/auth0/read doesn't accept interactivebrokers. It finds the FIX authorization under the module id, and only live/auth0/authorize uses interactivebrokers. de0e12b is the right fix. Its new test fails without the change and passes with it.
Blocking
-
A user name with capitals is rejected by
live/create.alias-ofcopies--ib-fix-user-nameexactly as typed intoib-fix-linked-account. The stored authorization keeps the user name lowercased, andlive/createcompares the linked account against it case-sensitively. I tested this end to end with the modules json entry plus{"id": "ib-fix-linked-account", "type": "internal-input", "alias-of": "ib-fix-user-name"}, using a linked user stored askronosfixuser:--ib-fix-user-name KronosFixUser: the read underInteractiveBrokersFixBrokeragefound the authorization and the account, and the request carried"userId": "kronosfixuser"but"ib-fix-linked-account": "KronosFixUser".live/createfailed with "Account and user id mismatch, please log out and log in again."--ib-fix-user-name kronosfixuser: the deployment was accepted, andlean cloud statusshowed it running withBrokerage: Interactive Brokers (FIX). I stopped it afterwards.
The web wizard doesn't hit this, because it sends the lowercased user id the server stored. The read already returns that id (
userIdin the authorization), and the CLI already sends it in the settings. Sending that value asib-fix-linked-account, or having the deployment compare the user name case-insensitively, avoids the problem. Please add a test that uses a mixed-case user name. -
CI is red because of this change.
Check READMEfails on Linux:README.mdlistsInteractive Brokers (FIX),--ib-fix-user-nameand--ib-fix-account, but the hostedmodules-1.15.jsondoesn't have the entry yet. I checked, and it still doesn't. Because of fail-fast, that failure cancels the rest of the matrix, soRun testsnever finished on Windows or macOS 15. If this merges before the entry is published, master's README check fails for every pull request until it is published. Please drop 321dc9c and 554cf75 (the README regenerates once the entry is published), or publish the entry first and rerun CI. Locally, the whole suite passes on this head (2782 passed, 82 skipped). The one failure,test_command_process_runs_the_cli_as_a_child_process, comes from my local install starting the installed release instead of the source. -
The description is out of date. It still says both calls use
interactivebrokers. Its modules json entry has noib-fix-linked-account/alias-ofconfiguration, so publishing it as written gives the "No linked account user id found" error. Open question 1 is answered by 7241532. The testing section describes the first version. Please update the entry, what the code does, and the end-to-end outcome for the current head, including a mixed-case user name.
Minor
_get_auth0_authorizationhas a single call site (inline comment). Please inline it.
Still to update: QuantConnect/Documentation, the lean cloud live deploy options page (--ib-fix-user-name, --ib-fix-account) once the entry is published. The DU paper-account question still needs a person to decide. The CLI doesn't need a change for it either way.
Risk: risk:high (unchanged). Once the entry is published, this adds a user-facing brokerage and options to lean cloud live deploy, which places real-money live deployments. It also adds a new modules json key, alias-of.
There was a problem hiding this comment.
Approving 42fbdbd. I found no blocking defect introduced by the current diff. Keeping risk:high.
Verified
- Both authorization calls use
InteractiveBrokersFixBrokeragefor FIX. The current endpoint contract accepts that identifier; the lowercased display name does not reach the IB authorization flow. CharlesSchwab, TradeStation, Alpaca and Tastytrade retain their existing identifiers and behavior. - The module entry in the description matches the current implementation: the user name and account are supplied without the removed
alias-of/ linked-account configuration. - Focused authorization, module and live-command tests: 122 passed. Substituting master's
config_buildmakes the new FIX case fail while the other model tests pass (1 failed, 12 passed), confirming the regression test exercises the change. - Full suite (
PYTHONPATH="$PWD" python -m pytest -s -rs): 2,781 passed, 82 skipped, eight warnings. The first attempt reached its two-minute execution limit; the rerun completed successfully in 118 seconds. - Static analysis passed with five existing unused-import warnings. README regeneration produced no diff.
- CI: 66 passing checks, with six release jobs skipped.
End-to-end evidence and limits
The description records deployment acceptance at a70ad35. I verified that the final commit only inlines the same identifier selection and authorization call, without changing their arguments. Independently, I checked the authorization redirects and that the exact proposed module entry generates the brokerage choice and both CLI options.
I could not repeat a linked-account deployment because no linked FIX authorization was available to my test account. I therefore do not claim a fresh successful FIX connection or a completed brokerage OAuth round trip.
Release follow-up
- Publish the proposed
modules-1.15.jsonentry together with the CLI release, after the required authorization contract is deployed. The hosted catalog still lacks the entry, so merging this code alone does not expose the new brokerage. - QuantConnect/Documentation still needs an update to the
lean cloud live deployoptions page. Regenerate the README after publishing the entry. - The paper-account filtering question remains a release decision for the module entry.
I also reproduced a shared, pre-existing OAuth default-account bug on both master and this head and filed #699. Explicit account command-line options work; it is not caused by this identifier change and does not block this PR.
Risk: risk:high remains appropriate because this enables a new user-facing brokerage and options for live deployments, with coordinated API/catalog/CLI release requirements. The small code diff and passing tests do not remove those traits.
- the readme is generated from the hosted modules json, which gets the Interactive Brokers (FIX) entry with the release of this change; adding the brokerage choice and the two options now keeps the readme in step with the entry in the PR description instead of a follow-up commit after the publish - the readme check compares against the hosted json, so it fails until the entry is published
There was a problem hiding this comment.
Approving 045babe. The code is the same as the 42fbdbd I approved, apart from one removed comment. The README now matches the published modules json. The only red check comes from a stale CDN cache, not from this change (details below). The label stays risk:high.
What changed since my last review (42fbdbd)
- 4d32f2b adds
Interactive Brokers (FIX),--ib-fix-user-nameand--ib-fix-accounttoREADME.md. - 045babe removes the comment above the
brokerage_idchoice. That is the only change tolean/(git diff 42fbdbd 045babe -- leanis one deleted line).
The modules json entry is published
The uncompressed modules-1.15.json on the CDN was modified at 19:29 UTC. It holds the InteractiveBrokersFixBrokerage entry exactly as the description gives it: I compared the two key by key. It comes after ClearStreetBrokerage. When I regenerate README.md from that file with scripts/readme.py, the output is byte for byte this PR's README. No released CLI shows the entry yet: 1.0.233, the latest on PyPI, still reads modules-1.14.json.
CI
Check READMEfails onubuntu-24.04, 3.11. Because of fail-fast, the failure cancelled every otherBuildjob, so the test suite didn't run in CI at this head. The cause is the CDN, not the README. CloudFront still serves the gzip copy ofmodules-1.15.jsonit cached from the Oct 29 version, which has 37 modules and no FIX entry.requestsasks for gzip, so CI andscripts/readme.pyget the stale copy, while a plain uncompressed request gets the new one. When I reproduced it locally,scripts/readme.pywith the downloaded (gzip) json removed the FIX lines, the same diff CI shows. With the published json it changed nothing.Regression Testingpasses at this head on Ubuntu, macOS 15 and Windows (3.14).- The
Buildsuite was green at 42fbdbd, and the code there is identical apart from the removed comment. Locally at this head,tests/models/test_json_module.py,tests/commands/cloud/liveandtests/commands/livepass (101 passed). - Before merging: invalidate the CDN copy of
modules-1.15.json, or wait for it to expire, then rerun the failed jobs, so the full suite runs green at this head. Once the cache refreshes, master's own README check fails on every pull request until this PR merges. So merge it soon after that.
Minor, non-blocking
- The removed comment gave the only reason for the hard-coded
"InteractiveBrokersFixBrokerage"check, and that reason isn't obvious from the code (inline comment). - The description's first open question says the second end-to-end run was at
42fbdbd. The mixed-case run reported in the reviews was at a70ad35. The code didn't change in between, so the conclusion holds.
Before release
- Production still doesn't accept the module id. Right now,
live/auth0/authorize?brokerage=InteractiveBrokersFixBrokerageredirects to the plain/login, whileinteractivebrokersredirects to/login/?target=auth-interactivebrokers. Don't release this CLI until the server-side change is live in production. A released CLI readsmodules-1.15.json, which already lists the brokerage, so releasing first would send FIX users who aren't linked yet to a login that doesn't authorize them. - Still needing an update: QuantConnect/Documentation, the
lean cloud live deploypage (--ib-fix-user-name,--ib-fix-account). - The
DUpaper-account question is still open for a person to decide. It needs no CLI change either way.
Risk: risk:high (unchanged). The diff is small and easy to revert. What keeps the label high is what it enables: a new user-facing brokerage and options for lean cloud live deploy, which places real-money live deployments. The release also has to wait for the server-side change to reach production.
- the Interactive Brokers (FIX) entry now carries its module id as display id, so the rule every other oauth module uses sends a name the API knows and the CLI needs no case for it
- the hosted modules json entry uses `InteractiveBrokersFixBrokerage` as display id, so the brokerage choice and the two options follow the generator output for that entry
Description
lean cloud live deploygets the Interactive Brokers (FIX) brokerage through a new entry in the hosted modules json. The CLI authorizes anoauth-tokenmodule under its lowercased display id, so the entry uses the module id,InteractiveBrokersFixBrokerage, as display id: the CLI sendsinteractivebrokersfixbrokeragetolive/auth0/authorizeandlive/auth0/read, the name the API knows since the change of 2026-11-03. No CLI code changes.This PR regenerates
README.mdfor that entry:InteractiveBrokersFixBrokeragein the--brokeragechoice and the two options--ib-fix-user-nameand--ib-fix-account.Modules json entry
After the
ClearStreetBrokerageentry. Same pattern as Charles Schwab: the user name the account is authorized with, then the account chosen among the ones the authorization returns.{ "configurations": [ { "help": "Using OAuth authentication with QuantConnect.", "id": "ib-fix-oauth-token", "prompt-info": "Using OAuth authentication for QuantConnect.", "require-user-name": true, "type": "oauth-token", "value": "Yes" }, { "help": "Your Interactive Brokers user name", "id": "ib-fix-user-name", "input-method": "prompt", "log-message": "The FIX integration trades through your Interactive Brokers user name, which you authorize from the link the CLI shows the first time.", "prompt-info": "Username", "type": "input" }, { "filters": [ { "condition": { "dependent-config-id": "ib-fix-oauth-token", "pattern": "^(?!\\s*$).+", "type": "regex" } } ], "help": "Your Interactive Brokers account id", "id": "ib-fix-account", "input-method": "choice", "prompt-info": "Account id", "type": "input" } ], "display-id": "InteractiveBrokersFixBrokerage", "id": "InteractiveBrokersFixBrokerage", "installs": true, "live-cash-balance-state": "not-supported", "live-holdings-state": "not-supported", "minimum-seat": "Researcher", "platform": [ "cloud" ], "type": [ "brokerage" ] }The copy on the CDN since 2026-11-03 still has the display id
Interactive Brokers (FIX), which the API does not know; the entry above replaces it. The README check regenerates from the hosted json, so it passes once this entry is published.Related Issue
Closes #692
Motivation and Context
Members who moved an IB account to the FIX integration can only deploy it from the web wizard, so they lose scripted deployments.
Requires Documentation Change
Yes: the
lean cloud live deploypage should list--ib-fix-user-nameand--ib-fix-account.How Has This Been Tested?
scripts/readme.pywith the entry above in the local modules json produces thisREADME.mdbyte for byte.live/auth0/readwithbrokerage=InteractiveBrokersFixBrokerageanduserId=<IBKR user name>returns the stored token and accounts, in any casing of the id. On beta, after the API change,authorize?brokerage=InteractiveBrokersFixBrokerageredirects to the Interactive Brokers login. Before the change the two endpoints disagreed (authorizeknew onlyinteractivebrokers,readonly the module id) and/live/createrequiredib-fix-linked-account; the API change removed both.readunder the module id, noauthorize,/live/createwithid,ib-refresh-token,userId,ib-fix-user-name,ib-fix-accountanswered 200 andlean cloud statusshowed the deployment running on the FIX brokerage.static_analysis.pypasses.Open questions
authorizewith the lowercased id,interactivebrokersfixbrokerage, is what the CLI sends.readaccepts it;authorizeis to be confirmed once the API change is deployed.DUpaper accounts. The entry does not filter the account choices; aninput-regexonib-fix-accountwould, with no CLI change. Should it?Types of changes
🤖 Generated with Claude Code
https://claude.ai/code/session_016wy9obSrFd8mX9UTb2nNfK