Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TradingView to Kotak Neo Trading Bot

FastAPI-based backend that receives TradingView strategy alerts, validates them, applies risk checks, and then routes them to paper trading or Kotak Neo live execution. Phase 1 is intentionally backend-only and defaults to paper mode for safety.

Features

  • TradingView webhook endpoint at POST /webhook/tradingview
  • Secret validation, symbol allow-listing, action checks, quantity checks, and duplicate alert protection
  • Risk engine with daily trade limits, daily loss limit, open-position limit, and trading window enforcement
  • Paper trading mode with simulated order IDs and local position tracking
  • Live trading safety gate that requires both TRADING_MODE=live and ENABLE_LIVE_ORDERS=true
  • Broker-source-of-truth position reconciliation every 10 seconds in live mode
  • Order/trade state machine with PENDING, PLACED, PARTIAL, FILLED, CLOSED, and REJECTED
  • Startup recovery that rebuilds local trade state from broker positions after restart
  • Broker heartbeat monitoring, global circuit breaker, exponential-backoff retries, and slippage protection
  • Best-effort Kotak order-feed websocket support with polling fallback
  • Kotak Neo auth and order service wrappers using the official Python SDK
  • SQLite by default, with SQLAlchemy models that can be moved to PostgreSQL later
  • Structured JSON logging
  • Docker and docker-compose support
  • Basic pytest coverage for webhook and risk behaviour

Important Warnings

  • Default mode is paper. Keep it that way until you have verified the full alert flow end to end.
  • Live trading is blocked unless both TRADING_MODE=live and ENABLE_LIVE_ORDERS=true.
  • Broker positions are treated as the source of truth in live mode. Local database state is reconciled to the broker, not the other way around.
  • If startup reconciliation fails, the API can still start, but the global circuit breaker keeps live orders blocked until broker connectivity recovers.
  • As of 2026-05-15, the currently published Kotak Neo v2 flow uses an app/web dashboard token plus TOTP, MPIN, and UCC. Older access-token/consumer-secret login flows are deprecated.
  • This project stores and executes alerts exactly as received. You should test thoroughly on a disposable setup before routing real capital.
  • Commodity lot sizes, symbol names, and product selection must match your Kotak account permissions and current exchange contracts.

Project Structure

tradingview-kotak-bot/
  app/
    main.py
    config.py
    models.py
    database.py
    schemas.py
    routes/
      webhook.py
      health.py
      trades.py
    services/
      circuit_breaker.py
      kotak_auth.py
      kotak_orders.py
      reconciliation.py
      retry.py
      risk_engine.py
      signal_parser.py
      state_machine.py
      trade_logger.py
      duplicate_guard.py
    utils/
      logging.py
      time_utils.py
  tests/
  .env.example
  requirements.txt
  Dockerfile
  docker-compose.yml
  README.md

Local Setup

  1. Create and activate a Python 3.11+ virtual environment.
  2. Install dependencies:
pip install -r requirements.txt
  1. Copy the environment file:
cp .env.example .env
  1. Edit .env and set at least:
WEBHOOK_SECRET=your-long-random-secret
TRADING_MODE=paper
ENABLE_LIVE_ORDERS=false
ALLOWED_SYMBOLS=SILVERMIC
DATABASE_URL=sqlite:///./trades.db
RECONCILIATION_POLL_INTERVAL_SECONDS=10
MAX_SLIPPAGE_PCT=0.5
  1. Start the API:
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
  1. Verify health:
curl http://127.0.0.1:8000/health

Docker Setup

  1. Create .env from .env.example.
  2. Start the stack:
docker-compose up --build
  1. The API will be available at http://127.0.0.1:8000.

TradingView Webhook Setup

  1. Open your TradingView strategy alert.
  2. Enable webhook URL.
  3. Set the webhook URL to:
https://your-public-url/webhook/tradingview
  1. Use JSON in the alert message body.

Sample TradingView alert JSON:

{
  "secret": "MY_SECRET_KEY",
  "strategy": "MACD_SILVER_MICRO",
  "symbol": "SILVERMIC",
  "exchange": "MCX",
  "action": "BUY",
  "quantity": 1,
  "price": "{{close}}",
  "time": "{{time}}",
  "alert_id": "{{strategy.order.id}}"
}

Supported actions:

  • BUY
  • SELL
  • EXIT

Exposing Localhost with ngrok

  1. Install ngrok and authenticate it with your account.
  2. Run your API locally on port 8000.
  3. Start ngrok:
ngrok http 8000
  1. Copy the HTTPS forwarding URL from ngrok and append /webhook/tradingview.
  2. Paste that URL into your TradingView alert webhook configuration.

Example:

https://abcd-1234.ngrok-free.app/webhook/tradingview

API Endpoints

  • GET /health
  • POST /webhook/tradingview
  • GET /signals
  • GET /orders
  • GET /trades
  • GET /positions
  • POST /positions/exit

GET /health now also exposes broker heartbeat state, circuit breaker state, startup recovery status, and the latest reconciliation timestamp.

Example Manual Webhook Test

curl -X POST http://127.0.0.1:8000/webhook/tradingview \
  -H "Content-Type: application/json" \
  -d '{
    "secret": "your-long-random-secret",
    "strategy": "MACD_SILVER_MICRO",
    "symbol": "SILVERMIC",
    "exchange": "MCX",
    "action": "BUY",
    "quantity": 1,
    "price": 101250.0,
    "time": "2026-05-15T10:15:00+05:30",
    "alert_id": "manual-buy-001"
  }'

Paper Mode

Paper mode is the default and safest place to start.

  • Orders are not sent to Kotak Neo.
  • A synthetic broker order ID like PAPER-20260515101500-ab12cd34 is generated.
  • Paper entry orders are marked FILLED immediately so the same order/trade state machine can be exercised before going live.
  • Signals, orders, and local position state are still written to the database.
  • GET /positions returns positions derived from open paper trades.

Recommended paper-mode checklist:

  1. Send a BUY alert and confirm it appears in /signals, /orders, /trades, and /positions.
  2. Send the same alert_id again and confirm it is rejected.
  3. Send an EXIT alert or call POST /positions/exit and confirm the position closes.

Switching to Live Mode Safely

Do not switch to live mode until paper mode has been fully validated.

  1. Keep TRADING_MODE=paper while validating TradingView alert formatting.
  2. Fill live credentials in .env.
  3. Add your current Kotak UCC because the present v2 flow requires it.
  4. Confirm your symbol naming and product configuration with your Kotak account.
  5. Switch both flags:
TRADING_MODE=live
ENABLE_LIVE_ORDERS=true
  1. Restart the API.
  2. Send one controlled low-risk alert first and review logs plus /orders.

Recommended live-mode safeguards to keep enabled:

  • RECONCILIATION_POLL_INTERVAL_SECONDS=10
  • ENABLE_ORDER_FEED_WEBSOCKET=true
  • ENFORCE_SLIPPAGE_PROTECTION=true
  • MAX_SLIPPAGE_PCT=0.5
  • BROKER_HEARTBEAT_FAILURE_THRESHOLD=3

Current live-related notes:

  • KOTAK_CONSUMER_KEY should be the token generated from the Kotak Neo app/web Trade API dashboard.
  • KOTAK_TOTP_SECRET, KOTAK_MPIN, KOTAK_MOBILE_NUMBER, and KOTAK_UCC are required for the current SDK-backed login path.
  • KOTAK_CONSUMER_SECRET and KOTAK_PASSWORD remain in .env.example as placeholders because older setups used them, but the current v2 flow does not rely on them.
  • The code now attempts to use Kotak's official subscribe_to_orderfeed() support when available in the SDK, and falls back to polling order/position state when websocket streaming is unavailable or unstable.
  • Quote-field and search-token parsing for slippage protection include guarded TODO comments where exact response keys should be confirmed against your Kotak contract documentation.

Database Tables

  • signals
  • orders
  • trades
  • risk_events
  • broker_sessions

The SQLAlchemy setup is database-URL driven, so moving to PostgreSQL later is primarily a configuration and migration exercise.

Live State Management

  • Live orders are created locally as PENDING, then move through broker reconciliation to PLACED, PARTIAL, FILLED, CLOSED, or REJECTED.
  • Broker positions are polled every 10 seconds and used as the live source of truth for /positions and restart recovery.
  • If the broker reports an open position with no matching local trade, the system creates a recovered orphan trade and marks it accordingly.
  • If local state shows duplicate live trades for the same symbol after restart, the circuit breaker opens and blocks new live execution.

Logging

Logs are emitted as structured JSON and include:

  • Incoming alerts
  • Validation and risk rejections
  • Paper order simulations
  • Broker errors
  • Successful order execution events

Running Tests

pytest

Kotak Neo Integration Notes

This code uses the official Kotak Neo Python SDK wrapper for live flows. The live implementation is intentionally isolated in:

If Kotak changes the SDK response structure, you will likely only need to adjust the order-id extraction or the login metadata handling inside those two files.

Official References Used

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages