IB@stoqey/ib
@stoqey/ib (Low-Level SDK)Guides & Resources

Automated Trading Bot Quickstart

Complete step-by-step example building an automated algorithmic trading bot with @stoqey/ib.

Building a Basic Trading Bot

This guide demonstrates how to create a complete Node.js script that:

  1. Connects to IB Gateway / TWS paper trading account (7497).
  2. Requests account balance & cash availability.
  3. Subscribes to real-time market quotes for a target stock.
  4. Triggers a limit buy order when target conditions are met.

Full TypeScript Code

import {
  IBApi,
  EventName,
  Contract,
  SecType,
  Order,
  OrderAction,
  OrderType,
  TickType,
} from "@stoqey/ib";

// Configure client instance for paper trading
const ib = new IBApi({
  host: "127.0.0.1",
  port: 7497, // TWS Paper Trading
  clientId: 42,
});

let nextOrderId = 0;
let hasPlacedOrder = false;

// Define Target Instrument
const stockContract: Contract = {
  symbol: "AAPL",
  secType: SecType.STK,
  currency: "USD",
  exchange: "SMART",
};

// 1. Connection Initialization
ib.once(EventName.nextValidId, (orderId: number) => {
  console.log(`Connected! Next Valid Order ID: ${orderId}`);
  nextOrderId = orderId;

  // Request real-time quote for AAPL (reqId = 1)
  ib.reqMktData(1, stockContract, "", false, false);
});

// 2. Listen for Real-Time Price Updates
ib.on(EventName.tickPrice, (reqId: number, tickType: TickType, price: number) => {
  // TickType 4 = LAST price, TickType 1 = BID, TickType 2 = ASK
  if (tickType === 4 && price > 0) {
    console.log(`Current AAPL Last Price: $${price}`);

    // Trigger condition: place limit order if price drops below $220
    if (price < 220.0 && !hasPlacedOrder && nextOrderId > 0) {
      hasPlacedOrder = true;
      placeLimitBuyOrder(price);
    }
  }
});

// 3. Place Order Function
function placeLimitBuyOrder(currentPrice: number) {
  const buyOrder: Order = {
    orderId: nextOrderId,
    action: OrderAction.BUY,
    orderType: OrderType.LMT,
    lmtPrice: Number((currentPrice * 0.999).toFixed(2)), // Limit price 0.1% below last
    totalQuantity: 10,
    tif: "DAY",
  };

  console.log(`Submitting Limit BUY order for 10 AAPL @ $${buyOrder.lmtPrice}...`);
  ib.placeOrder(nextOrderId, stockContract, buyOrder);
}

// 4. Order Execution & Status Listener
ib.on(EventName.orderStatus, (orderId: number, status: string, filled: number, remaining: number, avgFillPrice: number) => {
  console.log(`[Order ${orderId}] Status: ${status} | Filled: ${filled} | Avg Price: $${avgFillPrice}`);

  if (status === "Filled") {
    console.log("Order filled! Cleaning up connection...");
    ib.cancelMktData(1);
    ib.disconnect();
  }
});

// Start bot
ib.connect();

On this page