// callback (from controller) to indicate no more contracts
        private void SearchContractReady()
        {
            try
            {
                // limit result list
                if (securityDatas.Count > maxDisplayedContract)
                {
                    securityDatas.RemoveRange(maxDisplayedContract, securityDatas.Count - maxDisplayedContract);
                }

                // InvokeRequired did not always work! May be called back on UI thread as well.
                // However, there can be a lengthy operation to do it on background thread.
                sorting = true;

                if (securityDatas.Count > 1)
                {
                    securityDatas.Sort(new SecurityDataComparer(SecurityDataField.LocalSymbol, SortOrder.Ascending));
                }

                // if window is not shown, we cannot invoke a method through window message loop
                if (IsHandleCreated)
                {
                    BeginInvoke(new MethodInvoker(ShowContracts));
                }
            }
            catch (Exception ex)
            {
                LogAndMessage.Log(MessageType.Error, "Search form could not collect contracts: " + ex);
                MessageBox.Show("Error while retrieving contracts:" + ex, "Search form error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
        }
        internal void HeadTimestampReceived(string headTimestamp)
        {
            DateTime date;
            bool     result = DateTime.TryParseExact(headTimestamp, "yyyyMMdd  HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out date);

            lock (TickerData)  // event handling
            {
                if (result)
                {
                    TickerData.EarliestDataPoint   = date;
                    TickerData.HeadTimestampStatus = HeadTimestampStatus.Ok;
                }
                else
                {
                    TickerData.EarliestDataPoint   = DateTime.MinValue;
                    TickerData.HeadTimestampStatus = HeadTimestampStatus.Failed;
                }
            }

            if (result)
            {
                LogAndMessage.Log(TickerData, MessageType.Info, "Earliest data point value is updated. " + ToString(true, LogAndMessage.VerboseLog));
            }
            else
            {
                LogAndMessage.Log(TickerData, MessageType.Error, "Invalid earliest data point value received: " + headTimestamp + " " + ToString(true, LogAndMessage.VerboseLog));
            }
        }
Beispiel #3
0
        /// <summary>
        /// Get the contract for the historical data request for a specified start date
        /// </summary>
        /// <param name="startDate"></param>
        ///
        /// <returns></returns>
        private Contract GetCurrentContract(DateTime startDate)
        {
            Contract contract;

            if (TickerData.SymbolParts.IsContinuous)
            {
                string exStr = startDate.ToString("yyyyMMdd");
                int    i     = 0;
                for (; i < TickerData.contractDetailsList.Count - 1; i++)
                {
                    if (TickerData.contractDetailsList[i].Contract.LastTradeDateOrContractMonth.CompareTo(exStr) >= 0)
                    {
                        break;
                    }
                }

                contract = TickerData.contractDetailsList[i].Contract;
            }
            else
            {
                contract = TickerData.ContractDetails.Contract;
            }

            contract.IncludeExpired = IBClientHelper.IsContractExpired(contract);

            // TODO: Do we need it? Does not hurt...
            if (string.IsNullOrEmpty(contract.LocalSymbol))
            {
                LogAndMessage.Log(MessageType.Trace, "No valid security for continuous contract.");
                return(null);
            }

            return(contract);
        }
        /// <summary>
        /// This method creates a new or gets an existing TickerData object for a ticker
        /// </summary>
        /// <param name="ticker"></param>
        /// <returns></returns>
        /// <remarks>It looks for registered ticker object first and returns it. If ticker is not registered yet, it registers it and returns the new object. </remarks>
        internal TickerData RegisterTickerData(string ticker)
        {
            lock (mapTickerToTickerData)
            {
                TickerData tickerData;

                if (mapTickerToTickerData.TryGetValue(ticker, out tickerData))
                {
                    return(tickerData);
                }

                tickerData = new TickerData();

                tickerData.Ticker = ticker;

                mapTickerToTickerData.Add(ticker, tickerData);

                SymbolParts ftTicker;
                try
                {
                    ftTicker = new SymbolParts(ticker);
                }
                catch (Exception)
                {
                    ftTicker = null;
                    tickerData.QuoteDataStatus = QuotationStatus.Failed;
                    LogAndMessage.LogAndQueue(tickerData, MessageType.Warning, "Invalid symbol.");
                }
                tickerData.SymbolParts = ftTicker;

                return(tickerData);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Convert contract expiry string to DateTime
        /// </summary>
        /// <param name="contract"></param>
        /// <returns></returns>
        internal static DateTime GetContractExpiryDateTime(Contract contract)
        {
            if (contract == null || string.IsNullOrEmpty(contract.LastTradeDateOrContractMonth))
            {
                return(DateTime.MaxValue);
            }

            try
            {
                if (contract.LastTradeDateOrContractMonth.Length == 8)
                {
                    return(DateTime.ParseExact(contract.LastTradeDateOrContractMonth, "yyyyMMdd", CultureInfo.InvariantCulture));
                }

                if (contract.LastTradeDateOrContractMonth.Length == 6)
                {
                    // format: "yyyyMM"
                    int year  = int.Parse(contract.LastTradeDateOrContractMonth.Substring(0, 4));
                    int month = int.Parse(contract.LastTradeDateOrContractMonth.Substring(4, 2));

                    DateTime lastTradeDay = new DateTime(year, month, 1);
                    lastTradeDay = lastTradeDay.AddMonths(1);
                    lastTradeDay = lastTradeDay.AddDays(-1);        // last day of the month
                    return(lastTradeDay);
                }
                LogAndMessage.LogAndQueue(MessageType.Error, "Program error. Unknown format of last trade data/contract month:" + contract.LastTradeDateOrContractMonth);
            }
            catch
            {
                LogAndMessage.LogAndQueue(MessageType.Error, "Program error. Cannot interpret format of last trade data/contract month:" + contract.LastTradeDateOrContractMonth);
            }

            return(DateTime.MinValue);
        }
        private void buttonAdd_Click(object sender, EventArgs e)
        {
            if (dataGridViewResult.SelectedRows.Count == 0)
            {
                return;
            }

            try
            {
                Type   appType = Type.GetTypeFromProgID("Broker.Application");
                object abApp   = Activator.CreateInstance(appType);

                object abStocks   = appType.InvokeMember("Stocks", System.Reflection.BindingFlags.GetProperty, null, abApp, null);
                Type   stocksType = abStocks.GetType();

                for (int i = 0; i < dataGridViewResult.SelectedRows.Count; i++)
                {
                    SecurityData sd = (SecurityData)dataGridViewResult.SelectedRows[i].DataBoundItem;;

                    SymbolParts ibTicker = new SymbolParts(sd.LocalSymbol, sd.Exchange, sd.SecType, sd.Currency, "");

                    object stock = stocksType.InvokeMember("Add", System.Reflection.BindingFlags.InvokeMethod, null,
                                                           abStocks, new object[] { ibTicker.Ticker });
                    if (stock != null)
                    {
                        Type stockType = stock.GetType();
                        stockType.InvokeMember("Alias", System.Reflection.BindingFlags.SetProperty, null, stock,
                                               new object[] { sd.Symbol });
                        stockType.InvokeMember("Currency", System.Reflection.BindingFlags.SetProperty, null, stock,
                                               new object[] { sd.Currency });
                        stockType.InvokeMember("FullName", System.Reflection.BindingFlags.SetProperty, null, stock,
                                               new object[] { sd.LongName });
                        stockType.InvokeMember("PointValue", System.Reflection.BindingFlags.SetProperty, null, stock,
                                               new object[] { sd.PriceMagnifier });
                        stockType.InvokeMember("TickSize", System.Reflection.BindingFlags.SetProperty, null, stock,
                                               new object[] { sd.MinTick });
                        stockType.InvokeMember("WebID", System.Reflection.BindingFlags.SetProperty, null, stock,
                                               new object[] { sd.ContractId });
                    }

                    if (checkBoxAddContinuous.Checked && sd.SecType.ToUpper() == "FUT")
                    {
                        string      localNamePart = sd.LocalSymbol.Substring(0, sd.LocalSymbol.Length - 2);
                        SymbolParts contTicker    = new SymbolParts(localNamePart + "~/" + sd.Symbol, sd.Exchange, sd.SecType, sd.Currency, "");

                        stock = stocksType.InvokeMember("Add", System.Reflection.BindingFlags.InvokeMethod, null,
                                                        abStocks, new object[] { contTicker.Ticker });
                    }
                }
            }
            catch (Exception ex)
            {
                LogAndMessage.Log(MessageType.Error, "Search form could not add tickers: " + ex);
                MessageBox.Show("Error while adding tickers: " + ex, "Search form error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
        }
Beispiel #7
0
        private void mUpdateSymbolInfo_Click(object sender, EventArgs e)
        {
            if (currentSI == null)
            {
                return;
            }

            LogAndMessage.Log(MessageType.Info, currentTicker + ": Symbol info manually updated.");
            controller.UpdateSymbolInfo(currentTicker);
        }
Beispiel #8
0
 private void Listener_MessageReceived(object sender, XDMessageEventArgs e)
 {
     if (e.DataGram.Message == "reconnect")
     {
         LogAndMessage.Log(MessageType.Info, "Reconencting...");
         //manuallyDisconnected = true;
         //if (controller.IsIbConnected)
         controller.Disconnect();
         controller.Connect(false);
     }
 }
        private void SaveQuote(Quotation quote)
        {
            DateTime quoteDate = (DateTime)quote.DateTime;

            // get the trading day
            //DateTime tradingDay = DateTime.MinValue;
            //tradingDay = tickerData.LiquidHours.GetTradeDate(quoteDate);
            //if (!IBDataSource.RthOnly && tradingDay == DateTime.MinValue)
            //tradingDay = tickerData.TradingDays.GetTradeDate(quoteDate);

            // if no trading day found and RTH only
            //if (tradingDay == DateTime.MinValue)
            //    if (IBDataSource.RthOnly)
            //        return;
            //    else
            //        tradingDay = DateTime.Now.Date;

            DateTime tradingDay = tickerData.TradingDays.GetTradeDate(quoteDate);

            if (tradingDay == DateTime.MinValue)
            {
                tradingDay = DateTime.Now.Date;
            }

            try
            {
                lock (tickerData.Quotes)
                {
                    // Merge quote into last intraday quote in QuotationList
                    if (tickerData.Quotes.Periodicity != Periodicity.EndOfDay)
                    {
                        tickerData.Quotes.Merge(quote);
                    }

                    // Merge quote into last EOD quote in QuotationList
                    if (tickerData.Quotes.Periodicity == Periodicity.EndOfDay || FTDataSource.AllowMixedEODIntra)
                    {
                        tickerData.Quotes.MergeEod(quote, (AmiDate)tradingDay);
                    }
                }
            }
            catch (Exception ex)
            {
                LogAndMessage.Log(tickerData, MessageType.Error, "Error while merging received quote: " + ex);
            }
        }
Beispiel #10
0
        internal virtual bool ProcessQueuedRequests(FTController ibController, bool allowNewRequest, bool writeLog)
        {
            int cntAtStart;
            int cntAtEnd;

            bool savedAllowNewRequest = allowNewRequest;

            lock (requestList)
            {
                cntAtStart = requestList.Count;

                for (int i = cntAtStart - 1; i >= 0; i--)
                {
                    noTimeOuts &= requestList.Values[i].RequestTimeouts == 0;

                    if (requestList.Values[i].IsFinished)
                    {
                        requestList.RemoveAt(i);
                    }
                }

                cntAtEnd = requestList.Count;
            }

            // we must limit the open requests to 5
            for (int i = 0; i < cntAtEnd && i < 5; i++)
            {
                allowNewRequest &= requestList.Values[i].Process(ibController, allowNewRequest);
            }

            if (cntAtEnd == 0)
            {
                noTimeOuts = true;
            }
#if DEBUG
            if (writeLog)
            {
                LogAndMessage.Log(MessageType.Trace, queueName + ": Allow new request: " + (savedAllowNewRequest ? "1" : "0") + "/" + (allowNewRequest ? "1" : "0") + "  Requests: " + cntAtStart.ToString("#0") + "/" + cntAtEnd.ToString("#0"));
            }
#endif
            return(allowNewRequest);
        }
Beispiel #11
0
        /// <summary>
        /// Start processing the list of contract details in the event of ContractDetailsEnd
        /// </summary>
        internal void ContractDetailsReceived(List <ContractDetails> list)
        {
            bool result = false;

            lock (TickerData)   // event handling
            {
                result = ProcessContractDetailsList(list);

                TickerData.ContractStatus = result ? ContractStatus.Ok : ContractStatus.Failed;
            }

            if (result)
            {
                LogAndMessage.Log(TickerData, MessageType.Info, "Contract is updated. " + ToString(true, LogAndMessage.VerboseLog));
            }
            else
            {
                LogAndMessage.Log(TickerData, MessageType.Error, "Failed to update contract. " + ToString(true, LogAndMessage.VerboseLog));
            }
        }
Beispiel #12
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);
                }
            }
        }
Beispiel #13
0
        public static FTConfiguration GetConfigObject(string config)
        {
            // if no config string, set default values
            if (string.IsNullOrEmpty(config) || config.Trim().Length == 0)
            {
                return(GetDefaultConfigObject());
            }

            try
            {
                XmlSerializer serializer = new XmlSerializer(typeof(FTConfiguration));
                Stream        stream     = new MemoryStream(ASCIIEncoding.Default.GetBytes(config));

                return((FTConfiguration)serializer.Deserialize(stream));
            }
            catch (Exception ex)
            {
                LogAndMessage.Log(MessageType.Error, "Configuration error:" + ex);
                return(GetDefaultConfigObject());
            }
        }
Beispiel #14
0
        private void mFindIBContract_Click(object sender, EventArgs e)
        {
            try
            {
                if (searchForm == null)
                {
                    searchForm = new SearchForm(controller);
                }
                searchForm.ShowDialog();

                PostMessage(MainWindowHandle, 0x001C, new IntPtr(1), new IntPtr(0));     // WM_ACTIVATEAPP = 0x001C
                PostMessage(MainWindowHandle, 0x0086, new IntPtr(1), new IntPtr(0));     // WM_NCACTIVATE = 0x0086
                PostMessage(MainWindowHandle, 0x0006, new IntPtr(1), new IntPtr(0));     // WM_ACTIVATE = 0x0006
                PostMessage(MainWindowHandle, 0x36E, new IntPtr(1), new IntPtr(0));      // WM_ACTIVATETOPLEVEL = 0x36E
                PostMessage(MainWindowHandle, 0x2862, new IntPtr(0xb6d), new IntPtr(0)); //WM_USER + 9314
                PostMessage(MainWindowHandle, 0x0111, new IntPtr(0xb6d), new IntPtr(0)); //WM_COMMAND = 0x0111;
            }
            catch (Exception ex)
            {
                LogAndMessage.Log(MessageType.Error, "Error while opening Search window:" + ex);
            }
        }
Beispiel #15
0
        internal override bool ProcessQueuedRequests(FTController ibController, bool allowNewRequest, bool writeLog)
        {
            int cntAtStart;
            int cntAtEnd;

            bool savedAllowNewRequest = allowNewRequest;

            //
            // we must limit the open requests to 1
            //

            lock (requestList)
            {
                cntAtStart = requestList.Count;

                if (cntAtStart > 0)
                {
                    if (requestList.Values[0].IsFinished)
                    {
                        requestList.RemoveAt(0);
                    }
                }

                cntAtEnd = requestList.Count;
            }

            if (cntAtEnd > 0)
            {
                allowNewRequest &= requestList.Values[0].Process(ibController, allowNewRequest);
            }

#if DEBUG
            if (writeLog)
            {
                LogAndMessage.Log(MessageType.Trace, queueName + ": Allow new request: " + (savedAllowNewRequest ? "1" : "0") + "/" + (allowNewRequest ? "1" : "0") + "  Requests: " + cntAtStart.ToString("#0") + "/" + cntAtEnd.ToString("#0"));
            }
#endif
            return(allowNewRequest);
        }
Beispiel #16
0
        private void mBackfill_Click(object sender, EventArgs e)
        {
            if (firstGetQuotesExCall)                   // db periodicity not known yet
            {
                return;
            }

            if (string.IsNullOrEmpty(currentTicker))    // no selected ticker
            {
                return;
            }

            DateTime refreshStartDate = GetRefreshStartDate(sender);

            refreshStartDate = IBClientHelper.GetAdjustedStartDate(refreshStartDate, Periodicity, DateTime.MinValue, false);

            LogAndMessage.Log(MessageType.Info, currentTicker + ": Manual backfill from " + refreshStartDate.ToShortDateString() + ".");

            StringCollection tickerToBackfill = new StringCollection();

            tickerToBackfill.Add(currentTicker);

            StartBackfills(refreshStartDate, tickerToBackfill);
        }
Beispiel #17
0
        private void mCancel_Click(object sender, EventArgs e)
        {
            LogAndMessage.Log(MessageType.Info, "All backfill operations are manually cancelled.");

            controller.CancelAllRefreshes();
        }
Beispiel #18
0
        private void StartBackfills(DateTime refreshStartDate, StringCollection tickersToBackfill)
        {
            if (tickersToBackfill.Count == 0)
            {
                return;
            }

            //
            // checking if long download is accepted
            //

            int      stepSize   = IBClientHelper.GetDownloadStep(Periodicity);
            TimeSpan ts         = DateTime.Now.Subtract(refreshStartDate);
            int      requestsNo = (int)Math.Ceiling(ts.TotalMinutes / stepSize * tickersToBackfill.Count);

            // if mixed database, add number of EOD requests
            requestsNo = (Periodicity != Periodicity.EndOfDay && Workspace.AllowMixedEODIntra != 0) ? requestsNo + tickersToBackfill.Count : requestsNo;

            //
            // checking if database can accomodate the data
            //

            // quoteNum is aproximate value
            int quoteNum = (int)(ts.TotalSeconds / (int)Periodicity);       // total number of bars if traded 24 hours

            if (Periodicity != Periodicity.EndOfDay)
            {
                if (IBConfiguration.RthOnly)
                {
                    quoteNum /= 3;
                }
            }

            //
            // building and showing warning
            //

            bool tooManyRequest = requestsNo > 3;
            bool tooManyQuotes  = quoteNum / 1.2 > Workspace.NumBars;

            if (tooManyRequest || tooManyQuotes)
            {
                TimeSpan mts = new TimeSpan(0, 0, requestsNo * 10);

                StringBuilder msg = new StringBuilder(500);

                msg.Append("The requested data refresh");

                if (tooManyRequest)
                {
                    msg.Append(" may download more bar data (~");
                    msg.Append((quoteNum / 1.2).ToString("N0"));
                    msg.Append(") than your database can accomodate (");
                    msg.Append(Workspace.NumBars.ToString());
                    msg.Append(")");
                }
                if (tooManyRequest)
                {
                    if (tooManyRequest)
                    {
                        msg.Append(" and it");
                    }

                    msg.Append(" may start a long data download operation (~");
                    msg.Append(mts);
                    msg.Append(")");
                }

                msg.AppendLine(".");
                msg.AppendLine("Do you still want it?");

                if (MessageBox.Show(msg.ToString(),
                                    "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No)
                {
                    return;
                }
            }

            //
            // start backfills of selected length
            //

            foreach (var ticker in tickersToBackfill)
            {
                if (!controller.RefreshTicker(ticker, refreshStartDate))
                {
                    LogAndMessage.LogAndQueue(MessageType.Warning, ticker + ": Cannot start manual backfill because ticker is being backfilled.");
                }
            }
        }
        internal void MergePrice(int tickerId, int field, float price, DateTime time)
        {
            //
            // if price is 0 or less (no live data)
            //
            if (price <= 0.0f)
            {
                return;
            }

            decimal p = (decimal)price;

            //
            // save BID and ASK prices
            //
            if (field == TickType.ASK)
            {
                lastAsk = p;
            }

            else if (field == TickType.BID)
            {
                lastBid = p;
            }

            //
            // calc MID price if data is available
            //
            if (lastAsk > 0m && lastBid > 0m)
            {
                lastMid = (lastAsk + lastBid) / 2m;
            }

            //
            // check if we need to use this price tick or it is irrelevant
            //
            if (tickerData.SymbolParts.DataType == IBHistoricalDataType.Midpoint || tickerData.SymbolParts.DataType == IBHistoricalDataType.BidAsk)
            {
                if (field != TickType.BID && field != TickType.ASK && field != TickType.LAST)
                {
                    return;
                }
            }
            else if (tickerData.SymbolParts.DataType == IBHistoricalDataType.Trades || tickerData.SymbolParts.DataType == IBHistoricalDataType.Adjusted)
            {
                if (field != TickType.LAST)
                {
                    return;
                }
            }
            else if (tickerData.SymbolParts.DataType == IBHistoricalDataType.Bid)
            {
                if (field != TickType.BID)
                {
                    return;
                }
            }
            else if (tickerData.SymbolParts.DataType == IBHistoricalDataType.Ask)
            {
                if (field != TickType.ASK)
                {
                    return;
                }
            }
            else if (tickerData.SymbolParts.DataType == IBHistoricalDataType.HistoricalVolatility)
            {
                if (field != TickType.OPTION_HISTORICAL_VOL)
                {
                    return;
                }
            }
            else if (tickerData.SymbolParts.DataType == IBHistoricalDataType.ImpliedVolatility)
            {
                if (field != TickType.OPTION_IMPLIED_VOL)
                {
                    return;
                }
            }
            else
            {
                return;
            }

            //
            // check if tick is in acceptable range
            //
            if (filter)
            {
                //
                // filter #1
                //

                // it is a simple filter to remove bad price ticks
                // it works only during high volume, continuously traded period, fell free to improve it
                if (lastMid != 0.0m &&                                                 // there is a midpoint price already
                    (DateTime.Now.Ticks - date.Ticks) / TimeSpan.TicksPerSecond < 5 && // time elapsed since last tick event is less then 5 second
                    Math.Abs(p - lastMid) / lastMid > 0.03m)                           // price change is greater then 3 %
                {
                    // This may impose 5 sec delay and loss of some ticks in higly volatily and thin market (not in Forex)
                    LogAndMessage.Log(tickerData, MessageType.Trace, "Bad tick has been rejected. Price:" + price.ToString() + " MidPoint:" + lastMid.ToString());
                    return;
                }

                //
                // filter #2
                //

                //
                //
                //

                // it is a "round robin" array store
                // check if index points behind last element of the array
                if (sampleIdx == MaxSampleNo)
                {
                    sampleIdx = 0;
                    sampleOk  = true;
                }

                // if there is enough data yet
                if (sampleOk)
                {
                    // calc avg prior to this tick
                    decimal avg = 0;
                    for (int i = 0; i < MaxSampleNo; i++)
                    {
                        avg += sample[i];
                    }

                    // calc price move compared to avg price
                    decimal rate = avg / MaxSampleNo / p;

                    // if to big, reject tick
                    if (rate > 1.02M || rate < 0.98M)
                    {
                        LogAndMessage.Log(tickerData, MessageType.Trace, "Bad tick has been rejected. Price:" + price.ToString() + " Avg of last " + MaxSampleNo + " ticks:" + (avg / MaxSampleNo).ToString());
                        return;
                    }

                    // store current price in sample array
                    sample[sampleIdx] = p;
                    sampleIdx++;
                }
                // if there is NOT enough data yet
                else
                {
                    // store current price in sample array
                    sample[sampleIdx] = p;
                    sampleIdx++;
                }
            }

            // storing the tick into a Quote to merge
            if (tickerData.SymbolParts.DataType == IBHistoricalDataType.Midpoint)
            {
                if (lastMid == 0.0m)
                {
                    return;
                }
                lastPrice = (float)lastMid;
            }
            else
            {
                lastPrice = price;
            }

            date = time;

            Quotation quote = new Quotation();

            quote.DateTime = (AmiDate)date;
            quote.Price    = lastPrice;
            quote.Low      = lastPrice;
            quote.High     = lastPrice;
            quote.Open     = prevPrice != 0 ? prevPrice : lastPrice;
            quote.Volume   = 0;

            prevPrice = lastPrice;

            SaveQuote(quote);
        }
Beispiel #20
0
        internal override bool Process(FTController ibController, bool allowNewRequest)
        {
            const int requestTimeoutPeriod = 10;

            lock (TickerData)  // request handling
            {
                // if not waiting for response
                switch (TickerData.ContractStatus)
                {
                // if marked to get contract details
                case ContractStatus.SendRequest:

                    if (allowNewRequest)
                    {
                        LogAndMessage.Log(TickerData, MessageType.Trace, "Getting contract. " + ToString(false, LogAndMessage.VerboseLog));

                        Contract contract = new Contract();

                        contract.Exchange       = TickerData.SymbolParts.Exchange;
                        contract.SecType        = TickerData.SymbolParts.SecurityType;
                        contract.Currency       = TickerData.SymbolParts.Currency;
                        contract.IncludeExpired = true;

                        if (TickerData.SymbolParts.IsContinuous)
                        {
                            if (!string.IsNullOrEmpty(TickerData.SymbolParts.Underlying))
                            {
                                contract.Symbol = TickerData.SymbolParts.Underlying;
                            }
                            else
                            {
                                contract.Symbol = TickerData.SymbolParts.Symbol;
                            }
                        }
                        else
                        {
                            contract.LocalSymbol = TickerData.SymbolParts.Symbol;
                        }

                        TickerData.contractDetailsList.Clear();
                        TickerData.ContractStatus = ContractStatus.WaitForResponse;
                        RequestTime = DateTime.Now;

                        ibController.SendContractDetailsRequest(Id, contract);
                    }

                    return(false);

                // if request is sent, but response has not arrived yet
                // see ibclient_ContractDetails and ibclient_ContractDetailsEnd event handlers
                case ContractStatus.WaitForResponse:

                    // if no answer in Time
                    if (RequestTime.AddSeconds(requestTimeoutPeriod) < DateTime.Now)
                    {
                        LogAndMessage.LogAndQueue(TickerData, MessageType.Error, "Getting contract info timed out, symbol is offline. " + ToString(true, LogAndMessage.VerboseLog));

                        TickerData.ContractStatus = ContractStatus.Failed;

                        goto case ContractStatus.Failed;
                    }

                    return(allowNewRequest);

                // if new, offline ticker
                case ContractStatus.Offline:
                    goto case ContractStatus.Failed;

                // contract found
                case ContractStatus.Ok:
                    goto case ContractStatus.Failed;

                // no contract found
                case ContractStatus.Failed:

                    IsFinished = true;
                    return(allowNewRequest);

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
        }
        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);
                }
            }
        }
Beispiel #22
0
        public override PluginStatus GetStatus()
        {
            PluginStatus status = new PluginStatus();

            IBPluginState ibPluginState = IBPluginState.Disconnected;

            if (controller != null)
            {
                ibPluginState = controller.GetIBPluginState();
            }

            switch (ibPluginState)
            {
            case IBPluginState.Disconnected:
                status.Status       = StatusCode.SevereError;
                status.Color        = System.Drawing.Color.IndianRed;
                status.ShortMessage = "Off-line";

                break;

            case IBPluginState.Busy:
                status.Status       = StatusCode.OK;
                status.Color        = System.Drawing.Color.Yellow;
                status.ShortMessage = "Busy";

                break;

            case IBPluginState.Ready:
                status.Status       = StatusCode.OK;
                status.Color        = System.Drawing.Color.ForestGreen;
                status.ShortMessage = "Ready";

                break;
            }

            status.LongMessage = LogAndMessage.GetMessages();

            // collect and display data issues
            string failedTickers = controller.GetFailedTickers();
            bool   dataError     = !string.IsNullOrEmpty(failedTickers);

            if (dataError && ibPluginState != IBPluginState.Disconnected)     // if disconnected, data issues are meaningless...
            {
                status.ShortMessage += " !";
                status.Status        = StatusCode.Warning;
                if (string.IsNullOrEmpty(status.LongMessage))
                {
                    status.LongMessage = "Failed tickers: " + failedTickers;
                }
            }

            // if there is no message, we show the short message (Busy, Ok, etc)
            if (string.IsNullOrEmpty(status.LongMessage))
            {
                status.LongMessage = status.ShortMessage;

                // save as last shown message to avoid status popup
                lastLongMessageText = status.ShortMessage;
            }

            // if new message we use a new lastLongMessageTime value to cause status popup
            if (lastLongMessageText != status.LongMessage)
            {
                lastLongMessageText = status.LongMessage;
                lastLongMessageTime = (int)DateTime.Now.TimeOfDay.TotalMilliseconds;
            }

            // set status and "timestamp"
            status.Status = (StatusCode)((int)status.Status + lastLongMessageTime);

            return(status);
        }
Beispiel #23
0
        /// <summary>
        /// Process the list of contract details received from TWS, and selects the current front month contract
        /// </summary>
        /// <param name="TickerData"></param>
        /// <returns></returns>
        private bool ProcessContractDetailsList(List <ContractDetails> list)
        {
            try
            {
                TickerData.contractDetailsList = list;

                // if no contract found
                if (TickerData.contractDetailsList.Count == 0)
                {
                    return(false);
                }

                // not a continuos contract there must be exactly 1 found contract
                if (TickerData.contractDetailsList.Count == 1 && !TickerData.SymbolParts.IsContinuous)
                {
                    TickerData.ContractDetails = TickerData.contractDetailsList[0];
                    return(true);
                }

                // continuos contract
                if (TickerData.SymbolParts.IsContinuous)
                {
                    //
                    // only expired and the nearest expiration may remain in the list
                    //

                    // sort contract details on expiry
                    TickerData.contractDetailsList.Sort(new ContractDetailsComparer());

                    // current date in the format of contract expiry
                    string frontMonthExpiry = DateTime.Now.ToString("yyyyMMdd");

                    // this may be an already expired contract or a contract that will expire in the far future
                    ContractDetails temp = TickerData.contractDetailsList[0];

                    // find the contract that ...
                    for (int i = 1; i < TickerData.contractDetailsList.Count; i++)
                    {
                        if (TickerData.contractDetailsList[i].Contract.LastTradeDateOrContractMonth.CompareTo(frontMonthExpiry) >= 0)       // expires in the future or today
                        {
                            temp = TickerData.contractDetailsList[i];
                            break;
                        }
                    }

                    // setting the found CURRENT (front month) contract as the contractdetails
                    TickerData.ContractDetails = temp;

                    frontMonthExpiry = temp.Contract.LastTradeDateOrContractMonth;

                    // remove all future contract with later expiry then current front month
                    for (int i = TickerData.contractDetailsList.Count - 1; i >= 0; i--)
                    {
                        if (TickerData.contractDetailsList[i].Contract.LastTradeDateOrContractMonth.CompareTo(frontMonthExpiry) > 0)
                        {
                            TickerData.contractDetailsList.RemoveAt(i);
                        }
                    }

                    return(true);
                }

                return(false);
            }
            finally
            {
                try
                {
                    // update trading days using current contract details
                    if (TickerData.ContractDetails != null)
                    {
                        //tickerData.LiquidHours = new TradingDayList(tickerData.ContractDetails.LiquidHours, true);
                        //if (IBDataSource.RthOnly && string.IsNullOrEmpty(tickerData.ContractDetails.LiquidHours))
                        //    LogAndMessage.LogAndQueue(tickerData, MessageType.Warning, "No liquid hours data is available.");
                        //else
                        //    LogAndMessage.Log(tickerData, MessageType.Trace, "Liquid hour:" + tickerData.ContractDetails.LiquidHours);

                        TickerData.TradingDays = new TradingDayList(TickerData.ContractDetails.TradingHours, false);
                        if ((FTDataSource.AllowMixedEODIntra || FTDataSource.Periodicity == Periodicity.EndOfDay) && string.IsNullOrEmpty(TickerData.ContractDetails.TradingHours))
                        {
                            LogAndMessage.Log(TickerData, MessageType.Warning, "No trading hours data is available. Daily quotation data may not be correct.");
                        }
                        //else
                        //    LogAndMessage.Log(tickerData, MessageType.Trace, "Trading hour:" + tickerData.ContractDetails.TradingHours);
                    }
                    else
                    {
                        //tickerData.LiquidHours = new TradingDayList(null, true);
                        TickerData.TradingDays = new TradingDayList(null, false);
                    }
                }
                catch (Exception e)
                {
                    LogAndMessage.Log(TickerData, MessageType.Error, "Failed to parse (" + TickerData.ContractDetails.TradingHours + ") and update trading hours:" + e.ToString());
                }
            }
        }
Beispiel #24
0
        /// <summary>
        /// Timer event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <remarks>
        /// If connection is broken, it tries to reconnect in every 30 secs.
        /// If it reconnects, it starts a backfill of all tickers
        /// If status is ready and autorefresh is configured, it starts the scheduled refresh
        /// </remarks>
        private void timer_Tick(object sender)
        {
            if (controller == null)
            {
                return;
            }

            // check and indicate thread entry
            if (Interlocked.CompareExchange(ref inTimerTick, 1, 0) != 0)
            {
                return;
            }

            IBPluginState currPluginState = IBPluginState.Disconnected;

            try
            {
                currPluginState = controller.GetIBPluginState();

                if (currPluginState != prevPluginState)
                {
                    LogAndMessage.Log(MessageType.Info, "Plugin status: " + currPluginState);
                }

                // if no connection between the data plugin and the TWS client
                if (currPluginState == IBPluginState.Disconnected)
                {
                    // if not manually disconnected, try to reconnect
                    if (manuallyDisconnected == false)
                    {
                        // if retry period has elapsed
                        if (connectionRetryTime < DateTime.Now)
                        {
                            // if connection has just got broken (prevent repeated log entries)
                            if (prevPluginState != IBPluginState.Disconnected)
                            {
                                LogAndMessage.LogAndQueue(MessageType.Warning, "Data plugin has been disconnected from TWS. Trying to reconnect in every " + ConnectionRetryInterval + " sec.");
                            }

                            // set new retry time and increase interval up to 30 secs
                            connectionRetryTime = DateTime.Now.AddSeconds(ConnectionRetryInterval);

                            // try to reconnect
                            controller.Connect(true);
                        }
                    }
                }

                // data plugin is connected to TWS
                else
                {
                    // reset connection retrying
                    connectionRetryTime = DateTime.MinValue;

                    // if an existing connection  was disconnected
                    if (prevPluginState == IBPluginState.Disconnected && !firstConnection || controller.RestartStreaming)
                    {
                        LogAndMessage.LogAndQueue(MessageType.Warning, "TWS has been reconnected. Starting database refresh.");

                        // request refresh of all tickers, restart subscriptions, etc.
                        controller.RestartAfterReconnect(lastUptodateTime);

                        return;
                    }

                    // clear flag of first connection
                    firstConnection = false;

                    // check if it's time to run AutoRefresh
                    if (prevPluginState == IBPluginState.Ready)             // Plugin works with up to date data
                    {
                        lastUptodateTime = DateTime.Now;

                        if (IBConfiguration != null && IBConfiguration.AutoRefreshEnabled && // Auto refresh is enabled
                            nextAutoRefreshTime < DateTime.Now)                              // The time of auto refresh has passed
                        {
                            DateTime refreshStartDate = DateTime.Now.Date.AddDays(-IBConfiguration.AutoRefreshDays);
                            LogAndMessage.LogAndQueue(MessageType.Warning, "Starting automatic database refresh (" + refreshStartDate.ToShortDateString() + ").");

                            controller.RefreshAllUsed(refreshStartDate);

                            CalcNextAutoRefreshTime();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogAndMessage.Log(MessageType.Error, "Error in data source timer event handler: " + ex);
            }
            finally
            {
                // update plugin state
                prevPluginState = currPluginState;

                // indicate thread exit
                Interlocked.Exchange(ref inTimerTick, 0);
            }
        }
Beispiel #25
0
        internal override bool Process(FTController ibController, bool allowNewRequest)
        {
            // if no contract received yet
            if (TickerData.ContractStatus == ContractStatus.SendRequest || TickerData.ContractStatus == ContractStatus.WaitForResponse)
            {
                return(allowNewRequest);
            }

            // if GetQuotesEx was not yet called (stockInfo is not ready yet), symbol data cannot be updated
            if (TickerData.StockInfo == null)
            {
                IsFinished = true;
                return(allowNewRequest);
            }

            // if not waiting for response
            switch (TickerData.SymbolStatus)
            {
            // if marked to update AB symbol's data
            case SymbolStatus.WaitForContractUpdate:

                // if no contract found
                if (TickerData.ContractStatus != ContractStatus.Ok)
                {
                    LogAndMessage.LogAndQueue(TickerData, MessageType.Error, "Getting contract info failed, AmiBroker symbol data cannot be updated.");

                    TickerData.SymbolStatus = SymbolStatus.Failed;

                    goto case SymbolStatus.Failed;
                }

                // plugin may call it when StockInfo is not available (E.g. start watchlist backfill)
                if (TickerData.StockInfo == null)
                {
                    LogAndMessage.Log(TickerData, MessageType.Trace, "StockInfo data is not available. AmiBroker symbol data is not updated.");
                    return(false);
                }

                try
                {
                    // update AB's information
                    TickerData.StockInfo.AliasName  = TickerData.ContractDetails.Contract.LocalSymbol + '/' + TickerData.ContractDetails.Contract.Symbol;
                    TickerData.StockInfo.FullName   = TickerData.ContractDetails.LongName;
                    TickerData.StockInfo.PointValue = TickerData.ContractDetails.PriceMagnifier;
                    TickerData.StockInfo.TickSize   = (float)TickerData.ContractDetails.MinTick;
                    TickerData.StockInfo.WebId      = TickerData.ContractDetails.Contract.ConId.ToString();
                    TickerData.StockInfo.Currency   = TickerData.ContractDetails.Contract.Currency;

                    TickerData.SymbolStatus = SymbolStatus.Ok;

                    LogAndMessage.LogAndQueue(TickerData, MessageType.Info, "AmiBroker symbol data is updated.");
                }
                catch (Exception ex)
                {
                    TickerData.SymbolStatus = SymbolStatus.Failed;

                    LogAndMessage.LogAndQueue(TickerData, MessageType.Error, "AmiBroker symbol data update failed:" + ex);
                    return(false);
                }

                goto case SymbolStatus.Ok;

            // if new ticker
            case SymbolStatus.Offline:
            // AB symbol's data are updated
            case SymbolStatus.Ok:
            // AB symbol's data NOT updated, e.g: no contract found
            case SymbolStatus.Failed:

                IsFinished = true;
                return(allowNewRequest);

            default:

                TickerData.SymbolStatus = SymbolStatus.Failed;

                IsFinished = true;
                return(allowNewRequest);
            }
        }
Beispiel #26
0
        public override bool Notify(ref PluginNotification notifyData)
        {
            bool result = true;

            switch (notifyData.Reason)
            {
            case Reason.DatabaseLoaded:

                // if database is loaded
                if (controller != null)
                {
                    // disconnect from TWS and reset all data
                    controller.Disconnect();
                    ((IDisposable)controller).Dispose();
                    controller = null;
                }

                Workspace          = notifyData.Workspace;
                DatabasePath       = notifyData.DatabasePath;
                MainWindowHandle   = notifyData.MainWnd;
                AllowMixedEODIntra = Workspace.AllowMixedEODIntra != 0;

                // start logging the opening of the database
                LogAndMessage.Log(MessageType.Info, "Database: " + DatabasePath);
                LogAndMessage.Log(MessageType.Info, "Mixed EOD/Intra: " + (Workspace.AllowMixedEODIntra != 0));
                LogAndMessage.Log(MessageType.Info, "Number of bars: " + Workspace.NumBars);
                LogAndMessage.Log(MessageType.Info, "Database config: " + Settings);

                // create the config object
                IBConfiguration          = FTConfiguration.GetConfigObject(Settings);
                LogAndMessage.VerboseLog = IBConfiguration.VerboseLog;
                RthOnly = IBConfiguration.RthOnly;
                CalcNextAutoRefreshTime();

                // create new controller
                connectionRetryTime = DateTime.Now.AddSeconds(ConnectionRetryInterval);
                prevPluginState     = IBPluginState.Disconnected;
                firstConnection     = true;
                controller          = new FTController();

                // connect database to tws
                controller.Connect(false);

                if (rtWindowTickersBck.Count > 0)
                {
                    for (int i = 0; i < rtWindowTickersBck.Count; i++)
                    {
                        controller.GetRecentInfo(rtWindowTickersBck[i]);
                    }
                }

                break;

            // user changed the db
            case Reason.DatabaseUnloaded:

                // disconnect from TWS
                if (controller != null)
                {
                    controller.Disconnect();
                    ((IDisposable)controller).Dispose();
                    controller = null;
                }

                // clean up
                Workspace        = new Workspace();
                DatabasePath     = null;
                MainWindowHandle = IntPtr.Zero;
                searchForm       = null;

                break;

            // seams to be obsolete
            case Reason.SettingsChanged:

                break;

            // user right clicks data plugin area in AB
            case Reason.RightMouseClick:

                if (controller != null)
                {
                    currentSI = notifyData.CurrentSI;
                    if (currentSI != null)
                    {
                        currentTicker = currentSI.ShortName;
                        if (currentTicker.Length > 10)
                        {
                            currentTickerShortend = currentTicker.Substring(0, 7) + "...";
                        }
                        else
                        {
                            currentTickerShortend = currentTicker;
                        }
                    }
                    else
                    {
                        currentTicker         = null;
                        currentTickerShortend = null;
                    }
                }

                SetContextMenuState();

                ShowContextMenu(mContextMenu);

                break;

            default:
                result = false;

                break;
            }
            return(result);
        }
Beispiel #27
0
 private void mReconnect_Click(object sender, EventArgs e)
 {
     LogAndMessage.Log(MessageType.Info, "TWS is manually reconnected.");
     manuallyDisconnected = false;
     controller.Connect(false);
 }
Beispiel #28
0
 private void mDisconnect_Click(object sender, EventArgs e)
 {
     LogAndMessage.Log(MessageType.Info, "TWS is manually disconnected.");
     manuallyDisconnected = true;
     controller.Disconnect();
 }
Beispiel #29
0
        private void mBackfillAll_Click(object sender, EventArgs e)
        {
            if (firstGetQuotesExCall)                   // db periodicity not known yet
            {
                return;
            }

            if (string.IsNullOrEmpty(currentTicker))    // no selected ticker
            {
                return;
            }

            DateTime refreshStartDate = GetRefreshStartDate(sender);

            refreshStartDate = IBClientHelper.GetAdjustedStartDate(refreshStartDate, Periodicity, DateTime.MinValue, false);

            //
            // collecting all tickers
            //

            int stockCount = 0;
            StringCollection tickersInDatabase = new StringCollection();

            LogAndMessage.Log(MessageType.Info, "Manual backfill of all tickers from " + refreshStartDate.ToShortDateString() + ".");

            try
            {
                Type   abAppType = Type.GetTypeFromProgID("Broker.Application");
                object abApp     = Activator.CreateInstance(abAppType);

                // access AB COM interface to get current ticker
                if (abAppType != null && abApp != null)
                {
                    object abStocks     = abAppType.InvokeMember("Stocks", BindingFlags.GetProperty, null, abApp, null);
                    Type   abStocksType = abStocks.GetType();

                    // get the number of stocks in the db
                    stockCount = (int)abStocksType.InvokeMember("Count", BindingFlags.GetProperty, null, abStocks, null);

                    if (stockCount > 0)
                    {
                        Type abStockType = abStocksType.InvokeMember("Item", BindingFlags.GetProperty, null, abStocks, new object[] { 0 }).GetType();

                        for (int i = 0; i < stockCount; i++)
                        {
                            object abStock = abStocksType.InvokeMember("Item", BindingFlags.GetProperty, null, abStocks, new object[] { i });
                            if (abStock != null)
                            {
                                string ticker = (string)abStockType.InvokeMember("Ticker", BindingFlags.GetProperty, null, abStock, null);
                                if (!tickersInDatabase.Contains(ticker))
                                {
                                    tickersInDatabase.Add(ticker);
                                }
                            }
                        }
                    }
                    else
                    {
                        LogAndMessage.Log(MessageType.Trace, "Manual backfill of all symbols failed. Database has no symbols.");
                    }
                }
                else
                {
                    LogAndMessage.Log(MessageType.Warning, "Manual backfill of all symbols failed. ActiveX interface error.");
                }
            }
            catch (Exception ex)
            {
                LogAndMessage.LogAndQueue(MessageType.Error, "Manual backfill of all symbols failed. Exception: " + ex);
            }

            StartBackfills(refreshStartDate, tickersInDatabase);
        }
Beispiel #30
0
        private void mBackfillWL_Click(object sender, EventArgs e)
        {
            if (firstGetQuotesExCall)                   // db periodicity not known yet
            {
                return;
            }

            if (string.IsNullOrEmpty(currentTicker))    // no selected ticker
            {
                return;
            }

            DateTime refreshStartDate = GetRefreshStartDate(sender);

            refreshStartDate = IBClientHelper.GetAdjustedStartDate(refreshStartDate, Periodicity, DateTime.MinValue, false);

            WatchlistForm watchlistForm = new WatchlistForm(DatabasePath);

            if (DialogResult.OK != watchlistForm.ShowDialog() || watchlistForm.SelectedWatchlistIndices == null)
            {
                return;
            }

            int[] selectedWatchlistIndices = watchlistForm.SelectedWatchlistIndices;

            watchlistForm.Dispose();

            StringCollection tickersInWatchlists = new StringCollection();

            ulong watchlistBits = 0;

            foreach (int watchlistId in selectedWatchlistIndices)
            {
                watchlistBits |= (ulong)1 << watchlistId;
            }

            LogAndMessage.Log(MessageType.Info, "Manual backfill of watchlists (" + watchlistBits.ToString("0x") + ") from " + refreshStartDate.ToShortDateString() + ".");

            try
            {
                Type   abAppType = Type.GetTypeFromProgID("Broker.Application");
                object abApp     = Activator.CreateInstance(abAppType);

                // access AB COM interface to get current ticker
                if (abAppType != null && abApp != null)
                {
                    object abStocks     = abAppType.InvokeMember("Stocks", BindingFlags.GetProperty, null, abApp, null);
                    Type   abStocksType = abStocks.GetType();

                    // get the number of stocks in the db
                    int stockCount = (int)abStocksType.InvokeMember("Count", BindingFlags.GetProperty, null, abStocks, null);

                    if (stockCount > 0)
                    {
                        Type abStockType = abStocksType.InvokeMember("Item", BindingFlags.GetProperty, null, abStocks, new object[] { 0 }).GetType();

                        for (int i = 0; i < stockCount; i++)
                        {
                            object abStock = abStocksType.InvokeMember("Item", BindingFlags.GetProperty, null, abStocks, new object[] { i });
                            if (abStock != null)
                            {
                                string ticker                = (string)abStockType.InvokeMember("Ticker", BindingFlags.GetProperty, null, abStock, null);
                                uint   watchlistBits1        = (uint)(int)abStockType.InvokeMember("WatchListBits", BindingFlags.GetProperty, null, abStock, null);
                                uint   watchlistBits2        = (uint)(int)abStockType.InvokeMember("WatchListBits2", BindingFlags.GetProperty, null, abStock, null);
                                ulong  watchlistBitsCombined = (watchlistBits2 << 32) + watchlistBits1;

                                if ((watchlistBitsCombined & watchlistBits) != 0)
                                {
                                    if (!tickersInWatchlists.Contains(ticker))
                                    {
                                        tickersInWatchlists.Add(ticker);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        LogAndMessage.Log(MessageType.Trace, "Manual backfill of watchlists failed. Database has no symbols.");
                    }
                }
                else
                {
                    LogAndMessage.Log(MessageType.Warning, "Manual backfill of watchlists failed. ActiveX interface error.");
                }
            }
            catch (Exception ex)
            {
                LogAndMessage.LogAndQueue(MessageType.Error, "Manual backfill of watchlists failed. Exception: " + ex);
            }

            if (tickersInWatchlists.Count == 0)
            {
                LogAndMessage.Log(MessageType.Trace, "Manual backfill of watchlists failed. Selected watchlists have no symbols.");
            }
            else
            {
                StartBackfills(refreshStartDate, tickersInWatchlists);
            }
        }