Example #1
0
        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;
        }
Example #2
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);
                }
            }
        }