/// <summary> /// This event is raised in the case of some error /// This includes pacing violations, in which case we re-enqueue the request. /// </summary> private void _client_Error(object sender, ErrorEventArgs e) { //if we asked for too much real time data at once, we need to re-queue the failed request if ((int)e.ErrorCode == 420) //a real time pacing violation { HandleRealTimePacingViolationError(e); } else if ((int)e.ErrorCode == 162) //a historical data pacing violation { HandleHistoricalDataPacingViolationError(e); } else if ((int)e.ErrorCode == 200) //No security definition has been found for the request. { HandleNoSecurityDefinitionError(e); } //different messages depending on the type of request var errorArgs = TWSUtils.ConvertErrorArguments(e); HistoricalDataRequest histReq; RealTimeDataRequest rtReq; var isHistorical = _historicalDataRequests.TryGetValue(e.TickerId, out histReq); if (isHistorical) { int origId = _subRequestIDMap.ContainsKey(histReq.RequestID) ? _subRequestIDMap[histReq.RequestID] : histReq.RequestID; errorArgs.ErrorMessage += string.Format(" Historical Req: {0} @ {1} From {2} To {3} - TickerId: {4} ReqID: {5}", histReq.Instrument.Symbol, histReq.Frequency, histReq.StartingDate, histReq.EndingDate, e.TickerId, histReq.RequestID); errorArgs.RequestID = origId; } else if (_realTimeDataRequests.TryGetValue(e.TickerId, out rtReq)) //it's a real time request { errorArgs.ErrorMessage += string.Format(" RT Req: {0} @ {1}", rtReq.Instrument.Symbol, rtReq.Frequency); errorArgs.RequestID = rtReq.RequestID; } RaiseEvent(Error, this, errorArgs); }
/// <summary> /// This event is raised in the case of some error /// This includes pacing violations, in which case we re-enqueue the request. /// </summary> private void _client_Error(object sender, ErrorEventArgs e) { //if we asked for too much real time data at once, we need to re-queue the failed request if ((int)e.ErrorCode == 420) //a real time pacing violation { lock (_queueLock) { if (!_realTimeRequestQueue.Contains(e.TickerId)) { //since the request did not succeed, what we do is re-queue it and it gets requested again by the timer _realTimeRequestQueue.Enqueue(e.TickerId); } } } else if ((int)e.ErrorCode == 162) //a historical data pacing violation { //turns out that more than one error uses the same error code! What were they thinking? if (e.ErrorMsg.StartsWith("Historical Market Data Service error message:HMDS query returned no data")) { //no data returned = we return an empty data set RaiseEvent(HistoricalDataArrived, this, new QDMS.HistoricalDataEventArgs( _historicalDataRequests[e.TickerId], new List <OHLCBar>())); } else if (e.ErrorMsg.StartsWith("Historical Market Data Service error message:No market data permissions")) { //We don't have permission to view this data, return an empty data set RaiseEvent(HistoricalDataArrived, this, new QDMS.HistoricalDataEventArgs( _historicalDataRequests[e.TickerId], new List <OHLCBar>())); } else { //simply a data pacing violation lock (_queueLock) { if (!_historicalRequestQueue.Contains(e.TickerId)) { //same as above _historicalRequestQueue.Enqueue(e.TickerId); } } } } else if ((int)e.ErrorCode == 200) //No security definition has been found for the request. { //Again multiple errors share the same code... if (e.ErrorMsg.Contains("No security definition has been found for the request")) { //this will happen for example when asking for data on expired futures //return an empty data list if (_historicalDataRequests.ContainsKey(e.TickerId)) { HistoricalDataRequestComplete(e.TickerId); } } else //in this case we're handling a "Invalid destination exchange specified" error { //not sure if there's anything else to do, if it's a real time request it just fails... if (_historicalDataRequests.ContainsKey(e.TickerId)) { HistoricalDataRequestComplete(e.TickerId); } } } //different messages depending on the type of request var errorArgs = TWSUtils.ConvertErrorArguments(e); HistoricalDataRequest histReq; RealTimeDataRequest rtReq; var isHistorical = _historicalDataRequests.TryGetValue(e.TickerId, out histReq); if (isHistorical) { errorArgs.ErrorMessage += string.Format(" Historical Req: {0} @ {1} From {2} To {3} - ID {4}", histReq.Instrument.Symbol, histReq.Frequency, histReq.StartingDate, histReq.EndingDate, histReq.RequestID); } else if (_realTimeDataRequests.TryGetValue(e.TickerId, out rtReq)) //it's a real time request { errorArgs.ErrorMessage += string.Format(" RT Req: {0} @ {1}", rtReq.Instrument.Symbol, rtReq.Frequency); } RaiseEvent(Error, this, errorArgs); }