Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Docs for the development version; the latest release is v0.8.1.

Commands Reference

stockwise --help lists every command by group; stockwise <command> --help shows its arguments. This page adds detail.

Looking for a walkthrough instead? What do you want to do? lists task-based guides, and each section below links to its guide.

Global options

OptionEnv varDescription
-m, --market <MARKET>STOCKWISE_MARKETMarket for bare tickers. Default in: TCS → TCS.NS. us: AAPL. crypto: BTC → BTC-USD; BTC/USD, BTC_USD and BTC USD also resolve to BTC-USD. fx (or forex): USDINR, usd/inr → USDINR=X. commodity: GOLD → GC=F, SILVER → SI=F, other bare tickers → NSE (GOLDBEES → GOLDBEES.NS). Global exchanges from the market table: uk (VOD → VOD.L), de (SAP.DE), jp (7203 → 7203.T), hk (5 → 0005.HK), sg (D05.SI), ca (RY.TO), au (BHP.AX). Symbols with a suffix (RELIANCE.BO, VOD.L), indices (^NSEI), FX (USDINR=X), futures (GC=F) and crypto pairs (BTC-INR) pass through unchanged
--quote-currency <CODE>STOCKWISE_QUOTE_CURRENCYCurrency bare crypto tickers are quoted in with -m crypto. Default usd; inr gives BTC-INR
--lang <en|hi>STOCKWISE_LANGLanguage for help groups, tables and messages. Default: your locale (LC_ALL / LC_MESSAGES / LANG starting with hi picks Hindi), else English. --json and --csv output is never translated
--aiSTOCKWISE_AIAdd an AI section to analyze, technical, compare, screen, backtest, deep (slow with a local model; see ai.md)
--no-aiTurn the AI section off for one run, even if STOCKWISE_AI or the config file turn it on
--portfolio <NAME>STOCKWISE_PORTFOLIOUse a named portfolio (portfolios/NAME.json) instead of the default portfolio.json. Applies to portfolio, import, tax, wealth, dashboard, trade holdings and every other command that reads holdings
--profile <MODE[:RISK]>STOCKWISE_PROFILEInvestor profile mode (passive, active, active:low, active:med, active:high, ultra) and personal guardrails

Other environment variables: STOCKWISE_HOME (data directory), STOCKWISE_REDIS_URL (cache server, or off), STOCKWISE_DATA_PROVIDER and its API key (data-providers.md), STOCKWISE_AI_PROVIDER, STOCKWISE_MODEL, OLLAMA_HOST and the cloud AI keys (ai.md), STOCKWISE_CONFIG (config file path), STOCKWISE_BIND and STOCKWISE_API_TOKEN (serve), and the notification variables (bots.md). NO_COLOR disables colour; colour is also off when output is piped.

Defaults for most of these, and for each command’s -p, can live in a config file. Precedence: command-line flag > environment variable > config file > built-in default. API keys and the server token are read from the environment only.

Crypto and FX: prices show with the precision they need (FX pairs 4 decimals, coins under 1 up to 8) and quote notes trading hours (crypto 24/7; FX 24 hours Monday–Friday, closed at weekends). Commands built on exchange sessions, sectors or fundamentals — sectors, rotation, sectorcmp, screen, picks, matrix, surprise, peers, intraday, longterm, daemon, sim start — refuse -m crypto / -m fx with an explanation; movers, heatmap, history, technical, backtest and friends work.

Global exchanges (-m uk|de|jp|hk|sg|ca|au): quotes, history, charts, technicals, movers (each exchange’s large caps), markets and alerts work as for India and the US. Prices show in the local currency (£, €, ¥, HK$, S$, C$, A$); London quotes in pence, so VOD.L shows 118.20p while its market cap shows in pounds. sectors, rotation and sectorcmp need sector indices or ETFs, which Yahoo has for Japan (TOPIX-17 ETFs), Hong Kong, Canada and Australia only. Sessions, lunch breaks, half days and holidays come from each exchange’s calendar (markets.md). tax has rules for India, the US and the UK only, and names the other listings it leaves out. Backtest costs default to the US model outside India. The bots and the simulator (intraday, longterm, daemon, sim start, sim replay, sim challenge, report) size positions from the capital you type, so they refuse -m uk, whose prices are in pence; replays on other exchanges use their main index as the benchmark.

Commodities (-m commodity): GOLD/SILVER resolve to COMEX futures, so history gold, chart silver, technical gold and alert add gold above 4200 work; commodity and bonds have their own commands (below).

Hindi (--lang hi): help group titles and the main command descriptions, quote, markets, dashboard, portfolio, search and doctor labels, and common errors. Other commands are still English. Indian amounts keep lakh/crore grouping (₹16.27 लाख करोड़).

Periods (-p): 1d, 5d, 1w (same as 5d), 1mo, 3mo, 6mo, ytd, 1y, 2y, 5y, 10y, max. Value names (screen growth, tax in, -s macd) are case-insensitive.

Exit codes: 0 success, 1 runtime error (unknown symbol, no data, network, invalid config file), 2 invalid arguments.

Machine-readable output: commands marked [--json] print JSON, and [--json\|--csv] print JSON or CSV, instead of a table. See Scripting.

Start here

Guide: Quickstart: five minutes walks through the first commands.

stockwise SYMBOL with no command prints a one-screen overview, and bare stockwise prints a quick start. Short names: q (quote), d (dashboard), a (analyze), t (technical), c (compare), p (portfolio), w (watch), ev (events). The aliases are lowercase: a capital single letter is a ticker, so stockwise C -m us (Citigroup), T, D, A and W work as bare symbols, and stockwise c TCS INFY still compares. A longer ticker that spells a command, such as ALL or PATH, is a symbol when you give -m (stockwise PATH -m us). stockwise quote C -m us always works. Common names resolve to NSE symbols (SBI → SBIN, L&T → LT, index names), and quote suggests close matches for a mistyped symbol.

CommandDescription
quote <SYMBOLS...> [--json|--csv] (q)Price, change, day/52-week range, volume, market cap, P/E, EPS, moving averages. Unknown symbols are named in the error
deep <SYMBOL> [-p PERIOD]Everything about one stock: fundamentals, technicals, support/resistance, Fibonacci, risk, gaps, volume, insights. Default 3mo
markets [--crypto] [--fx] [--global] [--json|--csv]US + India indices (S&P 500, Dow, NASDAQ, Russell, VIX, NIFTY 50, SENSEX, Bank NIFTY, NIFTY IT) and the India 10-year G-sec yield (CCIL, RBI fallback; left out when neither answers); --crypto adds the largest coins, --fx major pairs (USD/INR, EUR/USD, …), --global one row per exchange’s main index (NIFTY 50, S&P 500, FTSE 100, DAX, Nikkei 225, Hang Seng, Straits Times, S&P/TSX, S&P/ASX 200) with whether it is open and its local time. With -m crypto, -m fx, -m commodity or a global exchange that section comes first. --json rows carry region: Indian Markets, US Markets, Crypto, FX, Commodities, a country (United Kingdom, Japan, …) or Global
dashboard (d)Indices + portfolio P&L + watchlist + triggered alerts; first-run hints when empty
search <QUERY> [--json|--csv]Find a ticker by company name
doctorCheck the config file, market and language, data directory, Yahoo reachability, the data provider that answered, Redis, AI provider and model (never the key), broker config. Exits 1 if market data is unreachable or the config file is invalid

Analysis

Guide: Check a stock or fund fast.

CommandDescription
analyze <SYMBOL> (a)Valuation, profitability, growth, analyst ratings, plain-English outlook
results <SYMBOL> [--quarters N] [--annual] [--json|--csv]Last 8+ quarters side by side: revenue, operating profit, OPM %, other income, interest, depreciation, PBT, tax %, PAT, diluted EPS, YoY %, QoQ %, OPM change in bps, a TTM column, and EPS against consensus with the 1-day and 5-day move versus the index. Banks add NII and GNPA/NNPA. --annual shows fiscal years with CFO/PAT, FCF, ROE, ROCE and 3/5/10-year CAGR. Needs no key; results are kept in cache.db for six hours
results --holdings / --universe nifty50 [--sort date|pat|margin|surprise]Earnings-season scoreboard: how many companies reported the active quarter, aggregate revenue, operating profit and PAT growth YoY, beat / in-line / miss counts, and the reporters table
events <SYMBOL> [--days N] [--ai] (ev)Unified timeline of material corporate events, exchange filings, earnings results, and excess market reaction vs NIFTY/S&P 500
insights <SYMBOL>Positive, negative and neutral findings (Growth, Valuation, Margins, Ownership, etc.) with quantified metrics and XBRL shareholding patterns
verdict <SYMBOL> [--explain] [--json]6-pillar score: valuation (20%), growth & profitability (25%), balance sheet (15%), smart money & ownership (15%), analyst consensus (10%) and technical trend (15%). Each pillar gets 0–100 and a Strong / Moderate / Weak band, or “no data” when its inputs are missing; the composite (0–100) leaves “no data” pillars out and data_coverage says how much of the input was present. Crypto, FX and indices get only the technical pillar. Size cut-offs (cash, insider trades; market cap in longterm) are written in US dollars and amounts in other currencies are converted at rough fixed rates, so the same size scores the same in rupees and dollars. A description of the data, not a recommendation; --explain lists the weights and rules
score <SYMBOL> [--json] [--explain] (scorecard, fundamental score)Transparent accounting scorecards. Piotroski F-Score (2000): nine yes/no signals, most of them this year against last year. A signal whose data is missing shows n/a, earns no point and is not counted, so the score reads like 5/7 evaluated; it is rated only when all nine ran. Net income is estimated from trailing EPS × shares, or margin × revenue, only when no period reports it, and is marked (est.). Altman Z (1968): needs all five ratios; with any missing it shows n/a and names them, with no zone, and no input is guessed. Altman Z’’ (1995, non-manufacturers) uses book equity over liabilities and is shown with its own factor table whenever X1–X4 exist. In --json: piotroski.evaluated and criteria[].evaluated (piotroski.rating is null when not rated), altman.missing_factors, altman.z_double_prime_components and altman.z_double_prime_formula_str
technical <SYMBOL> [-p] [--json] [--explain] (t)RSI, MACD, Bollinger Bands, ATR, VWAP, SMA/EMA, braille charts. Default 3mo
history <SYMBOL> [-p] [--json|--csv]Braille price chart, volume bars, last 20 bars. --json/--csv emit every OHLCV bar. Default 1mo
chart <SYMBOL>1W, 1M, 3M and 1Y charts at once
compare <SYMBOLS...> [--json|--csv] (c)Two or more stocks side by side across 16 metrics
risk <SYMBOL> [-p] [--json]Annualized volatility, Sharpe/Sortino/Calmar, max drawdown, VaR 95/99% — always from daily bars, annualized with 252 bars a year for stocks and indices, 365 for crypto and 260 for FX. Default 1y
correlate <SYMBOLS...> [--json|--csv] (corr)Correlation matrix of daily returns (two or more symbols), from the days both traded, so NSE, NYSE and crypto calendars line up; null/N/A when two symbols share fewer than 20 returns
timeframes <SYMBOL> (mtf)1M–5Y return, volatility, RSI, SMA/MACD signals
returns <SYMBOL> [--json|--csv]1W–5Y returns. The annualized figure (CAGR) uses the calendar time between the first and last bar, and is shown only for spans of a year or more (null otherwise)
patterns <SYMBOL> [-p]Candlestick patterns (doji, hammer, engulfing, morning star)
support <SYMBOL> [-p]Pivot points (R1–R3, S1–S3) from the last completed daily session (named on screen), whatever -p is, + Fibonacci levels
fibs <SYMBOL>Fibonacci retracement with a “you are here” marker, for the last 21, 63 and 126 trading days (1, 3 and 6 months of daily bars). Always reads a year of daily bars; -p is accepted but ignored
volume <SYMBOL> [-p] (vol)OBV, A/D line, volume ratio, volume bars
gaps <SYMBOL> [-p]Filled and unfilled price gaps
stoploss <SYMBOL> [-e PRICE] [--capital AMT] [--risk-pct PCT] [-p]ATR (1.5x/2x/3x), percentage and Chandelier stops, position sizing (shares and position value for risk budget) and R:R targets
forecast <SYMBOL> [-d DAYS] [-p]Linear trend projection with 95% bands — a projection, not a prediction

--explain on verdict, technical, score and options oi adds plain-English notes for beginners.

Market

Guide: Check a stock or fund fast.

CommandDescription
movers [--universe INDEX] [--cap TIER] [--json|--csv]Top gainers and losers among 30 large caps, or an NSE index’s members (see below), with a cap-tier column
sectors [--json|--csv]Sector ETF/index performance with bars
heatmap [--universe INDEX] [--cap TIER]Heatmap of the 30-stock universe, or an NSE index’s members
sentimentFear & Greed style gauge from VIX, momentum and trend
news <SYMBOL>Headlines collated from Yahoo Finance and Google News
rotationSector rotation vs 50-day average
sectorcmp <SECTOR1> <SECTOR2>Two sectors head to head
peers <SYMBOL>Same-sector peers on P/E, P/B, market cap
insider <SYMBOL>Analyst consensus + insider-related news
ipo [SYMBOL] [--board all|mainboard|sme] [--capital 2.5L] [--recent N] [--json]Indian IPOs from NSE. Without a symbol: the live board of issues open now, upcoming and recently listed (price band, lot, minimum application, QIB/NII/retail subscription, a demand label such as “STRONG DEMAND” or “BOOK BUILDING”) and an IPO-market regime. With a symbol or company name: issue structure (fresh vs OFS, anchor, lead managers), subscription by category with the mutual-fund share of QIB demand, demand by price, SEBI allotment odds for retail, sNII and bNII (with --capital, the odds at that amount, including for several separate applications), unofficial GMP and broker calls from press headlines, and a 6-pillar score with a listing demand label and a long-term profile label. In --json: listing_demand, long_term_profile and timeline replace listing_verdict, long_term_verdict and timing_guidance; capital_odds and allotment_rules replace capital_plan and golden_rules. Not a recommendation
earningsEarnings growth for portfolio and watchlist
surpriseEarnings momentum — accelerating vs decelerating
matrixQuality vs growth quadrants
picksThe highest-scoring large caps on 8 fundamental and technical factors, with the factors that raised each score. A score, not a recommendation
screen <CATEGORY> [--universe INDEX] [--cap TIER] [--json|--csv]undervalued (P/E<15), growth (forward EPS > trailing), dividend (yield>2%), momentum (top gainers), bluechip (>$100B / >₹5L Cr)
dividends <SYMBOL> [--json]Yield, income projection, 10-year DRIP growth

--universe (Indian market): scan the current members of an NSE index instead of the built-in 30 large caps — nifty50, niftynext50 (next50), nifty100, banknifty (niftybank), niftyit, nifty500, midcap150 or smallcap250. NSE’s website lists the members and prices them in one bulk request (all 500 of nifty500), whichever data provider you use. movers and heatmap rank from that snapshot alone, so they work when Yahoo Finance is unreachable; screen needs P/E and market cap too, so it asks Yahoo for them and falls back to the snapshot (no P/E or market cap) when Yahoo fails. Every scan also saves the prices into cache.db (market_snapshots) and the index members for the cap tiers below. When NSE can’t be reached or refuses, StockWise says so on stderr and scans a built-in list instead (the 30 large caps for nifty50 / nifty100, a built-in member list for banknifty and niftyit); niftynext50 has no built-in list and fails with the reason.

Cap tiers (mega, large, mid, small, micro): a badge such as [Large] next to the market cap in quote, deep, analyze and compare (and a Cap column in movers, screen and portfolio), and a cap_tier field in their --json / --csv (unknown when there is no market cap, or no exchange rate for the currency). Indian stocks follow the SEBI/AMFI ranks when the index members are known: NIFTY 100 is large (the top 10, or above ₹5,00,000 Cr, is mega), NIFTY MIDCAP 150 is mid, NIFTY SMALLCAP 250 is small and anything outside NIFTY 500 is micro. Scanning those indexes with --universe saves their members (cap_membership.json in the data directory); until then, and offline, rupee cut-offs decide (large from ₹1,00,000 Cr, mid from ₹33,000 Cr, small from ₹10,000 Cr). Every other market converts the market cap to dollars at the built-in approximate rates (London pence GBp and Japanese yen JPY included): mega from $200B, large from $10B, mid from $2B, small from $300M. A display and filtering aid, not a regulatory classification.

--cap all|mega|large|mid|small|micro keeps one tier in movers, heatmap and screen. With a tier, -m in and -m us scans read fresh (under 30 minutes old) market_snapshots rows from cache.db when cache warm or the worker has stored most of the market’s list, with no request at all; otherwise they scan live. There is no per-sector drilldown command yet, so --cap has nothing to filter there.

Funds & F&O

Guide: Check a stock or fund fast covers funds and SIP returns.

CommandDescription
mf search <QUERY...> [-n N] [--json]Find Indian mutual-fund schemes by words in the name, fund house, category or ISIN; add direct growth to narrow. Shows the AMFI scheme code the other mf commands take
mf nav <CODES...> [--json]Latest NAV and date, fund house, category, ISINs, and the plan’s expense ratio (TER) with the other plan’s for comparison
mf history <CODE> [-p PERIOD] [--json]NAV chart for the period (default 1y), expense ratio (TER), trailing 1M–10Y returns (annualized from 1Y), since-inception CAGR, max drawdown. --json includes every NAV in the period
mf sip <CODE> <AMOUNT> [-p PERIOD] [--json]Monthly SIP from NAV history (default 5y): value-vs-invested chart, gain, units, and XIRR on the actual purchase dates
mf screen [CATEGORY...] [--plan direct|regular|all] [-s 1y|3y|5y|ter] [--max-ter PERCENT] [-n N] [--max N] [--json]Bare: list categories with their active scheme counts. With words (flexi cap, elss, liquid, equity etf): rank the category’s growth-option schemes by return (default 3Y CAGR, direct plans) or by expense ratio (-s ter, lowest first — with more matches than --max, the cheapest are screened), with a TER column. --max-ter 1.0 keeps only funds whose disclosed TER is at most 1%
mf bleed [--return PERCENT] [--json]Held Regular-plan funds vs their Direct growth twin: TER gap (AMFI disclosure), yearly rupee cost, 10-year compounded cost at a stated gross return, units that redeem tax-free inside the unused Sec. 112A exemption, and breakeven months for younger units
mf overlap <A> <B> [--json]Shared top holdings, holdings and sector overlap, and expense ratios of two funds or ETFs, e.g. mf overlap SPY QQQ -m us
options chain <SYMBOL> [-e DATE] [-n STRIKES] [--rate %] [--div-yield %] [--json]Calls and puts around the money: last price, open interest (and change on NSE/BSE), volume, IV, delta, gamma, theta, vega, rho, and the lot size. Default: nearest expiry, 10 strikes each side (-n 0 for all)
options pcr <SYMBOL> [-e DATE] [--json]Put/call ratio by open interest and by volume, and the three strikes with the most call and put open interest
options oi <SYMBOL> [-e DATE] [-n N] [--json] [--explain] (open-interest, fno oi)Open-interest analytics: PCR, Max Pain, top call resistance and put support walls with institutional build-up classification (LB, SC, SB, LU), and aggregate volume breakdown. Sentiment is read for the underlying: put buying (LB on a put) is bearish and put writing (SB) is bullish; --json carries calls_sentiment and puts_sentiment
options maxpain <SYMBOL> [-e DATE] [--json] (max-pain)The settlement strike at which open options pay their holders least, with the payout curve around it
options payoff <SYMBOL> [--leg LEG]... [-s PRESET] [-w WIDTH] [-e DATE] [-l LOTS] [--lot-size N] [--rate %] [--div-yield %] [--iv %] [--today] [--json]A multi-leg position priced from the live chain: legs with price source, IV and delta; net debit/credit; max profit and loss (or “unlimited”); breakevens; probability of profit; position greeks; and a braille P/L chart at expiry (green/red), plus today’s curve with --today. Analysis only — no orders
options <SYMBOL> [-p] / options moves <SYMBOL> [-p]Expected 1/5/10/30-day moves and OTM strike ideas from realized volatility

MF periods (-p) are <n>mo, <n>y or max, e.g. 6mo, 3y, 10y. Expiries (-e) are YYYY-MM-DD.

options payoff legs and presets

  • A leg is buy|sell [QTY] call|put STRIKE [@PRICE] or buy|sell [QTY] stock [@PRICE]: --leg "buy call 24500" --leg "sell call 24800", --leg "sell 2 put atm-1", --leg "buy stock @2450". STRIKE is a listed strike, or atm, atm+N, atm-N (N listed strikes from the money). An unlisted strike is an error that names the nearest listed ones.
  • Prices: the bid/ask mid where both are quoted, else the last trade (flagged ltp — it can be stale), else the leg needs @PRICE. A stock leg is priced at the current underlying value (for an index that stands in for the future).
  • Presets around the at-the-money strike, W = --width (default two strike steps; a strike that isn’t listed snaps to the nearest one, with a note): bull-call (buy ATM call, sell ATM+W), bear-put (buy ATM put, sell ATM−W), straddle (buy ATM call and put), strangle (buy ATM−W put and ATM+W call), iron-condor (sell ATM±W, buy ATM±2W wings — a credit), butterfly (buy ATM±W calls, sell two ATM calls), covered-call (stock at spot, sell ATM+W call). --strategy and --leg combine.
  • Sizes: every amount is per position — per-unit P/L × lot size × --lots. Lot sizes come from the chain (NSE/BSE order-book quantities are whole lots; US contracts are 100 shares). After hours BSE shows no order book: pass --lot-size, otherwise amounts are per unit and the output says so.
  • Probability of profit: the chance the expiry price lands where P/L > 0 if the price is lognormal with the at-the-money IV (or --iv) and risk-neutral drift. It is a model, not a forecast. Costs (brokerage, STT, exchange charges) are not included. StockWise never places orders from this command.

Where the data comes from, and what has none

  • NAVs: AMFI’s public NAVAll.txt, every Indian scheme, cached in the data directory (cache/) and re-downloaded after 12 hours. NAV history: api.mfapi.in, a free community mirror of AMFI data, cached the same way. If a download fails, a stale cached copy is used with a warning on stderr.
  • Returns are point-to-point NAV returns of the growth option, before tax and exit load. mf sip buys at the first NAV on or after each monthly due date.
  • Expense ratios (TER): AMFI’s monthly TER disclosure (amfiindia.com/ter-of-mf-schemes), fetched from the API behind that page as one spreadsheet export for the month (/api/populate-te-rdata-revised?MF_ID=All&Month=MM-YYYY&strCat=-1&strType=-1&excel=true, ~3 MB; the previous month if the current one isn’t published yet). It lists each scheme’s TER per day for the regular and direct plan — from April 2026 split into base expense ratio, brokerage, transaction costs and statutory levies. StockWise keeps each scheme’s latest day, caches the result in cache/amfi_ter.json for a day, and uses a stale copy with a warning if AMFI is unreachable. The disclosure has no AMFI scheme code, so schemes are joined on their name (case and punctuation ignored); a plan the scheme doesn’t offer (AMFI writes 0) has no TER. When TERs can’t be loaded, mf nav/history/screen still print NAVs and returns with a note; --sort ter and --max-ter fail instead. In JSON, ter holds plan, total, the breakdown, both plans’ totals and the disclosure date, as fractions (null when not disclosed). mf overlap shows Yahoo’s expense ratio for the funds it covers.
  • Holdings (mf overlap) come from Yahoo Finance, which publishes the top 10 holdings and sector weights for US ETFs and mutual funds (SPY, QQQ, VTI, VFIAX, … with -m us) and for some funds under Yahoo’s 0P… IDs. NSE-listed ETFs such as NIFTYBEES and AMFI scheme codes have no holdings data — StockWise says so instead of guessing. With only the top 10 known, the holdings overlap is a lower bound; sector weights cover the whole fund.
  • Option chains: in the Indian market (the default), NSE’s public option-chain API — index options on NIFTY, BANKNIFTY, FINNIFTY, MIDCPNIFTY and NIFTYNXT50 (^NSEI and ^NSEBANK work too) and NSE F&O stocks such as RELIANCE. NSE serves browser sessions only: StockWise loads its option-chain page once for cookies, makes two API calls, and stops with a clear error if NSE refuses — wait a minute and retry. SENSEX, BANKEX and SENSEX50 (also ^BSESN, BSE-BANK.BO) and BSE stock options as SYMBOL.BO come from BSE’s derivatives API, the one behind bseindia.com’s option-chain page: one session, calls 400 ms apart, answers cached for a minute in cache/, no retries. BSE’s site sometimes refuses scripted requests (HTTP 403) — StockWise then says so; wait and retry, or use the website. BSE stock options are rarely traded. With -m us, Yahoo Finance (delayed quotes) for US stocks and ETFs.
  • Lot sizes: NSE and BSE quote order-book quantities in whole lots, so the lot is their greatest common divisor across the chain (with at least five quotes; a divisor of 1 counts as unknown); US contracts are 100 shares. options chain shows it and --json has lot_size (null when unknown).
  • IV and greeks: Black-Scholes-Merton. IV is solved from the bid/ask mid (else the last trade) at the data timestamp; when that fails, the source’s IV is shown (iv_from in JSON). Risk-free rate defaults to 6.5% (India) / 4.0% (US) — pass --rate with the current T-bill yield. Theta is per calendar day, vega and rho per percentage point. NSE options are European; US equity options are American, so their greeks are the usual European approximation.
  • PCR and max pain describe positioning for one expiry; they are not forecasts.

Commodities & bonds

CommandDescription
commodity [--json|--csv] / commodity spotGold and silver in USD per troy ounce and in ₹ per gram, per 10 g (gold) and per kg (silver), with the day’s change. ₹ prices are international prices converted at USD/INR — before Indian import duty and GST
commodity futures [--json|--csv]COMEX gold and silver futures (GC=F, MGC=F, SI=F, SIL=F) with the front contract month and volume
commodity etfs [--json|--csv]Gold and silver ETFs on NSE: GOLDBEES, SETFGOLD, HDFCGOLD, GOLDIETF, GOLD1, GOLDCASE, SILVERBEES, SILVERIETF, HDFCSILVER, SILVER1
commodity sgb [--json|--csv]Sovereign Gold Bonds trading on NSE: price per unit (1 g), premium or discount to 1 g of gold at the international spot price, current yield of the 2.5% interest, maturity and volume
bonds [--json|--csv] / bonds yieldsBenchmark yields by tenor — 91/182/364-day T-bills, G-secs from 1–2 to 28–30 years (India 10Y = the 9Y–10Y bucket) and state loans (SDLs)
bonds list [QUERY] [--json|--csv]Government of India securities outstanding: ISIN, name, maturity, NSE symbol, outstanding stock. QUERY is a maturity year (2033), part of a name (GS 2036), an ISIN or an NSE symbol
bonds calc [SECURITY] (--price P | --ytm Y) [--coupon C --maturity DATE] [--settle DATE] [--dirty] [--tbill] [--json]Price ↔ yield to maturity, accrued interest, dirty price, current yield, Macaulay and modified duration, next coupon. SECURITY (718GS2033, "7.18% GS 2033", IN0020230085) is looked up in RBI’s list for its coupon and maturity; or give --coupon and --maturity. --dirty: the price includes accrued interest (NSE quotes G-secs that way). --tbill: a Treasury bill, priced on its discount yield. Settlement defaults to today in India

Where the data comes from, and what has none

  • Gold and silver spot: Yahoo Finance has no free spot quote, so spot is the COMEX front-month future (GC=F, SI=F, USD per troy ounce) converted at USDINR=X (1 troy ounce = 31.1035 g). It excludes Indian import duty and GST, so jewellers’ rates, IBJA rates and MCX prices are higher.
  • MCX futures have no free public feed (MCX’s site is bot-protected and its data is licensed), so StockWise shows COMEX contracts and labels them.
  • ETFs are NSE listings via Yahoo, in ₹ per unit; each ETF holds a different amount of metal per unit, so compare % moves, not prices.
  • SGB prices come from NSE’s Sovereign Gold Bond list (/api/sovereign-gold-bonds) through the same polite NSE session as the NSE provider, cached for 5 minutes and kept on disk. When NSE refuses (it often blocks scripts), the last saved list is shown with its date; with none, every outstanding tranche is listed without a price — never a guessed one. Tranche details (series, issue date, issue price, maturity = issue + 8 years, early redemption from year 5) are bundled from public tranche tables; 33 of the 44 issue dates were checked against RBI press releases, and RBI moves a maturity a day or two earlier when it falls on a holiday. Their NSE symbols come from a public list and are only shown when NSE’s own list is unavailable. No new SGBs have been issued since February 2024. SGBs you hold are valued from the same list in portfolio and the other holdings commands (see Mutual funds and SGBs).
  • Yields: CCIL’s tenor-wise indicative yields, end of day, cached for 6 hours; when CCIL can’t be reached, the five benchmark G-sec yields and T-bill cut-offs on the RBI home page. CCIL and RBI data are for personal, non-commercial use.
  • Outstanding G-secs: RBI’s list of Government of India securities, cached for a day.
  • Prices of individual G-secs and T-bills are not shown: neither CCIL nor RBI publishes them as a plain page, and NSE’s live debt quotes have no documented API. Enter the price your broker shows into bonds calc.
  • Bond math: half-yearly coupons on the maturity date’s day, 30/360 (European) day count, yield compounded half-yearly, simple interest in the final coupon period — the G-sec convention. T-bill yield = (100 − price) / price × 365 / days. Floating-rate bonds (FRBs) are not supported.

Strategies & bots

Guide: Backtest and practise on past markets and Set up alerts and the daemon.

CommandDescription
backtest <SYMBOL> [-s STRATEGY] [-P NAME=VALUE] [-p] [--json|--csv]Backtest one stock after costs: net and gross return, buy & hold, CAGR, drawdown, Sharpe/Sortino, exposure, trades. Fills at the next bar’s open. Strategies: rsi (default), macd, sma, bb, vwap, mr, or your own TOML file. Default 2y
backtest portfolio <SYMBOLS...> [-s] [--weights equal|inverse-vol|0.5,0.3,...] [--rebalance none|monthly|quarterly] [--json|--csv]One strategy across several stocks sharing the capital; combined equity curve and per-symbol contribution
backtest walkforward <SYMBOL> [-s] [--train 1y] [--test 3mo] [--json|--csv] (wf)Tunes the strategy’s [grid] on rolling train windows and reports only the unseen test windows, with an overfitting verdict. Default 5y
backtest strategies [FILES...] [--json]List built-in and your own strategies, or check strategy files (exit 1 on errors)
sip <SYMBOL> <AMOUNT> [-p] [--json]Monthly SIP/DCA simulation with value-vs-invested chart and XIRR. Default 5y
whatif <SYMBOL> <AMOUNT> <YYYY-MM-DD> [--json]What a lump sum on a past date is worth today
intraday [-s STRATEGY] (bot)9-strategy intraday signal scanner: sector heat, trend breadth, a table of regime, score and strategy agreement, and the strategies behind the strongest signals. No position sizes, entries, stops or targets. -s adds a strategy file’s rules as a tenth signal. Old CAPITAL TARGET% arguments are accepted and ignored
longterm [MONTHLY_BUDGET]6-pillar scores (0–100) for the market’s stock universe, with the facts that added or took away points (“P/E 9.8 (below 12)”, “Analyst mean rating 1.4/5 (1 = most positive)”), a data-coverage figure, a risk level (Lower / Moderate / Higher) and rule-based moat signals. A pillar with no inputs shows a dash and the composite shows n/a when under half of the weight had data. Also an illustration at an assumed annual return set from the score (5- and 10-year growth, the monthly SIP that would reach 10 lakh / 1 million, your MONTHLY_BUDGET compounded) and a simulated 5-year range (10th, median, 90th percentile). It describes data; it is not a recommendation and gives no entry, stop or target. No --json yet. Wording changes in 0.8.1: the analyst lines no longer say “buy consensus” / “sell consensus” / “upside”, the risk tier names Conservative / Aggressive became Lower / Higher, and “Best case” / “Worst case” became the 90th / 10th percentile
daemon intraday [CAPITAL] [--once]Paper-trading loop on the NSE clock (IST, holidays included; -m us uses NYSE hours in ET): scan, enter at the open, trail stops every 60s, book half at T1, square off 15 minutes before the close, settle into sim history, then wait for the next trading day (--once exits after one session). Survives network blips, resumes the day after a restart, and squares off on Ctrl+C. Never sends broker orders
daemon longtermPost-market scan: the highest long-term scores, portfolio value and wealth snapshot, triggered alerts, holdings priced below their average cost, and optional AI research notes
sim start [CAPITAL] [TARGET%]Start a paper session with the bot’s picks (default ₹25,000, 2%) on a trading day before the close
sim status / history [--json]Live P&L / record + confidence rating
sim settle [--now]Settle open sessions from that day’s 5-minute bars: stop or target first, else exit at the 15:15 bar. Today’s session waits for the close unless --now
sim reset [--yes]Delete simulator history after confirmation (a timestamped backup is kept)
sim replay list [--json] (scenarios)Built-in historical replays: covid-crash-2020, gfc-2008, adani-2023, dotcom-2000, bull-run-2021, rate-hikes-2022. See simulator.md
sim replay start SCENARIO|file:PATH.toml [--capital] [--costs] [--json]Start a replay: daily history is fetched once, then you trade day by day and only ever see bars up to the replay date
sim replay start --from DATE --to DATE --symbols A,B,... [--benchmark SYM]Your own replay window in the active market (-m in/-m us); benchmark NIFTY 50 / S&P 500 by default
sim replay buy SYMBOL QTY [--stop P] [--target P] / sell SYMBOL [QTY]Queue an order for the next day’s open (backtest cost models; long only). sell without a quantity sells the whole position
sim replay next [N] / status / chart SYMBOL|index [--days]Move N trading days (stops and targets on each day’s range); account, positions, orders and the market on the replay date; a chart up to it
sim replay cancel [ID] / set SYMBOL [--stop P] [--target P]Cancel pending orders; move a position’s stop or target
sim replay end [--json]Finish: 0–100 score and grade, badges, streaks, and what actually happened
sim challenge list|start NAME|status|end [--json]Goal-based challenges with hard and soft rules over the running replay or your live paper sessions: beat-the-index, steady-hands, position-limit, stop-loss, sip-discipline, crash-survivor, or file:PATH.toml
sim profile [--json]Badges (earned and how to earn the rest), streaks, best score per scenario, recent runs
sim card [--svg FILE] [--text]Your last run as a text card, or a 640 × 360 SVG image — with the paper-trading disclaimer
report <intraday|longterm|portfolio|SYMBOL>Educational AI notes (signals, risks, what to watch) via local Ollama or an opt-in cloud model — see ai.md

Every backtest form also takes:

OptionDefault
-s, --strategyrsiA built-in, a file in your strategies folder, file:PATH.toml, or wasm:PATH.wasm (a WASM plugin; --features wasm-plugins builds)
-P, --param NAME=VALUEOverride a strategy parameter (repeatable)
--costsautoauto, in-delivery, in-intraday, us, crypto, fx, none. auto = crypto/FX models for coins and pairs, India delivery for INR stocks, US otherwise
--brokeragepresetPer order: 20 (flat), 0.03%, or 20,0.03% (whichever is lower)
--slippage-bps5Slippage per fill, in basis points
--fillnext-opennext-open or close (fills at the signal bar’s close — look-ahead)
--capital100000Starting capital in the stock’s currency
--json / --csvPrint the whole result as JSON, or the trades as CSV

Costs, fills, the metrics, walk-forward and the strategy file format are in backtesting.md.

Portfolio

Guide: Import your trades and see true returns and Rebalance to target weights.

Data lives in the directory shown by stockwise doctor.

CommandDescription
portfolio [show] [--base inr|usd] [--json|--csv] (p)Holdings with live P&L, XIRR and allocation; mutual funds at AMFI’s NAV and SGBs from NSE (below); holdings without a price show N/A. Mixed INR/USD holdings are totalled in --base (default: the market’s currency)
portfolio add <SYMBOL> <SHARES> <COST> [--date YYYY-MM-DD] [--force]Add a purchase as a new lot (default date: today). A ticker Yahoo does not know is refused with “did you mean” names; --force saves it anyway (also on watch add and alert add). A mutual fund is MF:<AMFI code> or MF:<ISIN> (units and NAV per unit), kept as typed in every market
portfolio sell <SYMBOL> <SHARES> [PRICE] [--date YYYY-MM-DD]Record a sale, oldest lots first (FIFO). Price defaults to the live price (a fund’s latest NAV); a past --date needs a price. Refused while a split or bonus before the sale isn’t applied to your lots
portfolio lots <SYMBOL> [--lot N --date YYYY-MM-DD]Lots, sales, dividends and XIRR of one holding; --lot N --date corrects a purchase date
portfolio actions [SYMBOL] [--apply]Splits, bonuses and dividends since your purchases, including positions you have sold (from Yahoo). Shows them; --apply adjusts lots and records dividends, and is safe to repeat
portfolio listYour portfolios: the default one and every named one
portfolio benchmark [NIFTY|SENSEX|SP500|...] [-p 1y] [--base inr|usd] [--json|--csv]Time-weighted return against an index over the period, from the lots held each day: alpha, beta, tracking error, and attribution by holding and sector (see below)
portfolio pme [NIFTY|SPY|VOO|VWCE|NIFTYBEES|...] [--base inr|usd] [--json|--csv]Public Market Equivalent (Index Twin): mirror exact tradebook cash flows into a passive benchmark; computes Kaplan-Schoar PME, Direct Alpha, twin value, and net currency value added vs the index (see below)
portfolio remove <SYMBOL>Remove a holding and its lots without recording a sale
portfolio target [show] / portfolio target set <KEY> <PCT> / portfolio target remove <KEY> / portfolio target drift <PCT>Custom target weights by symbol or sector and configurable drift tolerance band
portfolio xray [--json] (or portfolio x-ray)Portfolio X-Ray: look-through overlap across direct stocks, ETFs and mutual funds, combined effective company exposures, 10% concentration risk alerts, broad asset-class split, market-cap breakdown, and sector concentration
watch [show] [--json|--csv] / watch add <SYMBOLS...> [--force] / watch remove <SYMBOLS...> (w)Watchlist
alert [list] [--json|--csv] / alert add <SYMBOL> <CONDITION> <NUMBER> [--period N] [--force] / alert check [--json|--csv] / alert remove <N>Price and technical alerts — conditions below; alert list shows each condition in words
alert watch [--interval 60] [--once]Check alerts while their market is open and notify each trigger once (see notifications). --once checks every alert once and exits, for cron
calendar [SYMBOLS...] [--days 30] [--holdings|--watchlist] [--json|--csv]Upcoming results, ex-dividend and dividend payment dates, splits and bonus issues for your holdings and watchlist (or the named symbols), sorted by date, with today and the next 7 days marked. See the calendar
import <kite|indmoney|groww|upstox|cas|csv> <FILE> [--replace] [--sheet NAME]Import broker holdings, a lot list, a tradebook (CSV or .xlsx: one sheet is read, the first whose header fits, or --sheet NAME; Excel date cells included) or a CAS (casparser JSON/CSV); re-importing updates instead of doubling (see below and brokers.md)
export <portfolio|watchlist>Write a CSV to the current directory
wealthSave today’s portfolio value and show growth (run daily)
rebalance [--inflow N] [--drift N] [--json] (or portfolio rebalance)Trades to rebalance to targets (or equal weight); --inflow buys underweight assets with new cash without selling; --drift ignores minor deviations
harvest [--json|--csv]Tax-loss and LTCG-exemption harvesting candidates, by FIFO sale (see below)
tax <in|us|uk> [--json|--csv]Capital-gains estimate for the current tax year: realized sales and unrealized lots, each with its own holding period (see below)
tax export [in|us] [--fy 2025-26] [--out FILE] [--json]Capital-gains schedule of a tax year’s sales: an ITR Schedule CG / 112A CSV for India, a Form 8949 worksheet for the US (see below)
tax advance [--fy 2025-26] [--paid [DATE:]AMOUNT]... [--json]Advance tax quarterly schedule (15 Jun, 15 Sep, 15 Dec, 15 Mar) under Indian Income-tax Act Section 208/211 with Section 234C(1) capital-gains proviso and interest estimator (see below)
divcalDividend ranking and income for portfolio + watchlist
income [--months 12] [--by-holding] [--json|--csv] (or portfolio income / portfolio dividends)12-month trailing and projected dividend, coupon and passive-income calendar, Yield-on-Cost (YoC), and dividend payout safety checks (see below)
income upcoming [--days 60] [--json|--csv]Radar of upcoming ex-dividend and payment dates for held and watchlisted shares (see below)
pcorrCorrelation between holdings from the days both traded, diversification warnings (N/A when two holdings share too few days)

Lots, sales and tax

Guide: File your Indian capital-gains tax.

Every purchase is a lot: quantity, price, date and where it came from (manual, import:kite, broker:angel, …). portfolio sell takes shares from the oldest lots first — FIFO, as Indian demat accounts and the IRS default work — and keeps each slice as a realized sale.

tax classifies every lot by its own purchase date (long-term after more than 12 months for India and the US) and shows realized gains (sales this tax year) separately from unrealized ones (if you sold everything today). For India it applies the set-off rules: gains and losses of the same kind net first; a short-term loss is set off against short-term gains, then long-term gains; a long-term loss only against long-term gains; then ₹1.25 lakh of LTCG is exempt and STCG is taxed at 20%, LTCG at 12.5%. Losses left over are shown as carry forward. Holdings in another currency (e.g. US shares in tax in) are listed but not included. It is an estimate — it includes the 4% cess but not surcharge or brought-forward losses.

Grandfathering (India): for a long-term lot bought on or before 31 Jan 2018, the cost is the higher of the actual cost and the lower of the 31 Jan 2018 price and the sale price (Section 112A). tax in, tax export in, tax advance and harvest all use it. The price is the day’s highest for a listed share (Yahoo) and the NAV for a mutual fund with an AMFI code; it is looked up once and cached. A lot whose price cannot be found keeps its actual cost, and tax export in says so in its notes. Prices are split-adjusted, so a lot recorded before a split or bonus must carry its adjusted cost.

Same-day trades (India): a buy and sell of one share on the same day net against each other first, in a tradebook import and in trade sync fills. The matched quantity is recorded as an intraday sale (priced at that day’s average buy and sell) and the older lots are left alone. tax in, tax export in and tax advance keep intraday results out of Sec. 111A/112A and show them separately as speculative business income at your slab rate (losses can only be set off against speculative gains). Without a date-time column a delivery buy and sell of held shares on one day cannot be told apart from intraday.

Mutual funds and SGBs in tax in: equity-oriented funds — by their AMFI category: equity schemes (ELSS included), arbitrage, aggressive hybrid and equity savings funds, and Nifty/Sensex index funds — are counted like listed shares and named under the estimate. Debt and other funds (taxed at your slab rate for units bought from 1 Apr 2023, at 12.5% after 24 months for older units), funds not found in AMFI’s file, and SGBs (tax-free when RBI redeems them; sold on the exchange, 12.5% after 12 months without the ₹1.25 lakh exemption) are left out and listed with the rule that applies (other_rules in --json). So are exchange-traded gold, silver and international ETFs (12.5% after 12 months with no exemption, slab rate before) and liquid and debt ETFs (slab rate at any holding period). StockWise knows them from a built-in list of NSE symbols (GOLDBEES, SILVERBEES, LIQUIDBEES, MON100, Bharat Bond EBBETF…, …) and from …BEES names that say gold, silver, liquid, gilt, Nasdaq or Hang Seng; an ETF it does not know is counted like a listed share, as are equity ETFs such as NIFTYBEES. harvest skips the same holdings (they are listed under “Not checked”) and tax export in and tax advance leave their sales out.

tax in, harvest, tax export in and tax advance share one rule for what counts as a listed share or an equity-oriented fund (Sec. 111A/112A); the other three load AMFI’s file to read the category of any fund you sold. Crypto (such as BTC-INR) is never in 111A/112A: it is taxed at a flat 30% under Sec. 115BBH with no set-off of losses, tax export in lists it under virtual_digital_assets, and the other commands name it among the holdings they leave out.

Mutual funds and SGBs

Guide: Import your trades shows how to load a CAS.

Holdings that Yahoo Finance doesn’t quote are priced by StockWise itself, the same way in portfolio, dashboard, tui, serve, wealth, rebalance, harvest, tax, portfolio sell and report portfolio:

  • Mutual funds — MF:<AMFI code> (portfolio add MF:120503 10 50) or MF:<ISIN> (the growth/payout or IDCW-reinvestment ISIN, as import cas and Groww imports store them) — at the latest NAV in AMFI’s NAVAll.txt (cached 12 hours). NAVs are end of day: the table says “NAV as of <date>” for each fund, and --json rows carry name, price_source: "amfi_nav" and nav_date. A code or ISIN that isn’t in AMFI’s file, or a scheme AMFI lists without a NAV, stays N/A with a note (find codes with mf search) — never 0. A scheme whose last NAV is over a month older than the file is flagged as possibly matured. MF: symbols are never sent to Yahoo, and watch/alert see the NAV too.
  • Sovereign Gold Bonds — the NSE symbol (SGBNOV26, stored as SGBNOV26.NS) or the tranche’s ISIN — at the last price in NSE’s SGB list (price_source: "nse_sgb"). When NSE refuses or shows no trade, the value is one gram of gold at the international spot price per unit, labelled “estimated from gold spot” (gold_estimate). Values leave out the 2.5% yearly interest, which is paid to your bank every six months.

Older versions stored portfolio add MF:120503 as MF:120503.NS (and watch add / alert add likewise); those symbols are repaired when the files load.

Passive income and dividend calendar

stockwise income (or stockwise portfolio income) is a 12-month trailing and projected dividend, coupon and passive-income engine for dividend-growth investors, retirees, and bond/SGB holders:

  • Monthly Cashflow Schedule: Shows month-by-month cash flows across trailing 12 months (received dividends recorded in portfolio.dividends) and forward N months (default 12), with a visual terminal bar chart and --json/--csv serialization.
  • Yield on Cost (YoC): Calculates per-holding and per-lot Yield-on-Cost (YoC = Annual Dividend / Original Lot Cost), comparing it against current market yield to reveal dividend-growth compounding over time.
  • TDS and Withholding Tax: Automatically computes withholding tax (flat 10% TDS for Indian dividends and 25% WHT for US foreign dividends; 0% assumed for other currencies) to report net spendable income.
  • Sovereign Gold Bonds & Fixed Income: Models half-yearly 2.5% p.a. SGB coupons on issue nominal values across maturity cycles.
  • Payout Safety & Sustainability: Evaluates earnings payout ratios, diagnosing distributions as SAFE (< 60%), CAUTION (60–85%), or WARNING (> 85% or negative earnings).
  • Upcoming Radar (stockwise income upcoming): Checks upcoming ex-dividend and payment dates for holdings and watchlists, showing held share counts and calendar details.

Harvest

Guide: File your Indian capital-gains tax.

harvest lists what you could sell to book a loss, and which long-term winners you could sell to use this year’s unused ₹1.25 lakh LTCG exemption. For India it follows FIFO, as a demat account does: to reach a losing lot you must sell the older lots first, so the row shows that whole sale (shares, and the net st_pnl and lt_pnl it books). If selling up to a losing lot books a net gain in all, the holding is not offered as a loss; fifo_blocked (and a note on screen) says how many shares you would sell and what the sale books. For the US you can choose lots, so only the losing lots are offered.

estimated_tax_saved is how much the tax estimate falls when the loss is booked on top of this year’s realized gains, so set-off order, the exemption and cess are counted; a loss with nothing to offset saves 0 and is carried forward. The remaining exemption is shared: each winner takes its part of it, biggest first, and the saving counts only that part. Holdings in another currency (US shares for in) are listed under other_currency and not counted; holdings taxed under other rules (crypto, debt funds, SGBs, gold and similar ETFs) under other_rules.

Tax export

Guide: File your Indian capital-gains tax.

tax export in writes the realized sales of an Indian financial year as a spreadsheet laid out for ITR Schedule CG and Schedule 112A: one row per lot sold with section (111A short-term, 112A long-term), ISIN, scrip, quantity, sale date and value, purchase date and cost, days held and the gain, then a summary block — gains and losses of each kind, the short-term loss set off against LTCG, the ₹1.25 lakh LTCG exemption, taxable STCG/LTCG, the estimated tax and losses to carry forward. ISINs come from NSE’s equity list (shares) and AMFI’s NAV file (funds imported from a CAS), both cached for 12 hours; one that can’t be found is left blank and named. tax export us writes a Form 8949 worksheet instead: Part I (held one year or less) and Part II rows with description, dates (MM/DD/YYYY), proceeds, cost basis and gain, then the Schedule D totals, the $3,000 loss deduction and the carryover.

stockwise tax export in --fy 2025-26 --out cg-2025-26.csv   # file + summary on screen
stockwise tax export in --fy AY2026-27 > cg.csv            # same year, by assessment year
stockwise tax export us --fy 2025 --json | jq '.summary'

--fy takes 2025-26, 2025-2026 or AY2026-27 (India) and 2025 (US); the default is the current tax year. Without --out the CSV (or --json) goes to stdout. It is an estimate — verify it with your broker’s tax P&L: it only knows sales StockWise recorded (portfolio sell, tradebook and CAS imports) at their recorded prices, without brokerage or STT. Shares bought on or before 31 Jan 2018 are flagged — Schedule 112A lets you use that day’s fair market value as the cost, which StockWise doesn’t apply; sales in another currency (US shares for in) and crypto (taxed at 30% under section 115BBH, Schedule VDA) are listed but left out, and so are debt and other funds and SGBs.

The rates follow the sale date: sales before 23 Jul 2024 are taxed at 15% (STCG) and 10% (LTCG), later ones at 20% and 12.5%. The LTCG exemption is ₹1 lakh up to FY 2023-24 and ₹1.25 lakh from FY 2024-25, for the whole of that year. In a mixed FY 2024-25, losses and the exemption are used against the higher-rate gains first (the lowest tax; the Act does not prescribe an order), and the summary shows how much of the taxable gain came from before 23 Jul 2024.

Advance tax (India)

Guide: File your Indian capital-gains tax.

Under Section 208 and 211 of the Indian Income-tax Act, any taxpayer whose estimated tax liability for the financial year is ₹10,000 or more must pay advance tax in four quarterly instalments:

  • By 15 June: At least 15% of estimated tax
  • By 15 September: At least 45% of estimated tax
  • By 15 December: At least 75% of estimated tax
  • By 15 March: 100% of estimated tax (capital gains realized between 16 and 31 March are payable by 31 March)

Because capital gains cannot always be predicted in advance, the proviso to Section 234C(1) specifies that deferment interest is not levied if the shortfall is due to capital gains realized after an instalment date, provided the remaining tax is paid in subsequent instalments. stockwise tax advance groups realized sales into the four statutory quarterly cut-offs and calculates cumulative set-offs under Indian equity rules, by sale date: from 23 July 2024 STCG @ 20% and LTCG @ 12.5%, before it 15% and 10%; the LTCG exemption is ₹1.25L (₹1L up to FY 2023-24):

stockwise tax advance                             # current FY advance tax schedule
stockwise tax advance --fy 2025-26                # specific financial year
stockwise tax advance --paid 2025-06-14:3000 --paid 2026-01-10:17800   # dated payments: exact Section 234C interest
stockwise tax advance --paid 25000                # a total with no date: assumed paid on time
stockwise tax advance --json                      # programmatic JSON output
  • Section 208 Check: Automatically flags whether advance tax is mandatory (total liability ≥ ₹10,000) or exempt.
  • Status: A quarter is Paid only when payments dated on or before its due date cover the minimum. With no --paid, a quarter past its due date is Overdue, because StockWise has no record of any payment.
  • Section 234C Deferment Interest: Section 234C looks at what was paid by each due date, so pass each payment with its date (--paid 2025-06-14:3000, repeated). It then charges 1% a month (3% for Q1–Q3, 1% for Q4) on each shortfall, rounded down to ₹100, when the payments by that date are below the safe-harbour level (12% in Q1, 36% in Q2, 75% in Q3, 100% in Q4). For Q4 the requirement on 15 March is the tax on gains up to 15 March; tax on gains after it carries no interest when paid by 31 March (the proviso). A payment dated before the financial year began is ignored (it was made for an earlier year) and the output says so. A payment without a date is assumed to have been made before every due date, which can understate the interest.
  • Cess: The tax and the instalments include the 4% health and education cess; surcharge is left out.
  • Section 234B Note: Flags potential Section 234B liability if assessed after 31 March and cumulative advance tax paid is below 90% of total liability.

Benchmark and attribution

Guide: Import your trades and see true returns.

portfolio benchmark rebuilds what you held at each close of the period from your lots and sales (in today’s share count, so splits don’t break the history), and compares the portfolio’s time-weighted return with an index over the same days.

stockwise portfolio benchmark                  # vs NIFTY 50 over 1 year (S&P 500 with -m us)
stockwise portfolio benchmark SENSEX -p 2y
stockwise portfolio benchmark SP500 --base inr # S&P 500 converted to rupees day by day
stockwise portfolio benchmark NIFTYBEES -p 6mo --csv
  • Benchmarks by name: NIFTY, SENSEX, BANKNIFTY, NIFTY500, SP500, NASDAQ, NASDAQ100, DOW; or an index symbol (^NSEI) or any ticker. Periods: 1mo, 3mo, 6mo, ytd, 1y (default), 2y, 5y, 10y, max.
  • The period starts at the first close where something was held. Returns come from daily closes: a purchase or sale counts at that day’s close, so the figure measures the holdings, not your fill prices. Dividends are left out on both sides (NIFTY 50 and the S&P 500 on Yahoo are price indices).
  • Alpha (annualized, risk-free rate 0), beta, tracking error, information ratio and correlation come from the daily returns and need 20 of them.
  • Attribution: each holding’s average weight, its return while held, its contribution to the portfolio return and to the return over the index, in percentage points (linked with Carino’s method, so they add up exactly to the totals); the same by sector, from Yahoo’s asset profile (“Unknown” when Yahoo has none, “Mutual fund” for funds imported from a CAS, valued from their NAV history).
  • Holdings in another currency are converted into the base currency (--base, else the holdings’ one currency, else the market’s) at each day’s exchange rate; an index in another currency is converted too.
  • Flagged under Partial history: holdings with no price history (left out), days held before a holding’s price history starts (left out of those days), and purchases inside the period with an estimated date (the shares may have been held earlier than the history shows).

Public Market Equivalent (Index Twin)

stockwise portfolio pme mirrors your exact tradebook cash flows into a passive benchmark index or ETF (e.g. SPY, VOO, VWCE, NIFTY, NIFTYBEES) on their matching trade dates:

  • Every buy of $X on date D buys $X worth of the benchmark twin.
  • Every sell on date D distributes the equivalent proceeds from the benchmark twin.
  • Recorded dividends are distributed from the twin on matching dates.

It answers: “Did my active trading and stock picking actually beat investing in a passive index on the exact same dates?”

Metrics reported:

  • Index Twin Value: Current value of the synthetic benchmark portfolio.
  • Value Added / Lost: Terminal portfolio value minus Index Twin value (in exact currency units: +$ / +₹).
  • Kaplan-Schoar PME (KS-PME): Compounded future value of distributions + terminal portfolio value over future value of investments (> 1.000 indicates active outperformance; 1.000 is parity).
  • Direct Alpha (Gredil, Griffiths, Stucke 2014): Annualized IRR of benchmark-discounted cash flows, yielding 0.00% on parity.
  • Holding Breakdown: Direct Alpha and Value Added breakdown for each held asset.

XIRR (in portfolio and portfolio lots) is the money-weighted annual return from each lot’s purchase, each sale, recorded dividends and today’s value. It shows — with under 30 days of history. The portfolio figure includes closed positions and converts other currencies at today’s rate.

Lots marked * have an estimated date: holdings from before lot tracking (dated when they were added to StockWise) or imported from a file without dates. Fix one with portfolio lots SYMBOL --lot N --date YYYY-MM-DD.

Corporate actions. portfolio actions lists splits, bonus issues (Yahoo reports a 1:1 bonus as a 2:1 split) and dividends since each holding’s first purchase. Nothing changes until --apply, which multiplies the quantity and divides the price of lots bought before the split (cost and date unchanged) and records each dividend on the shares held at its ex-date. Each lot remembers the splits applied to it, so running it again is a no-op. Indian tax treats bonus shares as bought at zero cost on the allotment date — check bonus lots against your tax statement.

Imports. A holdings export (Kite, INDmoney) has no purchase dates: existing lots are kept and only the quantity is matched — more shares add a lot dated today, fewer shares come out of the oldest lots (not recorded as a sale). trade holdings syncs the same way. When the snapshot has more shares and a split or bonus isn’t applied to your lots yet, that holding is skipped until you run portfolio actions --apply (otherwise the bonus shares would be counted twice). A file with a date column (Date, Purchase Date, Buy Date, trade_date, …) is a list of lots: each symbol’s lots are rebuilt from it. With a buy/sell column (trade_type, Type, Side) it is a tradebook — such as Zerodha Console’s — sells come out FIFO as realized sales, and splits and bonuses are applied as they happened (this needs a network connection). StockWise keeps the trades of each tradebook import and merges the next file with them, so several yearly tradebooks (Console allows 365 days per download) can be imported one after another, in any order, and re-importing a file changes nothing. A symbol is left unchanged when its sells have no earlier buy yet (the trades are kept; import the earlier tradebook to finish), or when it already has lots or sales from elsewhere (manual entries, another import, or a tradebook imported before StockWise kept trades) — --replace rebuilds it from this file alone anyway. A file of dated buys only (no buy/sell column) is the symbol’s whole list of lots and replaces them. Dates may be YYYY-MM-DD, DD-MM-YYYY, DD/MM/YYYY (MM/DD/YYYY with -m us) or 15-Mar-2024; a file with an unrecognized date is refused.

Mergers. A dated row (or portfolio add --date) for a ticker that was merged away is restated in the acquirer’s shares, keeping the date and the total cost: HDFC up to the 13 Jul 2023 record date becomes HDFCBANK at 42 shares for every 25, and Mindtree up to 24 Nov 2022 becomes LTIM at 73 for every 100 (quantity × ratio, price ÷ ratio). Rows without a date, and plain renames such as ZOMATO → ETERNAL, are mapped to the new name only. Fractional shares from the swap are kept as a fraction (the cash paid for them is not recorded). Existing lots already imported under the new name are not corrected — re-import the tradebook with --replace.

Accounts. Each lot and sale carries the demat account it came from, named after the broker: import kite and trade … --broker zerodha are zerodha, import groww is groww, and so on. A holdings file or tradebook only matches, rebuilds or sells the lots of its own account, so the same stock held at two brokers is two sets of lots in one holding (portfolio lots shows the account). Lots entered by hand or saved by an older version, with no account of their own, count as the account of their source, or — for manual lots — join the first broker that syncs the symbol. Totals and tax span all accounts. portfolio sell works on the whole holding, oldest lot first.

Groww, Upstox, CAS. Groww and Upstox exports are snapshots (quantity sync, like Kite). A CAS whose transactions cover a fund’s whole balance rebuilds it as dated lots, with redemptions as realized sales; otherwise only the quantity is synced. See brokers.md.

Upgrading. Portfolios saved before lot tracking are upgraded on first load: each holding becomes one lot dated when it was added, and the original file is kept once as portfolio.json.bak.

Planning

CommandDescription
goal sip --target AMOUNT (--years N | --months N | --horizon 18mo | --by YYYY-MM[-DD]) [--return PCT] [--inflation PCT] [--tax equity|arbitrage|debt|none] [--slab PCT] [--exit-load PCT] [--net] [--glide-path] [--step-up PCT] [--savings AMOUNT | --from-portfolio | --holdings SYM,...] [--json]Monthly SIP that reaches the target. Without --return the return follows the horizon: capital preservation up to 24 months (6.75% India / 4.25% US, or the cached 364-day T-bill yield), conservative hybrid to 60 months (9% / 6.5%), long-term growth beyond (12% / 9%). Shows tax and exit load at redemption per instalment (equity: 20% STCG under 12 months, 12.5% LTCG above with the ₹1.25 L exemption; debt: slab rate; cess 4%), the net in hand and the SIP that leaves the target after tax (--net makes the target itself post-tax), P10 / median / P90 outcome bands with the chance of reaching the target, a ±2% return sensitivity, and a month-by-month (up to 24 months), quarterly (to 36) or yearly schedule. Forcing an equity return on a short goal prints a warning with the simulated downside
goal retire --monthly-expense AMOUNT --years-to-retire N --years-in-retirement N [--inflation 6] [--return-pre 12] [--return-post 7] [--monthly-income AMOUNT] [--buffer-years N] [--legacy AMOUNT] [--step-up PCT] [--savings AMOUNT] [--json]Corpus needed on the day you retire to pay today’s expenses (grown by inflation, less any pension or rent) for every month of retirement, and the SIP that builds it; the initial withdrawal rate, how long the corpus lasts after a 30% fall on day one, and the year-1 tax of an SWP against FD interest
goal education --cost AMOUNT (--years N | --months N | --horizon D | --by DATE) [--inflation 8] [--return PCT] [tax flags] [--json]Today’s cost after the horizon of education inflation, and the SIP that pays it, with the same return basis, tax, bands and sensitivity as goal sip
goal swp (--corpus AMOUNT | --from-portfolio | --holdings SYM,...) --withdrawal AMOUNT [--inflation 6] [--return 10] [--years 30] [--fd-return 7] [--slab 30] [--cost AMOUNT] [--json]How long the corpus lasts under monthly withdrawals that rise with inflation: an equity SWP (tax on the gain share only) against an FD (interest at the slab rate)
goal emergency --monthly-expense AMOUNT [--months-cover 6] [--horizon 12mo] [--savings AMOUNT | --from-portfolio | --holdings SYM,...] [--return PCT] [--json]Reserve to hold, how much of it your liquid money covers, and the monthly build-up
goal prepay --principal AMOUNT --loan-rate PCT --remaining-months N (--extra AMOUNT | --lump-sum AMOUNT) [--return PCT] [--tax KIND] [--slab PCT] [--json]Exact interest and tenure saved by prepaying, against the after-tax SIP outcome of the same money (P10 / median / P90), the chance the SIP wins and the before-tax return it needs to break even
goal add NAME --target AMOUNT --by YYYY-MM[-DD] [--inflation PCT] [--holdings SYM,...] [--return PCT]Save a goal in goals.json (a --inflation target is in today’s money)
goal [list] [--json] · goal show NAME [--json] · goal remove NAMESaved goals with months left, the live value of their linked holdings, the funded share and the SIP still needed; one goal in full; remove one

--from-portfolio and --holdings value the portfolio (or the named holdings, such as MF:122639 or NIFTYBEES) at live prices, or at cost when offline, and use that as existing savings; they replace --savings. Taxes and exit loads are estimates, not advice; --tax defaults to debt up to 60 months and equity beyond, with a 1% exit load on equity lots held under 12 months in India.

stockwise goal sip --target 1cr --years 15                  # ₹19,819 a month at 12%
stockwise goal sip --target 1cr --years 15 --step-up 10     # ₹11,516 a month, rising 10% a year
stockwise goal sip --target 10L --months 9                  # short goal: 6.75% baseline, month-by-month table
stockwise goal sip --target 50L --by 2031-06 --inflation 6 --from-portfolio
stockwise goal retire --monthly-expense 80k --years-to-retire 20 --years-in-retirement 30
stockwise goal education --cost 25L --years 10 --savings 3L
stockwise goal add house --target 50L --by 2031-06 --holdings NIFTYBEES
stockwise goal swp --corpus 1cr --withdrawal 50k
stockwise goal prepay --principal 50L --loan-rate 9 --remaining-months 240 --extra 10k

Amounts take Indian units — 50k, 25L / 25 lakh, 1cr / 1.5 crore, 2,50,000 — and results print in lakhs and crores (dollars with -m us). The math, as Indian SIP calculators do it: the monthly rate is the annual return ÷ 12 and SIPs are paid at the start of each month; a step-up raises the SIP once a year; --savings already invested grows at the same return and lowers the SIP. In retirement the expense rises with inflation once a year and the corpus earns --return-post until it runs out at the end of the last year. Returns are assumptions, not promises.

AI assistants

Guide: Use StockWise from Claude or Cursor.

Both use the same read-only tools (quotes, history, technicals, risk, scorecards, insights, events, mutual funds, option chains, IPOs, screens, backtests, your portfolio, lots, tax estimate, advance tax, harvest and rebalance plans, calendar, goals, watchlist and alerts). See ai.md.

CommandDescription
ask <QUESTION> [--verbose] [--max-steps 6] [--max-tokens 100000] [--json]Ask in plain English; the configured model (local Ollama by default, or the cloud provider in STOCKWISE_AI_PROVIDER) calls the tools and answers. Needs a model with tool calling. --verbose prints each tool call on stderr; --json prints the transcript (answer, tool calls with arguments, token usage). The last request runs without tools, so the model must answer. Educational, not financial advice
mcp [--http ADDR] [--allow-remote] [--allow-orders] [--list-tools]Model Context Protocol server for Claude Desktop, Claude Code, Cursor and other assistants: 35 read-only tools, the portfolio, watchlist and alerts as resources, and three prompts. Stdio by default; --http 127.0.0.1:8788 serves Streamable HTTP at /mcp (other addresses need --allow-remote and STOCKWISE_API_TOKEN). --allow-orders adds a dry-run order_preview that returns the stockwise trade command for you to run — it never places orders. --list-tools prints the tools and their input schemas as JSON. Cargo feature mcp (on by default)
stockwise ask "how is my portfolio doing?"
claude mcp add stockwise -- stockwise mcp     # Claude Code
stockwise mcp --list-tools | jq '.[].name'

Interfaces

Both are read-only and share the data layer with the commands above, so they show the same numbers. They are on by default and can be left out of a build with --no-default-features (cargo features tui and server).

CommandDescription
tui [-i SECONDS]Full-screen live dashboard: indices, watchlist, portfolio P&L, alerts and a chart of the selected symbol. Refreshes every 30s by default (10-3600). ? shows the keys. See tui.md
serve [--bind ADDR] [--allow-remote] [--open]Web dashboard at / (--open opens it in your browser), JSON API (/api/quote, /api/history/{symbol}, /api/markets, /api/search, /api/portfolio, /api/watchlist, /api/alerts), /healthz and Prometheus /metrics. Listens on 127.0.0.1:8787; other addresses need --allow-remote and STOCKWISE_API_TOKEN. See server.md

Live trading

See brokers.md. Orders are previewed and need a typed yes. Every trade command takes --broker angel|zerodha|upstox|dhan|fyers (default angel, or STOCKWISE_BROKER); all but angel are experimental — untested against a live account.

CommandDescription
trade setup / trade config [--keyring]How to connect / create the owner-only credentials file, move secrets into the OS keyring
trade loginDaily login (Zerodha, Upstox, Fyers) or paste a Dhan token
trade holdings / positions / ordersLive holdings (synced into portfolio, keeping your lots), open positions, order book
trade buy <SYMBOL> <QTY> [--limit P] [--trigger T] [--dry-run] [--yes]Buy on NSE: MARKET, LIMIT, SL-M (--trigger) or SL (both)
trade sell <SYMBOL> <QTY> [--limit P] [--trigger T] [--dry-run] [--yes]Sell on NSE, same order types
trade limit <SYMBOL> <QTY> <PRICE> [--dry-run] [--yes]Limit buy on NSE
trade gtt <buy|sell> <SYMBOL> <QTY> --trigger T --limit P [--dry-run] [--yes]Single-leg GTT (not Upstox)
trade gtt list [--notify] [--json] / trade gtt cancel <ID>List GTTs with status changes since the last look (triggered, cancelled, expired, gone; --notify sends them) / cancel one (asks for confirmation)
trade sync [--since DATE] [--apply] [--notify] [--json]Today’s executed delivery trades into the portfolio — buys become dated lots, sells come out FIFO — idempotent by broker trade id; previews unless --apply. Dhan also reads older fills with --since. See brokers.md
trade selftest [--redact-amounts] [--json]Read-only check of the integration against your account (session, profile, holdings, positions, orders, trades, GTTs, instrument lookup, a dry-run order, response shapes); prints a redacted report for a broker test report. Exits 1 if a check failed

Setup

CommandDescription
profile [show] [--json]Show active investor profile mode (passive, active:low|med|high, ultra), effective tax parameters and personal guardrails
profile set [MODE[:RISK]] [--risk low|med|high] [--tax-slab PCT] [--tax-regime new|old] [--horizon-years N] [--max-stock-weight PCT] [--max-smallcap-weight PCT] [--risk-per-trade PCT] [--json]Save investor profile mode and personal guardrails to config.toml
profile resetReset profile mode and guardrails in config.toml to defaults (active:med)
config [show] [--json]Effective settings and where each comes from (flag, env, config file, default), plus the config file’s status
config pathPrint the config file path (it may not exist yet)
config init [--force]Write a commented template to the config file path; refuses to replace an existing file without --force
notify [status] / notify testShow the configured notification channels (Telegram, Slack, Discord, email, desktop) / send a test message. See notifications
completions <bash|zsh|fish|powershell|elvish>Print a completion script, e.g. stockwise completions zsh > ~/.zfunc/_stockwise
man [--dir <DIR>]Print the stockwise.1 man page, or write it plus one stockwise-<command>.1 page per command into DIR, e.g. stockwise man --dir ~/.local/share/man/man1

Scripting with --json and --csv

Guide: Script it with JSON, CSV and jq.

stockwise portfolio --json | jq '.totals'
stockwise portfolio --json | jq -r '.holdings | sort_by(.pnl_percent) | .[:3][] | "\(.symbol) \(.pnl_percent)%"'
stockwise portfolio --csv > portfolio.csv                 # open in a spreadsheet
stockwise history TCS -p 1y --csv > tcs.csv               # every daily bar
stockwise alert check --json | jq -r '.[] | select(.status == "triggered") | .symbol'
stockwise screen dividend --csv | column -s, -t
stockwise tax in --json | jq '.realized.total_tax'
stockwise tax export in --fy 2025-26 --json | jq '.summary.taxable_ltcg'
stockwise portfolio benchmark --json | jq '{portfolio_return, benchmark_return, beta: .metrics.beta}'
stockwise goal sip --target 1cr --years 15 --json | jq '.monthly_sip'
for s in rsi macd sma bb vwap mr; do
  stockwise backtest INFY -s "$s" --json | jq -r '"\(.strategy)\t\(.total_return_percent)"'
done
for s in $(stockwise watch --json | jq -r '.[].symbol'); do
  stockwise technical "$s" --json | jq -r '"\(.symbol)\t\(.rsi_14)\t\(.bias.verdict)"'
done
stockwise quote TCS INFY --json | jq '.[] | {symbol, regularMarketPrice}'
stockwise markets --json | jq '.[] | select(.change_percent < -1)'
stockwise mf sip 122639 5000 -p 3y --json | jq '{invested, value, xirr}'
stockwise options chain NIFTY -n 2 --json | jq '.rows[] | {strike, delta: .call.greeks.delta}'
stockwise options payoff NIFTY -s straddle --json | jq '{breakevens, pop, max_loss}'
stockwise mf screen flexi cap -s ter --json | jq '.[] | {name, ter, return_3y}'

Rules

  • stdout holds only the JSON or CSV; errors go to stderr with exit code 1, so set -e and || work. --json and --csv can’t be combined.
  • Empty states are not errors: an empty portfolio prints {"holdings": [], ...} or a CSV header with no rows.
  • Keys are stable snake_case. The exceptions are quote --json and search --json, which pass Yahoo’s own fields through (camelCase, unchanged since 0.3); their --csv uses snake_case columns.
  • A value that isn’t available is null in JSON and an empty cell in CSV — never 0. A holding without a live price keeps its row but is left out of totals and listed in unpriced.
  • Fields ending in _percent are percentages (12.5 = 12.5%). dividend_yield in quote, compare and screen is a fraction as Yahoo reports it (0.012 = 1.2%). Prices are as Yahoo returns them; derived money values are rounded to 2 decimals, indicators to 4.
  • Dates are YYYY-MM-DD; history bar times are RFC 3339 in UTC.
  • CSV follows RFC 4180 quoting (fields with a comma, quote or newline are quoted, quotes doubled), starts with a header row, and ends lines with \n. CSV columns are the same names as the JSON row keys.
  • The --ai section is never part of JSON or CSV output.
  • mf and options have their own --json (no --csv); fractions there are decimals (0.1234 = 12.34%), and missing values are null, never 0.
  • options payoff --json is {symbol, source, underlying, currency, as_of, expiry, days_to_expiry, strategy, width, lot_size, lot_size_from, lots, multiplier, rate, div_yield, legs: [{side, qty, instrument, strike, price, price_from, iv, iv_from, delta}], net_premium, net_premium_total, premium_type, max_profit, max_loss, breakevens, profit_ranges: [{from, to}], pop, pop_iv, pop_iv_from, greeks: {delta, gamma, theta, vega, rho}, notes, curve: [{price, expiry, today}]}. net_premium and leg prices are per unit (positive = debit); money totals, greeks and the curve are for the whole position (× multiplier = lot size × lots). max_profit/max_loss are null when unlimited; max_loss is negative; to: null means “and above”. price_from is mid, ltp, manual or spot. Money values, prices and breakevens are rounded to 2 decimals.

Shapes ([...] is an array; row is described next to it)

Command--json--csv — one row per
quote[quote] — Yahoo’s quote fields, plus cap_tier and dataSource when another provider supplied the price, and deliveryPercent, lowerCircuit, upperCircuit when NSE did (data-providers.md)quote: symbol, name, currency, price, change, change_percent, open, day_low, day_high, year_low, year_high, volume, avg_volume_3m, market_cap, cap_tier, pe_ttm, eps_ttm, dividend_yield, delivery_percent, lower_circuit, upper_circuit (the last three empty unless NSE answered)
markets[{region, symbol, name, price, change, change_percent, currency}] — region is Indian Markets, US Markets, Crypto, FX, Commodities, a country (United Kingdom, Germany, Japan, Hong Kong, Singapore, Canada, Australia) or Global. The India 10-year yield is the row with symbol IN10Y: price is the yield in percent, currency and change are nullindex
search[hit] — Yahoo’s search fieldshit: symbol, name, quote_type, exchange
commodity / commodity spot[{metal, unit, price, currency, change_percent, source}] — metal is gold or silver; unit is USD/oz, INR/g, INR/10g or INR/kgrow
commodity futures, commodity etfs[{symbol, metal, name, contract, price, change, change_percent, volume, currency}] — contract is Yahoo’s short name (the front month for futures)instrument
commodity sgb[{symbol, isin, series, issue_date, issue_price, maturity, early_redemption_from, years_to_maturity, price, change_percent, volume, gold_value, premium_percent, interest_per_year, current_yield_percent}] — price is ₹ per unit (1 g) and null when NSE gave none; gold_value is 1 g at the international spot price; maturity is nominal (issue + 8 years); NSE’s notes go to stderrtranche
bonds / bonds yields[{date, tenor, kind, security, ytm, source}] — kind is tbill, gsec or sdl; source is CCIL or RBI; ytm in percent, null when the page shows noneyield
bonds list[{isin, name, coupon, issue_date, maturity, outstanding_cr}] — coupon is null for floating-rate bonds; outstanding_cr in ₹ croresecurity
bonds calc{security, isin, kind, coupon, maturity, settlement, days_to_maturity, clean_price, accrued_interest, dirty_price, ytm, current_yield, macaulay_duration, modified_duration, next_coupon, coupons_left} — kind is gsec or tbill; prices per ₹100 face value, yields in percent—
history{symbol, currency, period, interval, bars: [{time, open, high, low, close, volume}]}bar
technical{symbol, currency, period, interval, bars, price, sma_10, sma_20, sma_50, sma_100, sma_200, ema_12, ema_26, rsi_14, rsi_signal, macd: {line, signal, histogram, trend}, bollinger: {upper, middle, lower, position}, atr_14, atr_percent, vwap, bias: {verdict, bullish, bearish}} — position is above_upper, below_lower or within; verdict is bullish, bearish or neutral—
risk{symbol, currency, period, interval, bars, price, return_percent, volatility_percent, risk_level, sharpe, sortino, calmar, max_drawdown: {percent, peak_price, trough_price, trading_days}, var_95_percent, var_99_percent} — risk_level is low, moderate, high or very_high—
compare[{symbol, name, currency, price, change_percent, market_cap, cap_tier, pe_ttm, pe_forward, eps_ttm, price_to_book, dividend_yield, profit_margin, revenue_growth, debt_to_equity, beta, year_high, year_low, sma_50, analyst_mean_rating}] — the table’s transposestock
correlate{period, interval, symbols: [..], matrix: [[..]]} — matrix[i][j] pairs symbols[i] and symbols[j]symbol: symbol, <SYM1>, <SYM2>, ...
returns{symbol, currency, price, returns: [{period, label, start_price, end_price, return_percent, annualized_percent, growth_of_100000}]} — annualized_percent is null for spans under a yearperiod
movers{gainers: [row], losers: [row]}, row = {side, rank, symbol, price, change_percent, volume, currency, cap_tier}stock, gainers then losers
sectors[{sector, symbol, price, change_percent, currency}], best firstsector
screen[{symbol, name, price, change_percent, pe, market_cap, dividend_yield, currency, cap_tier}]match
dividends{symbol, currency, price, pays_dividend, dividend_yield_percent, annual_dividend_per_share, income: [{invested, shares, annual_income, monthly_income}], drip: [{year, shares, growth_percent}]}—
backtest{symbol, currency, strategy, period, interval, bars, start, end, fill, capital, start_value, end_value, total_return_percent, cagr_percent, max_drawdown_percent, sharpe, sortino, exposure_percent, trade_count, win_rate_percent, avg_win_percent, avg_loss_percent, profit_factor, costs_paid, gross_return_percent, buy_hold_return_percent, alpha_percent, skipped_entries, costs, cost_model, rules, trades: [trade], equity: [{date, value}]} — returns are after costs except gross_return_percent; portfolio and walkforward shapes are in backtesting.md. trade = {symbol, entry_date, exit_date, qty, entry_price, exit_price, gross_pnl, costs, net_pnl, pnl_percent, bars_held, exit_reason}trade (every form)
sip{symbol, currency, period, interval, monthly_amount, months, total_invested, final_value, profit, total_return_percent, xirr_percent, total_units, avg_cost, current_price}—
whatif{symbol, currency, amount, date, buy_date, buy_price, shares, invested, current_price, value, pnl, pnl_percent, cagr_percent, days, years} — buy_date is the trading day closest to date—
portfolio{holdings: [holding], totals: {cost_basis, value, pnl, pnl_percent, currency}, unpriced: [symbol], unconverted: [symbol], notes: [text]}, holding = {symbol, shares, avg_cost, cost_basis, price, value, pnl, pnl_percent, weight_percent, xirr_percent, currency, name, price_source, nav_date} — a holding’s money values are in its own currency; totals and weight_percent are in the base currency (--base); unconverted holdings had no exchange rate; price_source is quote, amfi_nav, nse_sgb, gold_estimate or null (no price) and nav_date the date of a fund’s NAV; notes explain fund and SGB prices (unknown codes, estimates)holding
watch[{symbol, price, change, change_percent, volume, currency}], in watchlist ordersymbol
alert list[{index, symbol, condition, target, created_at, period, description}] — index is what alert remove takes; condition is the CLI name (above, rsi-below, …), period the RSI or volume-average length (else null), description the condition in English wordsalert
alert check[{index, symbol, condition, target, price, currency, status, period, description, value, reference}] — status is triggered, waiting, no_price (price alert without a live price) or no_data (too little history, or no results date); value is what the condition compared (price, RSI, day change %, volume multiple, days to results; the close for crosses and breakouts) and reference the moving average, previous high/low or average volumealert
calendar[{date, days_until, when, symbol, event, detail, source, estimate}] — when is today, tomorrow, this_week (within 7 days) or later; event is results, board_meeting, ex_dividend, dividend_paid, split, bonus, rights or other; source is yahoo or nse; estimate marks Yahoo’s unconfirmed earnings dates. Notes (e.g. NSE refused) go to stderrevent
portfolio benchmark{benchmark: {symbol, name, currency, converted_to_base}, base_currency, period, start, end, trading_days, portfolio_return, benchmark_return, excess_return, portfolio_annualized, benchmark_annualized, metrics: {observations, alpha, beta, tracking_error, information_ratio, correlation}, holdings: [holding], sectors: [{sector, holdings, avg_weight, end_weight, return_pct, contribution, active_contribution}], flagged: [{symbol, reason}], series: [{date, portfolio, benchmark}]}, holding = {symbol, sector, avg_weight, end_weight, return_pct, contribution, active_contribution, days_held, days_unpriced, flag} — returns, weights, alpha and tracking_error are percentages, contributions are percentage points; annualized returns only for periods over about 13 months; series is growth of 100; figures are null when nothing was heldholding
portfolio pme{summary: {benchmark_symbol, benchmark_name, base_currency, start_date, end_date, total_invested, total_distributed, actual_value, twin_value, value_added, kaplan_schoar_pme, direct_alpha_percent, portfolio_xirr_percent, twin_xirr_percent, twin_shares, benchmark_end_price}, holdings: [{symbol, actual_value, twin_value, value_added, pme_ratio, direct_alpha_percent, actual_xirr_percent, twin_xirr_percent, cashflows_count}]} — Public Market Equivalent (Index Twin) analysis; kaplan_schoar_pme is the KS-PME ratio (> 1.0 indicates outperformance); direct_alpha_percent is the annualized excess return rate (%)holding row
portfolio xray{portfolio_name, base_currency, total_value, effective_holdings: [{symbol, name, direct_value, direct_weight_pct, fund_value, fund_weight_pct, total_value, effective_weight_pct, is_concentrated, via_funds: [{fund_symbol, value, weight_in_fund_pct, effective_weight_pct}]}], concentrations_above_10pct: [effective_holding], market_cap_breakdown: {large_cap_value, large_cap_pct, mid_cap_value, mid_cap_pct, small_cap_value, small_cap_pct, unclassified_value, unclassified_pct}, sector_allocation: [{sector, value, weight_pct}], asset_class_split: {equity_value, equity_pct, debt_value, debt_pct, commodity_value, commodity_pct, cash_value, cash_pct}, funds_analyzed: [{symbol, name, look_through_available, holdings_count, coverage_pct}]}effective holding
tax export{country, tax_year, period_start, period_end, currency, disclaimer, sales: [sale], summary, other_currency: [symbol], virtual_digital_assets: [symbol], intraday_sales, intraday_gain, other_rules: [symbol], notes: [text]} (virtual_digital_assets, intraday_sales, intraday_gain and other_rules for India only) — India: sale = {section, term, isin, scrip, symbol, quantity, sale_date, sale_price, sale_value, purchase_date, purchase_price, cost, actual_cost, fmv_31_jan_2018, holding_days, gain, grandfathered, purchase_date_estimated}, summary = {stcg_111a_sale_value, stcg_111a_cost, stcg_gains, stcg_losses, ltcg_112a_sale_value, ltcg_112a_cost, ltcg_gains, ltcg_losses, st_loss_set_off_against_ltcg, taxable_stcg, ltcg_after_set_off, ltcg_exemption, taxable_ltcg, taxable_stcg_before_23_jul_2024, taxable_ltcg_before_23_jul_2024, stcg_tax, ltcg_tax, cess, total_tax, st_loss_carried_forward, lt_loss_carried_forward}; US: sale = {part, description, symbol, quantity, date_acquired, date_sold, proceeds, cost_basis, gain_or_loss, date_acquired_estimated}, summary = {short_term_proceeds, short_term_cost, short_term_gain, long_term_proceeds, long_term_cost, long_term_gain, net_gain, taxable_short_term, taxable_long_term, loss_deductible_this_year, loss_carryover, short_term_tax, long_term_tax, total_tax}— (the CSV is the schedule itself, see Tax export)
harvest{country, currency, total_st_loss_harvestable, total_lt_loss_harvestable, estimated_loss_tax_saved, ltcg_exemption_limit, ltcg_exemption_remaining, loss_candidates: [row], gain_harvest_candidates: [row], fifo_blocked: [{symbol, shares_to_sell, net_result, lot_loss}], unpriced: [symbol], other_rules: [{symbol, reason}], other_currency: [symbol]}, row = {symbol, shares, avg_cost, price, pnl, pnl_pct, st_pnl, lt_pnl, estimated_tax_saved, harvest_type} — harvest_type is tax_loss or ltcg_exemption_step_up; for India shares, st_pnl and lt_pnl describe the whole FIFO sale that reaches the losing lot; fifo_blocked holdings would book a net gain (net_result > 0) if sold up to the losing lot, so they are not offered as losses; other_currency and other_rules holdings are left outrow
rebalance{total_value, projected_value, currency, inflow, drift_tolerance, items: [{symbol, current_value, current_pct, target_pct, projected_value, projected_pct, price, diff_value, diff_shares, action_type, action_display, is_fund}]} — action_type is buy, sell or ok; with --inflow nothing is solditem
verdict{symbol, name, price, currency, overall_score, data_coverage, pillar_bands: {strong, moderate, weak, no_data}, pillars: [{name, score, weight, band, inputs_present, inputs_possible, summary}], note, bull_points: [text], bear_points: [text], next_catalyst, warnings: [text], disclaimer} — score and overall_score are 0–100 and null when there is no data (then band is no_data and the pillar is left out of the composite); band is strong (65+), moderate (45–64), weak or no_data; weight is a share of 1; data_coverage is the share of input data present, in percent; note says why there is no composite—
score / scorecard{symbol, name, currency, price, market_cap, sector, industry, piotroski: {score, max_score, evaluated, rating, rating_label, profitability_score, leverage_score, efficiency_score, criteria: [{id, category, name, formula, formatted_value, passed, points, explanation, evaluated}]}, altman: {z_score, zone, zone_label, formula_str, is_financial, note, missing_factors, components, z_double_prime, z_double_prime_zone, z_double_prime_components, z_double_prime_formula_str}, evaluation_date} — evaluated counts the signals that had data (score out of evaluated, not always out of 9); rating is null unless all nine ran; z_score is null with the missing ratios in missing_factors—
options oi{symbol, source, underlying, currency, expiry, expiries, lot_size, pcr: {call_oi, put_oi, call_volume, put_volume, oi_ratio, volume_ratio}, pcr_sentiment, max_pain, top_calls: [wall], top_puts: [wall], breakdown: {calls: {long_buildup_oi, short_covering_oi, short_buildup_oi, long_unwinding_oi, neutral_oi, long_buildup_count, ...}, puts: {...}}, calls_sentiment, puts_sentiment}, wall = {strike, open_interest, share_pct, oi_change, price_change, last_price, buildup} — buildup is long_buildup, short_covering, short_buildup, long_unwinding or null (on screen LB, SC, SB, LU); calls_sentiment and puts_sentiment read each side for the underlying (put buying is bearish, put writing bullish); pcr_sentiment, calls_sentiment and puts_sentiment are words such as Bullish—
tax advance{fy_label, fy_start, fy_end, as_of, total_stcg, total_ltcg, total_tax_estimated, sec_208_threshold, sec_208_applicable, total_paid, payments: [{date, amount}], assumed_on_time, ignored_before_year, total_sec_234c_interest, sec_234b_applicable, quarters: [{quarter, due_date, cutoff_date, stcg_quarter, ltcg_quarter, stcg_cumulative, ltcg_cumulative, cumulative_tax_estimated, required_cumulative_pct, min_cumulative_tax_required, quarter_tax_payable, paid, shortfall, sec_234c_interest, status}]} — paid is what was paid on or before that due date; status is paid, pending, upcoming, overdue or nothingduequarter row
goal sip{target, years, months, annual_return_pct, effective_annual_pct, step_up_pct, savings, savings_future_value, monthly_sip, final_monthly_sip, total_invested, gains, lump_sum_today, schedule: [{year, monthly_sip, invested, value}], monthly_schedule: [{month, monthly_sip, invested, value, lots_long_term}], regime: {kind, name, return_pct, vol_pct, source}, glide, target_today, inflation_pct, real_value_today, real_value_cpi_pct, net_target, tax: {kind, slab_pct, exit_load_pct, short_term_lots, long_term_lots, short_term_gain, long_term_gain, exit_load, tax}, net_after_tax, monthly_sip_for_net_target, percentiles: {p10, p50, p90, success_prob_pct, basis, gross: {p10, p50, p90}, net}, sensitivity: [{return_pct, monthly_sip}], mismatch, tax_compare: [{kind, net_after_tax}], warnings: [text], goal, currency} — goal is sip, retire, education, swp, prepay, emergency, list or show; monthly_schedule only up to 24 months; glide, target_today, real_value_today, mismatch and tax_compare only when they apply—
goal retire{monthly_expense_today, years_to_retire, years_in_retirement, inflation_pct, return_pre_pct, return_post_pct, monthly_expense_at_retirement, monthly_income_today, monthly_need_at_retirement, buffer_years, legacy, corpus, initial_withdrawal_rate_pct, survival_years, crash_survival_years, swp_drag: {annual_withdrawal, gain_fraction, swp_tax, fd_tax}, sip: plan, goal, currency} — plan is the first part of the goal sip object (up to schedule)—
goal education{cost_today, years, months, inflation_pct, future_cost, sip: report, goal, currency} — report is the full goal sip object—
goal swp{corpus, cost_basis, monthly_withdrawal, inflation_pct, return_pct, years, fd_return_pct, slab_pct, initial_withdrawal_rate_pct, swp: path, fd: path, goal, currency} — path = {runway_months, lasts, final_value, total_withdrawn, total_tax}—
goal prepay{principal, loan_rate_pct, remaining_months, emi, extra_monthly, lump_sum, new_tenure_months, tenure_saved_months, interest_without_prepay, interest_saved, sip_return_pct, sip_tax, sip_net, prepay_equivalent, sip_percentiles, breakeven_return_pct, goal, currency}—
goal emergency{monthly_expense, months_cover, target, liquid, funded_pct, horizon_months, build: plan, goal, currency}—
goal list{goal, currency, goals: [{name, target, target_future, by, months_left, holdings, linked_value, funded_pct, monthly_sip, status}]} — status is funded, needs_sip or overdue—
tax{country, tax_year, currency, sales: [{symbol, qty, bought, bought_estimated, sold, gain, term}], holdings: [{symbol, cost, value, short_term_gain, long_term_gain, estimated_dates}], realized: estimate, if_sold_today: estimate, ltcg_exemption_left, unpriced: [symbol], other_currency: [symbol], equity_funds: [symbol], other_rules: [{symbol, reason}], intraday_sales: [{symbol, qty, bought, bought_estimated, sold, gain, term}], intraday_gain}, estimate = {short_term_gains, short_term_losses, long_term_gains, long_term_losses, taxable_short_term, taxable_long_term, exemption_used, short_term_tax, long_term_tax, cess, total_tax, loss_carried_forward} — term is short, long, or null (UK); ltcg_exemption_left is India only; equity_funds (counted at listed-share rates), other_rules (left out: debt/other funds, SGBs) and intraday_sales (bought and sold on one day: slab-rate speculative income, left out of every estimate) are filled for Indiaopen holding
sim history{stats: {days, winning_days, day_win_rate_percent, total_pnl, avg_daily_pnl, best_day, worst_day, trades, winning_trades, losing_trades, trade_win_rate_percent, sharpe, max_win_streak, max_loss_streak}, confidence, sessions: [{date, market, capital, target_percent, settled, trades, pnl, pnl_percent, wins, losses}]} — confidence is high, moderate, low, or null before 5 settled days—
trade selftest{stockwise, os, date, market, broker, broker_name, experimental, account, secrets, orders_enabled, max_order_value_set, amounts_redacted, read_only, checks: [{name, status, detail}], shapes: [{endpoint, status, rows, missing, unknown, error}], summary: {pass, warn, fail, skip}} — status is pass, warn, fail or skip; account is the last 2 characters only—
trade sync{broker, experimental, portfolio, since, applied, orders: [{symbol, order_id, side, date, time, qty, price, fills, result, sales?, held?}], already_synced, skipped: [{order_id, symbol, reason}], open_orders: [{order_id, symbol, side, status, qty, filled_qty}], quantity_check: [{symbol, portfolio_qty, broker_qty}], gtt_changes: [change], notes} — result is lot, sold (with sales) or unmatched (with held); applied is true only when --apply wrote something—
trade gtt list{broker, experimental, gtts: [{id, symbol, side, qty, trigger, limit, status}], changes: [change], first_check, last_checked}, change = {kind, id, symbol, side, qty, trigger, from, to, state} — kind is new, status or gone; state is active, triggered, cancelled, expired, rejected or other—
sim replay list[{name, title, market, from, to, benchmark, benchmark_name, capital, stocks, description}]—
sim replay status{scenario, title, market, date, day, days, last_day, capital, cash, invested, equity, return_percent, max_drawdown_percent, costs_paid, cost_model, benchmark: {symbol, name, close, return_percent}, positions: [{symbol, sector, qty, avg_price, close, value, pnl, pnl_percent, weight_percent, stop, target, opened}], orders: [order], universe: [{symbol, sector, close, change_percent, change_20d_percent}], challenge, finished_challenges: [outcome], disclaimer} — only data known at the replay date’s close; sim replay start adds description and skipped. order = {id, side, symbol, qty, stop, target, placed}; challenge = {name, title, description, day, days, started, rules: [{rule, goal, hard}], violations: [{date, rule, detail, hard}]}; outcome = {name, title, passed, reason, from, to, goals: [{goal, met, detail}], violations, sip}—
sim replay next{days: [{date, events: [event]}], new_badges, status} — event is fill ({date, symbol, side, qty, price, charges, reason, with_stop, weight_percent, pnl}, reason = order, stop-loss or target), contribution ({amount}), rejected ({symbol, side, qty, reason}), waiting ({symbol, side}), rule_broken (a violation), challenge_over (an outcome) or last_day—
sim replay buy / sell{order, warnings: [violation]} — warnings are soft challenge rules the order breaks—
sim replay end{kind, name, title, market, benchmark_name, from, to, finished, scorecard: {days, score, grade, return_percent, benchmark_return_percent, max_drawdown_percent, benchmark_max_drawdown_percent, sharpe, benchmark_sharpe, sortino, benchmark_sortino, exposure_percent, parts: {risk_adjusted, drawdown, discipline, diversification}}, badges, new_badges, disciplined, challenges: [{name, title, passed, reason}], curve, benchmark_curve, debrief, disclaimer} — score/grade are null under 5 trading days; curves are rebased to 100—
sim challenge list[{name, title, description, days, modes, monthly_contribution, rules: [{kind, ...}]}] — days 0 = until the replay ends—
sim challenge status{mode, challenge, ...} — mode replay adds finished: [outcome]; live adds sessions, complete, return_percent, benchmark_return_percent, max_drawdown_percent, violations; challenge is null when none runs—
sim challenge endreplay: {outcome, new_badges}; live: the sim replay end shape plus outcome—
sim profile{badges: [{id, title, how, earned, run}], streaks: {disciplined: {current, best}, challenges: {current, best}}, best: {NAME: {score, grade, date}}, challenges_passed, challenges_failed, runs: [run], disclaimer} — earned is null for badges not earned yet; run = the sim replay end shape without debrief/disclaimer—
config show{path, status, error, settings: [{key, value, source}]} — status is loaded, missing or invalid; source is flag, env, file or default—

Alert conditions

Guide: Set up alerts and the daemon.

stockwise alert add <SYMBOL> <CONDITION> <NUMBER>:

ConditionNUMBERFires when
above / below (> / <)pricethe live price is at or beyond the level
rsi-below / rsi-aboveRSI level (0–100)RSI (14-day, or --period N) is at or beyond the level
cross-above-sma / cross-below-smadays (2–400)the daily close crosses its simple moving average — on the crossing day only
cross-above-ema / cross-below-emadays (2–400)the same with an exponential moving average
breakout-high / breakdown-lowdays (2–1000)the close is above the highest high (below the lowest low) of the previous N sessions
change-above / change-belowpercentthe day’s change is +N% or more / −N% or less (change-below 3 and change-below -3 are the same)
volume-spikemultiple (1–100)today’s volume is at least N times its 20-day (--period) average
results-indays (0–90)the next results date is at most N days away (from calendar)

Technical conditions read daily bars (one chart request per symbol per check), with the last bar updated to the live quote, so a cross or breakout fires on the session it happens in. A symbol with too little history reads no_data and never triggers. alert watch notifies each alert once until it re-arms, at most once per trading day.

stockwise alert add INFY rsi-below 30
stockwise alert add INFY rsi-above 70 --period 9
stockwise alert add RELIANCE cross-above-sma 200
stockwise alert add AAPL -m us breakout-high 52
stockwise alert add HDFCBANK change-below 3
stockwise alert add TCS volume-spike 2
stockwise alert add TCS results-in 7

Alerts saved by earlier versions keep working unchanged.

Results and corporate calendar

Guide: Check a stock or fund fast and Set up alerts and the daemon.

stockwise calendar lists what is coming up for your holdings and watchlist (--holdings or --watchlist for one of them, or name symbols), over the next 30 days (--days 1-365):

SourceCoversEvents
Yahoo Finance (quoteSummary calendarEvents)US and Indian stocksresults (earnings) date or expected window with the EPS estimate, ex-dividend date, dividend payment date
NSE board meetings.NS / .BO stocks (looked up by their NSE symbol)board meetings; those that consider results are listed as results
NSE corporate actions.NS / .BO stocksex-dates of dividends, splits, bonus and rights issues, other actions
  • For an Indian stock, NSE’s filed results date replaces Yahoo’s estimate, and NSE’s ex-dividend date replaces Yahoo’s.
  • Upcoming splits come from NSE only; Yahoo lists splits after they happen, so US splits don’t appear in advance.
  • BSE filings are not read; a .BO symbol uses the same company’s NSE filings.
  • NSE’s API serves browser sessions. StockWise opens one session per run, waits a second between requests and caches every answer for a day in calendar_cache.json (failures for an hour). When NSE refuses, the table says so and shows Yahoo’s dates.
  • Crypto, FX and indices have no calendar and are skipped.
stockwise calendar
stockwise calendar --holdings --days 14
stockwise calendar TCS INFY
stockwise calendar AAPL MSFT -m us --json

Configuration file

Everything works without one. To set your own defaults:

stockwise config init     # write a commented template
stockwise config path     # where it is
stockwise config show     # every effective setting and where it came from

The file is config.toml in your platform’s config directory — ~/Library/Application Support/stockwise/ on macOS, ~/.config/stockwise/ on Linux ($XDG_CONFIG_HOME), %APPDATA%\stockwise\ on Windows — or the file named by STOCKWISE_CONFIG.

market = "us"                       # in | us | crypto | fx | commodity | uk | de | jp | hk | sg | ca | au
lang = "hi"                         # en | hi
quote_currency = "inr"              # BTC → BTC-INR with -m crypto
portfolio = "long-term"             # a named portfolio
ai = false
ai_provider = "ollama"              # ollama | openai | anthropic | gemini
model = "llama3.1:8b"
ollama_host = "http://gpu-box:11434"
data_provider = "yahoo"             # yahoo | alphavantage | massive | twelvedata
redis_url = "off"
home = "~/Dropbox/stockwise"        # data directory; ~ is your home

[periods]                           # default -p per command
technical = "6mo"
backtest = "5y"
sip = "10y"

[notify]                            # STOCKWISE_* notification variables, lower-case, no prefix
telegram_chat_id = "123456789"
smtp_host = "smtp.gmail.com"
email_to = "me@example.com"
KeyOverridden byBuilt-in default
market-m, STOCKWISE_MARKETin
ai--ai / --no-ai, STOCKWISE_AIfalse
modelSTOCKWISE_MODELqwen3:14b
ollama_hostOLLAMA_HOSThttp://localhost:11434
redis_urlSTOCKWISE_REDIS_URLredis://127.0.0.1:6379/
homeSTOCKWISE_HOMEplatform data directory (see doctor)
lang--lang, STOCKWISE_LANGyour locale, else en
quote_currency--quote-currency, STOCKWISE_QUOTE_CURRENCYusd
portfolio--portfolio, STOCKWISE_PORTFOLIOdefault
ai_providerSTOCKWISE_AI_PROVIDERollama
data_providerSTOCKWISE_DATA_PROVIDERyahoo
[periods] <command>-pper command, see <command> --help
[notify] <key>STOCKWISE_<KEY>none (see notifications)

[periods] accepts the commands that take -p: deep, technical, history, risk, patterns, support, fibs, volume, gaps, stoploss, forecast, options, backtest, sip. --help shows the default from your file, e.g. [default: 6mo].

A file that doesn’t parse — an unknown key, a wrong type, an unknown market or period — stops every command with exit code 1 and an error naming the file and the key. config, doctor and completions still run, so you can inspect it or replace it with stockwise config init --force.

API keys (OPENAI_API_KEY, the data provider’s key, …) and STOCKWISE_API_TOKEN are read from the environment only. Notification tokens and passwords may go in [notify]; if they do, keep the file private (chmod 600) — config show and doctor warn when other users can read it.

stockwise serve answers with the same shapes over HTTP — see server.md.