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 Scout 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 Scout 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:

  • Equity: AAPL, SPY
  • Crypto: BTC.USD, ETH.USD (PAXOS venue)
  • Options: SPY/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 Scout, 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.