Skip to content

Latest commit

Β 

History

415 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ SmartAPI Intraday Trading Algorithm

CI Pipeline Node.js Version TypeScript License: MIT Coverage

A robust, enterprise-grade intraday trading algorithm built with Node.js and TypeScript, specifically designed for automating Short Straddle strategies on NIFTY (Tuesday) and SENSEX (Thursday) weekly index options using Angel One's SmartAPI (BANKNIFTY is monthly expiry and strictly excluded).


🌟 Key Features

  • πŸ” Automated Smart Login: Hands-free authentication with automated 6-digit TOTP generation.
  • πŸ“‘ Compliance Ready: Automatic resolution of Public IP, Local IP, and MAC addresses for secure API header requirements.
  • πŸ“‰ Real-time Risk Management: Active MTM tracking with automated stop-loss placement (125% factor: trigger = entry Γ— 2.25, limit = trigger Γ— 1.05) for all sell positions.
  • πŸ“Š Local Positions Tracking: Persistent local state bookkeeping in positions.json to track open legs and prevent duplicate trade entries; broker truth via SmartAPI GET_POSITIONS is queried for post-expiry reports and P&L verification, while getMtm filters to the algo's own symbol whitelist.
  • πŸ§ͺ Paper Trading Mode: High-fidelity simulation mode to test strategies against live market data without financial risk.
  • πŸ’¬ Multi-Channel Remote Control: Dual support for Telegram and Slack interactive commands to monitor and control the algorithm remotely.
  • πŸ“… Datewise Logging & Retention: Dynamically logs application status and MTM metrics daily, with automated script-based log retention cleanup.
  • πŸ“Š Weekly Expiry Reports: Track and analyze performance with detailed P&L and straddle breakdowns under expiry-reports/.
  • 🧩 Developer Agent Customizations: Integrated workspace agent skills (.agents/skills) to automate PR creation, git cleanup, and description validation.
  • πŸ—οΈ Modular Architecture: Clean, domain-driven design for high maintainability and testability.
  • πŸ›‘οΈ High Test Coverage: Robust test suite with >= 80% branch coverage threshold ensuring reliable execution.
  • 🐳 Docker Ready: Fully containerized for consistent deployment across environments.

πŸ› οΈ Tech Stack

  • Runtime: Node.js v22+ (LTS)
  • Language: TypeScript
  • Framework: Express.js
  • API Client: SmartAPI (via krb-smart-api-module)
  • Testing: Jest
  • Formatting/Linting: Prettier & ESLint
  • Package Manager: pnpm

πŸ“₯ Installation

Prerequisites

  • Node.js v22+
  • pnpm (recommended) or npm
  • SmartAPI Credentials: API Key and 16-character TOTP Secret.

Setup

  1. Clone the repository:

    git clone https://github.com/kunalrbhatia/smart-api.git
    cd smart-api
  2. Install dependencies:

    pnpm install
  3. Configure Environment:

    cp .env.example .env

    Edit .env and fill in your API_KEY, CLIENT_CODE, CLIENT_PIN, and CLIENT_TOTP_PIN (16-character secret).

    Strategy Parameters (.env)

    Variable Default Description
    ENTRY_TIME 09:15 Session entry start time (HH:mm format) for market open checks and initial trade timing (deployed VPS setting: 09:30).
    NO_ENTRY_AFTER 15:10 Session entry cutoff time (HH:mm format); no new straddles or rolls are entered after this time.
    EXIT_TIME 15:17 Session exit time (HH:mm format) when open sell positions are force-closed (deployed VPS setting: 15:35).
    INDEX Auto (day of week) Optional index override (NIFTY or SENSEX only). BANKNIFTY is ignored and falls back to day-of-week selection.

⏰ Dual-Index Cron Setup (NIFTY & SENSEX)

The algorithm automatically selects the index based on the day of the week (getAlgoIndex()):

  • Tuesdays (* * 2): NIFTY weekly option expiry (NSE / NFO)
  • Thursdays (* * 4): SENSEX weekly option expiry (BSE / BFO)
  • Note: BANKNIFTY is strictly excluded (monthly expiry, out of scope).

Crontab slices for single-machine VPS execution:

# NIFTY expiry Tuesdays
16 09 * * 2 cd /home/ubuntu/smart-api && node dist/run-algo.js >> logs/algo_run.log 2>&1
20-55/5 09 * * 2 cd /home/ubuntu/smart-api && node dist/run-algo.js >> logs/algo_run.log 2>&1
*/5 10-14 * * 2 cd /home/ubuntu/smart-api && node dist/run-algo.js >> logs/algo_run.log 2>&1
0-40/5 15 * * 2 cd /home/ubuntu/smart-api && node dist/run-algo.js >> logs/algo_run.log 2>&1

# SENSEX expiry Thursdays
16 09 * * 4 cd /home/ubuntu/smart-api && node dist/run-algo.js >> logs/algo_run.log 2>&1
20-55/5 09 * * 4 cd /home/ubuntu/smart-api && node dist/run-algo.js >> logs/algo_run.log 2>&1
*/5 10-14 * * 4 cd /home/ubuntu/smart-api && node dist/run-algo.js >> logs/algo_run.log 2>&1
0-40/5 15 * * 4 cd /home/ubuntu/smart-api && node dist/run-algo.js >> logs/algo_run.log 2>&1

πŸš€ Usage

Development Mode

Run with hot-reloading:

pnpm run dev

Production Build

Compile and start:

pnpm run build
pnpm start

Testing

Run the comprehensive test suite:

pnpm test
pnpm run test:coverage # Generate coverage report

Backtesting

Run live-fidelity option chain backtests for NIFTY or SENSEX:

# Default NIFTY backtest (Tuesdays, lot size 65, strike diff 50/100, hedge Β±500)
node scripts/backtest-straddle.mjs --expiry-days-only --from 2026-02-01 --to 2026-08-03

# SENSEX backtest (Thursdays, lot size 20, strike diff 200/300, hedge Β±1500)
node scripts/backtest-straddle.mjs --index sensex --expiry-days-only --data-dir ../nifty-optionchain-data/data/chains-sensex

Note: The chains-sensex data directory must be populated by the option chain collector prior to running SENSEX backtests.

Log Clean-up

The algorithm generates daily date-wise log files (app-YYYY-MM-DD.log and mtm-YYYY-MM-DD.log). To delete logs older than 30 days, run:

node scripts/clean-logs.js

πŸ“Š Expiry Reports

Performance analyses and P&L breakdowns for each weekly expiry date are documented in the expiry-reports/ directory formatted as expiry-<INDEX>-YYYY-MM-DD.md (e.g. expiry-NIFTY-2026-08-18.md or expiry-SENSEX-2026-08-20.md).

Each report highlights:

  • P&L Summary: Net Premium, Realised vs Unrealised P&L, and winner/loser counts.
  • Position Breakdown: Status (LONG/SHORT/CLOSED) and individual P&L for each traded contract.
  • Straddle Pair Analysis: Grouped CE/PE strike performance.

πŸ“ˆ Backtesting the Short Straddle

The repository includes an offline backtester for the Short Straddle at ATM strategy. It reads the unified option-chain snapshots produced by the nifty-optionchain-data pipeline (data/chains/YYYY-MM-DD/YYYY-MM-DD_HHmm.json) and replays each trading session.

How it works

For every (trading day, expiry) session, the backtester:

  1. Enters: at >= ENTRY_TIME IST (default 09:15, deployed 09:30), buys 5-lot hedges (ATM+500 CE & ATM-500 PE for NIFTY; ATM+1500 CE & ATM-1500 PE for SENSEX), and sells 1-lot ATM straddle.
  2. Rolls: on subsequent ticks, if |ATM - nearestTradedSellStrike| >= strikeDiff (NIFTY: 50 when India VIX < 14, 100 otherwise; SENSEX: 200 when India VIX < 14, 300 otherwise), sells a new ATM straddle (or missing leg if LTP > 5).
  3. Exits:
    • Per-leg 125% Stop Loss: trigger = entry * 2.25. Checked per leg on every snapshot. Fills at max(slLimitPrice, currentLtp) + slSlippage.
    • Close rule (EXIT_TIME+): sell legs with LTP > 5 are bought back at market; sell legs with LTP <= 5 and all long hedges expire worthless.

By default only the nearest expiry is traded per day (--expiries all to trade every expiry present in the data).

Running

# Point at the option-chain data lake
pnpm backtest -- --data-dir ../nifty-optionchain-data/data/chains

# Or set it once via environment
export OPTIONCHAIN_DATA_DIR=../nifty-optionchain-data/data/chains
pnpm backtest

Options

Flag Default Description
--data-dir <path> auto-detected Path to the data/chains directory.
--index nifty|sensex nifty Index profile to select strategy parameters (lot size, hedge variance, strike differences, expiry day).
--from YYYY-MM-DD / --to YYYY-MM-DD all Restrict the backtest date range.
--entry HHMM 0915 Session entry time (IST); reads ENTRY_TIME environment variable if set.
--close HHMM 1517 Session close time (IST) when sell legs > 5 LTP are bought back; reads EXIT_TIME environment variable if set.
--strike-diff N / --vix <14|>=14 profile default Strike step for rolling ATM entries (NIFTY: 50/100; SENSEX: 200/300).
--entry-slippage N 0 Premium points deducted from sell entries / added to buy hedges for open execution slippage.
--sl-slippage N 0 Additional premium points added to SL limit fill price on stop loss triggers.
--lot-size N profile default Index lot size used for P&L in rupees (65 for NIFTY, 20 for SENSEX).
--expiries nearest nearest nearest (one per day) or all (every expiry present).
--json <file> β€” Also write full per-session + position details to a JSON file.

Fidelity Notes

  1. Stop Loss Fills: SL trigger is entry * 2.25; limit order is placed at entry * 2.25 * 1.05. On trigger, fills occur at max(slLimitPrice, currentLtp) + slSlippage to model limit execution and gap-through slippage.
  2. Expiry Settlement: At EXIT_TIME+ (Phase A), sell legs with LTP > 5 are bought back at market price. Any legs remaining open are settled at the final snapshot LTP of the day (~15:40, CAS market close) in Phase B (SETTLED_ITM if LTP > 5, else EXPIRED_WORTHLESS).
  3. Entry Execution: Initial entries use the ENTRY_TIME (default 09:15, deployed 09:30) chain LTP. Live market fills at 09:16 or 09:31 can differ during volatile opens; --entry-slippage allows configuring realistic entry slippage.

Example output

 Date       Expiry     ATM strike  Traded Strikes      Positions  P&L (β‚Ή)
 2026-05-04  2026-05-05      24150  24150,24200,24250,24300         10     -β‚Ή2,223.00
 2026-07-01  2026-07-07      23950  23950                       4         +β‚Ή0.00

Note: Non-expiry session rows in the example output above originate from a full-range backtest run without the --expiry-days-only filter.

The summary block reports total P&L, win rate, average per session, profit factor, and maximum drawdown. Trades are simulated in index points β€” no live brokerage fees are modeled.


πŸ€– Remote Control (Telegram & Slack)

The application supports remote monitoring and control via both Telegram and Slack.

Configuration

In your .env file, configure the following:

  • Telegram: Set USE_TELEGRAM=true, TELEGRAM_BOT_TOKEN, and TELEGRAM_CHAT_ID.
  • Slack: Set USE_SLACK=true, SLACK_WEBHOOK_URL (for outbound notifications), and SLACK_SIGNING_SECRET (to verify slash commands).

Point your Slack App's Slash Commands endpoint to: https://<your-domain>/api/slack/commands.

Supported Commands

These commands can be sent as messages on Telegram or run as slash commands in Slack (e.g., /status):

Command / Slack Slash Description
/status or /check Get current algo status (Running/Stopped) and trading mode.
/paperon Enable Paper Trading Mode (trades are mocked locally).
/paperoff Enable Live Trading Mode (trades execute on your broker account).
/logs Retrieve the last 20 lines of application logs from local log files in logs/.
/kill Sets the kill switch (.kill file) to stop the algo from placing new trades.
/resume / /start Clear the kill switch to allow the algo to resume operations.

πŸš€ Deployment

The project is configured for automated deployment to Oracle Cloud via GitHub Actions.

Automated Workflow

The .github/workflows/ci.yml workflow triggers on every push to the development branch. It performs the following on the target server:

  1. Builds the project (babel transpilation) and runs lint, typecheck, and test checks.
  2. Copies build artifacts to the Oracle Cloud instance via SCP.
  3. Generates the .env file from GitHub Secrets (including API credentials, notification tokens, and ENTRY_TIME/EXIT_TIME/NO_ENTRY_AFTER strategy timings).
  4. Installs production dependencies.

Note: The trading algorithm runs via system crontab triggers (Tuesday for NIFTY, Thursday for SENSEX). PM2 on the server is used exclusively for hosting the MCP server (mcp-smart-api).

Required GitHub Secrets

To use the deployment workflow, add the following secrets in your repository settings (Settings > Secrets and variables > Actions):

Secret Name Description
ORACLE_HOST Public IP of your Oracle Cloud instance.
ORACLE_USER SSH username (e.g., ubuntu).
ORACLE_SSH_KEY Your private SSH key (.key or .pem content).
PORT The port the app should run on (default: 3000).
API_KEY Your SmartAPI Key.
CLIENT_CODE Your SmartAPI Client Code.
CLIENT_PIN Your SmartAPI Client Pin.
CLIENT_TOTP_PIN Your 16-character TOTP Secret Key.
USE_TELEGRAM Set to true to enable Telegram notifications.
TELEGRAM_BOT_TOKEN Your Telegram Bot Token.
TELEGRAM_CHAT_ID Your Telegram Chat ID.
USE_SLACK Set to true to enable Slack notifications.
SLACK_WEBHOOK_URL Your Slack Webhook URL.
SLACK_SIGNING_SECRET Your Slack App Signing Secret.
ENTRY_TIME Intraday strategy entry time (e.g. 09:15).
EXIT_TIME Intraday strategy exit time (e.g. 15:17).
NO_ENTRY_AFTER Intraday strategy no-entry cutoff time (e.g. 15:10).

πŸ“‚ Project Structure

smart-api/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ helpers/
β”‚   β”‚   β”œβ”€β”€ apiService/     # Domain-specific API logic (positions, orders, strategy)
β”‚   β”‚   └── ...             # Utility helpers (logger, notifier, etc.)
β”‚   β”œβ”€β”€ store/              # In-memory state management
β”‚   β”œβ”€β”€ routes/             # API Endpoints
β”‚   └── app.ts              # Express application configuration
β”œβ”€β”€ __tests__/              # High-coverage test suite
└── jest.config.js          # Testing configuration

🧩 Developer Agent Skills

For AI developers using AI agents (like Antigravity), workspace customization skills are configured under .agents/skills/:

  • gh-pr-workflow: Automates branching, staging, committing (Conventional Commits), pushing, and opening GitHub Pull Requests.
  • git-cleanup-sync: Cleans up local feature branches, switches back to development, and pulls the latest changes.
  • pr-description-check: Validates PR descriptions to ensure paths, commands, and code snippets are wrapped in backticks (e.g., `src/app.ts`).
  • readme-auto-update: Automates and verifies updating the README.md file whenever core application changes are made.
  • verify-pr-status: Watches and verifies that all GitHub PR checks complete and pass successfully before concluding a PR lifecycle.

πŸ“– API Documentation

Detailed documentation for all endpoints (Algo control, Account info, Market data) can be found in ENDPOINTS.md.


⚠️ Disclaimer

Trading in the stock market involves significant risk. This algorithm is provided for educational and demonstration purposes. Kunal and the contributors are not responsible for any financial losses incurred through the use of this software. Always backtest thoroughly and trade responsibly.


🀝 Contributing

Contributions are welcome! Please ensure that any new features include corresponding unit tests and maintain the existing branch coverage standards (>= 80%).


Developed with ❀️ by Kunal
Full-stack Developer | Stock Market Trader

About

Automated intraday trading algorithm for Nifty50 options (short straddle strategy) using Angel One's SmartAPI, built with Node.js, Express, and TypeScript.

Topics

Resources

Stars

1 star

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages