// get stock latest options chain public ArrayList GetOptionsChain(string ticker) { XmlDocument xml = null; System.Windows.Forms.HtmlElement elem = null; // correct symbol SymbolSet.SymbolTableRow tck = CorrectSymbolRow(ticker); if (tck == null) { return(null); } // check cache for option data if (!cache_dict.ContainsKey(tck.Id)) { // get url for quote page string url = @"http://www.nasdaqomxnordic.com/shares/optionsandfutures/?Instrument=" + tck.Id; // read first page (try twice before giving up) System.Windows.Forms.HtmlDocument doc = wbf.GetHtmlDocumentWithWebBrowser(url, null, "optionsAndFuturesTable", "TABLE", 30); if (doc == null || doc.Body == null || string.IsNullOrEmpty(doc.Body.InnerText)) { return(null); } elem = doc.GetElementById("optionsAndFuturesTable"); if (elem == null) { return(null); } xml = cap.ConvertHtmlToXml(elem.OuterHtml); } else { xml = cache_dict[tck.Id]; } if (xml == null) { return(null); } // create options array list ArrayList options_list = new ArrayList(); options_list.Clear(); for (int i = 1; ; i++) { XmlNode nd, row_nd = prs.GetXmlNodeByPath(xml.FirstChild, @"TBODY\TR(" + i.ToString() + ")"); if (row_nd == null) { break; } try { // get title string title = null; foreach (XmlAttribute attr in row_nd.Attributes) { if (attr.Name.ToUpper() == "TITLE") { title = attr.Value; break; } } if (title == null) { continue; } string[] split = title.Split('-'); if (split.Length == 1 || (!split[1].Contains("CALL OPTION") && !split[1].Contains("PUT OPTION"))) { continue; } Option option = new Option(); // set option stock option.stock = tck.Symbol; // set option symbol option.symbol = "." + split[0].Trim(); // get option type by parsing the option symbol string stmp = option.symbol.TrimEnd(new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }).ToUpper(); char ctmp = stmp[stmp.Length - 1]; if (ctmp >= 'A' && ctmp <= 'L') { option.type = "Call"; } else if (ctmp >= 'M' && ctmp <= 'X') { option.type = "Put"; } else { continue; } // get expiration date nd = prs.GetXmlNodeByPath(row_nd, @"TD(2)"); if (nd == null || nd.InnerText.Trim() == "") { continue; } split = nd.InnerText.Trim().Split(new char[] { '.', '-' }); option.expiration = Convert.ToDateTime(split[1] + "/" + split[2] + "/" + split[0], ci).AddDays(1); // get strike price nd = prs.GetXmlNodeByPath(row_nd, @"TD(11)"); if (nd == null || nd.InnerText.Trim() == "") { continue; } option.strike = Convert.ToDouble(nd.InnerText); // get stocks per contract nd = prs.GetXmlNodeByPath(row_nd, @"TD(10)"); try { option.stocks_per_contract = (int)Convert.ToDecimal(nd.InnerText); } catch { option.stocks_per_contract = 100; } // get bid price nd = prs.GetXmlNodeByPath(row_nd, @"TD(3)"); if (nd == null || nd.InnerText == "") { option.price.bid = double.NaN; } else { try { option.price.bid = Convert.ToDouble(nd.InnerText); } catch { option.price.bid = double.NaN; } } // get ask price nd = prs.GetXmlNodeByPath(row_nd, @"TD(4)"); if (nd == null || nd.InnerText == "") { option.price.ask = double.NaN; } else { try { option.price.ask = Convert.ToDouble(nd.InnerText); } catch { option.price.ask = double.NaN; } } // get last price nd = prs.GetXmlNodeByPath(row_nd, @"TD(5)"); if (nd == null || nd.InnerText == "") { option.price.last = double.NaN; } else { try { option.price.last = Convert.ToDouble(nd.InnerText); } catch { option.price.last = double.NaN; } } // set price change option.price.change = double.NaN; // get option open-int nd = prs.GetXmlNodeByPath(row_nd, @"TD(8)"); if (nd == null || nd.InnerText == "") { option.open_int = 0; } else { try { option.open_int = (int)Convert.ToDecimal(nd.InnerText); } catch { option.open_int = 0; } } // get option volume nd = prs.GetXmlNodeByPath(row_nd, @"TD(9)"); if (nd == null || nd.InnerText == "") { option.volume.total = 0; } else { try { option.volume.total = (int)Convert.ToDecimal(nd.InnerText); } catch { option.volume.total = 0; } } // update time stamp option.update_timestamp = DateTime.Now; // add option to list options_list.Add(option); } catch { } } return(options_list); }
// get stock latest quote public Quote GetQuote(string ticker) { XmlDocument xml = null; System.Windows.Forms.HtmlElement elem = null; // correct symbol SymbolSet.SymbolTableRow tck = CorrectSymbolRow(ticker); if (tck == null) { return(null); } // is index ? bool is_index = tck.Symbol.StartsWith("^"); // clear global cache cache_dict.Clear(); XmlNode nd, row_nd = null; System.Windows.Forms.HtmlDocument doc = null; // @"http://www.nasdaqomxnordic.com/shares/optionsandfutures/?Instrument={0}" // @"http://www.nasdaqomxnordic.com/optionsandfutures/microsite?Instrument={0}" // get url to quote+option-chain page string url = string.Format(@"http://www.nasdaqomxnordic.com/shares/optionsandfutures/?Instrument={0}", is_index ? tck.Isin : tck.Id); // read first page (try twice before giving up) doc = wbf.GetHtmlDocumentWithWebBrowser(url, null, "optionsAndFuturesTable", "TABLE", 60); if (doc == null || doc.Body == null || string.IsNullOrEmpty(doc.Body.InnerText)) { return(null); } // get quote table elem = doc.GetElementById("avistaTable"); if (elem == null) { return(null); } xml = cap.ConvertHtmlToXml(elem.OuterHtml); if (xml == null) { return(null); } row_nd = prs.GetXmlNodeByPath(xml.FirstChild, @"TBODY\TR"); if (row_nd == null) { return(null); } // create quote Quote quote = new Quote(); // get stock symbol / name quote.stock = tck.Symbol; // get name quote.name = quote.stock; nd = prs.GetXmlNodeByPath(row_nd, @"TD(1)"); if (nd != null && nd.InnerText != "") { try { quote.name = nd.InnerText.Trim(); } catch { } } // get last price quote.price.last = double.NaN; nd = prs.GetXmlNodeByPath(row_nd, @"TD(2)"); if (nd != null && nd.InnerText != "") { try { quote.price.last = Convert.ToDouble(nd.InnerText); } catch { } } // get price change quote.price.change = double.NaN; nd = prs.GetXmlNodeByPath(row_nd, @"TD(3)"); if (nd != null && nd.InnerText != "") { try { quote.price.change = Convert.ToDouble(nd.InnerText); } catch { } } // get open price quote.price.open = quote.price.last - quote.price.change; // get bid price quote.price.bid = double.NaN; nd = prs.GetXmlNodeByPath(row_nd, @"TD(5)"); if (nd != null && nd.InnerText != "") { try { quote.price.bid = Convert.ToDouble(nd.InnerText); } catch { } } // get ask price quote.price.ask = double.NaN; nd = prs.GetXmlNodeByPath(row_nd, @"TD(6)"); if (nd != null && nd.InnerText != "") { try { quote.price.ask = Convert.ToDouble(nd.InnerText); } catch { } } // get high price quote.price.high = double.NaN; nd = prs.GetXmlNodeByPath(row_nd, @"TD(7)"); if (nd != null && nd.InnerText != "") { try { quote.price.high = Convert.ToDouble(nd.InnerText); } catch { } } // get low price quote.price.low = double.NaN; nd = prs.GetXmlNodeByPath(row_nd, @"TD(8)"); if (nd != null && nd.InnerText != "") { try { quote.price.low = Convert.ToDouble(nd.InnerText); } catch { } } // get total volume quote.volume.total = double.NaN; elem = doc.GetElementById("tradingInformationTable"); if (elem != null) { xml = cap.ConvertHtmlToXml(elem.OuterHtml); if (xml != null) { nd = prs.GetXmlNodeByPath(xml.FirstChild, @"TBODY\TR(3)\TD(2)"); if (nd != null && nd.InnerText != "") { try { quote.volume.total = Convert.ToDouble(nd.InnerText) * quote.price.last; } catch { } } } } // time-stamp quote.update_timestamp = DateTime.Now; // get and cache option table elem = doc.GetElementById("optionsAndFuturesTable"); if (elem != null) { xml = cap.ConvertHtmlToXml(elem.OuterHtml); if (xml != null) { cache_dict.Add(tck.Id, xml); } } return(quote); }