/// <summary> /// This event is raised when historical data arrives from TWS /// </summary> private void _client_HistoricalData(object sender, QDMSIBClient.HistoricalDataEventArgs e) { int id; lock (_subReqMapLock) { //if the data is arriving for a sub-request, we must get the id of the original request first //otherwise it's just the same id id = _subRequestIDMap.ContainsKey(e.RequestId) ? _subRequestIDMap[e.RequestId] : e.RequestId; } if (!_historicalDataRequests.ContainsKey(id)) { //this means we don't have a request with this key. If all works well, //it should mean that this is actually a realtime data request using the new system return; } var bar = TWSUtils.HistoricalDataEventArgsToOHLCBar(e); //stocks need to have their volumes multiplied by 100, I think all other instrument types do not if (_historicalDataRequests[id].Instrument.Type == InstrumentType.Stock) { bar.Volume *= 100; } _arrivedHistoricalData[id].Add(bar); }
/// <summary> /// This event is raised when historical data arrives from TWS /// </summary> private void _client_HistoricalData(object sender, Krs.Ats.IBNet.HistoricalDataEventArgs e) { //convert the bar and add it to the Dictionary of arrived data var bar = TWSUtils.HistoricalDataEventArgsToOHLCBar(e); int id; lock (_subReqMapLock) { //if the data is arriving for a sub-request, we must get the id of the original request first //otherwise it's just the same id id = _subRequestIDMap.ContainsKey(e.RequestId) ? _subRequestIDMap[e.RequestId] : e.RequestId; } //stocks need to have their volumes multiplied by 100, I think all other instrument types do not if (_historicalDataRequests[id].Instrument.Type == InstrumentType.Stock) { bar.Volume *= 100; } _arrivedHistoricalData[id].Add(bar); if (e.RecordNumber >= e.RecordTotal - 1) //this was the last item to receive for this request, send it to the broker { bool requestComplete = true; lock (_subReqMapLock) { if (_subRequestIDMap.ContainsKey(e.RequestId)) { _subRequestIDMap.Remove(e.RequestId); _subRequestCount[id]--; if (_subRequestCount[id] > 0) { //What happens here: this is a subrequest. //We check how many sub-requests in this group have been delivered. //if this is the last one, we want to call HistoricalDataRequestComplete() //otherwise there's more data to come, so we have to wait for it requestComplete = false; } else { //if it is complete, we'll need to sort the data because subrequests may not come in in order _arrivedHistoricalData[id] = _arrivedHistoricalData[id].OrderBy(x => x.DTOpen).ToList(); } } } if (requestComplete) { HistoricalDataRequestComplete(id); } } }
/// <summary> /// This event is raised when historical data arrives from TWS /// </summary> private void _client_HistoricalData(object sender, Krs.Ats.IBNet.HistoricalDataEventArgs e) { //convert the bar and add it to the Dictionary of arrived data var bar = TWSUtils.HistoricalDataEventArgsToOHLCBar(e); int id; lock (_subReqMapLock) { //if the data is arriving for a sub-request, we must get the id of the original request first //otherwise it's just the same id id = _subRequestIDMap.ContainsKey(e.RequestId) ? _subRequestIDMap[e.RequestId] : e.RequestId; } //stocks need to have their volumes multiplied by 100, I think all other instrument types do not if (_historicalDataRequests[id].Instrument.Type == InstrumentType.Stock) { bar.Volume *= 100; } _arrivedHistoricalData[id].Add(bar); if (e.RecordNumber >= e.RecordTotal - 1) //this was the last item to receive for this request, send it to the broker { bool requestComplete = true; lock (_subReqMapLock) { if (_subRequestIDMap.ContainsKey(e.RequestId)) { //If there are sub-requests, here we check if this is the last one requestComplete = ControlSubRequest(e.RequestId); if (requestComplete) { //If it was the last one, we need to order the data because sub-requests can arrive out of order _arrivedHistoricalData[id] = _arrivedHistoricalData[id].OrderBy(x => x.DTOpen).ToList(); } } } if (requestComplete) { HistoricalDataRequestComplete(id); } } }