Ejemplo n.º 1
0
        // get stock latest options chain
        public ArrayList GetOptionsChain(string ticker)
        {
            ticker = CorrectSymbol(ticker);

            string symbol;

            Krs.Ats.IBNet.SecurityType type;

            if (ticker.StartsWith("^"))
            {
                symbol = ticker.TrimStart(new char[] { '^' });
                type   = Krs.Ats.IBNet.SecurityType.Option;
            }
            else if (ticker.StartsWith("~"))
            {
                symbol = ticker.TrimStart(new char[] { '~' });
                type   = Krs.Ats.IBNet.SecurityType.FutureOption;
            }
            else
            {
                symbol = ticker;
                type   = Krs.Ats.IBNet.SecurityType.Option;
            }

            Tws.ContData cont = tws.RequestDetails(symbol, null, config["Exchange.Option"], type, config["Currency"], true);
            if (cont == null)
            {
                return(null);
            }

            ArrayList list = new ArrayList();

            // progress report
            int current, last = 0, n = 0;
            BackgroundWorker bw = null;

            if (host != null)
            {
                bw = host.BackgroundWorker;
            }

            List <Krs.Ats.IBNet.ContractDetails> cont_list = new List <Krs.Ats.IBNet.ContractDetails>();

            int download_mode = int.Parse(config["DownloadMode"]);

            DateTime max_expdate_filter = DateTime.Parse(config["MaxExpirationLimit"]);
            DateTime min_expdate_filter = DateTime.Parse(config["MinExpirationLimit"]);

            double max_strike_filter = double.NaN;
            double min_strike_filter = double.NaN;

            if (quote_cache.ContainsKey(ticker))
            {
                Quote quote = quote_cache[ticker];

                max_strike_filter = (1 + double.Parse(config["MaxStrikeLimit"]) * 0.01) * quote.price.last;
                min_strike_filter = (1 + double.Parse(config["MinStrikeLimit"]) * 0.01) * quote.price.last;
            }

            MappingSet mapping = null;

            if (download_mode == 1)
            {
                mapping = new MappingSet();

                // update type list table
                mapping.TypeTable.AddTypeTableRow("Call", "Call", false);
                mapping.TypeTable.AddTypeTableRow("Put", "Put", false);

                // update expiration/strike list table
                foreach (Krs.Ats.IBNet.ContractDetailsEventArgs d in cont.contracts)
                {
                    try
                    {
                        if (d.ContractDetails.Summary.SecurityType != Krs.Ats.IBNet.SecurityType.Option &&
                            d.ContractDetails.Summary.Right == Krs.Ats.IBNet.RightType.Undefined)
                        {
                            continue;
                        }

                        // expiration date
                        DateTime expdate = Tws.TwsDateStringToDateTime(d.ContractDetails.Summary.Expiry);
                        if (mapping.ExpirationTable.FindByExpiration(expdate) == null)
                        {
                            mapping.ExpirationTable.AddExpirationTableRow(expdate, expdate.ToString("d-MMM-yyyy"), false);
                        }

                        // strike
                        double strike = d.ContractDetails.Summary.Strike;
                        if (mapping.StrikeTable.FindByStrike(strike) == null)
                        {
                            mapping.StrikeTable.AddStrikeTableRow(strike, strike.ToString("N2"), false);
                        }
                    }
                    catch { }
                }

                mapping.AcceptChanges();

                // open dialog to select filter
                OptionsFilterForm optionsFilterForm = new OptionsFilterForm(mapping);
                optionsFilterForm.ShowDialog();
            }

            foreach (Krs.Ats.IBNet.ContractDetailsEventArgs d in cont.contracts)
            {
                try
                {
                    if (d.ContractDetails.Summary.SecurityType != Krs.Ats.IBNet.SecurityType.Option &&
                        d.ContractDetails.Summary.Right == Krs.Ats.IBNet.RightType.Undefined)
                    {
                        continue;
                    }

                    if (download_mode != 0)
                    {
                        // expiration date
                        DateTime expdate = Tws.TwsDateStringToDateTime(d.ContractDetails.Summary.Expiry);

                        // strike
                        double strike = d.ContractDetails.Summary.Strike;

                        // type
                        string optype = d.ContractDetails.Summary.Right == Krs.Ats.IBNet.RightType.Call ? "Call" : "Put";

                        if (download_mode == 1 && mapping != null) // dynamic filter
                        {
                            if (!mapping.ExpirationTable.FindByExpiration(expdate).Enabled ||
                                !mapping.StrikeTable.FindByStrike(strike).Enabled ||
                                !mapping.TypeTable.FindByType(optype).Enabled)
                            {
                                continue;
                            }
                        }
                        else if (download_mode == 2) // predefined filter
                        {
                            if ((expdate > max_expdate_filter) ||
                                (expdate < min_expdate_filter) ||
                                (!double.IsNaN(max_strike_filter) && strike > max_strike_filter) ||
                                (!double.IsNaN(min_strike_filter) && strike < min_strike_filter))
                            {
                                continue;
                            }
                        }
                    }

                    cont_list.Add(d.ContractDetails);
                }
                catch { }
            }

            bool filter_no_price_options = bool.Parse(config["FilterNoPriceOptions"]);
            int  max_parallel_tickers    = int.Parse(config["MaxParallelTickers"]);

            for (int i = 0; i < cont_list.Count; i += max_parallel_tickers)
            {
                try
                {
                    List <Krs.Ats.IBNet.ContractDetails> cont_sub_list = cont_list.GetRange(i, (int)Math.Min(max_parallel_tickers, cont_list.Count - i));
                    List <Tws.TickData> tick_list = tws.RequestQuote(symbol, config["Exchange.Option"], null, type, null, cont_sub_list);
                    if (tick_list == null || tick_list.Count != cont_sub_list.Count)
                    {
                        continue;
                    }

                    // keep rate down
                    if (i % 500 == 0 && i != 0)
                    {
                        Thread.Sleep(5000);
                    }

                    for (int j = 0; j < tick_list.Count; j++)
                    {
                        try
                        {
                            Tws.TickData tick = tick_list[j];

                            Option option = new Option();

                            option.symbol = "." + cont_sub_list[j].Summary.LocalSymbol.Replace(" ", "").Trim();
                            option.stock  = ticker.Trim(); // cont_sub_list[j].Summary.Symbol;

                            option.type       = cont_sub_list[j].Summary.Right == Krs.Ats.IBNet.RightType.Call ? "Call" : "Put";
                            option.expiration = Tws.TwsDateStringToDateTime(cont_sub_list[j].Summary.Expiry);

                            option.strike = cont_sub_list[j].Summary.Strike;
                            option.stocks_per_contract = (double)decimal.Parse(cont_sub_list[j].Summary.Multiplier);

                            option.price.ask = tick.price.ask;
                            if (option.price.ask <= 0)
                            {
                                option.price.ask = double.NaN;
                            }

                            option.price.bid = tick.price.bid;
                            if (option.price.bid <= 0)
                            {
                                option.price.bid = double.NaN;
                            }

                            option.price.last = tick.price.last;
                            if (option.price.last <= 0)
                            {
                                option.price.last = double.NaN;
                            }

                            if (tick.price.last > 0 && tick.price.close > 0)
                            {
                                option.price.change = tick.price.last - tick.price.close;
                            }
                            else
                            {
                                option.price.change = double.NaN;
                            }

                            option.volume.total = tick.size.volume;
                            option.open_int     = tick.size.open_int;

                            try
                            {
                                option.update_timestamp = TimeZone.CurrentTimeZone.ToLocalTime(tick.timestamp);
                            }
                            catch { }

                            if (!filter_no_price_options ||
                                !double.IsNaN(option.price.last) ||
                                !double.IsNaN(option.price.ask) ||
                                !double.IsNaN(option.price.bid))
                            {
                                list.Add(option);
                            }
                        }
                        catch { }

                        // update progress bar
                        n++;
                        if (bw != null)
                        {
                            current = n * 95 / cont_list.Count;
                            if (current != last)
                            {
                                bw.ReportProgress(current);
                                last = current;
                            }
                        }
                    }
                }
                catch { }
            }

            return(list);
        }
Ejemplo n.º 2
0
        // get stock latest quote
        public Quote GetQuote(string ticker)
        {
            ticker = CorrectSymbol(ticker);

            string symbol;

            Krs.Ats.IBNet.SecurityType type;

            if (ticker.StartsWith("^"))
            {
                symbol = ticker.TrimStart(new char[] { '^' });
                type   = Krs.Ats.IBNet.SecurityType.Index;
            }
            else if (ticker.StartsWith("~"))
            {
                symbol = ticker.TrimStart(new char[] { '~' });
                type   = Krs.Ats.IBNet.SecurityType.Future;
            }
            else
            {
                symbol = ticker;
                type   = Krs.Ats.IBNet.SecurityType.Stock;
            }

            List <Tws.TickData> tick_list;

            if (type == Krs.Ats.IBNet.SecurityType.Index)
            {
                tick_list = tws.RequestQuote(symbol, config["Exchange.Underlying"], config["Exchange.Option"], type, config["Currency"], null);
            }
            else
            {
                tick_list = tws.RequestQuote(symbol, config["Exchange.Underlying"], null, type, config["Currency"], null);
            }
            if (tick_list == null || tick_list.Count == 0)
            {
                return(null);
            }

            Tws.TickData tick = tick_list[0];

            Quote quote = new Quote();

            quote.stock = ticker;

            // resolve name & last closing price
            string name = nlk.GetNameBySymbol(symbol, config["Exchange.Underlying"], config["Currency"], type);

            if (!string.IsNullOrEmpty(name))
            {
                quote.name = name;
            }
            else if (!string.IsNullOrEmpty(tick.name))
            {
                quote.name = tick.name;
            }
            else
            {
                quote.name = quote.stock;
            }

            // if price is not available try to get it from the lookup
            if (tick.price.ask <= 0 && tick.price.bid <= 0 && tick.price.last <= 0)
            {
                tick.price.last = nlk.GetLastPriceBySymbol(symbol, config["Exchange.Underlying"], config["Currency"], type);
            }

            // copy prices
            quote.price.last = tick.price.last;
            if (quote.price.last <= 0)
            {
                quote.price.last = double.NaN;
            }

            quote.price.ask = tick.price.ask;
            if (quote.price.ask <= 0)
            {
                quote.price.ask = double.NaN;
            }

            quote.price.bid = tick.price.bid;
            if (quote.price.bid <= 0)
            {
                quote.price.bid = double.NaN;
            }

            quote.price.low = tick.price.low;
            if (quote.price.low <= 0)
            {
                quote.price.low = double.NaN;
            }

            quote.price.high = tick.price.high;
            if (quote.price.high <= 0)
            {
                quote.price.high = double.NaN;
            }

            quote.price.open = tick.price.close;
            if (quote.price.open <= 0)
            {
                quote.price.open = double.NaN;
            }

            if (quote.price.last > 0 && quote.price.open > 0)
            {
                quote.price.change = quote.price.last - quote.price.open;
            }
            else
            {
                quote.price.change = double.NaN;
            }

            // copy volume
            quote.volume.total = tick.size.volume;

            quote.general.dividend_rate = 0;
            quote.update_timestamp      = TimeZone.CurrentTimeZone.ToLocalTime(tick.timestamp);

            // save in cache
            if (quote_cache.ContainsKey(ticker))
            {
                quote_cache[ticker] = quote;
            }
            else
            {
                if (quote_cache.Count >= MAX_CACHE_SIZE)
                {
                    quote_cache.Remove(quote_cache.Keys.GetEnumerator().Current);
                }

                quote_cache.Add(ticker, quote);
            }

            return(quote);
        }