cli

package
v0.31.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 21, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package cli implements the ibkr CLI's user-facing subcommands. The CLI process is stateless; each subcommand opens a Unix-socket connection to the daemon, sends one or more JSON-RPC calls, formats the response, and exits. A missing daemon is autospawned on demand by the dispatcher in cmd/ibkr.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsKnown

func IsKnown(name string) bool

IsKnown reports whether name is a registered subcommand. Used by cmd/ibkr to skip the daemon autospawn for typos and unknown commands — otherwise `ibkr nonsense` would spawn ibkrd just to fail with "unknown subcommand", which is wasteful and confusing if it tips a dormant install into a long startup.

func PreviewRenderAccount added in v0.12.3

func PreviewRenderAccount(env *Env, a *rpc.AccountResult)

Preview* expose the user-facing text renderers to the cmd/_preview tool so it can demo the visual output with synthetic fixture data — useful for screenshots, social-preview images, and README updates without touching a live account.

These are thin pass-throughs to the unexported renderers; they don't add behaviour and are not intended to be part of any stable public API. The Preview prefix and the placement in this file are the convention.

func PreviewRenderChainExpiries added in v0.12.3

func PreviewRenderChainExpiries(env *Env, r *rpc.ChainExpiriesResult, withIV bool)

func PreviewRenderChainStrikes added in v0.12.3

func PreviewRenderChainStrikes(env *Env, c *rpc.ChainResult)

func PreviewRenderHistory added in v0.12.3

func PreviewRenderHistory(env *Env, r *rpc.HistoryDailyResult)

func PreviewRenderPositions added in v0.12.3

func PreviewRenderPositions(env *Env, r *rpc.PositionsResult)

func PreviewRenderPositionsByUnderlying added in v0.12.3

func PreviewRenderPositionsByUnderlying(env *Env, r *rpc.PositionsResult)

func PreviewRenderQuoteSnapshot added in v0.12.3

func PreviewRenderQuoteSnapshot(env *Env, qs []rpc.Quote)

func PreviewRenderRegime added in v0.22.0

func PreviewRenderRegime(env *Env, r *rpc.RegimeSnapshotResult)

func PreviewRenderScan added in v0.12.3

func PreviewRenderScan(env *Env, r *rpc.ScanResult)

func PreviewRenderSize added in v0.12.3

func PreviewRenderSize(env *Env, r *SizeResult)

func PreviewRenderStatus added in v0.12.3

func PreviewRenderStatus(env *Env, h *rpc.HealthResult)

func PrintUsage

func PrintUsage(w io.Writer)

PrintUsage writes the top-level help text. The subcommand list is followed by global hints — most importantly the per-command --help pointer, since users discovering the tool need to know that every subcommand has its own flag list.

func Run

func Run(ctx context.Context, env *Env, cmd string, args []string) int

Run dispatches the subcommand named by cmd. Returns the process exit code.

Args are reordered so all flags come before positional arguments — Go's flag package stops at the first non-flag token, but users naturally write `ibkr quote AAPL --json` rather than `ibkr quote --json AAPL`.

On an unknown subcommand we print the full top-level usage to stderr, not just the bare hint, so a user who typo'd or guessed wrong sees the real list of verbs immediately. Pattern matches git/kubectl/gh.

func ShouldColor

func ShouldColor(w io.Writer) bool

ShouldColor reports whether ANSI color escapes should be emitted to w. Policy, in order:

  1. IBKR_COLOR=always → on (overrides TTY check)
  2. IBKR_COLOR=never → off
  3. NO_COLOR set (any) → off (https://no-color.org)
  4. w is a character device (interactive terminal) → on
  5. otherwise → off (pipes, file redirects, bytes.Buffer in tests)

Computed once per process and cached on Env.Color so colored renderers don't re-syscall on every value.

Types

type Command

type Command struct {
	Name    string
	Summary string
	Usage   string // optional one-line usage example shown in `ibkr X --help`
	Fn      CommandFunc
}

Command bundles a subcommand's name, one-line summary, optional usage example, and handler. One slice — single source of truth for both the dispatcher and the help table. `status` is listed first because users hitting any other command without a healthy gateway will be redirected here by the gateway_unavailable hint.

func Commands

func Commands() []Command

Commands returns the registered subcommand entries in declaration order. Exported so the MCP server's parity test can assert that every CLI command has an MCP tool counterpart (or is on the documented exclude list).

type CommandFunc

type CommandFunc func(ctx context.Context, env *Env, args []string) int

CommandFunc is the signature implemented by every subcommand handler.

type Env

type Env struct {
	Stdout io.Writer
	Stderr io.Writer
	Conn   *dial.Conn
	// Color is true when ANSI color escapes should be emitted on Stdout.
	// Computed once in main.go via ShouldColor(Stdout) so renderers don't
	// re-syscall stat() per value. Defaults to false in tests (Stdout is
	// usually a *bytes.Buffer), keeping golden-substring assertions stable.
	Color bool
}

Env is the per-invocation context shared by every subcommand.

type SizeInput

type SizeInput struct {
	Symbol      string
	Side        string  // "long" | "short"
	Entry       float64 // quote currency
	Stop        float64 // quote currency
	Target      float64 // optional take-profit; 0 disables the R block
	RiskPct     float64 // percent of NLV; (0, 100]
	Lot         int     // round shares down to this multiple; >= 1
	FX          float64 // quote-currency units per 1 base-currency unit; > 0
	NLV         float64 // base currency
	BuyingPower float64 // base currency (0 disables BP check)
	Currency    string  // base currency code, surfaced in output only
}

SizeInput is the validated input to ComputeSize. Fields mirror the CLI flags one-for-one so the pure function is testable without the runner.

Target is optional. When set, ComputeSize derives the R-multiple (reward-to-risk ratio = profit-to-stop distance / entry-to-stop distance) and the breakeven win rate. Long trades require target > entry; short trades require target < entry.

type SizeResult

type SizeResult struct {
	Symbol           string   `json:"symbol"`
	Side             string   `json:"side"`
	Entry            float64  `json:"entry"`
	Stop             float64  `json:"stop"`
	Target           *float64 `json:"target,omitempty"`
	RiskPct          float64  `json:"risk_pct"`
	Lot              int      `json:"lot"`
	FX               float64  `json:"fx"`
	NLV              float64  `json:"nlv"`
	BaseCurrency     string   `json:"base_currency,omitempty"`
	RiskBase         float64  `json:"risk_base"`  // NLV * pct/100
	RiskQuote        float64  `json:"risk_quote"` // RiskBase * fx
	PerShareRisk     float64  `json:"per_share_risk"`
	Shares           int      `json:"shares"`
	Notional         float64  `json:"notional"`    // shares * entry
	MaxLoss          float64  `json:"max_loss"`    // shares * per_share_risk (quote ccy)
	R                *float64 `json:"r,omitempty"` // (|target-entry|) / (|entry-stop|)
	RewardQuote      *float64 `json:"reward_quote,omitempty"`
	RewardBase       *float64 `json:"reward_base,omitempty"`
	BreakevenWinRate *float64 `json:"breakeven_win_rate,omitempty"` // 1 / (1+R), fraction
	Status           string   `json:"status"`                       // "ok" | "tight_risk" | "exceeds_buying_power"
}

SizeResult is the wire shape of `ibkr size --json` and the input to the text renderer. Keep this struct stable — Claude consumes it.

Target / R / RewardQuote / RewardBase / BreakevenWinRate are populated only when the input carries a non-zero Target. R is the reward-to-risk ratio (|target − entry| / |entry − stop|), the canonical "is this trade worth taking" filter; ≥ 2R is the common discretionary threshold. BreakevenWinRate is 1 / (1 + R) — at this win rate the strategy breaks even, so any sustained edge above it is profitable.

func ComputeSize

func ComputeSize(in SizeInput) (SizeResult, error)

ComputeSize is the pure sizing function. All validation lives here so the runner stays a thin wiring layer; tests cover the math and the validations without spinning up a daemon. Exported because the MCP server reuses it for the ibkr_size tool — the daemon has no size RPC; sizing is account-snapshot + local arithmetic.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL