From b43d5991fb0c15579122d3ba14c6d48c88d5cea7 Mon Sep 17 00:00:00 2001 From: Ronan-Yann Lorin Date: Thu, 21 Sep 2023 18:43:04 +0200 Subject: [PATCH] Upgrade to server v178 (10.25.1) --- README.md | 5 +- src/api/api.ts | 4 +- src/api/data/enum/fad-data-type.ts | 4 +- src/api/data/enum/min-server-version.ts | 2 + src/api/market/tickType.ts | 15 +++ src/api/order/enum/orderType.ts | 18 +++ src/api/order/execution.ts | 2 + src/api/order/order.ts | 2 +- src/common/errorCode.ts | 3 + src/core/io/decoder.ts | 118 ++++++++++-------- src/core/io/encoder.ts | 42 +++++-- .../unit/api-next/get-all-open-orders.test.ts | 1 - src/tests/unit/api/order/cancelOrder.test.ts | 5 +- src/tests/unit/api/wsh-event-data.test.ts | 26 +++- 14 files changed, 175 insertions(+), 72 deletions(-) diff --git a/README.md b/README.md index ba07f142..f61e4b4f 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,11 @@
- Language grade: JavaScript
-`@stoqey/ib` is an [Interactive Brokers](http://interactivebrokers.com/) TWS (or IB Gateway) Typescript API client library for [Node.js](http://nodejs.org/). It is a direct port of Interactive Brokers' Java Client Version 9.76 from May 08 2019. +`@stoqey/ib` is an [Interactive Brokers](http://interactivebrokers.com/) TWS (or IB Gateway) Typescript API client library for [Node.js](http://nodejs.org/). It is a direct port of Interactive Brokers' Java Client Version 10.25 ("latest") from Sept 7 2023. Refer to the [Trader Workstation API](https://interactivebrokers.github.io/tws-api/) for the official documentation and the C#/Java/VB/C++/Python client. @@ -117,7 +116,7 @@ ib.on(EventName.error, (err: Error, code: ErrorCode, reqId: number) => { (account: string, contract: Contract, pos: number, avgCost?: number) => { console.log(`${account}: ${pos} x ${contract.symbol} @ ${avgCost}`); positionsCount++; - } + }, ) .once(EventName.positionEnd, () => { console.log(`Total: ${positionsCount} positions.`); diff --git a/src/api/api.ts b/src/api/api.ts index 70656b0f..d2513986 100644 --- a/src/api/api.ts +++ b/src/api/api.ts @@ -77,7 +77,8 @@ export interface IBApiCreationOptions { } /** Maximum supported version. */ -export const MAX_SUPPORTED_SERVER_VERSION = MIN_SERVER_VER.BOND_ISSUERID; +export const MAX_SUPPORTED_SERVER_VERSION = + MIN_SERVER_VER.PENDING_PRICE_REVISION; /** Minimum supported version. */ export const MIN_SERVER_VER_SUPPORTED = 38; @@ -2252,6 +2253,7 @@ export declare interface IBApi { volume: number, count: number | undefined, WAP: number, + /** @deprecated */ hasGaps: boolean | undefined, ) => void, ): this; diff --git a/src/api/data/enum/fad-data-type.ts b/src/api/data/enum/fad-data-type.ts index 21bc784e..c9fe7fec 100644 --- a/src/api/data/enum/fad-data-type.ts +++ b/src/api/data/enum/fad-data-type.ts @@ -2,10 +2,12 @@ * Financial Advisor's configuration data types. */ export enum FADataType { + NA = 0, + /** Offer traders a way to create a group of accounts and apply a single allocation method to all accounts in the group. */ GROUPS = 1, - /** Let you allocate shares on an account-by-account basis using a predefined calculation value. */ + /** @deprecated Let you allocate shares on an account-by-account basis using a predefined calculation value. */ PROFILES = 2, /** Let you easily identify the accounts by meaningful names rather than account numbers. */ diff --git a/src/api/data/enum/min-server-version.ts b/src/api/data/enum/min-server-version.ts index 07398abc..39b450d5 100644 --- a/src/api/data/enum/min-server-version.ts +++ b/src/api/data/enum/min-server-version.ts @@ -123,6 +123,8 @@ export enum MIN_SERVER_VER { INSTRUMENT_TIMEZONE = 174, HMDS_MARKET_DATA_IN_SHARES = 175, BOND_ISSUERID = 176, + FA_PROFILE_DESUPPORT = 177, + PENDING_PRICE_REVISION = 178, } export default MIN_SERVER_VER; diff --git a/src/api/market/tickType.ts b/src/api/market/tickType.ts index 4d5057b2..ed387886 100644 --- a/src/api/market/tickType.ts +++ b/src/api/market/tickType.ts @@ -333,6 +333,21 @@ export enum TickType { /** The low price of ETF's Net Asset Value (NAV). */ ETF_NAV_LOW = 99, + /** TBD */ + SOCIAL_MARKET_ANALYTICS = 100, + + /** Midpoint is calculated based on IPO price range */ + ESTIMATED_IPO_MIDPOINT = 101, + + /** Final price for IPO */ + FINAL_IPO_LAST = 102, + + /** TBD */ + DELAYED_YIELD_BID = 103, + + /** TBD */ + DELAYED_YIELD_ASK = 104, + UNKNOWN = 2147483647, // MAX int32 } diff --git a/src/api/order/enum/orderType.ts b/src/api/order/enum/orderType.ts index a0f56c6a..d1ed853e 100644 --- a/src/api/order/enum/orderType.ts +++ b/src/api/order/enum/orderType.ts @@ -45,4 +45,22 @@ export enum OrderType { PEG_SRF_VOL = "PSV", } +export const isPegBenchOrder = (orderType: OrderType): boolean => { + if (orderType == OrderType.PEG_BENCH || (orderType as string) == "PEGBENCH") + return true; + else return false; +}; + +export const isPegBestOrder = (orderType: OrderType): boolean => { + if (orderType == OrderType.PEG_BEST || (orderType as string) == "PEGBEST") + return true; + else return false; +}; + +export const isPegMidOrder = (orderType: OrderType): boolean => { + if (orderType == OrderType.PEG_MID || (orderType as string) == "PEGMID") + return true; + else return false; +}; + export default OrderType; diff --git a/src/api/order/execution.ts b/src/api/order/execution.ts index 8de80859..dc405343 100644 --- a/src/api/order/execution.ts +++ b/src/api/order/execution.ts @@ -83,6 +83,8 @@ export interface Execution { * Requires TWS 968+ and API v973.05+. */ lastLiquidity?: Liquidities; + + pendingPriceRevision?: boolean; } export default Execution; diff --git a/src/api/order/order.ts b/src/api/order/order.ts index 90d68514..d35d2eff 100644 --- a/src/api/order/order.ts +++ b/src/api/order/order.ts @@ -208,7 +208,7 @@ export interface Order { /** The Financial Advisor group the trade will be allocated to. Use an empty string if not applicable. */ faGroup?: string; - /** The Financial Advisor allocation profile the trade will be allocated to. Use an empty string if not applicable. */ + /** @deprecated The Financial Advisor allocation profile the trade will be allocated to. Use an empty string if not applicable. */ faProfile?: string; /** The Financial Advisor allocation method the trade will be allocated to. Use an empty string if not applicable.FaMethod */ diff --git a/src/common/errorCode.ts b/src/common/errorCode.ts index cbb9c9c6..c5ee4899 100644 --- a/src/common/errorCode.ts +++ b/src/common/errorCode.ts @@ -264,4 +264,7 @@ export enum ErrorCode { /* Requested market data is not subscribed. Displaying delayed market data. */ DISPLAYING_DELAYED_DATA = 10167, + + /* News feed is not allowed. */ + NEWS_FEED_NOT_ALLOWED = 10276, } diff --git a/src/core/io/decoder.ts b/src/core/io/decoder.ts index 5a2f36f0..2e09015d 100644 --- a/src/core/io/decoder.ts +++ b/src/core/io/decoder.ts @@ -28,7 +28,7 @@ import { ConjunctionConnection } from "../../api/order/enum/conjunction-connecti import OrderAction from "../../api/order/enum/order-action"; import { OrderConditionType } from "../../api/order/enum/order-condition-type"; import { OrderStatus } from "../../api/order/enum/order-status"; -import { OrderType } from "../../api/order/enum/orderType"; +import { OrderType, isPegBenchOrder } from "../../api/order/enum/orderType"; import { TriggerMethod } from "../../api/order/enum/trigger-method"; import { Execution } from "../../api/order/execution"; import { Order } from "../../api/order/order"; @@ -477,6 +477,20 @@ export class Decoder { return val === Number.MAX_VALUE ? undefined : val; } + /** + * Read a token from queue and return it as floating point value. + * + * Returns undefined if the token is empty or is Number.MAX_VALUE. + */ + readDecimal(): number | undefined { + const token = this.readStr().replaceAll(",", ""); + if (!token || token === "") { + return undefined; + } + const val = parseFloat(token); + return val === Number.MAX_VALUE || val === Infinity ? undefined : val; + } + /** * Read a token from queue and return it as floating point value. * @@ -570,7 +584,7 @@ export class Decoder { let size = undefined; if (version >= 2) { - size = this.readInt(); + size = this.readDecimal(); } let canAutoExecute = undefined; @@ -618,7 +632,7 @@ export class Decoder { this.readInt(); // version const tickerId = this.readInt(); const tickType = this.readInt(); - const size = this.readInt(); + const size = this.readDecimal(); this.emit(EventName.tickSize, tickerId, tickType, size); } @@ -633,8 +647,8 @@ export class Decoder { : this.readInt(); const id = this.readInt(); const status = this.readStr(); - const filled = this.readInt(); - const remaining = this.readInt(); + const filled = this.readDecimal(); + const remaining = this.readDecimal(); const avgFillPrice = this.readDouble(); let permId: number | undefined = undefined; @@ -809,7 +823,6 @@ export class Decoder { orderDecoder.readIsOmsContainer(); orderDecoder.readDiscretionaryUpToLimitPrice(); orderDecoder.readUsePriceMgmtAlgo(); - orderDecoder.readDuration(); orderDecoder.readPostToAts(); orderDecoder.readAutoCancelParent(MIN_SERVER_VER.AUTO_CANCEL_PARENT); @@ -832,7 +845,7 @@ export class Decoder { } /** - * Decode a PORTFOLIO_VALUE message from data queue and emit a updatePortfolio event. + * Decode a PORTFOLIO_VALUE message from data queue and emit a updatePortfolio (PortfolioValue) event. */ private decodeMsg_PORTFOLIO_VALUE(): void { const version = this.readInt(); @@ -862,12 +875,7 @@ export class Decoder { contract.tradingClass = this.readStr(); } - let position: number; - if (this.serverVersion >= MIN_SERVER_VER.FRACTIONAL_POSITIONS) { - position = this.readDouble(); - } else { - position = this.readInt(); - } + const position: number = this.readDecimal(); const marketPrice = this.readDouble(); const marketValue = this.readDouble(); @@ -1032,13 +1040,13 @@ export class Decoder { this.serverVersion >= MIN_SERVER_VER.FRACTIONAL_SIZE_SUPPORT && this.serverVersion < MIN_SERVER_VER.SIZE_RULES ) { - this.readDouble(); // sizeMinTick - not used anymore + this.readDecimal(); // sizeMinTick - not used anymore } if (this.serverVersion >= MIN_SERVER_VER.SIZE_RULES) { - contract.minSize = this.readDouble(); - contract.sizeIncrement = this.readDouble(); - contract.suggestedSizeIncrement = this.readDouble(); + contract.minSize = this.readDecimal(); + contract.sizeIncrement = this.readDecimal(); + contract.suggestedSizeIncrement = this.readDecimal(); } } @@ -1094,7 +1102,7 @@ export class Decoder { exec.acctNumber = this.readStr(); exec.exchange = this.readStr(); exec.side = this.readStr(); - exec.shares = this.readInt(); + exec.shares = this.readDecimal(); exec.price = this.readDouble(); if (version >= 2) { @@ -1110,7 +1118,7 @@ export class Decoder { } if (version >= 6) { - exec.cumQty = this.readInt(); + exec.cumQty = this.readDecimal(); exec.avgPrice = this.readDouble(); } @@ -1131,11 +1139,15 @@ export class Decoder { exec.lastLiquidity = { value: this.readInt() }; } + if (this.serverVersion >= MIN_SERVER_VER.PENDING_PRICE_REVISION) { + exec.pendingPriceRevision = this.readBool(); + } + this.emit(EventName.execDetails, reqId, contract, exec); } /** - * Decode a MARKET_DEPTH message from data queue and emit a updateMktDepth event. + * Decode a MARKET_DEPTH message from data queue and emit a MarketDepth event. */ private decodeMsg_MARKET_DEPTH(): void { this.readInt(); // version @@ -1144,7 +1156,7 @@ export class Decoder { const operation = this.readInt(); const side = this.readInt(); const price = this.readDouble(); - const size = this.readInt(); + const size = this.readDecimal(); this.emit( EventName.updateMktDepth, @@ -1158,7 +1170,7 @@ export class Decoder { } /** - * Decode a MARKET_DEPTH_L2 message from data queue and emit a updateMktDepthL2 event. + * Decode a MARKET_DEPTH_L2 message from data queue and emit a MarketDepthL2 event. */ private decodeMsg_MARKET_DEPTH_L2(): void { this.readInt(); // version @@ -1168,7 +1180,7 @@ export class Decoder { const operation = this.readInt(); const side = this.readInt(); const price = this.readDouble(); - const size = this.readInt(); + const size = this.readDecimal(); let isSmartDepth = undefined; if (this.serverVersion >= MIN_SERVER_VER.SMART_DEPTH) { @@ -1256,8 +1268,9 @@ export class Decoder { const high = this.readDouble(); const low = this.readDouble(); const close = this.readDouble(); - const volume = this.readInt(); - const WAP = this.readDouble(); + const volume = this.readDecimal(); + const WAP = this.readDecimal(); + // TODO: hasGap is deprecated, we should readStr and ignore result let hasGaps: boolean | undefined = undefined; if (this.serverVersion < MIN_SERVER_VER.SYNT_REALTIME_BARS) { hasGaps = this.readBool(); @@ -1310,8 +1323,8 @@ export class Decoder { const close = this.readDouble(); const high = this.readDouble(); const low = this.readDouble(); - const WAP = this.readDouble(); - const volume = this.readInt(); + const WAP = this.readDecimal(); + const volume = this.readDecimal(); this.emit( EventName.historicalDataUpdate, reqId, @@ -1365,7 +1378,7 @@ export class Decoder { } /** - * Decode a BOND_CONTRACT_DATA message from data queue and emit a bondContractDetails event. + * Decode a BOND_CONTRACT_DATA message from data queue and emit a BondContractData event. */ private decodeMsg_BOND_CONTRACT_DATA(): void { let version = 6; @@ -1448,9 +1461,9 @@ export class Decoder { contract.marketRuleIds = this.readStr(); } if (this.serverVersion >= MIN_SERVER_VER.SIZE_RULES) { - contract.minSize = this.readDouble(); - contract.sizeIncrement = this.readDouble(); - contract.suggestedSizeIncrement = this.readDouble(); + contract.minSize = this.readDecimal(); + contract.sizeIncrement = this.readDecimal(); + contract.suggestedSizeIncrement = this.readDecimal(); } this.emit(EventName.bondContractDetails, reqId, contract); @@ -1681,7 +1694,7 @@ export class Decoder { } /** - * Decode a REAL_TIME_BARS message from data queue and emit a realtimeBar event. + * Decode a REAL_TIME_BARS message from data queue and emit a realtimeBars event. */ private decodeMsg_REAL_TIME_BARS(): void { this.readInt(); // version @@ -1691,8 +1704,8 @@ export class Decoder { const high = this.readDouble(); const low = this.readDouble(); const close = this.readDouble(); - const volume = this.readInt(); - const wap = this.readDouble(); + const volume = this.readDecimal(); + const wap = this.readDecimal(); const count = this.readInt(); this.emit( @@ -1834,10 +1847,7 @@ export class Decoder { contract.tradingClass = this.readStr(); } - const pos = - this.serverVersion >= MIN_SERVER_VER.FRACTIONAL_POSITIONS - ? this.readDouble() - : this.readInt(); + const pos = this.readDecimal(); let avgCost = 0; if (version >= 3) { @@ -1903,7 +1913,7 @@ export class Decoder { } /** - * Decode a POSITION_MULTI message from data queue and emit a accountSummary event. + * Decode a POSITION_MULTI message from data queue and emit a PositionMulti event. */ private decodeMsg_POSITION_MULTI(): void { this.readInt(); // version @@ -1922,7 +1932,7 @@ export class Decoder { contract.currency = this.readStr(); contract.localSymbol = this.readStr(); contract.tradingClass = this.readStr(); - const pos = this.readInt(); + const pos = this.readDecimal(); const avgCost = this.readDouble(); const modelCode = this.readStr(); @@ -2265,7 +2275,7 @@ export class Decoder { for (let i = 0; i < count; i++) { items[i] = { price: this.readDouble(), - size: this.readInt(), + size: this.readDecimal(), }; } @@ -2297,7 +2307,7 @@ export class Decoder { */ private decodeMsg_PNL_SINGLE(): void { const reqId = this.readInt(); - const pos = this.readInt(); + const pos = this.readDecimal(); const dailyPnL = this.readDouble(); let unrealizedPnL: number | undefined = undefined; @@ -2334,7 +2344,7 @@ export class Decoder { const time = this.readInt(); this.readInt(); //for consistency const price = this.readDouble(); - const size = this.readInt(); + const size = this.readDecimal(); ticks[i] = { time, price, @@ -2358,8 +2368,8 @@ export class Decoder { const flags = this.readInt(); const priceBid = this.readDouble(); const priceAsk = this.readDouble(); - const sizeBid = this.readInt(); - const sizeAsk = this.readInt(); + const sizeBid = this.readDecimal(); + const sizeAsk = this.readDecimal(); ticks[i] = { time: time, tickAttribBidAsk: { @@ -2388,7 +2398,7 @@ export class Decoder { const time = this.readInt(); const mask = this.readInt(); const price = this.readDouble(); - const size = this.readInt(); + const size = this.readDecimal(); const exchange = this.readStr(); const specialConditions = this.readStr(); ticks[i] = { @@ -2423,7 +2433,7 @@ export class Decoder { case 2: { // All-last const price = this.readDouble(); - const size = this.readInt(); + const size = this.readDecimal(); const mask = this.readInt(); const pastLimit = (mask & (1 << 0)) !== 0; const unreported = (mask & (1 << 1)) !== 0; @@ -2447,8 +2457,8 @@ export class Decoder { // BidAsk const bidPrice = this.readDouble(); const askPrice = this.readDouble(); - const bidSize = this.readInt(); - const askSize = this.readInt(); + const bidSize = this.readDecimal(); + const askSize = this.readDecimal(); const mask = this.readInt(); const bidPastLow = (mask & (1 << 0)) !== 0; const askPastHigh = (mask & (1 << 1)) !== 0; @@ -3141,7 +3151,10 @@ export class Decoder { private readLastTradeDate(contract: ContractDetails, isBond: boolean): void { const lastTradeDateOrContractMonth = this.readStr(); if (lastTradeDateOrContractMonth?.length) { - const tokens = lastTradeDateOrContractMonth.split("\\s+"); + const tokens = + lastTradeDateOrContractMonth.indexOf("-") > 0 + ? lastTradeDateOrContractMonth.split("-") + : lastTradeDateOrContractMonth.split("\\s+"); if (tokens.length > 0) { if (isBond) { @@ -3316,7 +3329,8 @@ class OrderDecoder { this.order.faGroup = this.decoder.readStr(); this.order.faMethod = this.decoder.readStr(); this.order.faPercentage = this.decoder.readStr(); - this.order.faProfile = this.decoder.readStr(); + if (this.serverVersion < MIN_SERVER_VER.FA_PROFILE_DESUPPORT) + this.order.faProfile = this.decoder.readStr(); } } @@ -3720,7 +3734,7 @@ class OrderDecoder { readPegToBenchParams(): void { if (this.serverVersion >= MIN_SERVER_VER.PEGGED_TO_BENCHMARK) { - if (this.order.orderType === OrderType.PEG_BENCH) { + if (isPegBenchOrder(this.order.orderType)) { this.order.referenceContractId = this.decoder.readInt(); this.order.isPeggedChangeAmountDecrease = this.decoder.readBool(); this.order.peggedChangeAmount = this.decoder.readDouble(); diff --git a/src/core/io/encoder.ts b/src/core/io/encoder.ts index 36a659c2..2a6271a9 100644 --- a/src/core/io/encoder.ts +++ b/src/core/io/encoder.ts @@ -17,7 +17,11 @@ import PriceCondition from "../../api/order/condition/price-condition"; import TimeCondition from "../../api/order/condition/time-condition"; import VolumeCondition from "../../api/order/condition/volume-condition"; import { OrderConditionType } from "../../api/order/enum/order-condition-type"; -import { OrderType } from "../../api/order/enum/orderType"; +import { + isPegBenchOrder, + isPegBestOrder, + isPegMidOrder, +} from "../../api/order/enum/orderType"; import { COMPETE_AGAINST_BEST_OFFSET_UP_TO_MID, Order, @@ -1272,10 +1276,12 @@ function tagValuesToTokens(tagValues: TagValue[]): unknown[] { } if (this.serverVersion >= 13) { + // srv v13 and above tokens.push(order.faGroup); tokens.push(order.faMethod); tokens.push(order.faPercentage); - tokens.push(order.faProfile); + if (this.serverVersion < MIN_SERVER_VER.FA_PROFILE_DESUPPORT) + tokens.push(""); // send deprecated faProfile field } if (this.serverVersion >= MIN_SERVER_VER.MODELS_SUPPORT) { @@ -1484,7 +1490,7 @@ function tagValuesToTokens(tagValues: TagValue[]): unknown[] { } if (this.serverVersion >= MIN_SERVER_VER.PEGGED_TO_BENCHMARK) { - if (order.orderType == OrderType.PEG_BENCH) { + if (isPegBenchOrder(order.orderType)) { tokens.push(order.referenceContractId); tokens.push(order.isPeggedChangeAmountDecrease); tokens.push(order.peggedChangeAmount); @@ -1637,7 +1643,7 @@ function tagValuesToTokens(tagValues: TagValue[]): unknown[] { if (this.serverVersion >= MIN_SERVER_VER.PEGBEST_PEGMID_OFFSETS) { let sendMidOffsets = false; if (contract.exchange == "IBKRATS") tokens.push(order.minTradeQty); - if (order.orderType == OrderType.PEG_BEST) { + if (isPegBestOrder(order.orderType)) { tokens.push(order.minCompeteSize); tokens.push(order.competeAgainstBestOffset); if ( @@ -1645,7 +1651,9 @@ function tagValuesToTokens(tagValues: TagValue[]): unknown[] { COMPETE_AGAINST_BEST_OFFSET_UP_TO_MID ) sendMidOffsets = true; - } else if (order.orderType == OrderType.PEG_MID) sendMidOffsets = true; + } else if (isPegMidOrder(order.orderType)) { + sendMidOffsets = true; + } if (sendMidOffsets) { tokens.push(order.midOffsetAtWhole); tokens.push(order.midOffsetAtHalf); @@ -1663,10 +1671,20 @@ function tagValuesToTokens(tagValues: TagValue[]): unknown[] { return this.emitError( "This feature is only available for versions of TWS >= 13.", ErrorCode.UPDATE_TWS, - -1, + reqId, ); } + if (this.serverVersion >= MIN_SERVER_VER.FA_PROFILE_DESUPPORT) { + if (faDataType == FADataType.PROFILES) { + return this.emitError( + "FA Profile is not supported anymore, use FA Group instead.", + ErrorCode.UPDATE_TWS, + reqId, + ); + } + } + const version = 1; const tokens: unknown[] = [OUT_MSG_ID.REPLACE_FA, version, faDataType, xml]; @@ -2830,7 +2848,7 @@ function tagValuesToTokens(tagValues: TagValue[]): unknown[] { /** * Encode a REQ_FA message. */ - requestFA(faDataType: number): void { + requestFA(faDataType: FADataType): void { if (this.serverVersion < 13) { return this.emitError( "This feature is only available for versions of TWS >= 13.", @@ -2839,6 +2857,16 @@ function tagValuesToTokens(tagValues: TagValue[]): unknown[] { ); } + if (this.serverVersion >= MIN_SERVER_VER.FA_PROFILE_DESUPPORT) { + if (faDataType == FADataType.PROFILES) { + return this.emitError( + "FA Profile is not supported anymore, use FA Group instead.", + ErrorCode.UPDATE_TWS, + -1, + ); + } + } + const version = 1; this.sendMsg(OUT_MSG_ID.REQ_FA, version, faDataType); diff --git a/src/tests/unit/api-next/get-all-open-orders.test.ts b/src/tests/unit/api-next/get-all-open-orders.test.ts index 0c82e18c..bf44e3bb 100644 --- a/src/tests/unit/api-next/get-all-open-orders.test.ts +++ b/src/tests/unit/api-next/get-all-open-orders.test.ts @@ -50,7 +50,6 @@ describe("RxJS Wrapper: getAllOpenOrders", () => { faGroup: "", faMethod: "", faPercentage: "", - faProfile: "", modelCode: "", goodTillDate: "", rule80A: "0", diff --git a/src/tests/unit/api/order/cancelOrder.test.ts b/src/tests/unit/api/order/cancelOrder.test.ts index 1341f15b..a52bd203 100644 --- a/src/tests/unit/api/order/cancelOrder.test.ts +++ b/src/tests/unit/api/order/cancelOrder.test.ts @@ -50,10 +50,9 @@ describe("CancelOrder", () => { orderType: OrderType.LMT, action: OrderAction.BUY, lmtPrice: 1, - orderId: refId, totalQuantity: 1, // account: "DU123567", - tif: "DAY", + tif: "GTC", transmit: true, }; @@ -64,7 +63,7 @@ describe("CancelOrder", () => { }) .on(EventName.openOrder, (orderId, _contract, _order, _orderState) => { expect(orderId).toEqual(refId); - if (orderId === refId) { + if (!order_found && orderId === refId) { order_found = true; ib.cancelOrder(refId); } diff --git a/src/tests/unit/api/wsh-event-data.test.ts b/src/tests/unit/api/wsh-event-data.test.ts index 08ce6bd1..333cc2d9 100644 --- a/src/tests/unit/api/wsh-event-data.test.ts +++ b/src/tests/unit/api/wsh-event-data.test.ts @@ -2,6 +2,8 @@ import { IBApi } from "../../../api/api"; import WshEventData from "../../../api/contract/wsh"; import { EventName } from "../../../api/data/enum/event-name"; import configuration from "../../../common/configuration"; +import { ErrorCode } from "../../../common/errorCode"; +import logger from "../../../common/logger"; describe("IBApi Fundamental Data", () => { jest.setTimeout(5000); @@ -38,7 +40,13 @@ describe("IBApi Fundamental Data", () => { done(); }) .on(EventName.error, (err, code, reqId) => { - if (reqId == refId) done(`[${reqId}] ${err.message} (#${code})`); + const msg = `[${reqId}] ${err.message} (#${code})`; + if (code == ErrorCode.NEWS_FEED_NOT_ALLOWED) { + logger.error(msg); + done(); + } else if (reqId == refId) { + done(msg); + } }); ib.connect(); @@ -61,7 +69,13 @@ describe("IBApi Fundamental Data", () => { done(); }) .on(EventName.error, (err, code, reqId) => { - if (reqId == refId) done(`[${reqId}] ${err.message} (#${code})`); + const msg = `[${reqId}] ${err.message} (#${code})`; + if (code == ErrorCode.NEWS_FEED_NOT_ALLOWED) { + logger.error(msg); + done(); + } else if (reqId == refId) { + done(msg); + } }); ib.connect(); @@ -87,7 +101,13 @@ describe("IBApi Fundamental Data", () => { done(); }) .on(EventName.error, (err, code, reqId) => { - if (reqId == refId) done(`[${reqId}] ${err.message} (#${code})`); + const msg = `[${reqId}] ${err.message} (#${code})`; + if (code == ErrorCode.NEWS_FEED_NOT_ALLOWED) { + logger.error(msg); + done(); + } else if (reqId == refId) { + done(msg); + } }); ib.connect();