private void okButton_Click(object sender, EventArgs e) { ArrayList list; list = GetPartialItems(typeListBox); foreach (MappingSet.TypeTableRow row in mapping.TypeTable) { if (list.Contains(row.TypeString)) { row.Enabled = true; } } list = GetPartialItems(strikeListBox); foreach (MappingSet.StrikeTableRow row in mapping.StrikeTable) { if (list.Contains(row.Strike)) { row.Enabled = true; } } list = GetPartialItems(expirationListBox); foreach (MappingSet.ExpirationTableRow row in mapping.ExpirationTable) { if (list.Contains(row.Expiration)) { row.Enabled = true; } } mapping.AcceptChanges(); }
// 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); }