A live, always-on trading dashboard + algorithmic SIP / swing / F.I.R.E. engine for the Indian stock market โ built for a Euro-resident investor.
"Earn in Euros, invest in Rupees, watch it from a Pi on the wall."
One Python package, three deliverables, one DuckDB file:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ pure strategy core โ
โ (no I/O, no Rich, async- โ
โ agnostic โ fully tested) โ
โโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
โโโโโโโโโผโโโโโโโโโ โโโโโโโโโโโโผโโโโโโโโโโโ
โ imbot daemon โ writes โโโโโโโโโโโโโโโ โ imbot ui โ
โ (asyncio + โโโโโโโโโโโบโ state.duck โโโโโค (Textual TUI; โ
โ APScheduler) โ โ db โ โ read-only; โ
โ โ โโโโโโโโโโโโโโโ โ refreshes 2-10s) โ
โโโโโโโโโโโโโโโโโโ โฒ โฒ โฒ โโโโโโโโโโโโโโโโโโโโโโโ
โ โ โ
โ โ โโโโโ imbot fire / dividend / swing / project
โ โโโโโโโ imbot backtest dividend / swing
โโโโโโโโโ imbot optimize --param atr-mult=...
imbot daemon runs cron-style jobs: refresh prices every 5min during NSE hours, scan for swing setups at 15:25 IST, regenerate the dividend list at 16:00 IST, deposit your monthly SIP on the last NSE trading day. imbot ui is a Textual dashboard with live positions, equity curve, bot brain, and event log โ read-only DuckDB so it never blocks the daemon.
# 1. Clone + venv
git clone https://github.com/GhostRoboticsLab/IndianMarketBot.git
cd IndianMarketBot
python3.11 -m venv venv
source venv/bin/activate
# 2. Install (editable, with dev extras)
pip install -e ".[dev]"
# 3. Verify
pytest -q # 69 tests, ~1s
# 4. Pick your entry point
imbot menu # interactive picker
imbot fire # one-shot: monthly F.I.R.E. allocation
imbot daemon # long-running scheduler (Ctrl+C to stop)
imbot ui # live dashboardThree console scripts ship: imbot (CLI), imbot-daemon (long-running scheduler), imbot-ui (Textual app). They all share one DuckDB file at ~/.imbot/state.duckdb (override via IMBOT_HOME=/var/lib/imbot).
Three F.I.R.E. routes, four bots, one regime-aware engine. Documented in Docs/FIRE_Strategies_40k_SIP.md.
| Route | Style | Vehicle | Wins when |
|---|---|---|---|
| 1. Snowball ๐ | Income | High-yield stocks + DRIP | Retirement โ live off dividends |
| 2. Indexing ๐ | Reliability | Nifty 50 / Next 50 ETFs | Always (given 15-year horizon) |
| 3. Momentum ๐ | Alpha | Mid/Small caps, 200-DMA + 6M momo | Bull markets |
The daemon rebalances dynamically based on Nifty 50's 200-DMA:
BULL (Nifty > 200-DMA) BEAR (Nifty < 200-DMA)
โโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโ
โ Core ETFs 40% โโโโโโโโโโโโโโโ โ Core ETFs 80% โโโโโโโโโโโโโโโโโโ
โ Alpha picks 60% โโโโโโโโโโโโโโโ โ Alpha picks 20% โโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโ
The V4.0 "institutional math" stack running inside the daemon:
- ATR-based 1%-risk sizing โ every position risks exactly 1% of equity if stopped out
- Relative Strength filter โ only buy stocks outperforming Nifty's 20-DMA-of-RS
- Market breadth gate โ refuse new entries unless >40% of universe is above 50-DMA
- Chandelier trailing stop โ
Close โ 2.5 ร ATR, lets winners run - Hard time-stop โ any position held โฅ20 days exits, win or lose (fixes runaway-winners-stuck-open bug in the legacy bot)
# screening / allocation (live, one-shot)
imbot fire --budget 500
imbot dividend --budget 10000
imbot swing --top 5 --rr 2.5
# forward projection (pure math, no network)
imbot project --years 15 --sip 500 --expense 2500
# backtests (downloads history)
imbot backtest dividend --years 5 --sip 500
imbot backtest swing --years 2 --capital 1000000
# parameter grid search
imbot optimize --list
imbot optimize --param atr-mult=2.0,3.0,0.25 --param time-stop=15,30,5
# daemon + dashboard
imbot daemon # foreground; for systemd see Docs/operations.md
imbot ui # Textual dashboard
# DuckDB helpers
imbot db init
imbot db inspect
imbot db migrate-json legacy/virtual_account_state.json health_beat every 30 s (heartbeat row)
paper_tick every 60 s, NSE (trailing stops + exits)
prices_tick every 5 min, NSE (OHLCV cache refresh)
signals_swing daily 15:25 IST (V4.0 swing setups)
paper_eod daily 15:25 IST (new entries if regime + breadth bull)
signals_dividend daily 16:00 IST (snowball candidates)
signals_fire daily 16:30 IST (FIRE allocation incl. regime)
monthly_sip 09:30 IST ยท last NSE day of month (deposits EURโINR)
Each job hits Yahoo Finance through data.yahoo.fetch_*_async โ 10s timeout, 3 retries, exponential backoff. NSE-hours gated via @requires_market_open so decisions never run at 2am on stale data.
Knobs you might actually want to turn live in config/default.toml. Override via:
~/.imbot/config.toml(per-user file, same TOML layout)IMBOT_*env vars:IMBOT_RISK__MAX_POSITIONS=5,IMBOT_SIP__AMOUNT_EUR=750
| To change... | Edit... |
|---|---|
| Tradable universe | src/indianmarket/universe.py |
| Risk per trade / max positions / ATR multiplier | config.risk |
| Monthly SIP amount / deposit time | config.sip |
| Daemon cadence | config.daemon |
| NSE holidays | src/indianmarket/data/market_calendar.py |
| FX fallbacks | config.fx |
| Bull/bear allocation split | config.allocation |
The strategy core is fully pure โ change a function in src/indianmarket/core/*.py and your update flows through the CLI, daemon, and dashboard with no extra wiring.
IndianMarketBot/
โโโ pyproject.toml # deps, console_scripts (imbot, imbot-daemon, imbot-ui)
โโโ config/
โ โโโ default.toml # canonical knobs (override via ~/.imbot or env)
โโโ src/indianmarket/
โ โโโ config.py # TOML + env var loader
โ โโโ universe.py # one source of truth for ticker lists
โ โโโ constants.py # risk + execution defaults
โ โโโ core/ # pure strategy: indicators, regime, sizing,
โ โ # momentum, dividend, swing, projection, backtest
โ โ # โ 100% I/O-free, fully unit-tested
โ โโโ data/
โ โ โโโ yahoo.py # the ONLY module that imports yfinance
โ โ โโโ cache.py # in-memory TTL cache
โ โ โโโ store.py # DuckDB read/write + JSON migration
โ โ โโโ schema.sql # prices / signals / positions / trades / ...
โ โ โโโ market_calendar.py # NSE hours + holidays + @requires_market_open
โ โโโ daemon/ # asyncio event loop + APScheduler jobs
โ โ โโโ runner.py # SIGTERM/SIGINT graceful shutdown
โ โ โโโ scheduler.py # cron triggers
โ โ โโโ jobs/ # prices, paper_trader, signals_*, monthly_sip
โ โโโ ui/ # Textual TUI (read-only DuckDB)
โ โ โโโ app.py # 3ร2 grid layout
โ โ โโโ widgets/ # header, positions, signals, brain, log,
โ โ # equity chart (textual-plotext), status bar
โ โโโ cli/ # Typer subcommands
โ โ โโโ commands/ # fire, dividend, swing, project, backtest,
โ โ # optimize, daemon, ui, menu, db
โ โโโ optimize/grid_search.py # cartesian-product param sweeps
โ โโโ tests/ # 69 unit + smoke tests (pytest)
โโโ Docs/
โ โโโ FIRE_Strategies_40k_SIP.md
โ โโโ development_journey.md
โโโ CLAUDE.md # guidance for Claude Code agents
โโโ LICENSE # Apache 2.0
# On the Pi
sudo apt install -y python3.11-venv git
git clone https://github.com/GhostRoboticsLab/IndianMarketBot.git ~/imbot
cd ~/imbot && python3.11 -m venv venv && source venv/bin/activate
pip install -e .
# systemd: start daemon at boot
sudo cp scripts/imbot.service /etc/systemd/system/ # see Docs/operations.md (C15)
systemctl --user enable --now imbot
# From the Pi's HDMI-attached monitor (or SSH session)
imbot ui # full-screen Textual dashboardThe UI auto-falls-back to an ASCII sparkline if textual-plotext doesn't render correctly on the Pi terminal. Layout collapses to single-column below ~100 cols.
This is research/educational code, not financial advice.
- The bots produce signals. They do not place real orders. Execution is on you.
paper_traderis virtual money only โ no broker API is wired in.- yfinance data can be delayed or wrong. Never trust a screen blindly.
- Past backtest performance does not predict future returns.
- Universe lists were curated knowing what works today โ survivorship bias is real in the backtests.
- The author is not a SEBI-registered investment advisor.
By using this code you accept full responsibility for any decisions made with it.
- Textual + textual-plotext โ the dashboard
- DuckDB โ embedded columnar database, single-writer + MVCC reads
- APScheduler โ async cron
- Typer โ CLI
- Rich โ terminal output
- pandas โ time-series everything
- yfinance โ free market data
- pyxirr โ Rust-backed XIRR
Apache 2.0 โ do what you want, just don't sue me.
Star โญ this repo if it sparked an idea. PRs welcome.