internal bool IsFinished; // Response/Timeout/Error closed this request internal Request(TickerData tickerData) { if (tickerData == null) { throw new ArgumentNullException(); } Id = IBClientHelper.GetNextReqId(); // this Id is used (instead of collections key) in case of HistoricalDataRequest and HeadTimestampRequest // because the same logical request may result in more actual request (e.g timeouts and multiple download periods) TickerData = tickerData; IsFinished = false; RequestTimeouts = 0; }
private void SendBackfillRequest(FTController ibController) { if (downloadContract != null // && (string.IsNullOrEmpty(contract.LastTradeDateOrContractMonth) || histStart.ToString("yyyyMMdd").CompareTo(contract.LastTradeDateOrContractMonth) <= 0) && (downloadStep > 24 * 60 || IBClientHelper.IsBankingHour(downloadStart) || IBClientHelper.IsBankingHour(downloadEnd))) //check if we need to queue a requests { //try to avoid intraday request for saturday-sunday Id = IBClientHelper.GetNextReqId(); // add quotelist of subcontracts of continuous contract if (TickerData.SymbolParts.IsContinuous) { if (!TickerData.ContinuousQuotesDictionary.ContainsKey(downloadContract.LocalSymbol)) { TickerData.ContinuousQuotesDictionary.Add(downloadContract.LocalSymbol, new QuotationList(FTDataSource.Periodicity)); } } if (downloadPeriodicity <= Periodicity.FifteenSeconds) // download step is smaller than a day { LogAndMessage.LogAndQueue(MessageType.Info, TickerData.ToString(downloadContract) + ": Requesting data from " + downloadStart.ToShortDateString() + " " + downloadStart.ToShortTimeString() + " to " + downloadEnd.ToShortDateString() + " " + downloadEnd.ToShortTimeString() + " " + ToString(false, LogAndMessage.VerboseLog)); } else { LogAndMessage.LogAndQueue(MessageType.Info, TickerData.ToString(downloadContract) + ": Requesting data from " + downloadStart.ToShortDateString() + " to " + downloadEnd.ToShortDateString() + " " + ToString(false, LogAndMessage.VerboseLog)); } WaitingForResponse = true; RequestTime = DateTime.Now; ibController.SendHistoricalDataRequest(Id, downloadContract, downloadEnd, downloadStart, downloadPeriodicity, TickerData.SymbolParts.DataType); } else { // calc next download period if (CalcNextBackfillRequest()) { SendBackfillRequest(ibController); } } }
internal override bool Process(FTController ibController, bool allowNewRequest) { const int requestTimeoutPeriod = 20; // if no contract received yet if (TickerData.ContractStatus == ContractStatus.SendRequest || TickerData.ContractStatus == ContractStatus.WaitForResponse) { return(allowNewRequest); } // if no contract found if (TickerData.ContractStatus != ContractStatus.Ok) { TickerData.HeadTimestampStatus = HeadTimestampStatus.Failed; IsFinished = true; return(allowNewRequest); } lock (TickerData) // request handling { // if not waiting for response switch (TickerData.HeadTimestampStatus) { // if marked to get headtimestamp case HeadTimestampStatus.SendRequest: if (allowNewRequest) { LogAndMessage.Log(TickerData, MessageType.Trace, "Requesting earliest data point. " + ToString(false, LogAndMessage.VerboseLog)); TickerData.HeadTimestampStatus = HeadTimestampStatus.WaitForResponse; RequestTime = DateTime.Now; ibController.SendHeadTimestampRequest(Id, TickerData); } return(false); // if request is sent, but response has not arrived yet // see ibClient_HeadTimestamp event handler case HeadTimestampStatus.WaitForResponse: // if no answer in time if (RequestTime.AddSeconds(requestTimeoutPeriod) < DateTime.Now) { if (RequestTimeouts == 0) { LogAndMessage.LogAndQueue(TickerData, MessageType.Error, "Request of earliest data point timed out. Retrying. " + ToString(true, LogAndMessage.VerboseLog)); RequestTimeouts++; TickerData.HeadTimestampStatus = HeadTimestampStatus.SendRequest; Id = IBClientHelper.GetNextReqId(); goto case HeadTimestampStatus.SendRequest; } LogAndMessage.LogAndQueue(TickerData, MessageType.Error, "Request of earliest data point timed out. " + ToString(true, LogAndMessage.VerboseLog)); TickerData.HeadTimestampStatus = HeadTimestampStatus.Failed; goto case HeadTimestampStatus.Failed; } return(allowNewRequest); // if new, offline ticker case HeadTimestampStatus.Offline: // ticker's HeadTimestamp is updated case HeadTimestampStatus.Ok: // ticker's HeadTimestamp is NOT updated (we do not mark ticker as failed. it still may work!) case HeadTimestampStatus.Failed: IsFinished = true; return(allowNewRequest); // this is program error default: TickerData.HeadTimestampStatus = HeadTimestampStatus.Failed; IsFinished = true; return(allowNewRequest); } } }