public override void historicalData( int reqId, string date, double open, double high, double low, double close, int volume, int count, double WAP, bool hasGaps) { var dateValue = DateTime.ParseExact(date, new[] { "yyyyMMdd", "yyyyMMdd HH\\:mm\\:ss" }, CultureInfo.InvariantCulture, DateTimeStyles.None); HistoricalDepthTickers.AddPoint( reqId, new HistoryDataPoint(dateValue, (decimal)high, (decimal)low, (decimal)open, (decimal)close, volume, count)); }
public override void error(int id, int errorCode, string errorMsg) { // See https://www.interactivebrokers.com/en/software/api/apiguide/tables/api_message_codes.htm switch (errorCode) { case 504: // Not connected case 1100: // Connectivity between IB and TWS has been lost case 1300: // TWS socket port has been reset and this connection is being dropped. Please reconnect on the new port - <port_num> Log.Error().Print(errorMsg); errorEvent.Set(); connectedEvent.Reset(); disconnectedEvent.Set(); connector.RaiseConnectionStatusChanged(ConnectionStatus.Disconnected); break; case 1102: Log.Info().Print(errorMsg); connectedEvent.Set(); disconnectedEvent.Reset(); connector.RaiseConnectionStatusChanged(ConnectionStatus.Connected); break; case 162: // Historical market data Service error message. // Historical data request pacing violation // HMDS query returned no data if (errorMsg.IndexOf("query returned no data", StringComparison.OrdinalIgnoreCase) >= 0) { // TODO ебаный стыд HistoricalDepthTickers.NoMoreData(id); } else if (errorMsg.IndexOf("Historical data request pacing violation", StringComparison.OrdinalIgnoreCase) >= 0) { // TODO ебаный стыд HistoricalDepthTickers.PaceViolation(id); } else if (errorMsg.IndexOf("Time length exceed max", StringComparison.OrdinalIgnoreCase) >= 0) { // TODO ебаный стыд HistoricalDepthTickers.TimeLengthExceedMax(id); } else { HistoricalDepthTickers.Fail(id, errorMsg); } break; case 200: // No security definition has been found for the request. { PendingTestResult testResult; if (pendingTestResultTickerContainer.TryGetPendingTestResult(id, out testResult)) { testResult.Reject(); pendingTestResultTickerContainer.RemoveTickerId(id); } } HistoricalDepthTickers.Fail(id, errorMsg); connector.ContractContainer.RejectContract(id); Log.Error().Print(errorMsg); break; case 202: // Order Canceled break; case 501: // Already connected case 2104: // A market data farm is connected. case 2106: // A historical data farm is connected. Log.Info().Print(errorMsg); break; case 10092: // Deep market data is not supported for this combination of security type/exchange Instrument instrument; if (marketDepthTickers.TryGetInstrument(id, out instrument)) { Log.Error().Print($"Unable to retreive order book on {instrument.Code}. {errorMsg.Preformatted()}"); break; } goto default; case 110: // The price does not conform to the minimum price variation for this contract. case 201: // Order rejected - reason:THIS ACCOUNT MAY NOT HOLD SHORT STOCK POSITIONS. case 203: // The security <security> is not available or allowed for this account HistoricalDepthTickers.Fail(id, errorMsg); using (orderInfoContainerLock.Lock()) { OrderInfo orderInfo; if (!orderInfoContainer.TryGetByTickerId(id, out orderInfo)) { // Неизвестная заявка, ничего не поделаешь goto default; } orderInfo.State = OrderState.Error; // Вычисляем OSCM var oscm = new OrderStateChangeMessage { TransactionId = orderInfo.NewOrderTransactionId, ActiveQuantity = (uint)orderInfo.ActiveQuantity, ChangeTime = DateTime.Now, FilledQuantity = (uint)(orderInfo.Quantity - orderInfo.ActiveQuantity), OrderExchangeId = orderInfo.PermId.ToString(CultureInfo.InvariantCulture), Quantity = (uint?)(orderInfo.Quantity), State = OrderState.Error }; // Выплевываем OSCM connector.IBOrderRouter.Transmit(oscm); Log.Error().Print($"Unable to place order {orderInfo.PermId}. {errorMsg.Preformatted()}"); } break; default: // Warning codes range if (errorCode >= 2100 && errorCode <= 2110) { Log.Warn().Print(errorMsg); } else { PendingTestResult testResult; Instrument subscriptionInstrument; if (pendingTestResultTickerContainer.TryGetPendingTestResult(id, out testResult)) { testResult.Reject(); pendingTestResultTickerContainer.RemoveTickerId(id); } else if (marketDataTickers.TryGetInstrumentAndPendingTestResult(id, out subscriptionInstrument, out testResult)) { testResult?.Reject(); marketDataTickers.RemoveTickerId(id); } Log.Error().Print($"IB error #{errorCode}: {errorMsg.Preformatted()}"); errorEvent.Set(); HistoricalDepthTickers.Fail(id, errorMsg); } break; } // TODO если пришла ошибка по тикеру - тикер нужно убить? }
public override void historicalDataEnd(int reqId, string start, string end) { HistoricalDepthTickers.Complete(reqId); }