mattsta / icli

interactive brokers ibkr api command line interface cli giving you the fastest way to lose all your money
Other
131 stars 22 forks source link

icli: IBKR live trade cli

icli is a command line interface for live trading (or sandbox/paper trading) using IBKR accounts.

The intended use case is for scalping or swing trading, so we prioritize easy of understanding your positions and active orders while removing unnecessary steps when placing orders.

Demo Replay

Watch the console replay demo below to see a paper trading account where we add some live quotes for stocks and options, remove quotes, place orders to buy and sell, check execution details to view aggregate commission charges, check outstanding order details, and add some live futures quotes too.

asciicast

Note: the capture preview is a couple years old at this point and we should make a new one. The interface has improved since then, so try it out from a recent clone and join us here in the future.

Overview

Welcome to icli! You can use icli to manage manual and automated trading using your IBKR account for stocks, futures, currencies, and options.

You can enable audio announcements of trade events if you also run awwdio and provide your awwdio address as an environment variable like ICLI_AWWDIO_URL=http://127.0.0.1:8000 poetry run icli (macOS only currently and you need to manually install the system speech voice packs in system settings).

There's always a hundred more features we could add, but focus goes mainly towards usability and efficient order entry currently. There's an unreleased in-progress algo trading agent plugin to automatically buy and sell stocks, futures, and/or options based on external signals too. Cleaning those up for public release isn't a priority at the moment unless sponsors would like to step up and motivate us for a wider code release to combine all the feautres into a finished product we can publish.

You can run multiple clients in different terminal windows using unique client ids for each session like ICLI_CLIENT_ID=4 poetry run icli. Note: IBKR restricts orders per-client-id, so for example if you place an order under client id 4, the order will not show up under other clients.

Some helpful advanced commands only available in icli:

See below for further account setup and environment variable conditions under the Download section.

For tracking feature updates, check the full commit history and you can always run ? for listing commands and getting help when running commands. The README is slightly undermaintained and some features are lacking complete documentation outside of the runtime itself, so feel free to suggest updates where useful.

Features

Streaming Quote View

Stocks / Futures

ES    :   4,360.25  ( 1.55%  67.00) (  1.09%   47.25)   4,362.00     4,293.25   4,360.00 x    158   4,360.25 x    112    4,310.25   4,313.00

Live stock / etf / etn / futures / etc quotes show:

For more detailed level 2 quotes, we'd recommend WeBull's TotalView integration because they have a special deal with NASDAQ to allow TotalView for $1.99/month instead of paying IBKR hundreds in fees per month to get limited depth views.

Options

TSLA  210716C00700000: [u   653.98 ( -7.04%)] [iv 0.47]  3.37 ( -32.57%   -1.65  5.00) (  14.29%    0.40  2.95) ( -24.24%   -1.10  4.45)   3.35 x      4    3.40 x      3

Live option quotes display more details because prices move faster:

For more detailed option level 2 quotes, we'd recommend futu/moomoo in-app real time OPRA Level 2 quotes for $3.99/month. They also have a built-in unusual options volume scanner, and they now have a trading and quote API, but API quotes are billed differently than in-app quotes and the API docs are poorly translated into english, so ymmv.

futu/moomoo also lets you buy equity depth for ARCA/OpenBook/CBOE/BZX/NASDAQ exchanges, but they charge regular market prices for each of those, so you'd be paying over $100/month for full depth coverage (and their TotalView alone is $25.99/month while WeBull offers it for $1.99/month).

Quote Order

The quote view uses this order for showing quotes based on security type:

Futures are sorted first by our specific futures order defined by the FUT_ORD dict in cli.py then by name if there isn't a specific sort order requested (because we want /ES /NQ /YM first in the futures list and not /GBP /BTC etc).

Stocks/etfs sort in REVERSE alphabetical order because it's easier to see the entry point of the stocks view at the lowest point rather than visually tracking the break where futures and stocks meet.

Single option quotes are displayed in alphabetical order.

Finally, option spreads show last because they are multi-line displays showing each symbol leg per spread.

The overall sort is controlled via cli.py:sortQuotes()

How to Login

IBKR only exposes their trade API via a gateway application (Gateway or TWS) which proxies requests between your API consumer applications and the IBKR upstream API itself.

First download the IBKR Gateway, login to the gateway (which will manage the connection attempts to IBKR trade and data services), then have your CLI connect to the gateway.

Download Gateway

Download icli

Download icli as a new repo:

git clone https://github.com/mattsta/icli

Create your local environment:

poetry install

Even though you are logged in to the gateway, the IBKR API still requires your account ID for some actions (because IBKR allows multiple account management, so even if you are logged in as you, it needs to know which account you really want to modify).

Configure environment settings as above, confirm the IBKR Gateway is started (and confirm whether you want read-only mode or full mode in addition to noting which port the gateway is opening for local connections), login to the IBKR Gateway (requires 2fa to the IBKR app on your phone), then run:

ICLI_IBKR_PORT=[gateway localhost port] poetry run icli

You should see your account details showing in the large bottom toolbar along with a default set of quotes (assuming you have all the streaming market data permissions required).

View all commands by just hitting enter on a blank line.

View all commands by category by entering ?.

View per-command documentation by entering a command name followed by a question: limit? or lim? or exec? or pos? or cancel? etc.

If you have any doubt about how a command may change your account, check the source for the command in lang.py yourself just to confirm the data workflow.

Caveats

You should also be comfortable diving into the code if anything looks wonky to you.

System Limits

icli is still limited by all regular IBKR policies including, but not limited to:

Architecture

Entry point for the CLI is __main__.py which handles the event loop setup, environment variable reading, and app launching.

The easiest way to launch the cli is via poetry in the repository directory: poetry run icli

cli commands are processed in a prompt-toolkit loop managed by the somewhat too long dorepl() method of class IBKRCmdlineApp in cli.py.

cli commands are implemented in lang.py with each command being a class with custom argument definitions as organized by the mutil/dispatch.py system. Check out the OP_MAP variable for how command names are mapped to categories and implementation classes.

Your CLI session history is persisted in ~/.tplatcli_ibkr_history.{live,sandbox} so you have search and up/down recall across sessions.

All actions taken by the underlying IBKR API wrapper are logged in a file named icli-{timestamp}.log so you can always review every action the API received (which will also be the log where you can view any series of order updates/modifications/cancels since IBKR removes all intermediate order states of orders after an order is complete).

All times in the interface are normalized to display in US Eastern Time where pre-market hours are 0400-0928, market hours are 0930-1600, and after hours is 1600-2000 (with options trading 0930-1600, with certain etf and index options trading until 1615 every day). Futures operate under their own weird futures hours schedule, so enjoy trading your Wheat Options and Mini-sized Wheat Futures between 1900-0745 and 0830-1345.

Notable Helpers

futsexchanges.py contains a mostly auto-generated mapping of future symbols to their matching exchanges and full text descriptions. The mapping can be updated by extracting updated versions of the table of IBKR futures using generateFuturesMapping(). The reason for this mapping is when entering a futures trade order, IBKR requires the exchange name where the futures symbol lives (i.e. there's no SMART futures router and futures only trade on their owning exchange), so we had to create a full lookup table on our own.

Also note: some of the future symbol descriptions are manually modified after the automatic mapping download. Read end of the file for notes about which symbols need additional metadata or symbol changes due to conflicting names or multiplier inconsistencies (example: BRR bitcoin contract is one symbol, but microbitcoin is 0.1 multiplier, while standard is 5 multiplier, and for some reason IBKR didn't implement the micro as the standard MBT symbol, so you have to use it as BRR with explicit multiple).

orders.py is a central location for defining IBKR order types and extracting order objects from specified order types using all 20+ poorly documented, conflicting, and multi-purpose optional metadata fields an order may need.

TODO

icli is still a work in progress and future features may include:

History

This is the second trade CLI I've written (the first being a tradier api cli which isn't public yet) because I wanted faster access to scalping options during high volatility times where seconds matter for good trade executions, but navigating apps or web page entry flows wasn't being the most efficient way to place orders.

Writing an IBKR seemed a good way to create a rapid order entry system also capable of using the only public simple fee broker which offers complex exchange-side and simulated order types via API like primary peg (relative orders), mini-algos like adaptive limit/market orders, peg to midpoint, snap to market/primary/midpoint, market with protection, etc.

so here we are.

Contributions

Feel free to open issues to suggest changes or submit your own PR changes or refactor any existing confusing flows into less coupled components.

Immediate next-step areas of interest are: