UNPKG

ib

Version:

Interactive Brokers TWS (or IB Gateway) API client library for Node.js

1,502 lines (1,194 loc) 39.7 kB
var _ = require('lodash'); var C = require('./constants'); var errors = require('./errors'); function Incoming(controller) { this._controller = controller; this._dataQueue = []; this._emitQueue = []; } Incoming.prototype._ACCT_DOWNLOAD_END = function () { var version = this.dequeueInt(); var accountName = this.dequeue(); this._emit('accountDownloadEnd', accountName); }; Incoming.prototype._ACCOUNT_SUMMARY = function () { var version = this.dequeueInt(); var reqId = this.dequeueInt(); var account = this.dequeue(); var tag = this.dequeue(); var value = this.dequeue(); var currency = this.dequeue(); this._emit('accountSummary', reqId, account, tag, value, currency); }; Incoming.prototype._ACCOUNT_UPDATE_MULTI_END = function () { var version = this.dequeueInt(); var reqId = this.dequeue(); this._emit('accountUpdateMultiEnd', reqId); }; Incoming.prototype._ACCOUNT_UPDATE_MULTI = function () { var version = this.dequeueInt(); var reqId = this.dequeueInt(); var account = this.dequeue(); var modelCode = this.dequeue(); var key = this.dequeue(); var value = this.dequeue(); var currency = this.dequeue(); this._emit('accountUpdateMulti', reqId, account, modelCode, key, value, currency); }; Incoming.prototype._ACCOUNT_SUMMARY_END = function () { var version = this.dequeueInt(); var reqId = this.dequeueInt(); this._emit('accountSummaryEnd', reqId); }; Incoming.prototype._ACCT_UPDATE_TIME = function () { var version = this.dequeueInt(); var timeStamp = this.dequeue(); this._emit('updateAccountTime', timeStamp); }; Incoming.prototype._ACCT_VALUE = function () { var version = this.dequeueInt(); var key = this.dequeue(); var value = this.dequeue(); var currency = this.dequeue(); var accountName = null; if (version >= 2) { accountName = this.dequeue(); } this._emit('updateAccountValue', key, value, currency, accountName); }; Incoming.prototype._COMMISSION_REPORT = function () { var version = this.dequeueInt(); var commissionReport = {}; commissionReport.execId = this.dequeue(); commissionReport.commission = this.dequeueFloat(); commissionReport.currency = this.dequeue(); commissionReport.realizedPNL = this.dequeueFloat(); commissionReport.yield = this.dequeueFloat(); commissionReport.yieldRedemptionDate = this.dequeueInt(); this._emit('commissionReport', commissionReport); }; Incoming.prototype._BOND_CONTRACT_DATA = function () { var version = this.dequeueInt(); var reqId = -1; var i; if (version >= 3) { reqId = this.dequeueInt(); } var contract = { summary: {} }; contract.summary.symbol = this.dequeue(); contract.summary.secType = this.dequeue(); contract.cusip = this.dequeue(); contract.coupon = this.dequeueFloat(); contract.maturity = this.dequeue(); contract.issueDate = this.dequeue(); contract.ratings = this.dequeue(); contract.bondType = this.dequeue(); contract.couponType = this.dequeue(); contract.convertible = this.dequeueBool(); contract.callable = this.dequeueBool(); contract.putable = this.dequeueBool(); contract.descAppend = this.dequeue(); contract.summary.exchange = this.dequeue(); contract.summary.currency = this.dequeue(); contract.marketName = this.dequeue(); contract.summary.tradingClass = this.dequeue(); contract.summary.conId = this.dequeueInt(); contract.minTick = this.dequeueFloat(); contract.orderTypes = this.dequeue(); contract.validExchanges = this.dequeue(); if (version >= 2) { contract.nextOptionDate = this.dequeue(); contract.nextOptionType = this.dequeue(); contract.nextOptionPartial = this.dequeueBool(); contract.notes = this.dequeue(); } if(version >= 4) { contract.longName = this.dequeue(); } if (version >= 6) { contract.evRule = this.dequeue(); contract.evMultiplier = this.dequeueFloat(); } var secIdListCount; var tagValue; if (version >= 5) { secIdListCount = this.dequeueInt(); if (secIdListCount > 0) { contract.secIdList = []; while (secIdListCount--) { tagValue = {}; tagValue.tag = this.dequeue(); tagValue.value = this.dequeue(); contract.secIdList.push(tagValue); } } } this._emit('bondContractDetails', reqId, contract); }; Incoming.prototype._CONTRACT_DATA = function () { var version = this.dequeueInt(); var reqId = -1; if (version >= 3) { reqId = this.dequeueInt(); } var contract = { summary: {} }; contract.summary.symbol = this.dequeue(); contract.summary.secType = this.dequeue(); contract.summary.expiry = this.dequeue(); contract.summary.strike = this.dequeueFloat(); contract.summary.right = this.dequeue(); contract.summary.exchange = this.dequeue(); contract.summary.currency = this.dequeue(); contract.summary.localSymbol = this.dequeue(); contract.marketName = this.dequeue(); contract.summary.tradingClass = this.dequeue(); contract.summary.conId = this.dequeueInt(); contract.minTick = this.dequeueFloat(); contract.summary.multiplier = this.dequeue(); contract.orderTypes = this.dequeue(); contract.validExchanges = this.dequeue(); if (version >= 2) { contract.priceMagnifier = this.dequeueInt(); } if (version >= 4) { contract.underConId = this.dequeueInt(); } if (version >= 5) { contract.longName = this.dequeue(); contract.summary.primaryExch = this.dequeue(); } if (version >= 6) { contract.contractMonth = this.dequeue(); contract.industry = this.dequeue(); contract.category = this.dequeue(); contract.subcategory = this.dequeue(); contract.timeZoneId = this.dequeue(); contract.tradingHours = this.dequeue(); contract.liquidHours = this.dequeue(); } if (version >= 8) { contract.evRule = this.dequeue(); contract.evMultiplier = this.dequeueFloat(); } var secIdListCount; var tagValue; var i; if (version >= 7) { secIdListCount = this.dequeueInt(); if (secIdListCount > 0) { contract.secIdList = []; for (i = 0; i < secIdListCount; ++i) { tagValue = {}; tagValue.tag = this.dequeue(); tagValue.value = this.dequeue(); contract.secIdList.push(tagValue); } } } this._emit('contractDetails', reqId, contract); }; Incoming.prototype._CONTRACT_DATA_END = function () { var version = this.dequeueInt(); var reqId = this.dequeueInt(); this._emit('contractDetailsEnd', reqId); }; Incoming.prototype._CURRENT_TIME = function () { var version = this.dequeueInt(); var time = this.dequeueInt(); this._emit('currentTime', time); }; Incoming.prototype._DELTA_NEUTRAL_VALIDATION = function () { var version = this.dequeueInt(); var reqId = this.dequeueInt(); var underComp = {}; underComp.conId = this.dequeueInt(); underComp.delta = this.dequeueFloat(); underComp.price = this.dequeueFloat(); this._emit('deltaNeutralValidation', reqId, underComp); }; Incoming.prototype._ERR_MSG = function () { var errorCode; var errorMsg; var id; var version = this.dequeueInt(); if (version < 2) { errorMsg = this.dequeue(); this._controller.emitError(errorMsg); } else { id = this.dequeueInt(); errorCode = this.dequeueInt(); errorMsg = this.dequeue(); this._controller.emitError(errorMsg, { id: id, code: errorCode }); } }; Incoming.prototype._EXECUTION_DATA = function () { var version = this.dequeueInt(); var reqId = -1; if (version >= 7) { reqId = this.dequeueInt(); } var orderId = this.dequeueInt(); // read contract fields var contract = {}; if (version >= 5) { contract.conId = this.dequeueInt(); } contract.symbol = this.dequeue(); contract.secType = this.dequeue(); contract.expiry = this.dequeue(); contract.strike = this.dequeueFloat(); contract.right = this.dequeue(); if (version >= 9) { contract.multiplier = this.dequeue(); } contract.exchange = this.dequeue(); contract.currency = this.dequeue(); contract.localSymbol = this.dequeue(); if (version >= 10) { contract.tradingClass = this.dequeue(); } var exec = {}; exec.orderId = orderId; exec.execId = this.dequeue(); exec.time = this.dequeue(); exec.acctNumber = this.dequeue(); exec.exchange = this.dequeue(); exec.side = this.dequeue(); exec.shares = this.dequeue(); exec.price = this.dequeueFloat(); if (version >= 2) { exec.permId = this.dequeueInt(); } if (version >= 3) { exec.clientId = this.dequeueInt(); } if (version >= 4) { exec.liquidation = this.dequeueInt(); } if (version >= 6) { exec.cumQty = this.dequeueInt(); exec.avgPrice = this.dequeueFloat(); } if (version >= 8) { exec.orderRef = this.dequeue(); } if (version >= 9) { exec.evRule = this.dequeue(); exec.evMultiplier = this.dequeueFloat(); } this._emit('execDetails', reqId, contract, exec); }; Incoming.prototype._EXECUTION_DATA_END = function () { var version = this.dequeueInt(); var reqId = this.dequeueInt(); this._emit('execDetailsEnd', reqId); }; Incoming.prototype._FUNDAMENTAL_DATA = function () { var version = this.dequeueInt(); var reqId = this.dequeueInt(); var data = this.dequeue(); this._emit('fundamentalData', reqId, data); }; Incoming.prototype._HISTORICAL_DATA = function () { var version = this.dequeueInt(); var reqId = this.dequeueInt(); var completedIndicator = 'finished'; var startDateStr; var endDateStr; if (version >= 2) { startDateStr = this.dequeue(); endDateStr = this.dequeue(); completedIndicator += '-' + startDateStr + '-' + endDateStr; } var itemCount = this.dequeueInt(); var date; var open; var high; var low; var close; var volume; var WAP; var hasGaps; var barCount; while (itemCount--) { date = this.dequeue(); open = this.dequeueFloat(); high = this.dequeueFloat(); low = this.dequeueFloat(); close = this.dequeueFloat(); volume = this.dequeueInt(); WAP = this.dequeueFloat(); hasGaps = this.dequeueBool(); barCount = -1; if (version >= 3) { barCount = this.dequeueInt(); } this._emit('historicalData', reqId, date, open, high, low, close, volume, barCount, WAP, hasGaps); } // send end of dataset marker this._emit('historicalData', reqId, completedIndicator, -1, -1, -1, -1, -1, -1, -1, false); }; Incoming.prototype._HISTORICAL_TICKS_LAST = function() { var reqId = this.dequeueInt(); var tickCount = this.dequeueInt(); var date; var mask; var price; var size; var exchange; var specialConditions; while (tickCount--) { date = this.dequeue(); mask = this.dequeueInt(); price = this.dequeueFloat(); size = this.dequeueInt(); exchange = this.dequeue(); specialConditions = this.dequeue(); this._emit('historicalTickTradeData', reqId, date, mask, price, size, exchange, specialConditions); } var done = this.dequeueBool(); if (done) { this._emit('historicalTickDataEnd', reqId); } }; Incoming.prototype._HISTORICAL_TICKS_BID_ASK = function() { var reqId = this.dequeueInt(); var tickCount = this.dequeueInt(); var date; var mask; var priceBid; var sizeBid; var priceAsk; var sizeAsk; while (tickCount--) { date = this.dequeue(); mask = this.dequeueInt(); priceBid = this.dequeueFloat(); priceAsk = this.dequeueFloat(); sizeBid = this.dequeueInt(); sizeAsk = this.dequeueInt(); this._emit('historicalTickBidAskData', reqId, date, mask, priceBid, priceAsk, sizeBid, sizeAsk); } var done = this.dequeueBool(); if (done) { this._emit('historicalTickDataEnd', reqId); } }; Incoming.prototype._HISTORICAL_TICKS = function() { // MIDPOINT (size appears to always be zero) var reqId = this.dequeueInt(); var tickCount = this.dequeueInt(); var date; var price; var size; while (tickCount--) { date = this.dequeue(); this.dequeueInt();//for consistency price = this.dequeueFloat(); size = this.dequeueInt(); this._emit('historicalTickMidPointData', reqId, date, price, size); } var done = this.dequeueBool(); if (done) { this._emit('historicalTickDataEnd', reqId); } }; Incoming.prototype._TICK_BY_TICK = function () { var reqId = this.dequeueInt(); var tickType = this.dequeueInt(); var time = this.dequeue(); var mask; switch (tickType){ case 0: // None break; case 1: // Last case 2: // Alllast var price = this.dequeueFloat(); var size = this.dequeueInt(); mask = this.dequeueInt(); var pastLimit = (mask & (1 << 0)) !== 0; var unreported = (mask & (1 << 1)) !== 0; var exchange = this.dequeue(); var specialConditions = this.dequeue(); this._emit('tickByTickAllLast', reqId, tickType, time, price, size, { pastLimit, unreported }, exchange, specialConditions); break; case 3: // BidAsk var bidPrice = this.dequeueFloat(); var askPrice = this.dequeueFloat(); var bidSize = this.dequeueInt(); var askSize = this.dequeueInt(); mask = this.dequeueInt(); var bidPastLow = (mask & (1 << 0)) !== 0; var askPastHigh = (mask & (1 << 1)) !== 0; this._emit('tickByTickBidAsk', reqId, time, bidPrice, askPrice, bidSize, askSize, { bidPastLow, askPastHigh }); break; case 4: // MidPoint var midPoint = this.dequeueFloat(); this._emit('tickByTickMidPoint', reqId, time, midPoint); break; } }; Incoming.prototype._HEAD_TIMESTAMP = function() { var reqId = this.dequeueInt(); var headTimestamp = this.dequeue(); this._emit('headTimestamp', reqId, headTimestamp); }; Incoming.prototype._MANAGED_ACCTS = function () { var version = this.dequeueInt(); var accountsList = this.dequeue(); this._emit('managedAccounts', accountsList); }; Incoming.prototype._MARKET_DATA_TYPE = function () { var version = this.dequeueInt(); var reqId = this.dequeueInt(); var marketDataType = this.dequeueInt(); this._emit('marketDataType', reqId, marketDataType); }; Incoming.prototype._MARKET_DEPTH = function () { var version = this.dequeueInt(); var id = this.dequeueInt(); var position = this.dequeueInt(); var operation = this.dequeueInt(); var side = this.dequeueInt(); var price = this.dequeueFloat(); var size = this.dequeueInt(); this._emit('updateMktDepth', id, position, operation, side, price, size); }; Incoming.prototype._MARKET_DEPTH_L2 = function () { var version = this.dequeueInt(); var id = this.dequeueInt(); var position = this.dequeueInt(); var marketMaker = this.dequeue(); var operation = this.dequeueInt(); var side = this.dequeueInt(); var price = this.dequeueFloat(); var size = this.dequeueInt(); this._emit('updateMktDepthL2', id, position, marketMaker, operation, side, price, size); }; Incoming.prototype._SYMBOL_SAMPLES = function () { var id = this.dequeueInt(); var itemCount = this.dequeueInt(); var contracts = []; while (itemCount--) { var contract = {}; contract.conId = this.dequeueInt(); contract.symbol = this.dequeue(); contract.secType = this.dequeue(); contract.primaryExchange = this.dequeue(); contract.currency = this.dequeue(); var nDerivativeSecTypes = this.dequeueInt(); contract.derivativeSecTypes = []; for (var i = 0;i<nDerivativeSecTypes;i++) { derivSecType = this.dequeue(); contract.derivativeSecTypes.push(derivSecType); } contracts.push(contract); } this._emit('symbolSamples', id, contracts); }; Incoming.prototype._NEWS_BULLETINS = function () { var version = this.dequeueInt(); var newsMsgId = this.dequeueInt(); var newsMsgType = this.dequeueInt(); var newsMessage = this.dequeue(); var originatingExch = this.dequeue(); this._emit('updateNewsBulletin', newsMsgId, newsMsgType, newsMessage, originatingExch); }; Incoming.prototype._NEXT_VALID_ID = function () { var version = this.dequeueInt(); var orderId = this.dequeueInt(); this._emit('nextValidId', orderId); }; Incoming.prototype._OPEN_ORDER = function () { var i; // read version var version = this.dequeueInt(); // read order id var order = {}; order.orderId = this.dequeueInt(); // read contract fields var contract = {}; if (version >= 17) { contract.conId = this.dequeueInt(); } contract.symbol = this.dequeue(); contract.secType = this.dequeue(); contract.expiry = this.dequeue(); contract.strike = this.dequeueFloat(); contract.right = this.dequeue(); if (version >= 32) { contract.multiplier = this.dequeue(); } contract.exchange = this.dequeue(); contract.currency = this.dequeue(); if (version >= 2) { contract.localSymbol = this.dequeue(); } if (version >= 32) { contract.tradingClass = this.dequeue(); } // read order fields order.action = this.dequeue(); order.totalQuantity = this.dequeueInt(); order.orderType = this.dequeue(); if (version < 29) { order.lmtPrice = this.dequeueFloat(); } else { order.lmtPrice = this.dequeueFloat() || Number.MAX_VALUE; } if (version < 30) { order.auxPrice = this.dequeueFloat(); } else { order.auxPrice = this.dequeueFloat() || Number.MAX_VALUE; } order.tif = this.dequeue(); order.ocaGroup = this.dequeue(); order.account = this.dequeue(); order.openClose = this.dequeue(); order.origin = this.dequeueInt(); order.orderRef = this.dequeue(); if (version >= 3) { order.clientId = this.dequeueInt(); } if (version >= 4) { order.permId = this.dequeueInt(); if (version < 18) { // will never happen /* order.ignoreRth = */ this.dequeueBool(); } else { order.outsideRth = this.dequeueBool(); } order.hidden = this.dequeueBool(); order.discretionaryAmt = this.dequeueFloat(); } if (version >= 5) { order.goodAfterTime = this.dequeue(); } if (version >= 6) { // skip deprecated sharesAllocation field this.dequeue(); } if (version >= 7) { order.faGroup = this.dequeue(); order.faMethod = this.dequeue(); order.faPercentage = this.dequeue(); order.faProfile = this.dequeue(); } if (version >= 8) { order.goodTillDate = this.dequeue(); } if (version >= 9) { order.rule80A = this.dequeue(); order.percentOffset = this.dequeueFloat() || Number.MAX_VALUE; order.settlingFirm = this.dequeue(); order.shortSaleSlot = this.dequeueInt(); order.designatedLocation = this.dequeue(); if (this._controller._serverVersion === 51) { this.dequeueInt(); // exemptCode } else if (version >= 23) { order.exemptCode = this.dequeueInt(); } order.auctionStrategy = this.dequeueInt(); order.startingPrice = this.dequeueFloat() || Number.MAX_VALUE; order.stockRefPrice = this.dequeueFloat() || Number.MAX_VALUE; order.delta = this.dequeueFloat() || Number.MAX_VALUE; order.stockRangeLower = this.dequeueFloat() || Number.MAX_VALUE; order.stockRangeUpper = this.dequeueFloat() || Number.MAX_VALUE; order.displaySize = this.dequeueInt(); if (version < 18) { // will never happen /* order.rthOnly = */ this.dequeueBool(); } order.blockOrder = this.dequeueBool(); order.sweepToFill = this.dequeueBool(); order.allOrNone = this.dequeueBool(); order.minQty = this.dequeueInt() || Number.MAX_VALUE; order.ocaType = this.dequeueInt(); order.eTradeOnly = this.dequeueBool(); order.firmQuoteOnly = this.dequeueBool(); order.nbboPriceCap = this.dequeueFloat() || Number.MAX_VALUE; } if (version >= 10) { order.parentId = this.dequeueInt(); order.triggerMethod = this.dequeueInt(); } var receivedInt; if (version >= 11) { order.volatility = this.dequeueFloat() || Number.MAX_VALUE; order.volatilityType = this.dequeueInt(); if (version === 11) { receivedInt = this.dequeueInt(); order.deltaNeutralOrderType = (receivedInt === 0 ? 'NONE' : 'MKT'); } else { // version 12 and up order.deltaNeutralOrderType = this.dequeue(); order.deltaNeutralAuxPrice = this.dequeueFloat() || Number.MAX_VALUE; if (version >= 27 && !_.isEmpty(order.deltaNeutralOrderType)) { order.deltaNeutralConId = this.dequeueInt(); order.deltaNeutralSettlingFirm = this.dequeue(); order.deltaNeutralClearingAccount = this.dequeue(); order.deltaNeutralClearingIntent = this.dequeue(); } if (version >= 31 && !_.isEmpty(order.deltaNeutralOrderType)) { order.deltaNeutralOpenClose = this.dequeue(); order.deltaNeutralShortSale = this.dequeueBool(); order.deltaNeutralShortSaleSlot = this.dequeueInt(); order.deltaNeutralDesignatedLocation = this.dequeue(); } } order.continuousUpdate = this.dequeueInt(); if (this._controller._serverVersion === 26) { order.stockRangeLower = this.dequeueFloat(); order.stockRangeUpper = this.dequeueFloat(); } order.referencePriceType = this.dequeueInt(); } if (version >= 13) { order.trailStopPrice = this.dequeueFloat() || Number.MAX_VALUE; } if (version >= 30) { order.trailingPercent = this.dequeueFloat() || Number.MAX_VALUE; } if (version >= 14) { order.basisPoints = this.dequeueFloat() || Number.MAX_VALUE; order.basisPointsType = this.dequeueInt() || Number.MAX_VALUE; contract.comboLegsDescrip = this.dequeue(); } var comboLeg; var comboLegsCount; var orderComboLeg; var orderComboLegsCount; var price; if (version >= 29) { comboLegsCount = this.dequeueInt(); if (comboLegsCount > 0) { contract.comboLegs = []; for (i = 0; i < comboLegsCount; ++i) { comboLeg = {}; comboLeg.conId = this.dequeueInt(); comboLeg.ratio = this.dequeueInt(); comboLeg.action = this.dequeue(); comboLeg.exchange = this.dequeue(); comboLeg.openClose = this.dequeueInt(); comboLeg.shortSaleSlot = this.dequeueInt(); comboLeg.designatedLocation = this.dequeue(); comboLeg.exemptCode = this.dequeueInt(); contract.comboLegs.push(comboLeg); } } orderComboLegsCount = this.dequeueInt(); if (orderComboLegsCount > 0) { order.orderComboLegs = []; for (i = 0; i < orderComboLegsCount; ++i) { orderComboLeg = {}; order.price = this.dequeueFloat() || Number.MAX_VALUE; order.orderComboLegs.push(orderComboLeg); } } } var smartComboRoutingParamsCount; var tagValue; if (version >= 26) { smartComboRoutingParamsCount = this.dequeueInt(); if (smartComboRoutingParamsCount > 0) { order.smartComboRoutingParams = []; for (i = 0; i < smartComboRoutingParamsCount; ++i) { tagValue = {}; tagValue.tag = this.dequeue(); tagValue.value = this.dequeue(); order.smartComboRoutingParams.push(tagValue); } } } if (version >= 15) { if (version >= 20) { order.scaleInitLevelSize = this.dequeueInt() || Number.MAX_VALUE; order.scaleSubsLevelSize = this.dequeueInt() || Number.MAX_VALUE; } else { var notSuppScaleNumComponents = this.dequeueInt() || Number.MAX_VALUE; order.scaleInitLevelSize = this.dequeueInt() || Number.MAX_VALUE; } order.scalePriceIncrement = this.dequeueFloat() || Number.MAX_VALUE; } if (version >= 28 && order.scalePriceIncrement > 0.0 && order.scalePriceIncrement !== Number.MAX_VALUE) { order.scalePriceAdjustValue = this.dequeueFloat() || Number.MAX_VALUE; order.scalePriceAdjustInterval = this.dequeueInt() || Number.MAX_VALUE; order.scaleProfitOffset = this.dequeueFloat() || Number.MAX_VALUE; order.scaleAutoReset = this.dequeueBool(); order.scaleInitPosition = this.dequeueInt() || Number.MAX_VALUE; order.scaleInitFillQty = this.dequeueInt() || Number.MAX_VALUE; order.scaleRandomPercent = this.dequeueBool(); } if (version >= 24) { order.hedgeType = this.dequeue(); if (!_.isEmpty(order.hedgeType)) { order.hedgeParam = this.dequeue(); } } if (version >= 25) { order.optOutSmartRouting = this.dequeueBool(); } if (version >= 19) { order.clearingAccount = this.dequeue(); order.clearingIntent = this.dequeue(); } if (version >= 22) { order.notHeld = this.dequeueBool(); } var underComp; if (version >= 20) { if (this.dequeueBool()) { underComp = {}; underComp.conId = this.dequeueInt(); underComp.delta = this.dequeueFloat(); underComp.price = this.dequeueFloat(); contract.underComp = underComp; } } var algoParamsCount; if (version >= 21) { order.algoStrategy = this.dequeue(); if (!_.isEmpty(order.algoStrategy)) { algoParamsCount = this.dequeueInt(); if (algoParamsCount > 0) { order.algoParams = []; for (i = 0; i < algoParamsCount; ++i) { tagValue = {}; tagValue.tag = this.dequeue(); tagValue.value = this.dequeue(); order.algoParams.push(tagValue); } } } } var orderState = {}; if (version >= 16) { order.whatIf = this.dequeueBool(); orderState.status = this.dequeue(); orderState.initMargin = this.dequeue(); orderState.maintMargin = this.dequeue(); orderState.equityWithLoan = this.dequeue(); orderState.commission = this.dequeueFloat() || Number.MAX_VALUE; orderState.minCommission = this.dequeueFloat() || Number.MAX_VALUE; orderState.maxCommission = this.dequeueFloat() || Number.MAX_VALUE; orderState.commissionCurrency = this.dequeue(); orderState.warningText = this.dequeue(); } this._emit('openOrder', order.orderId, contract, order, orderState); }; Incoming.prototype._OPEN_ORDER_END = function () { var version = this.dequeueInt(); this._emit('openOrderEnd'); }; Incoming.prototype._ORDER_STATUS = function () { var version = this.dequeueInt(); var id = this.dequeueInt(); var status = this.dequeue(); var filled = this.dequeueInt(); var remaining = this.dequeueInt(); var avgFillPrice = this.dequeueFloat(); var permId = 0; if (version >= 2) { permId = this.dequeueInt(); } var parentId = 0; if (version >= 3) { parentId = this.dequeueInt(); } var lastFillPrice = 0; if (version >= 4) { lastFillPrice = this.dequeueFloat(); } var clientId = 0; if (version >= 5) { clientId = this.dequeueInt(); } var whyHeld = null; if (version >= 6) { whyHeld = this.dequeue(); } this._emit('orderStatus', id, status, filled, remaining, avgFillPrice, permId, parentId, lastFillPrice, clientId, whyHeld); }; Incoming.prototype._PORTFOLIO_VALUE = function () { var version = this.dequeueInt(); var contract = {}; if (version >= 6) { contract.conId = this.dequeueInt(); } contract.symbol = this.dequeue(); contract.secType = this.dequeue(); contract.expiry = this.dequeue(); contract.strike = this.dequeueFloat(); contract.right = this.dequeue(); if (version >= 7) { contract.multiplier = this.dequeue(); contract.primaryExch = this.dequeue(); } contract.currency = this.dequeue(); if (version >= 2) { contract.localSymbol = this.dequeue(); } if (version >= 8) { contract.tradingClass = this.dequeue(); } var position = this.dequeueInt(); var marketPrice = this.dequeueFloat(); var marketValue = this.dequeueFloat(); var averageCost = 0.0; var unrealizedPNL = 0.0; var realizedPNL = 0.0; if (version >= 3) { averageCost = this.dequeueFloat(); unrealizedPNL = this.dequeueFloat(); realizedPNL = this.dequeueFloat(); } var accountName = null; if (version >= 4) { accountName = this.dequeue(); } if (version === 6 && this._controller._serverVersion === 39) { contract.primaryExch = this.dequeue(); } this._emit('updatePortfolio', contract, position, marketPrice, marketValue, averageCost, unrealizedPNL, realizedPNL, accountName); }; Incoming.prototype._POSITION = function () { var version = this.dequeueInt(); var account = this.dequeue(); var contract = {}; contract.conId = this.dequeueInt(); contract.symbol = this.dequeue(); contract.secType = this.dequeue(); contract.expiry = this.dequeue(); contract.strike = this.dequeueFloat(); contract.right = this.dequeue(); contract.multiplier = this.dequeue(); contract.exchange = this.dequeue(); contract.currency = this.dequeue(); contract.localSymbol = this.dequeue(); if (version >= 2) { contract.tradingClass = this.dequeue(); } var pos = this.dequeueInt(); var avgCost = 0; if (version >= 3) { avgCost = this.dequeueFloat(); } this._emit('position', account, contract, pos, avgCost); }; Incoming.prototype._POSITION_END = function () { var version = this.dequeueInt(); this._emit('positionEnd'); }; Incoming.prototype._POSITION_MULTI = function () { var version = this.dequeueInt(); var reqId = this.dequeueInt(); var account = this.dequeue(); var modelCode = null; var contract = {}; contract.conId = this.dequeueInt(); contract.symbol = this.dequeue(); contract.secType = this.dequeue(); contract.expiry = this.dequeue(); contract.strike = this.dequeueFloat(); contract.right = this.dequeue(); contract.multiplier = this.dequeue(); contract.exchange = this.dequeue(); contract.currency = this.dequeue(); contract.localSymbol = this.dequeue(); contract.tradingClass = this.dequeue(); var pos = this.dequeueInt(); var avgCost = 0; avgCost = this.dequeueFloat(); this._emit('positionMulti', reqId, account, modelCode, contract, pos, avgCost); }; Incoming.prototype._POSITION_MULTI_END = function () { var version = this.dequeueInt(); var reqId = this.dequeueInt(); this._emit('positionMultiEnd', reqId); }; Incoming.prototype._REAL_TIME_BARS = function () { var version = this.dequeueInt(); var reqId = this.dequeueInt(); var time = this.dequeueInt(); var open = this.dequeueFloat(); var high = this.dequeueFloat(); var low = this.dequeueFloat(); var close = this.dequeueFloat(); var volume = this.dequeueInt(); var wap = this.dequeueFloat(); var count = this.dequeueInt(); this._emit('realtimeBar', reqId, time, open, high, low, close, volume, wap, count); }; Incoming.prototype._RECEIVE_FA = function () { var version = this.dequeueInt(); var faDataType = this.dequeueInt(); var xml = this.dequeue(); this._emit('receiveFA', faDataType, xml); }; Incoming.prototype._SCANNER_DATA = function () { var version = this.dequeueInt(); var tickerId = this.dequeueInt(); var numberOfElements = this.dequeueInt(); var rank; while (numberOfElements--) { var contract = { summary: {} }; rank = this.dequeueInt(); if (version >= 3) { contract.summary.conId = this.dequeueInt(); } contract.summary.symbol = this.dequeue(); contract.summary.secType = this.dequeue(); contract.summary.expiry = this.dequeue(); contract.summary.strike = this.dequeueFloat(); contract.summary.right = this.dequeue(); contract.summary.exchange = this.dequeue(); contract.summary.currency = this.dequeue(); contract.summary.localSymbol = this.dequeue(); contract.marketName = this.dequeue(); contract.summary.tradingClass = this.dequeue(); var distance = this.dequeue(); var benchmark = this.dequeue(); var projection = this.dequeue(); var legsStr = null; if (version >= 2) { legsStr = this.dequeue(); } this._emit('scannerData', tickerId, rank, contract, distance, benchmark, projection, legsStr); } this._emit('scannerDataEnd', tickerId); }; Incoming.prototype._SCANNER_PARAMETERS = function () { var version = this.dequeueInt(); var xml = this.dequeue(); this._emit('scannerParameters', xml); }; Incoming.prototype._SECURITY_DEFINITION_OPTION_PARAMETER = function() { var reqId = this.dequeueInt(); var exchange = this.dequeue(); var underlyingConId = this.dequeueInt(); var tradingClass = this.dequeue(); var multiplier = this.dequeue(); var expCount = this.dequeueInt(); var expirations = []; for (var i = 0; i < expCount; i++) { expirations.push(this.dequeue()); } var strikeCount = this.dequeueInt(); var strikes = []; for (var j = 0; j < strikeCount; j++) { strikes.push(this.dequeueFloat()); } this._emit('securityDefinitionOptionParameter', reqId, exchange, underlyingConId, tradingClass, multiplier, expirations, strikes); }; Incoming.prototype._SECURITY_DEFINITION_OPTION_PARAMETER_END = function() { var reqId = this.dequeueInt(); this._emit('securityDefinitionOptionParameterEnd', reqId); }; Incoming.prototype._TICK_EFP = function () { var version = this.dequeueInt(); var tickerId = this.dequeueInt(); var tickType = this.dequeueInt(); var basisPoints = this.dequeueFloat(); var formattedBasisPoints = this.dequeue(); var impliedFuturesPrice = this.dequeueFloat(); var holdDays = this.dequeueInt(); var futureExpiry = this.dequeue(); var dividendImpact = this.dequeueFloat(); var dividendsToExpiry = this.dequeueFloat(); this._emit('tickEFP', tickerId, tickType, basisPoints, formattedBasisPoints, impliedFuturesPrice, holdDays, futureExpiry, dividendImpact, dividendsToExpiry); }; Incoming.prototype._TICK_GENERIC = function () { var version = this.dequeueInt(); var tickerId = this.dequeueInt(); var tickType = this.dequeueInt(); var value = this.dequeueFloat(); this._emit('tickGeneric', tickerId, tickType, value); }; Incoming.prototype._TICK_OPTION_COMPUTATION = function () { var version = this.dequeueInt(); var tickerId = this.dequeueInt(); var tickType = this.dequeueInt(); var impliedVol = this.dequeueFloat(); if (impliedVol == -1) { // -1 is the "not yet computed" indicator impliedVol = Number.MAX_VALUE; } var delta = this.dequeueFloat(); if (delta == -2) { // -2 is the "not yet computed" indicator delta = Number.MAX_VALUE; } var optPrice = Number.MAX_VALUE; var pvDividend = Number.MAX_VALUE; var gamma = Number.MAX_VALUE; var vega = Number.MAX_VALUE; var theta = Number.MAX_VALUE; var undPrice = Number.MAX_VALUE; if (version >= 6 || tickType === C.TICK_TYPE.MODEL_OPTION) { // introduced in version == 5 optPrice = this.dequeueFloat(); if (optPrice == -1) { // -1 is the "not yet computed" indicator optPrice = Number.MAX_VALUE; } pvDividend = this.dequeueFloat(); if (pvDividend == -1) { // -1 is the "not yet computed" indicator pvDividend = Number.MAX_VALUE; } } if (version >= 6) { gamma = this.dequeueFloat(); if (gamma == -2) { // -2 is the "not yet computed" indicator gamma = Number.MAX_VALUE; } vega = this.dequeueFloat(); if (vega == -2) { // -2 is the "not yet computed" indicator vega = Number.MAX_VALUE; } theta = this.dequeueFloat(); if (theta == -2) { // -2 is the "not yet computed" indicator theta = Number.MAX_VALUE; } undPrice = this.dequeueFloat(); if (theta == -1) { // -1 is the "not yet computed" indicator undPrice = Number.MAX_VALUE; } } this._emit('tickOptionComputation', tickerId, tickType, impliedVol, delta, optPrice, pvDividend, gamma, vega, theta, undPrice); }; Incoming.prototype._TICK_PRICE = function () { var version = this.dequeueInt(); var tickerId = this.dequeueInt(); var tickType = this.dequeueInt(); var price = this.dequeueFloat(); var size = 0; if (version >= 2) { size = this.dequeueInt(); } var canAutoExecute = 0; if (version >= 3) { canAutoExecute = this.dequeueBool(); } this._emit('tickPrice', tickerId, tickType, price, canAutoExecute); var sizeTickType = -1; if (version >= 2) { sizeTickType = -1 ; // not a tick switch (tickType) { case 1: // BID sizeTickType = 0; // BID_SIZE break; case 2: // ASK sizeTickType = 3; // ASK_SIZE break; case 4: // LAST sizeTickType = 5; // LAST_SIZE break; default: break; } if (sizeTickType !== -1) { this._emit('tickSize', tickerId, sizeTickType, size); } } }; Incoming.prototype._TICK_SIZE = function () { var version = this.dequeueInt(); var tickerId = this.dequeueInt(); var tickType = this.dequeueInt(); var size = this.dequeueInt(); this._emit('tickSize', tickerId, tickType, size); }; Incoming.prototype._TICK_SNAPSHOT_END = function () { var version = this.dequeueInt(); var reqId = this.dequeueInt(); this._emit('tickSnapshotEnd', reqId); }; Incoming.prototype._TICK_STRING = function () { var version = this.dequeueInt(); var tickerId = this.dequeueInt(); var tickType = this.dequeueInt(); var value = this.dequeue(); this._emit('tickString', tickerId, tickType, value); }; Incoming.prototype._DISPLAY_GROUP_LIST = function () { var version = this.dequeueInt(); var reqId = this.dequeueInt(); var list = this.dequeue(); this._emit('displayGroupList', reqId, list); }; Incoming.prototype._DISPLAY_GROUP_UPDATED = function () { var version = this.dequeueInt(); var reqId = this.dequeueInt(); var contractInfo = this.dequeue(); this._emit('displayGroupUpdated', reqId, contractInfo); }; Incoming.prototype._emit = function () { this._emitQueue.push(arguments); }; Incoming.prototype.dequeue = function () { if (this._dataQueue.length === 0) { throw new errors.UnderrunError(); } var result = this._dataQueue.shift(); return result; }; Incoming.prototype.dequeueBool = function () { return !!parseInt(this.dequeue(), 10); }; Incoming.prototype.dequeueFloat = function () { return parseFloat(this.dequeue()); }; Incoming.prototype.dequeueInt = function () { return parseInt(this.dequeue(), 10); }; Incoming.prototype.dequeueIncoming = function () { var token; do { token = this.dequeue(); } while (!token); return parseInt(token, 10); }; Incoming.prototype.enqueue = function (tokens) { this._dataQueue = this._dataQueue.concat(tokens); }; Incoming.prototype.process = function () { var constKey; var token; var dataQueueSnapshot; while (true) { dataQueueSnapshot = this._dataQueue.slice(); try { // Clear the Emit Queue; if this doesn't get cleared, it piles up whenever there's an error (added by heberallred) this._emitQueue = []; token = this.dequeueIncoming(); constKey = this._controller._ib.util.incomingToString(token); if (constKey && _.has(this.constructor.prototype, '_' + constKey) && _.isFunction(this['_' + constKey])) { this['_' + constKey](); } else { this._controller.emitError('Unknown incoming first token: ' + token); } } catch (e) { if (!(e instanceof errors.UnderrunError)) { throw e; } // Put data back in the queue, and don't emit any events. this._dataQueue = this._dataQueue.concat(dataQueueSnapshot); return; } // Drain _emitQueue. var toEmit = this._emitQueue; this._emitQueue = []; _.forEach(toEmit, (payload) => { this._controller.emit.apply(this._controller, payload); }); } }; module.exports = Incoming;