-
Notifications
You must be signed in to change notification settings - Fork 133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for reqHistoricalTicks & reqTickByTickData #127
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
var _ = require('lodash'); | ||
var chalk = require('chalk'); | ||
|
||
var ib = new(require('..'))({ | ||
// clientId: 0, | ||
// host: '127.0.0.1', | ||
// port: 4003 | ||
}).on('error', (err) => { | ||
console.error(chalk.red(err.message)); | ||
}).on('historicalTickTradeData', (...data) => { | ||
console.log( | ||
'%s %s%d %s%s %s%d %s%d %s%d %s%s %s%s', | ||
chalk.cyan('[historicalTickTradeData]'), | ||
chalk.bold('reqId='), data[0], | ||
chalk.bold('timestamp='), data[1], | ||
chalk.bold('mask='), data[2], | ||
chalk.bold('price='), data[3], | ||
chalk.bold('size='), data[4], | ||
chalk.bold('exchange='), data[5], | ||
chalk.bold('specialConditions='), data[6], | ||
); | ||
}).on('historicalTickBidAskData', (...data) => { | ||
console.log( | ||
'%s %s%d %s%s %s%d %s%d %s%d %s%d %s%d', | ||
chalk.cyan('[historicalTickBidAskData]'), | ||
chalk.bold('reqId='), data[0], | ||
chalk.bold('timestamp='), data[1], | ||
chalk.bold('mask='), data[2], | ||
chalk.bold('priceBid='), data[3], | ||
chalk.bold('priceAsk='), data[4], | ||
chalk.bold('sizeBid='), data[5], | ||
chalk.bold('sizeAsk='), data[6], | ||
); | ||
}).on('historicalTickMidPointData', (...data) => { | ||
console.log( | ||
'%s %s%d %s%s %s%d %s%d', | ||
chalk.cyan('[historicalTickMidPointData]'), | ||
chalk.bold('reqId='), data[0], | ||
chalk.bold('timestamp='), data[1], | ||
chalk.bold('price='), data[2], | ||
chalk.bold('size='), data[3] | ||
); | ||
}); | ||
|
||
|
||
ib.connect(); | ||
|
||
// tickerId, contract, startDateTime, endDateTime, numberOfTicks, whatToShow, useRTH, ignoreSize | ||
ib.reqHistoricalTicks(1, ib.contract.stock('SPY', 'SMART', 'USD'), '20180711 12:00:00', null, 10, 'TRADES', 1, false); | ||
ib.reqHistoricalTicks(2, ib.contract.stock('SPY', 'SMART', 'USD'), '20180711 12:00:00', null, 10, 'BID_ASK', 1, false); | ||
ib.reqHistoricalTicks(3, ib.contract.stock('SPY', 'SMART', 'USD'), '20180711 12:00:00', null, 10, 'MIDPOINT', 1, false); | ||
|
||
|
||
ib.on('historicalTickDataEnd', (reqId) => { | ||
console.log( | ||
'%s %s%d', | ||
chalk.cyan('[historicalTickDataEnd]'), | ||
chalk.bold('reqId='), reqId | ||
); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
var _ = require('lodash'); | ||
var chalk = require('chalk'); | ||
|
||
var ib = new(require('..'))({ | ||
// clientId: 0, | ||
// host: '127.0.0.1', | ||
// port: 4003 | ||
}).on('error', (err) => { | ||
console.error(chalk.red(err.message)); | ||
}).on('tickByTickAllLast', (...data) => { | ||
console.log( | ||
'%s %s%d %s%d %s%d %s%d %s%s %s%s %s%s', | ||
chalk.cyan('[tickByTickAllLast]'), | ||
chalk.bold('reqId='), data[0], | ||
chalk.bold('tickType='), data[1], | ||
chalk.bold('timestamp='), data[2], | ||
chalk.bold('price='), data[3], | ||
chalk.bold('size='), data[4], | ||
chalk.bold('attributes='), JSON.stringify(data[5]), | ||
chalk.bold('exchange='), data[6], | ||
chalk.bold('specialConditions='), data[7], | ||
); | ||
}).on('tickByTickBidAsk', (...data) => { | ||
console.log( | ||
'%s %s%d %s%s %s%d %s%d %s%d %s%d %s%s', | ||
chalk.cyan('[tickByTickBidAsk]'), | ||
chalk.bold('reqId='), data[0], | ||
chalk.bold('timestamp='), data[1], | ||
chalk.bold('priceBid='), data[2], | ||
chalk.bold('priceAsk='), data[3], | ||
chalk.bold('sizeBid='), data[4], | ||
chalk.bold('sizeAsk='), data[5], | ||
chalk.bold('attributes='), JSON.stringify(data[6]), | ||
); | ||
}).on('tickByTickMidPoint', (...data) => { | ||
console.log( | ||
'%s %s%d %s%s %s%d', | ||
chalk.cyan('[tickByTickMidPoint]'), | ||
chalk.bold('reqId='), data[0], | ||
chalk.bold('timestamp='), data[1], | ||
chalk.bold('midpoint='), data[2], | ||
); | ||
}); | ||
|
||
ib.connect(); | ||
|
||
// tickerId, contract, tick type (BidAsk, Last, AllLast, MidPoint), numberOfTicks, ignoreSize | ||
ib.reqTickByTickData(1, ib.contract.stock('SPY', 'SMART', 'USD'), 'BidAsk', 0, false) | ||
//ib.reqTickByTickData(1, ib.contract.stock('SPY', 'SMART', 'USD'), 'AllLast', 0, false) | ||
//ib.reqTickByTickData(1, ib.contract.stock('SPY', 'SMART', 'USD'), 'Last', 0, false) | ||
//ib.reqTickByTickData(1, ib.contract.stock('SPY', 'SMART', 'USD'), 'MidPoint', 0, false) | ||
|
||
setTimeout(() => { | ||
console.log( | ||
'%s %s%d', | ||
chalk.cyan('sending [cancelTickByTickData]'), | ||
chalk.bold('reqId='), 1); | ||
|
||
ib.cancelTickByTickData(1); | ||
ib.disconnect(); | ||
}, 5000); | ||
|
||
// | ||
// [tickByTickBidAsk] reqId=1 timestamp=1531426792 priceBid=279.15 priceAsk=279.18 sizeBid=200 sizeAsk=3100 attributes={"bidPastLow":false,"askPastHigh":false} | ||
// [tickByTickAllLast] reqId=1 tickType=2 timestamp=1531426753 price=279.15 size=200 attributes={"pastLimit":false,"unreported":false} exchange=BATS specialConditions= T | ||
// [tickByTickAllLast] reqId=1 tickType=1 timestamp=1531426672 price=279.15 size=213 attributes={"pastLimit":false,"unreported":false} exchange=BATS specialConditions= FT | ||
// [tickByTickMidPoint] reqId=1 timestamp=1531426697 midpoint=279.16 | ||
// |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -420,6 +420,128 @@ Incoming.prototype._HISTORICAL_DATA = function () { | |
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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Useful event but no correspondence with the IB API. By reading the documentation, I expected two parameters - an array of ticks, and a Boolean |
||
} | ||
}; | ||
|
||
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(); | ||
sizeBid = this.dequeueInt(); | ||
priceAsk = this.dequeueFloat(); | ||
sizeAsk = this.dequeueInt(); | ||
this._emit('historicalTickBidAskData', reqId, date, mask, priceBid, priceAsk, sizeBid, sizeAsk); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be |
||
} | ||
|
||
var done = this.dequeueBool(); | ||
|
||
if (done) { | ||
this._emit('historicalTickDataEnd', reqId); | ||
} | ||
}; | ||
|
||
Incoming.prototype._HISTORICAL_TICKS = function() { // MIDPOINT (size appears to always be zero) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here :-( |
||
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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be |
||
} | ||
|
||
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(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name
historicalTickTradeData
doesn't match the IB API documentation for TRADE data ticks. It should behistoricalTicksLast
. I've spent quite a bit of time trying to figure out this mismatch, because node-ib doesn't have documentation and points at the official IB API docs.