TickerTrail is a terminal app for tracking stocks and indices, comparing performance, and managing watchlists.
It works well for India-first workflows (.NS/NSE aware) and also supports global symbols.
Install uv first (if not already installed):
macOS / Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
uv --versionmacOS (Homebrew alternative):
brew install uv
uv --versionWindows (PowerShell):
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
uv --versionThen clone and run:
git clone https://github.com/vsjha18/tickertrail.git
cd tickertrail
uv sync
uv run tickertrail- Check live quote snapshots
- View swing and intraday charts in terminal
- Compare stocks vs benchmark (
cmp,t,tt) - Open index boards and constituent snapshots (
index,snap) - Build and manage persistent watchlists
- Run analytics boards (
move,trend,relret/rr,corr)
- Start REPL:
uv run tickertrail- Enter a symbol or index alias:
reliance
nifty
bank
- Run analytics and charts:
quote
c 6mo
t 1y
move 1mo
trend
relret 3mo
corr 6mo
Many commands are context-sensitive. You usually do not need arguments.
- Entered by typing a stock symbol (example:
infy). quote,c,cc,t,ttrun on the active symbol.move,trend,relretrun on the active symbol.corrneeds at least two symbols, so usecorr on <code1> <code2> ....
- Entered by typing an index alias/symbol (example:
nifty,it,defence,^cnxit). - If live quote fields are partial, TickerTrail still keeps you in index mode and shows the best available values.
snapshows constituents for supported indices.move,trend,relret,corrcan be run with no arguments:moveruns over index constituents when available.trendruns over index constituents when available.relretruns over index constituents with an index-appropriate benchmark.corrruns over index constituents and needs at least two valid overlapping series.
- Entered with
watchlist open <name>. move,trend,relret,corrwith no arguments run on symbols in that watchlist.snapshows the current watchlist snapshot.
- Works from any context.
move on <codes...> [period]trend on <codes...>relret on <codes...> [period] [vs <benchmark> [period]]corr on <codes...> [period]
movedefault period:1motrend: no period argumentrelret/rrdefault period:1mocorrdefault period:1mo
- Watchlist mode: benchmark defaults to
NIFTY 50 (^NSEI) - Index mode: benchmark defaults by active index context
- Explicit
relret on ...: default benchmark isNIFTY 50 (^NSEI) vs <benchmark>overrides default benchmark selection
cdefault period:6mo(default interval auto-selected from period)tdefault period:6mo(default bin auto-selected from period:<=7d -> 1d,<=1mo -> 1wk,>1mo and <=3y -> 1mo,>3y -> 1y)ccdefault interval:5mttdefault interval:5mcmpdefault period:6mo(with auto interval)
move->move 1moin index/watchlist contextstrend-> trend board for current context (index/watchlist/symbol)relret/rr->relret 1mofor current contextcorr->corr 1moin index/watchlist contextsc-> swing chart for active symbol (6mo defaults)t-> rebased table for active symbol (6mo defaults)cc-> intraday chart for active symbol (5m)tt-> intraday table for active symbol (5m)
These snippets are captured from the real CLI renderers with fixed sample data, so the formatting matches actual command output.
tt> quote
INFY.NS Infosys Ltd. [INR]
Px 1,941.20 Chg +19.80 (+1.03%) O 1,928.00 L/H 1,918.10/1,952.30
Vol 8.23M MCap 8.04T Updated 02-03-26 02:04:28
Day Range [──────────────────────────●─────────────] 1,918.10 .. 1,952.30
52W Range [──────────────────────────────────●─────] 1,380.20 .. 2,015.80
30D Moves oooooooooooooooooooooooooooooo
Returns 7D +0.85% 1MO +4.78% 3MO +18.69% 6MO +46.30% 9MO +92.17% 1Y n/a
Signal TrendScore 5/5 RSI14 100.0 Vol/20D 1.02x
Risk MaxDD(1Y) +0.00% WinRate(1Y) 100.00%
Extremes Best +0.73% (03-03-25) Worst +0.09% (28-02-26) Skew n/a
PE(TTM) 30.80 | PEG 2.10 | ROE 30.20%
tt> move on infy tcs reliance 1mo
Moves (1MO) - Explicit symbols
Symbol 1MO Moves Dots
INFY.NS 1MO Moves oooooooooooooooooooooooooooooo
TCS.NS 1MO Moves oooooooooooooooooooooooooooooo
RELIANCE.NS 1MO Moves oooooooooooooooooooooooooooooo
tt> trend on infy tcs reliance
Trend (Current) - Explicit symbols
Symbol Trend Score
INFY.NS 5.0/5.0
TCS.NS 5.0/5.0
RELIANCE.NS 5.0/5.0
tt> rr on infy tcs reliance vs nifty 1mo
Relative Return (1MO) - Explicit symbols vs NIFTY 50 (^NSEI)
Symbol Return Bench RelRet
INFY.NS +15.13% +12.06% +3.07%
RELIANCE.NS +13.24% +12.06% +1.18%
TCS.NS +10.86% +12.06% -1.20%
tt> corr on infy tcs reliance 1mo
Correlation Summary (1MO) - Explicit symbols
Universe: 3 symbols | overlap points: 29
Most Positive Pairs
TCS.NS <-> RELIANCE.NS +1.00
INFY.NS <-> RELIANCE.NS +1.00
INFY.NS <-> TCS.NS +1.00
Most Negative Pairs
n/a
Near-Zero Pairs (Diversifiers)
n/a
tt> snap
Snap: NIFTY IT (10 constituents)
Symbol Price Change Range
TCS.NS 1,010.00 +0.80 (+0.08%) [─────●──────]
LTIM.NS 1,070.00 +0.80 (+0.07%) [──────●─────]
PERSISTENT.NS 920.00 +0.50 (+0.05%) [──────●─────]
INFY.NS 1,070.00 +0.50 (+0.05%) [──────●─────]
HCLTECH.NS 940.00 +0.20 (+0.02%) [──────●─────]
...
Snap fetch passes used: 1
Grouped snapshot views (index, snap, and watchlist snapshots) use batched download minute bars during market hours, with missing symbols retried in later batch passes and no cached data in that live workflow. After market close they fall back to daily-close batch data.
Analytics that depend on the latest daily point, such as move, trend, relret, and corr, overlay the current batched minute-market price during market hours and fall back to cached/EOD history when the market is closed.
For supported indices that need a Yahoo-specific fetch code, TickerTrail keeps one explicit fetch-symbol mapping per index instead of probing multiple alternates at runtime.
If the index board's grouped batch fetch comes back empty after an idle session, TickerTrail falls back to direct per-index quote fields for those rows instead of showing a board full of n/a.
Grouped snapshot commands print one freshness line under the title or section header, and daily analytics commands print a live-overlay freshness line only when the latest daily point has been updated from minute-bar data.
tt> c 6mo
^CNXIT close (6mo, 1d) +68.71 (+47.72%)
┌─────────────────────────────────────────────────────────────────────────┐
246.3┼───────────────────────────────────────────────────────────────────────••┤
│ ••••••• │
231.7┼────────────────────────────────────────────────────────────•••••────────┤
│ •••••• │
217.0┼──────────────────────────────────────────────────•••••──────────────────┤
│ •••••• ▗▄▄▄▄▞▀•│
202.4┼───────────────────────────────────────•••••───────────────▄▄▄▞▀▀▘───────┤
└┬───────┬───────┬───────────────┬───────┬───────┬───────────────┬────────┘
03-09-25 23-09-25 13-10-25 21-11-25 11-12-25 31-12-25 09-02-26
Day Range [────────────────────────────●─────────────────────] 144.00 .. 212.71
52W Range [───────────────●──────────────────────────────] 120.00 .. 260.00
Last: 212.71
Move: +68.71 (+47.72%) | From: 03-09-25 -> 01-03-26
tt> cc 5m
^CNXIT close (1d, 5m) +7.21 (+0.50%)
┌────────────────────────────────────────────────────────────────────────┐
1448.3┼────────────────────────────•••─────────────────────────────────────────┤
│ ••▀• │
1446.6┼──────•───────────────────▗•────────────────────────────────────────────┤
│ ••▄•• •• │
1444.8┼───••───▚•───────────────•──────────────────────────────────────────────┤
│ •▘ •• •▘ │
1435.9┼────────────────••••────────────────────────────────────────────────────┤
└┬───────────────────────────────────┬──────────────────────────────────┬┘
05:55 10:45 15:30
Day Range [────────────────────────────●─────────────────────] 1,435.90 .. 1,448.30
52W Range [───────────────●──────────────────────────────] 120.00 .. 260.00
Move: +7.21 (+0.50%) | From: 05:55 -> 10:00
tt> t 1y
Rebased Co-Plot (base=100): ^CNXIT vs NIFTY 50 [period=1y, bin=1mo]
Date Range: 05-04-25 -> 01-03-26
Date Stock Bench Delta Alpha%
05-04-25 100.00 100.00 +0.00 +0.00%
05-05-25 100.44 100.59 -0.15 -0.15%
04-06-25 100.87 101.17 -0.30 -0.30%
...
Final Relative (Stock - Bench): -1.43
Final Alpha% (Stock vs Bench): -1.37%
tt> tt 15m
Rebased Co-Plot (base=100): ^CNXIT vs NIFTY 50 [period=1d, bin=15m]
Date Range: 21:45 -> 10:00
Date Stock Bench Delta Alpha%
21:45 100.00 100.00 +0.00 +0.00%
00:15 100.38 100.43 -0.05 -0.05%
02:45 100.00 100.00 -0.00 -0.00%
...
Final Relative (Stock - Bench): -0.07
Final Alpha% (Stock vs Bench): -0.07%
Tables are unsampled: row spacing always matches the header bin (for example bin=5m means 5-minute rows, bin=1wk means weekly rows).
tt> cmp tcs infy reliance 1y w
Compare (base=100): TCS.NS, INFY.NS, RELIANCE.NS [1y, 1wk]
Date Range: 09-03-25 -> 01-03-26
Date TCS.NS INFY.NS RELIANCE.NS
09-03-25 100.00 100.00 100.00
18-05-25 103.72 105.19 104.53
27-07-25 106.45 109.45 108.04
...
Final 118.48 126.02 122.63
h/help [topic|command]: help systemquote/q: show active symbol/index quotecache: show today's history cache summarycache clear: clear today's history cachereload/r: refresh quote and replay last chart/tablecls/clear: clear terminal- Press
Ctrl+Cduring an in-progress command to cancel that command and return to the prompt - Press
Ctrl+Con an empty prompt to exit the REPL quit/exit: leave REPL!<shell-cmd>: run shell command
<symbol>: switch active symbol and print quotecode <query>: fuzzy ticker lookup from local universenews <code>: recent headlines for a symbol/index aliasindex: index boardindex list: supported index catalogsnap: snapshot for active index/watchlist context
- Swing chart:
c [<benchmark>] [<period>] - Swing chart (dash override):
c [<benchmark>] - <period|agg> [agg] - Intraday chart:
cc [<benchmark>] [<1m|5m|15m|30m|1hr>] - Swing table:
t [<benchmark>] [<period>] - Swing table (dash override):
t [<benchmark>] - <period|agg> [agg] - Intraday table:
tt [<benchmark>] [<1m|5m|15m|30m|1hr>] - Multi-symbol compare:
cmp <symbol1> <symbol2> [symbolN ...] [period [agg]]
Period and aggregation tokens:
- Period units:
d,w,mo,y,max - Aggregation units:
m,d,w,mo,y mmeans minute,momeans month
Override examples (t/c/cc/tt):
- Active symbol stays the same; first positional token is benchmark override.
- Change only bin size:
t - w,c - mo,cc - 15m,tt - 30m - Change benchmark + bin size:
t bank - w,c nifty - mo,cc bank - 15m,tt bank - 30m - Change period + bin size (swing only):
t - 1y mo,c - 2y w - Yearly binning example:
t - 5y y
Top-level:
watchlist create <name>watchlist listwatchlist open <name>watchlist delete <name>watchlist merge <wl1> <wl2> <target>watchlist(exit watchlist mode)- If the watchlist database cannot be read temporarily, the app reports a database read error instead of incorrectly saying the watchlist does not exist.
Inside watchlist mode (tt>watchlist>sharekhan>):
add <code...>delete <code...>list/llsnapmove [period]move on <code1> <code2> ... [period]moveperiod acceptsNd,Nmo(N < 12), orNy(for example5d,2mo,3y).
trendtrend on <code1> <code2> ...relret [period]rr [period]relret [period] [vs <benchmark> [period]]relret on <code1> <code2> ... [period] [vs <benchmark> [period]]relretperiod acceptsNd,Nmo(N < 12), orNy(for example5d,2mo,3y).
corr [period]corr on <code1> <code2> ... [period]corrperiod acceptsNd,Nmo(N < 12), orNy(for example5d,2mo,3y).
help
code national thermal
watchlist create swing
watchlist open swing
add tcs infy reliance
snap
move 1mo
trend
relret
corr
c 1y
t nifty 6mo w
- Watchlists are stored locally in
data/db.json - Local symbol universe file:
data/nse_equity_list.csv - Index constituent mapping:
data/index_constituents.csv - Local history cache:
.cache/history/
- Some symbols/intervals can return partial market data.
- Intraday availability can vary by symbol and market session.
cc 1mandcc 5mcan differ slightly because of timing and data availability.- Quote
Day Rangeand52W Rangeare rendered as terminal-friendly bars. - You can also start directly with a symbol, for example:
uv run tickertrail RELIANCE