All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog 1.1.0, and this project adheres to Semantic Versioning.
- ibc/models.py:
OrderRequest.to_dict()andModifyOrder.to_dict()now useis not Nonechecks instead of truthiness, preventing silent omission ofprice=0.0orquantity=0.0.- Numeric fields (
price,aux_price,quantity,cash_qty,fx_qty,trailing_amt) changed fromfloat = 0.0tofloat | None = None.
- Numeric fields (
- ibc/rest/market_data.py: Fixed
for field in fieldsshadowing the builtin name insnapshot()andsnapshot_beta()— renamed loop variable tof. - ibc/rest/market_data.py: Fixed
since: int = NonemissingNonein type union — nowsince: int | None = None. Same fix formarket_barandexchangeparams onmarket_history()andmarket_history_beta(). - ibc/rest/market_data.py: Fixed
market_history()docstring — return type was documented asdictbut method returnsHistoryData.
- ibc/rest/market_data.py: Added docstring to
snapshot_beta()explaining it does not accept asinceparameter (unlikesnapshot()). Updated return type docstring fromdicttolist[MarketDataModel]. - ibc/rest/portfolio.py:
accounts()return typelist→list[dict];subaccounts()return typelist→list[dict]. - ibc/rest/accounts.py:
pnl_server_account()return typedict→dict[str, Any]. - ibc/rest/customer.py:
customer_info()return typedict→dict[str, Any]. - ibc/rest/data.py: All methods (
portfolio_news,top_news,news_sources,news_briefings,summary) return typedict→dict[str, Any]. - ibc/rest/fyi.py: All methods updated from bare
dict/listtodict[str, Any]/list[dict[str, Any]]. - ibc/rest/portfolio.py:
account_metadata(),account_summary(),subaccounts2(),account_allocation(),portfolio_allocation(),position_by_contract_id(),positions_by_contract_id()return types updated from baredicttodict[str, Any]. - ibc/session.py: Extracted
IB_GATEWAY_BASE_URLconstant for the hardcoded"https://localhost:5000/v1"base URL. - ibc/async_session.py: Now imports
IB_GATEWAY_BASE_URLfromibc.sessioninstead of hardcoding the base URL. - ibc/async_session.py: Added docstring documenting that the async session lacks the token-bucket rate limiter and configurable timeout that the sync session provides.
- ibc/session.py: Demoted request/response logging from
INFOtoDEBUGlevel to reduce noise in production.- Affected messages: "Request: %s %s", "JSON Payload: %s", "Response Status Code: %s".
- ibc/client.py: Removed unused
passwordparameter fromInteractiveBrokersClient.__init__().- The Client Portal API uses browser-based gateway login; the password was never used by the auth flow.
- Updated all docstring usage examples to reflect the new signature.
- ibc/rest/market_data.py: Fixed
fieldsparameter type annotation onsnapshot()andsnapshot_beta()fromstr | Enumtolist[str | Enum] | None. - ibc/session.py: Fixed
methodfallback in error constructors to avoid passingNoneto exception classes. - ibc/session.py: Annotated
response.json()return to satisfyno-any-returnmypy check. - ibc/async_session.py: Annotated
response.json()return to satisfyno-any-returnmypy check. - pyproject.toml: Enabled mypy error codes
no-any-return,arg-type, andunion-attr(previously disabled). - pyproject.toml: Added
"samples/**/*.py" = ["F841"]to[tool.ruff.lint.per-file-ignores]. - samples/: Removed
passwordparameter from all 19 sample files. - README.md: Removed
passwordparameter from all code examples. - docs/getting-started.md: Removed
passwordparameter from all code examples. - docs/index.md: Removed
passwordparameter from Quick Start example.
- .gitignore: Added explicit
ibc_api.egg-info/entry. - .github/dependabot.yml: Already present — confirmed Dependabot is configured for
pipandgithub-actions.
- ibc/client.py:
passwordparameter andself._passwordattribute. - tests/conftest.py: Removed
client._passwordassignment frommock_clientfixture. - tests/test_client.py: Removed
passwordargument fromibc_clientfixture.
- .gitignore: Added explicit
ibc_api.egg-info/entry. - .github/dependabot.yml: Already present — confirmed Dependabot is configured for
pipandgithub-actions. - ibc/session.py: Connection health monitoring —
requests.ConnectionErroris now caught and re-raised asIBCAuthenticationErrorwith a clear message indicating the gateway may have died. - ibc/session.py:
timeoutparameter onInteractiveBrokersSession(default 30 seconds).- Per-request
timeoutoverride onmake_request(). - Prevents indefinite blocking when the gateway hangs.
- Per-request
- ibc/session.py:
health_check()method — callsGET /api/tickleand returns a boolean. Useful for monitoring scripts and pre-trade readiness checks. - ibc/session.py: Request/response timing logging at DEBUG level — includes elapsed milliseconds in the debug log output.
- ibc/client.py:
verify_sslparameter onInteractiveBrokersClientconstructor, forwarded to the session. - tests/test_session.py: 16 new unit tests for connection health monitoring, timeout, health_check, and timing logging.
- ibc/session.py:
verify_sslparameter now acceptsbool | str— pass a path to a custom CA certificate file or directory. - README.md: Expanded SSL Certificates section documenting the
verify_sslparameter with a table of accepted values and examples for custom CA certs. - docs/getting-started.md: Added
verify_sslparameter documentation with usage examples for custom CA certificates.
- pyproject.toml: Removed
wheel>=0.47.0from[build-system] requires— not needed with modern setuptools.
-
ibc/session.py: Retry with exponential backoff on HTTP 429 responses using
tenacity.- Configurable
max_retries,backoff_min,backoff_maxparameters onInteractiveBrokersSession.
- Configurable
-
ibc/session.py: Token-bucket rate limiter (
TokenBucket) to prevent API throttling.- Configurable
rate_limitparameter (requests per second, default 10).
- Configurable
-
ibc/exceptions.py:
IBCRateLimitErrorexception for HTTP 429 responses. -
ibc/models.py: 20 typed response dataclasses generated from the IB API Swagger spec.
AuthStatus,Account,Contract,SecdefInfo,Order,OrderStatus,OrderRequest,ModifyOrder,Trade,HistoryBar,HistoryData,MarketData,Position,Ledger,AlertCondition,AlertResponse,ScannerFilter,ScannerParams,ScannerContract,ScannerResult,Summary,Transaction,Transactions,SystemError.- All models are frozen dataclasses with
from_dict()class methods and sensible defaults. - Request models (
OrderRequest,ModifyOrder,ScannerParams) includeto_dict()for API serialization.
-
ibc/async_session.py: Async REST session using
httpxwith retry on 429.AsyncInteractiveBrokersSessionwithasync make_request(), context manager support.
-
ibc/websocket.py: WebSocket streaming client for real-time market data.
IBWebSocketClientwith subscribe/unsubscribe for market data, orders, and account summary.- Async context manager and async iteration over incoming messages.
-
pyproject.toml: Added
tenacity>=8.2to core dependencies. -
pyproject.toml: Added
asyncoptional dependency group (httpx>=0.27,websockets>=12.0). -
pyproject.toml: Added
pytest-asyncio>=0.23to dev dependencies. -
tests/test_models.py: 52 unit tests for all response model dataclasses.
-
tests/test_async_session.py: 11 unit tests for async session.
-
tests/test_websocket.py: 16 unit tests for WebSocket client.
-
tests/test_session.py: 6 additional tests for retry/backoff and rate limiting.
-
samples/use_models.py: New sample demonstrating typed model access for contracts, market data, historical bars,
OrderRequest.to_dict(),ScannerParams.to_dict(), and portfolio positions/ledger. -
.github/workflows/docs.yml: GitHub Actions workflow to build and deploy MkDocs documentation to GitHub Pages on push to master.
-
docs/api/models.md: API reference page for all response and request models.
-
README.md: Complete rewrite with badges (Python versions, PyPI, license), Features table listing all 14 services, proper pip install instructions, and a concise quick-start example.
-
docs/: MkDocs-based API reference documentation auto-generated from docstrings.
mkdocs.ymlconfiguration with Material theme andmkdocstrings[python].- 15 API reference pages (one per service) plus Getting Started guide.
-
pyproject.toml: Added
docsoptional dependency group (mkdocs,mkdocs-material,mkdocstrings[python]).
- ibc/rest/orders.py:
orders()now returnslist[Order]instead of a raw dict. - ibc/rest/accounts.py:
accounts()now returnslist[Account]instead of a raw dict. Handles both dict and string account entries. - ibc/utils/auth.py:
is_authenticated(),tickle(), andlogin()now returnAuthStatusmodel instead of raw dicts.check_auth()usesAuthStatus.authenticatedinternally. - ibc/init.py: Added
__version__viaimportlib.metadata.version("ibc-api"). - README.md: Updated quick-start import to use
from ibc import InteractiveBrokersClient.
- samples/use_async_orders.py: New sample demonstrating placing and monitoring an order using sync REST and async WebSocket together.
- ibc/rest/market_data.py:
snapshot(),market_history(),market_history_beta(), andsnapshot_beta()now return typed models (list[MarketData],HistoryData). - ibc/rest/orders.py:
order_status()now returns anOrderStatusmodel instead of a raw dict. - ibc/rest/alert.py:
available_alerts()now returnslist[AlertResponse]andalert_details()returnsAlertResponse. - ibc/rest/contract.py:
contract_info()now returns aContractmodel andsecdef_info()returnslist[SecdefInfo]. - ibc/rest/portfolio.py:
account_ledger()now returnsdict[str, Ledger]andportfolio_positions()returnslist[Position]. - ibc/rest/portfolio_analysis.py:
transactions_history()now returns aTransactionsmodel. - ibc/rest/scanner.py:
run_scanner()now returns aScannerResultmodel. - ibc/rest/trades.py:
trades()now returnslist[Trade]. - docs/index.md: Quick start updated to demonstrate typed model access.
- docs/getting-started.md: Making Requests section rewritten to show typed responses and
OrderRequest.to_dict(). - mkdocs.yml: Added Models page to the navigation.
- samples/*.py: Polished all 14 sample files to follow project conventions.
- Added module-level docstrings.
- Added
# ---section dividers between logical blocks. - Added inline
# Output: ...comments showing expected response shapes. - Simplified boilerplate (removed redundant comments, used
wait_for_login()).
- README.md: Fixed typo "plesfe" → correct link text, removed reference to nonexistent
requirements.txt. - tests/test_market_data.py: Fixed
test_converts_enum_barusing wrong keywordbarinstead ofmarket_barformarket_history_beta(). - tests/test_alerts.py: Updated assertions to verify
AlertResponsemodel instances. - tests/test_contracts.py: Updated assertions to verify
ContractandSecdefInfomodel instances. - tests/test_orders.py: Updated assertions to verify
OrderStatusmodel instance. - tests/test_market_data.py: Updated assertions to verify
MarketDataandHistoryDatamodel instances.
- tests/test_portfolio.py: 16 new tests covering auto-call branches, return values, and
_validate_idvalidation for allPortfolioAccountsmethods. Coverage 83% → 93%. - tests/test_auth.py: 8 new tests covering
login()exception path,wait_for_login()poll success,_startup_gateway()gateway-not-installed and Unix paths,_is_already_running_windows()edge cases,close_gateway()Unix path. Coverage 90% → 100%. - tests/test_async_session.py: 4 new tests covering
__aenter__/__aexit__context manager, empty content error path, and invalid JSON error path. Coverage 92% → 100%. - tests/test_models.py: 5 new tests covering
OrderRequest.to_dict()andModifyOrder.to_dict()with all fields populated and zero-value edge cases. Coverage 95% → 99%. - tests/test_session.py:
IBCRequestError.__repr__()test covering the repr format string. - tests/test_accounts.py: 3 new
_validate_idedge-case tests for whitespace-only,None, and non-string inputs. - tests/test_client.py: Added missing
fyiservice property test and property caching assertion tests.
- ibc/utils/auth.py:
tickle()method — POST/api/tickleto keep the session alive.logout()method — POST/api/logoutto terminate the authenticated session.
- ibc/rest/contract.py: 8 new endpoint methods for expanded contract discovery.
search_stocks(symbols)— GET/api/trsrv/stocks.trading_schedule(asset_class, symbol, exchange)— GET/api/trsrv/secdef/schedule.secdef_strikes(contract_id, sectype, month, exchange)— GET/api/iserver/secdef/strikes.secdef_info(contract_id, sectype, month, exchange, strike, right)— GET/api/iserver/secdef/info.contract_algos(contract_id, algos, add_description, add_params)— GET/api/iserver/contract/{conid}/algos.contract_rules(contract_id, is_buy)— POST/api/iserver/contract/rules.contract_info_and_rules(contract_id, is_buy)— GET/api/iserver/contract/{conid}/info-and-rules.currency_pairs(currency)— GET/api/iserver/currency/pairs.
- ibc/rest/alert.py: 4 new endpoint methods for alert management.
create_or_modify_alert(account_id, alert)— POST/api/iserver/account/{account_id}/alert.activate_alert(account_id, alert_id, activate)— POST/api/iserver/account/{account_id}/alert/activate.delete_alert(account_id, alert_id)— DELETE/api/iserver/account/{account_id}/alert/{alert_id}.alert_details(alert_id)— GET/api/iserver/account/alert/{alert_id}.
- ibc/rest/orders.py: 3 new endpoint methods for order operations.
order_status(order_id)— GET/api/iserver/account/order/status/{order_id}.place_orders_for_fa_group(fa_group, orders)— POST/api/iserver/account/orders/{fa_group}.place_whatif_orders(account_id, orders)— POST/api/iserver/account/{account_id}/orders/whatif.
- ibc/rest/market_data.py: 5 new endpoint methods for market data operations.
unsubscribe(contract_id)— GET/api/iserver/marketdata/{conid}/unsubscribe.unsubscribe_all()— GET/api/iserver/marketdata/unsubscribeall.market_history_beta(contract_id, period, bar, outside_regular_trading_hours)— GET/api/hmds/history.snapshot_beta(contract_ids, fields)— GET/api/md/snapshot.scanner_beta(scanner)— POST/api/hmds/scanner.
- ibc/rest/portfolio.py:
subaccounts2(page)method — GET/api/portfolio/subaccounts2. - ibc/rest/fyi.py: New FYI notifications service with 12 endpoint methods.
unread_number(),settings(),toggle_setting(typecode, enabled),disclaimer(typecode),accept_disclaimer(typecode),delivery_options(),toggle_email_delivery(enabled),toggle_device_delivery(device_id, enabled),delete_device(device_id),notifications(max_count, include_read),more_notifications(notification_id),mark_notification_read(notification_id).
- ibc/client.py:
fyiproperty returning theFYIservice instance. - tests/test_contracts.py: 24 unit tests for all contract service methods.
- tests/test_alerts.py: 12 unit tests for all alert service methods.
- tests/test_fyi.py: 24 unit tests for all FYI service methods.
- tests/test_auth.py: 10 unit tests for authentication service methods.
- tests/test_orders.py: 6 new unit tests for order_status, place_orders_for_fa_group, place_whatif_orders.
- tests/test_market_data.py: 10 new unit tests for unsubscribe, unsubscribe_all, market_history_beta, snapshot_beta, scanner_beta.
- tests/test_portfolio.py: 2 new unit tests for subaccounts2.
- samples/use_contracts.py: Examples for search_stocks, trading_schedule, secdef_strikes, secdef_info, contract_algos, contract_rules, contract_info_and_rules, currency_pairs.
- samples/use_alerts.py: Examples for create_or_modify_alert, activate_alert, alert_details, delete_alert.
- samples/use_orders.py: Examples for order_status, place_orders_for_fa_group, place_whatif_orders.
- samples/use_market_data.py: Examples for unsubscribe, unsubscribe_all, market_history_beta, snapshot_beta, scanner_beta.
- samples/use_fyi.py: New sample file demonstrating the FYI notifications service.
-
tests/test_market_data.py: Fixed
test_converts_enum_bar_to_valueusing wrong keyword argumentbarinstead ofmarket_bar.IBCErrorbase exception for all IB API client errors.IBCRequestErrorwithstatus_code,url,method, andresponse_bodyattributes.IBCAuthenticationErrorfor gateway and login failures.IBCValidationErrorfor input validation failures.
-
ibc/init.py: Package init with explicit
__all__exports forInteractiveBrokersClient,InteractiveBrokersSession, and all exception classes. -
ibc/rest/init.py: Subpackage init with
__all__exporting all 12 REST service classes. -
ibc/utils/init.py: Subpackage init with
__all__exporting auth, gateway, and enum modules. -
ibc/py.typed: PEP 561 marker file for type information distribution.
-
ibc/utils/auth.py:
wait_for_login(timeout=300, poll_interval=3)method that polls the gateway for authentication with configurable timeout, replacing manual busy-wait loops in callers. -
ibc/utils/auth.py:
_is_already_running_unix()method usingpgrepfor Linux/macOS gateway process detection. -
tests/conftest.py: Shared pytest fixtures (
mock_client,mock_session) for offline testing without live credentials or gateway download. -
tests/test_client.py: 18 unit tests for
InteractiveBrokersClientinitialization and service properties. -
tests/test_session.py: 16 unit tests for
InteractiveBrokersSessionURL building, headers, and request handling.- Added 3 new tests:
__repr__, empty-body success response, invalid method validation, and case-insensitive method dispatch (19 total).
- Added 3 new tests:
-
tests/test_accounts.py: 4 unit tests for
Accountsservice methods. -
tests/test_orders.py: 10 unit tests for
Ordersservice methods including place, modify, and cancel flows. -
tests/test_market_data.py: 13 unit tests for
MarketDataservice methods. -
tests/test_portfolio.py: 18 unit tests for
Portfolioservice methods. -
tests/test_gateway.py: 21 unit tests for
ClientPortalGatewaycovering download, zip validation, extraction, path traversal rejection, and setup orchestration. -
pyproject.toml: PEP 621 project metadata replacing legacy
setup.py. Includesrequires-python >= 3.10, Python 3.10–3.13 classifiers, unpinnedrequests>=2.33.1andfake-useragent>=2.2.0, and dev extras withpytest>=7andpylint. -
.github/dependabot.yml: Weekly automated dependency updates for pip.
-
README.md: SSL Certificates section explaining self-signed certs,
verify_ssl=Falsedefault, and steps for custom certificate configuration.
- ibc/utils/gateway.py: Rewrote
ClientPortalGatewayfor resilience and security.- Added zip path traversal validation (
_validate_zip_entries) to prevent zip-slip attacks. - Fixed extraction path to use
self._gateway_folderinstead of a hardcoded relative string. - Added
timeout=60andraise_for_status()to the download request. - Wrapped download and zip parsing errors in
IBCErrorwith descriptive messages. - Replaced folder-existence check with marker-file check (
bin/run.batorbin/run.sh) to detect incomplete installs. - Made download URL configurable via
download_urlparameter. - Added
__repr__for debugging. - Removed unused
textwrapimport.
- Added zip path traversal validation (
- ibc/utils/auth.py: Rewrote authentication and gateway management for cross-platform support and robustness.
login()now checks if already authenticated before restarting the gateway, attempts reauthentication, and falls back to browser login._startup_gateway()usesclient.client_portal._gateway_folderinstead of hardcoded relative path; supports Linux/macOS viabash bin/run.sh._is_already_running()delegates to platform-specific methods; handles empty output, subprocess timeouts, andOSError.close_gateway()raisesIBCAuthenticationErrorwhen no PID is available; useskillon Linux/macOS.check_auth()usesresponse.get("authenticated")instead ofresponse["authenticated"] == True.- Replaced broad
except Exceptionwithexcept (IBCRequestError, requests.RequestException). - Added explicit
check=Falseto allsubprocess.runcalls. - Removed unused
_use_seleniumparameter fromlogin(). - Removed unused
checkparameter fromis_authenticated(). - Removed unused
requestsimport (replaced with targetedIBCRequestErrorimport). - Added
_GATEWAY_LOGIN_URLconstant to replace scattered URL strings. - Added
update_server_account()input validation viaIBCValidationError.
- ibc/session.py: Rewrote session to use persistent
requests.Sessionfor connection pooling and cookie handling.- Replaced standalone
requests.get/post/deletecalls withsession.request(method=...), eliminating the if/elif dispatch chain. - Removed dead code: second
elifbranch (len(content) > 0 and response.ok) was unreachable (identical condition to firstif). - Removed fragile
/api/iserver/accountspecial-case that silently returned errors as JSON instead of raisingIBCRequestError. - Moved
UserAgent().edgegeneration from per-requestbuild_headers()to__init__, eliminating repeatedfake_useragentcalls. - Removed
build_headers()method — headers now live on the persistent session. - Added HTTP method validation against a
_VALID_METHODSset with a clearValueError. - Method parameter is now case-insensitive.
- Narrowed
except Exceptionin JSON parsing toexcept (ValueError, requests.JSONDecodeError). - Made SSL verification configurable via
verify_sslparameter (defaultFalsefor localhost gateway). - Replaced
logging.basicConfig()withlogger = logging.getLogger(__name__)— libraries must not configure the root logger. - Demoted response body logging from
infotodebug. - Added
__repr__for debugging.
- Replaced standalone
- ibc/client.py: Improved client initialization and API consistency.
sessionis now a@propertyinstead of a method, matching all other service accessors.- Added
__repr__for debugging.
- ibc/rest/data.py: Fixed copy-paste bug where
news_sources()hit/api/iserver/news/topinstead of the correct endpoint. - ibc/rest/portfolio_analysis.py: Fixed copy-paste bug where
transactions_history()posted to/api/pa/summaryinstead of/api/pa/transactions. - ibc/rest/orders.py: Fixed copy-paste bug where
modify_order()ignored theorder_idparameter in the endpoint URL. - ibc/rest/contract.py: Fixed type hint bug where
search_symbol(name: str = False)had abooldefault withstrannotation. - ibc/rest/*.py: Added
from __future__ import annotations,TYPE_CHECKINGguard forInteractiveBrokersClient,__repr__, and input validation (_validate_id) across all 12 REST service classes. - ibc/rest/market_data.py: Removed
__init__()side-effect that called the accounts endpoint on instantiation. - ibc/rest/pnl.py: Removed duplicate
pnl_server_account()— consolidated intoAccountsservice only. - samples/*.py: Replaced manual
while not authenticatedbusy-wait loops withauth_service.wait_for_login()across all 9 sample files. - .github/workflows/python-package.yml: Updated to
actions/checkout@v4andactions/setup-python@v5, Python 3.10–3.13 matrix, fixed test filename typo. - .github/workflows/python-publish.yml: Updated actions and switched to OIDC Trusted Publishers.
- ibc/session.py: Removed
build_headers()method — headers are now set once on the persistent session. - ibc/rest/market_data.py: Removed
print()statement from library code. - ibc/utils/auth.py: Removed
print()statements from library code. - ibc/utils/gateway.py: Removed
print()statements and unusedtextwrapimport from library code.