ib icon indicating copy to clipboard operation
ib copied to clipboard

Unprocessed Data

Open electic opened this issue 1 year ago • 18 comments

Hi everyone,

Getting this error: Error: Decoding error on OPEN_ORDER: unprocessed data left on queue (["","","","",null]).

How can I debug this?

electic avatar Feb 12 '24 09:02 electic

Same for me.

Order in paper mode:

          orderType: ibOrderType.MKT,
          orderId: IBTransport.getReqId(),
          totalQuantity: pendingOrder.lots,
          action,
          tif: TimeInForce.IOC,
          transmit: true,

Fix via: https://github.com/stoqey/ib/pull/208

BusinessDuck avatar Mar 04 '24 17:03 BusinessDuck

Hello, Thanks for reporting. Cloud you please provide some information about the order? I was unable to reproduce this issue. Ideally add a test case to ./src/test/unit/api/order to help improving the reliably of the API. Thanks

rylorin avatar Mar 09 '24 05:03 rylorin

I am also getting the error on version 1.3.19 in the following code snippet:

createOrder(req: any) {
    const options = req.body.options;

    // Preparing the contract based on request options
    let contract: Contract;
    if (options.secId) {
      // If secType is FIGI, use this specific contract definition
      contract = {
        secIdType: "FIGI",
        secId: options.secId,
        exchange: options.exchange,
      };
    } else {
      // Default contract definition for other secTypes
      contract = {
        symbol: options.symbol,
        exchange: options.exchange,
        currency: options.currency,
        secType: this.getSecType(req),
      };
    }

    // Handling specific contract attributes based on secType
    if (contract.secType === "STK" && options.primaryExch) {
      contract.primaryExch = options.primaryExch;
    }

    // Futures
    if (contract.secType === "FUT" && options.lastTradeDateOrContractMonth) {
      contract.lastTradeDateOrContractMonth =
        options.lastTradeDateOrContractMonth;
    }
    if (contract.secType === "FUT" && options.localSymbol) {
      contract.localSymbol = options.localSymbol;
    }
    if (contract.secType === "FUT" && options.multiplier) {
      contract.multiplier = options.multiplier;
    }

    // Single order
    const singleOrder: Order = {
      orderId: this.nextOrderId++,
      action:
        options.orderAction === "BUY" ? OrderAction.BUY : OrderAction.SELL,
      orderType: this.getOrderType(req),
      totalQuantity: options.quantity,
      lmtPrice: options.orderType === "LMT" ? options.lmtPrice : undefined,
      auxPrice: options.orderType.startsWith("STP")
        ? options.auxPrice
        : undefined,
      account: this.account,
      transmit: true,
      tif: options.tif,
    };

    // Placing the single order
    this.ib.placeOrder(singleOrder.orderId!, contract, singleOrder);
    winston.log("info", `Order placed with ID: ${singleOrder.orderId}`);
  }

When sending this:

{
  "bracketOrder": false,
  "options": {
      "orderAction": "BUY",
      "symbol": "SPY",
      "exchange": "SMART",
      "lmtPrice": 1,
      "takeProfitLimitPrice": 1.2,
      "stopLossPrice": 0.9,
      "currency": "USD",
      "quantity": 1.0,
      "secType": "STK",
      "tif": "GTC",
      "orderType": "LMT"
  }
}

paaax avatar Apr 10 '24 22:04 paaax

Thanks. Could you please provide the values of singleOrder and contract when calling this.ib.placeOrder(singleOrder.orderId!, contract, singleOrder);? Don't forget to hide you account number.

rylorin avatar Apr 11 '24 16:04 rylorin

Thank you for answering. It looks like the order id is set correctly and increases with incoming signals. The order is also being placed in TWS, but the error remains.

Here is my complete log (I changed the account number):

{"level":"info","message":"Listening to requests on 443"} {"level":"info","message":"Connecting to database..."} {"level":"info","message":"Connection to database established."} Broker connected Next valid order ID: 519 {"level":"info","message":"Signal received."} {"level":"info","message":"Placing order AAPL"} {"level":"info","message":"Contract Data: {\"symbol\":\"AAPL\",\"exchange\":\"SMART\",\"currency\":\"USD\",\"secType\":\"STK\"}"} {"level":"info","message":"Order Data: {\"orderId\":519,\"action\":\"BUY\",\"orderType\":\"LMT\",\"totalQuantity\":1,\"lmtPrice\":1,\"account\":\"DU1234567\",\"transmit\":true,\"tif\":\"GTC\"}"} {"level":"info","message":"singleOrder.orderId! 519"} {"level":"info","message":"Order placed with ID: 519"} {"level":"info","message":"::ffff:110.136.217.116 - - [13/Apr/2024:23:19:17 +0000] \"POST /webhooks/test HTTP/1.1\" 200 2 \"-\" \"Thunder Client (https://www.thunderclient.com)\"\n"} Error code 505 for reqId -1: Decoding error on OPEN_ORDER: unprocessed data left on queue (["","","","",null]). Please report to https://github.com/stoqey/ib {"level":"info","message":"Order 519 status: PreSubmitted"} Error code 505 for reqId -1: Decoding error on OPEN_ORDER: unprocessed data left on queue (["","","","",null]). Please report to https://github.com/stoqey/ib {"level":"info","message":"Order 519 status: PreSubmitted"}

And the complete implementation (I removed the createBracketOrder()-, getSecType()- and getOrderType()-functions for simplicity):

import * as dotenv from "dotenv";
dotenv.config({ path: __dirname + "/.env" });
import {
  IBApi,
  EventName,
  ErrorCode,
  Contract,
  SecType,
  Order,
  OrderType,
  OrderAction,
} from "@stoqey/ib";
import winston from "../config/winston";

class Broker {
  clientId: number;
  account: string;
  ib: IBApi;
  nextOrderId: number;

  constructor(_mode: string) {
    this.account =
      _mode === "LIVE"
        ? String(process.env.TWS_LIVE_ACCOUNT)
        : String(process.env.TWS_PAPER_ACCOUNT);
    this.clientId =
      _mode === "LIVE"
        ? Number(process.env.TWS_LIVE_CLIENT_ID)
        : Number(process.env.TWS_PAPER_CLIENT_ID);
    this.ib = new IBApi({
      port:
        _mode === "LIVE"
          ? Number(process.env.TWS_LIVE_PORT)
          : Number(process.env.TWS_PAPER_PORT),
    });
    this.connect();
    this.nextOrderId = 0;
    this.setupListeners();
  }

  connect() {
    this.ib
      .connect(this.clientId)
      .on(EventName.connected, () => console.log("Broker connected"));
  }

  disconnect() {
    this.ib.disconnect();
    console.log("Broker disconnected");
  }

  setupListeners() {
    this.ib
      .on(EventName.nextValidId, (orderId) => {
        this.nextOrderId = orderId;
        console.log(`Next valid order ID: ${orderId}`);
      })
      .on(EventName.error, (err: Error, code: ErrorCode, reqId: number) => {
        console.error(`Error code ${code} for reqId ${reqId}: ${err.message}`);
      })
      .on(EventName.orderStatus, (orderId: number, status: string) => {
        winston.log("info", `Order ${orderId} status: ${status}`);
        if (status === "Submitted" || status === "Filled") {
          console.log(`Order ${orderId} processed with status: ${status}`);
        }
      });
  }

  createOrder(req: any) {
    const options = req.body.options;

    // Preparing the contract based on request options
    let contract: Contract;
    if (options.secId) {
      contract = {
        secIdType: "FIGI",
        secId: options.secId,
        exchange: options.exchange,
      };
    } else {
      // Default contract definition for other secTypes
      contract = {
        symbol: options.symbol,
        exchange: options.exchange,
        currency: options.currency,
        secType: this.getSecType(req),
      };
    }

    // Handling specific contract attributes based on secType
    if (contract.secType === "STK" && options.primaryExch) {
      contract.primaryExch = options.primaryExch;
    }

    // Futures
    if (contract.secType === "FUT" && options.lastTradeDateOrContractMonth) {
      contract.lastTradeDateOrContractMonth =
        options.lastTradeDateOrContractMonth;
    }
    if (contract.secType === "FUT" && options.localSymbol) {
      contract.localSymbol = options.localSymbol;
    }
    if (contract.secType === "FUT" && options.multiplier) {
      contract.multiplier = options.multiplier;
    }

    // Single order
    const singleOrder: Order = {
      orderId: Number(this.nextOrderId++),
      action:
        options.orderAction === "BUY" ? OrderAction.BUY : OrderAction.SELL,
      orderType: this.getOrderType(req),
      totalQuantity: Number(options.quantity),
      lmtPrice: options.orderType === "LMT" ? Number(options.lmtPrice) : undefined,
      auxPrice: options.orderType.startsWith("STP")
        ? options.auxPrice
        : undefined,
      account: this.account,
      transmit: true,
      tif: options.tif,
    };
    winston.log('info', 'Contract Data: '+JSON.stringify(contract))
    winston.log('info', 'Order Data: '+JSON.stringify(singleOrder))

    // Placing the single order
    winston.log('info', 'singleOrder.orderId! ' +singleOrder.orderId!)
    this.ib.placeOrder(singleOrder.orderId!, contract, singleOrder);
    winston.log("info", `Order placed with ID: ${singleOrder.orderId}`);
  }

}

module.exports = Broker;

paaax avatar Apr 13 '24 23:04 paaax

Hello, I can't reproduce your issue with v1.3.19:

info Contract Data: {"symbol":"SPY","exchange":"SMART","currency":"USD","secType":"STK"}
info Order Data: {"orderId":0,"action":"BUY","orderType":"LMT","totalQuantity":1,"lmtPrice":1,"account":"undefined","transmit":true,"tif":"GTC"}
info singleOrder.orderId! 0
info Order placed with ID: 0
info Contract Data: {"symbol":"SPY","exchange":"SMART","currency":"USD","secType":"STK"}
info Order Data: {"orderId":1,"action":"BUY","orderType":"LMT","totalQuantity":1,"lmtPrice":1,"account":"undefined","transmit":true,"tif":"GTC"}
info singleOrder.orderId! 1
info Order placed with ID: 1
Broker connected
Next valid order ID: 2
Error code 10149 for reqId 0: Invalid order id: 0
info Order 1 status: PreSubmitted

I called createOrder twice because the first one failed because of a zero order Id but not decoding error.

rylorin avatar Apr 19 '24 02:04 rylorin