def get_open_trades(portfolio_tree): session = Session() open_trades_resp = session.get(UrlHelper.route('opentrades')) open_tree = html.fromstring(open_trades_resp.text) open_trade_rows = open_tree.xpath( '//table[@class="table1"]/tbody/tr[@class="table_data"]/td[2]/a/parent::td/parent::tr' ) ot_xpath_map = { 'order_id': 'td[1]/text()', 'symbol': 'td[5]/a/text()', 'cancel_fn': 'td[2]/a/@href', 'order_date': 'td[3]/text()', 'quantity': 'td[6]/text()', 'order_price': 'td[7]/text()', 'trade_type': 'td[4]/text()' } open_orders = [] for tr in open_trade_rows: fon = lambda x: x[0] if len(x) > 0 else None open_order_dict = { k: fon(tr.xpath(v)) for k, v in ot_xpath_map.items() } symbol_match = re.search(r'^([^\.\d]+)', open_order_dict['symbol']) if symbol_match: open_order_dict['symbol'] = symbol_match.group(1) if open_order_dict['order_price'] == 'n/a': oid = open_order_dict['order_id'] quantity = int(open_order_dict['quantity']) pxpath = '//table[@id="stock-portfolio-table"]//tr[contains(@style,"italic")]//span[contains(@id,"%s")]/ancestor::tr/td[5]/span/text()' % oid cancel_link = open_order_dict['cancel_fn'] wrapper = CancelOrderWrapper(cancel_link) open_order_dict['cancel_fn'] = wrapper.wrap_cancel try: current_price = coerce_value( fon(portfolio_tree.xpath(pxpath)), Decimal) open_order_dict['order_price'] = current_price * quantity except Exception as e: warn("Unable to parse open trade value for %s" % open_order_dict['symbol']) open_order_dict['order_price'] = 0 open_orders.append(OpenOrder(**open_order_dict)) return open_orders
def get_portfolio(): session = Session() portfolio_response = session.get(UrlHelper.route('portfolio')) portfolio_tree = html.fromstring(portfolio_response.text) stock_portfolio = StockPortfolio() short_portfolio = ShortPortfolio() option_portfolio = OptionPortfolio() Parsers.parse_and_sort_positions(portfolio_tree, stock_portfolio, short_portfolio, option_portfolio) xpath_prefix = '//div[@id="infobar-container"]/div[@class="infobar-title"]/p' xpath_map = { 'account_value': '/strong[contains(text(),"Account Value")]/following-sibling::span/text()', 'buying_power': '/strong[contains(text(),"Buying Power")]/following-sibling::span/text()', 'cash': '/strong[contains(text(),"Cash")]/following-sibling::span/text()', 'annual_return_pct': '/strong[contains(text(),"Annual Return")]/following-sibling::span/text()', } xpath_get = lambda xpth: portfolio_tree.xpath("%s%s" % (xpath_prefix, xpth))[0] portfolio_args = {k: xpath_get(v) for k, v in xpath_map.items()} portfolio_args['stock_portfolio'] = stock_portfolio portfolio_args['short_portfolio'] = short_portfolio portfolio_args['option_portfolio'] = option_portfolio portfolio_args['open_orders'] = Parsers.get_open_trades(portfolio_tree) for order in portfolio_args['open_orders']: print(order.__dict__) return Portfolio(**portfolio_args)
def option_lookup(symbol, strike_price_proximity=3): logging.debug("OPTION LOOKUP FOR %s" % symbol) def filter_contracts(olist, stock_price, spp): if olist is None: return [] middle_index = 0 for i in range(len(olist)): if stock_price < olist[i]['StrikePrice']: middle_index += 1 break start = middle_index - spp end = middle_index + spp if start < 0: start = 0 if end > len(olist) - 1: end = len(olist) - 1 return olist[start:end] session = Session() resp = session.get(UrlHelper.route('optionlookup')) tree = html.fromstring(resp.text) option_token = None option_user_id = None token = None user_id = None param_script = tree.xpath( '//script[contains(text(),"quoteOptions")]/text()')[0] param_search = re.search( r'\#get\-quote\-options\'\)\,\s*\'(.+)\'\s*\,\s*(\d+)\s*\)\;', param_script) try: option_token = param_search.group(1) option_user_id = param_search.group(2) except Exception: raise Exception("Unable to get option lookup token") option_quote_qp = { 'IdentifierType': 'Symbol', 'Identifier': symbol, 'SymbologyType': 'DTNSymbol', 'OptionExchange': None, '_token': option_token, '_token_userid': option_user_id } url = UrlHelper.set_query(OPTIONS_QUOTE_URL, option_quote_qp) resp = requests.get(url) option_data = json.loads(resp.text) quote = option_data['Quote'] if quote is None: logging.debug(option_data) raise Exception("No option quote data for %s" % symbol) try: last_price = option_data['Quote']['Last'] except Exception as e: logging.debug(option_data) logging.debug(e) option_chains = [] for e in option_data['Expirations']: expiration = e['ExpirationDate'] filtered_calls = filter_contracts(e['Calls'], last_price, strike_price_proximity) filtered_puts = filter_contracts(e['Puts'], last_price, strike_price_proximity) calls = [OptionContract(o) for o in filtered_calls] puts = [OptionContract(o) for o in filtered_puts] option_chains.append(OptionChain(expiration, calls=calls, puts=puts)) option_chain_lookup = OptionChainLookup(symbol, *option_chains) return option_chain_lookup
def wrap_cancel(self): url = "%s%s" % (UrlHelper.route('opentrades'), self.link) print(url) session = Session() session.get(url)