Skip to content

rahultapase/trading-sdk-wrapper

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Trading SDK Wrapper

A simplified Trading API platform built with Node.js and Express for the Bajaj Broking Campus Hiring Assignment.

Table of Contents


Overview

This project implements a Wrapper SDK around a simplified Trading API platform. It simulates core trading workflows without real market connectivity.

What it does:

  • View available financial instruments (stocks)
  • Place buy and sell orders (MARKET/LIMIT)
  • Check order status
  • View executed trades
  • Fetch portfolio holdings and P&L

Features

Core Features

  • Instrument APIs - Fetch tradable instruments with filtering
  • Order Management - Place, view, and cancel orders
  • Trade History - View all executed trades
  • Portfolio Management - Holdings, balance, and P&L tracking

Bonus Features

  • Swagger Documentation - Interactive API docs at /api-docs
  • Winston Logging - Application and HTTP request logging
  • Centralized Error Handling - Consistent error responses
  • Request Validation - Using express-validator
  • Unit Tests - Jest + Supertest for API testing
  • Order Execution Simulation - Immediate execution for MARKET orders

Architecture

Technology Stack

Component Technology
Runtime Node.js
Framework Express.js
Validation express-validator
Documentation Swagger (swagger-jsdoc + swagger-ui-express)
Logging Winston + Morgan
Testing Jest + Supertest
Storage In-memory (JavaScript Maps)

Architecture Decisions

  1. In-Memory Storage: Used JavaScript Maps for simplicity and fast access. In production, this would be replaced with a database (PostgreSQL, MongoDB).

  2. Service Layer Pattern: Business logic is separated into services (instrumentService, orderService, portfolioService, tradeService) for better maintainability.

  3. Centralized Error Handling: All errors flow through a single error handler middleware for consistent API responses.

  4. Mock Authentication: A middleware injects userId: "user123" into all requests, simulating authenticated sessions.

  5. Immediate Order Execution: MARKET orders execute instantly. LIMIT orders execute if price conditions are met at order placement time.


Setup Instructions

Prerequisites

  • Node.js (v16 or higher)
  • npm (v8 or higher)

Installation

  1. Clone/Extract the project

    cd trading-sdk
  2. Install dependencies

    npm install
  3. Create environment file

    cp .env.example .env
  4. Start the server

    Development mode (with auto-reload):

    npm run dev

    Production mode:

    npm start
  5. Access the application

    • API Base URL: http://localhost:3000/api/v1
    • Swagger Docs: http://localhost:3000/api-docs
    • Health Check: http://localhost:3000/health

Environment Variables

Variable Default Description
PORT 3000 Server port
NODE_ENV development Environment (development/production/test)
LOG_LEVEL info Logging level
MOCK_USER_ID user123 Mock authenticated user ID
INITIAL_CASH_BALANCE 500000 Initial cash balance (₹)

API Endpoints

Instruments

Method Endpoint Description
GET /api/v1/instruments Fetch all tradable instruments
GET /api/v1/instruments/:symbol Get instrument by symbol

Orders

Method Endpoint Description
POST /api/v1/orders Place a new order
GET /api/v1/orders Get all orders (with optional status filter)
GET /api/v1/orders/:orderId Get order by ID
PUT /api/v1/orders/:orderId/cancel Cancel an order
GET /api/v1/orders/stats Get order statistics

Trades

Method Endpoint Description
GET /api/v1/trades Fetch all executed trades
GET /api/v1/trades/:tradeId Get trade by ID
GET /api/v1/trades/stats Get trade statistics
GET /api/v1/trades/order/:orderId Get trades for an order

Portfolio

Method Endpoint Description
GET /api/v1/portfolio Fetch portfolio holdings
GET /api/v1/portfolio/summary Get portfolio summary with P&L
GET /api/v1/portfolio/balance Get cash balance
GET /api/v1/portfolio/holdings/:symbol Get holding for specific symbol

Order Execution Flow

Order States

NEW → PLACED → EXECUTED
         ↓
     CANCELLED

Execution Logic

MARKET Orders

  • Execute immediately at lastTradedPrice
  • No price validation required
  • State transition: NEW → PLACED → EXECUTED

LIMIT Orders

  • BUY LIMIT: Execute if lastTradedPrice <= limitPrice
  • SELL LIMIT: Execute if lastTradedPrice >= limitPrice
  • If conditions not met, order stays in PLACED status

Order Placement Flow

1. Validate request (symbol, quantity, price, orderType, orderStyle)
2. Check instrument exists
3. For BUY: Validate sufficient cash balance
   For SELL: Validate sufficient holdings
4. Create order with status NEW
5. Transition to PLACED
6. Attempt execution based on order style
7. If executed:
   - Create trade record
   - Update portfolio (holdings + cash balance)
   - Update order status to EXECUTED

Portfolio Updates on Execution

BUY Order Executed

  • Deduct cash: availableCash -= quantity × price
  • Add/update holding with new average price:
    newAvgPrice = (oldQty × oldAvgPrice + newQty × newPrice) / (oldQty + newQty)
    

SELL Order Executed

  • Add cash: availableCash += quantity × price
  • Reduce holding quantity (remove if zero)

Assumptions

  1. Single User System: Mock authentication uses a single hardcoded user (user123).

  2. In-Memory Storage: All data is stored in memory and lost on server restart.

  3. Immediate Execution: Orders are evaluated for execution only at placement time. No background price monitoring.

  4. No Partial Fills: Orders are either fully executed or not executed at all.

  5. Static Prices: Instrument prices don't change during runtime (mock data).

  6. NSE Default: If exchange not specified, defaults to NSE.

  7. Initial Balance: User starts with ₹500,000 cash.

  8. Order Cancellation: Only NEW and PLACED orders can be cancelled.

  9. No Margin Trading: User can only buy with available cash.

  10. No Short Selling: User can only sell holdings they own.


Sample Usage

Place a MARKET BUY Order

curl -X POST http://localhost:3000/api/v1/orders \
  -H "Content-Type: application/json" \
  -d '{
    "symbol": "RELIANCE",
    "exchange": "NSE",
    "orderType": "BUY",
    "orderStyle": "MARKET",
    "quantity": 10
  }'

Place a LIMIT SELL Order

curl -X POST http://localhost:3000/api/v1/orders \
  -H "Content-Type: application/json" \
  -d '{
    "symbol": "RELIANCE",
    "exchange": "NSE",
    "orderType": "SELL",
    "orderStyle": "LIMIT",
    "quantity": 5,
    "price": 2500
  }'

Get Portfolio Summary

curl http://localhost:3000/api/v1/portfolio/summary

Get All Instruments

curl http://localhost:3000/api/v1/instruments

See API_EXAMPLES.md for complete request/response examples.


Running Tests

# Run all tests
npm test

# Run tests with coverage
npm test -- --coverage

# Run tests in watch mode
npm run test:watch

Test Coverage

  • Order placement (MARKET/LIMIT)
  • Order execution logic
  • Balance and holdings validation
  • Order cancellation
  • Portfolio calculations
  • Error scenarios

Project Structure

trading-sdk/
├── server.js                    # Entry point
├── package.json
├── .env.example
├── README.md
├── API_EXAMPLES.md
│
├── src/
│   ├── config/
│   │   ├── constants.js         # Order states, types, HTTP codes
│   │   └── swagger.js           # Swagger configuration
│   │
│   ├── models/
│   │   ├── storage.js           # In-memory Maps
│   │   └── mockData.js          # Mock instruments initialization
│   │
│   ├── services/
│   │   ├── instrumentService.js # Instrument business logic
│   │   ├── orderService.js      # Order business logic
│   │   ├── portfolioService.js  # Portfolio business logic
│   │   └── tradeService.js      # Trade business logic
│   │
│   ├── controllers/
│   │   ├── instrumentController.js
│   │   ├── orderController.js
│   │   ├── portfolioController.js
│   │   └── tradeController.js
│   │
│   ├── routes/
│   │   └── index.js             # All API routes
│   │
│   ├── middleware/
│   │   ├── errorHandler.js      # Centralized error handling
│   │   ├── validator.js         # Request validation
│   │   ├── authMock.js          # Mock authentication
│   │   └── logger.js            # Winston logger
│   │
│   └── utils/
│       └── errorClasses.js      # Custom error classes
│
├── tests/
│   ├── order.test.js            # Order API tests
│   └── portfolio.test.js        # Portfolio API tests
│
└── logs/
    ├── error.log                # Error logs
    └── combined.log             # All logs

Error Response Format

All errors follow a consistent format:

{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human readable error message"
  }
}

Common Error Codes

Code HTTP Status Description
VALIDATION_ERROR 400 Request validation failed
INSUFFICIENT_BALANCE 400 Not enough cash for BUY
INSUFFICIENT_HOLDINGS 400 Not enough shares for SELL
INSTRUMENT_NOT_FOUND 404 Symbol not found
ORDER_NOT_FOUND 404 Order ID not found
ORDER_CANNOT_BE_CANCELLED 400 Order already executed/cancelled
PRICE_REQUIRED_FOR_LIMIT 400 Price missing for LIMIT order

Available Mock Instruments

Symbol Exchange Last Traded Price (₹)
RELIANCE NSE 2,450.75
TCS NSE 3,425.50
INFY NSE 1,456.25
HDFCBANK NSE 1,678.90
ICICIBANK NSE 1,045.60
SBIN NSE 625.30
WIPRO NSE 512.45
LT NSE 2,890.15
BAJAJFINSV NSE 1,567.80
MARUTI NSE 3,150.25
ASIANPAINT NSE 2,845.60
AXISBANK NSE 1,125.75
BHARTIARTL NSE 945.20
BRITANNIA NSE 4,850.90
COALINDIA NSE 385.45
RELIANCE BSE 2,448.50
TCS BSE 3,422.75
HDFCBANK BSE 1,676.40

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published