Reference

Brokerages

.md

Link a brokerage to run your strategies against real (or paper) markets. Credentials stay on your machine — written to a local auth file, never leaving the CLI.

Supported brokerages

Alpaca
US equities and USD-quoted crypto. Paper and live endpoints. Crypto symbols like BTC-USDT are auto-normalized to BTC/USD. Taker fee modeled at 0.25%.
Binance
Crypto spot via testnet or live. Quotes default to USDT. Taker fee modeled at 0.1%. No futures.
Interactive Brokers (IBKR)
Equities, crypto (via PAXOS), options, and futures. Paper or live. Connects to TWS / IB Gateway over a local socket via ib_insync.
Polymarket · Questrade
Reserved in the broker registry; adapters not yet implemented.

The brokerage picker

finny_brokerage_switch selects the active broker and persists it to brokerage.json. It also auto-switches on asset-class mismatch — ask for an equity strategy while Binance is active and Finny moves the active broker to Alpaca or IBKR, whichever is connected. The TUI brokerage capsule reflects the change within ~1s.

For any canonical symbol, BrokerRegistry.compareForSymbol(symbol) returns every broker's support status, native symbol format, taker fee, and connected accounts — used by the picker to route intelligently.

Connecting a brokerage

There's no /connect command — accounts are added from the TUI. Open /portfolio and choose Add account, or open /settings Paper Trading. Pick the broker from the segmented control and fill in the dialog.

Alpaca

Fields prompted in the Add Account dialog:

Label       my-alpaca-paper
Key ID      ********************************
Secret      ****************************************
Endpoint    https://paper-api.alpaca.markets   # or live URL

Or set via environment variables (read at runtime if no saved account is selected):

bash
export ALPACA_API_KEY_ID="..."
export ALPACA_API_SECRET_KEY="..."
export ALPACA_ENDPOINT="https://paper-api.alpaca.markets"
export ALPACA_PAPER="true"

Requires alpaca-py>=0.30, which Finny installs into its managed Python venv on first use.

Binance

Fields prompted in the Add Account dialog:

Label        my-binance-testnet
API key      ********************************
API secret   ****************************************

No endpoint field — testnet is hardcoded in the UI today. Env-var fallback:

bash
export BINANCE_API_KEY="..."
export BINANCE_API_SECRET="..."
export BINANCE_TESTNET="true"

Powered by ccxt>=4 with set_sandbox_mode(True) for testnet routing.

Interactive Brokers

Native IBKR support connects to TWS or IB Gateway over a local socket via ib_insync. Paper port 7497, live port 7496 — auto-detected from the mode you pick. Choose a portfolio from the live/paper picker after the connection is established.

Symbol formats:

  • EquityAAPL, SPY
  • CryptoBTC.USD, ETH.USD (PAXOS venue)
  • OptionsSPY/20260619/500C (underlying/expiry/strike+side)
  • Futures (specific)ES/202612
  • Futures (continuous)ES/CONT (auto-rolls front month)
Futures require explicit qty
IBKR futures are margin-based, so default all-cash buys are refused. Pass an explicit qty when placing futures orders.

Where credentials live

All saved accounts are written to a single XDG auth file:

~/.local/share/finny/auth.json   (mode 0600, plaintext JSON)

Each entry is keyed by provider — e.g. alpaca-paper-…, binance-testnet-… — and stores key, secret, label, and (for Alpaca) endpoint. There is no OS keychain integration today; the file is plaintext with restrictive permissions, so treat your machine as the trust boundary.

How strategies use a connection

Generated strategies are plain Python files that receive a broker instance from Finny — you don't import or instantiate it yourself. The same strategy runs unchanged against Alpaca or Binance.

python
def run(broker):
    if not broker.market_is_open("BTC/USD"):
        return

    bar = broker.fetch_bar("BTC/USD", interval="1h")
    cash = broker.cash()

    if bar.close > bar.open and broker.position("BTC/USD") == 0:
        broker.buy("BTC/USD", notional=cash * 0.1)

Available methods on the injected broker:

buy(symbol, qty=None, notional=None)
sell(symbol, qty=None, notional=None)
position(symbol)
cash()
equity()
price(symbol)
fetch_bar(symbol, interval)
market_is_open(symbol)

Managing connections

All management lives in /settings Paper Trading:

  • List every saved account, with its broker and label.
  • Remove an account with the per-row Remove button — credentials are wiped from auth.json.
  • Reset the managed Python environment if backtest / live runs start failing after a dependency change.

Connections are validated implicitly — the broker SDK is exercised when the account is added, so invalid keys fail fast.

Things worth knowing
  • First run installs alpaca-py / ccxt into ~/.local/share/finny/python-env/ — expect a 30–60s cold start. Resettable from Settings.
  • auth.json is plaintext (0600, no keychain). Don't sync it. When generating API keys, disable withdrawals and IP-restrict where the broker supports it.
  • Binance is spot-only in the current UI — no futures.
  • IBKR requires TWS or IB Gateway running locally with API access enabled (Edit → Global Configuration → API → Settings).
  • Alpaca crypto is USD-quoted only; BTC-USDT auto-rewrites to BTC/USD.