Capstone: end-to-end mini strategy

Wire together every piece from chapters 1-98 into one working, minimal strategy: an opening range breakout on NIFTY futures, from auth through live monitoring. This is deliberately simple — the point is demonstrating correct plumbing, not a sophisticated edge.

Project structure (extends chapter 5)

algo-trading-bot/
├── main.py                     # entry point, wires everything together
├── auth/session.py             # ch 7-10
├── data/instruments.py         # ch 21-23
├── data/historical.py          # ch 27-31
├── watchlist.py                 # ch 35
├── brokers/kite_adapter.py      # ch 68
├── orders/manager.py            # ch 67
├── risk/sizing.py                # ch 71-72, 78
├── risk/limits.py                # ch 73-74
├── risk/kill_switch.py           # ch 90
├── strategy/orb_signal.py        # ch 80 (opening range breakout)
├── strategy/state_machine.py     # ch 88
├── monitoring/health_check.py    # ch 92
├── monitoring/alerts.py          # ch 91
└── journal/trade_journal.py      # ch 89, 97

main.py — the wiring

def main():
    kite = get_authenticated_kite()                          # ch 10
    validate_api_contract(kite)                                # ch 94
    assert_segment_enabled(kite, "NFO")                         # ch 11

    price_cache = PriceCache()                                  # ch 42
    order_manager = OrderManager(kite)                          # ch 67
    journal = TaxAwareJournal()                                  # ch 89, 97
    kill_switch = KillSwitch(kite, order_manager)                # ch 90
    health_check = HealthCheck(kite, price_cache, kill_switch)    # ch 92

    fut_token = resolve_current_month_future(nfo_df, "NIFTY")["instrument_token"]  # ch 23

    kws = KiteTicker(API_KEY, access_token)
    kws.on_connect = lambda ws, r: ws.subscribe([fut_token])       # ch 37
    kws.on_ticks = lambda ws, ticks: [price_cache.update(t) for t in ticks]  # ch 42
    kws.on_order_update = lambda ws, u: state_machine.on_order_update(u)   # ch 53
    kws.connect(threaded=True)

    account_start_equity = get_current_equity(kite)                # ch 73
    state_machine = StrategyStateMachine(order_manager, price_cache)  # ch 88

    threading.Thread(target=heartbeat_loop, args=(health_check,), daemon=True).start()  # ch 92

    intraday_candles = []   # accumulate today's 1-min bars for the ORB signal
    while market_is_open():
        if is_square_off_time():                                   # ch 70
            square_off_all_intraday(kite, order_manager)
            break

        if not check_daily_loss_limit(account_start_equity, get_current_equity(kite), MAX_DAILY_LOSS_PCT):  # ch 73
            kill_switch.trigger(KillLevel.HALT_NEW_ENTRIES, "Daily loss limit")

        df = pd.DataFrame(intraday_candles)
        if len(df) > 15:   # after opening range period
            signal_df = opening_range_breakout_signal(df)            # ch 80
            latest_signal = signal_df["signal"].iloc[-1]

            if kill_switch.is_entry_allowed():
                qty = atr_based_qty(account_start_equity, 1.0, price_cache.get_price(fut_token), compute_atr(df).iloc[-1])  # ch 72
                state_machine.on_signal(latest_signal, {
                    "code": "orb-nifty",
                    "order_kwargs": {"exchange": "NFO", "tradingsymbol": fut_symbol, "product": "NRML", "order_type": "MARKET", "quantity": qty},
                })

        time.sleep(5)

    reconcile_positions(kite, get_local_positions())                # ch 66, end-of-day sanity check

if __name__ == "__main__":
    main()

What this capstone deliberately leaves out, and why

No parameter optimization, no multi-instrument portfolio, no complex exit logic — every piece here is traceable to a specific earlier chapter, which is the point. Before adding sophistication, get this simple version running correctly in paper mode (chapter 87) for at least several weeks, reviewing the journal (chapter 89) honestly, before considering it a candidate for small real capital.

Next: 100 — Where to go next