from bs4 import BeautifulSoup from threading import Thread import datetime import file_writer import json import re import renderer import random import secrets import time import urllib.request, urllib.error, urllib.parse class stock_quote_renderer(renderer.debuggable_abstaining_renderer): # format exchange:symbol def __init__(self, name_to_timeout_dict, symbols): super(stock_quote_renderer, self).__init__(name_to_timeout_dict, False) self.symbols = symbols self.prefix = "https://www.alphavantage.co/query?" self.thread = None def debug_prefix(self): return "stock" def get_random_key(self): return random.choice(secrets.alphavantage_keys) def periodic_render(self, key): now = datetime.datetime.now() if ( now.hour < (9 - 3) or now.hour >= (17 - 3) or datetime.datetime.today().weekday() > 4 ): self.debug_print("The stock market is closed so not re-rendering") return True if self.thread is None or not self.thread.is_alive(): self.debug_print("Spinning up a background thread...") self.thread = Thread(target=self.thread_internal_render, args=()) self.thread.start() return True def thread_internal_render(self): symbols_finished = 0 f = file_writer.file_writer("stock_3_86400.html") f.write("

Stock Quotes


") f.write("") for symbol in self.symbols: # print "---------- Working on %s\n" % symbol # https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=MSFT&interval=5min&apikey= # https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=MSFT&apikey= attempts = 0 cooked = "" while True: key = self.get_random_key() url = self.prefix + "function=GLOBAL_QUOTE&symbol=%s&apikey=%s" % ( symbol, key, ) raw = urllib.request.urlopen(url).read() cooked = json.loads(raw) if "Global Quote" not in cooked: # print "%s\n" % cooked print( "Failure %d, sleep %d sec...\n" % (attempts + 1, 2 ** attempts) ) time.sleep(2 ** attempts) attempts += 1 if attempts > 10: # we'll wait up to 512 seconds per symbol break else: break # These fuckers... if "Global Quote" not in cooked: print("Can't get data for symbol %s: %s\n" % (symbol, raw)) continue cooked = cooked["Global Quote"] # { # u'Global Quote': # { # u'01. symbol': u'MSFT', # u'02. open': u'151.2900', # u'03. high': u'151.8900', # u'04. low': u'150.7650', # u'05. price': u'151.1300', # u'06. volume': u'16443559', # u'07. latest trading day': u'2019-12-10', # u'08. previous close': u'151.3600', # u'09. change': u'-0.2300' # u'10. change percent': u'-0.1520%', # } # } price = "?????" if "05. price" in cooked: price = cooked["05. price"] price = price[:-2] percent_change = "?????" if "10. change percent" in cooked: percent_change = cooked["10. change percent"] if not "-" in percent_change: percent_change = "+" + percent_change change = "?????" cell_color = "#bbbbbb" if "09. change" in cooked: change = cooked["09. change"] if "-" in change: cell_color = "#b00000" else: cell_color = "#009000" change = change[:-2] if symbols_finished % 4 == 0: if symbols_finished > 0: f.write("") f.write("") symbols_finished += 1 f.write( """ """ % (cell_color, symbol, price, percent_change, change) ) f.write("
%s
$%s
(%s)
$%s
") f.close() return True # x = stock_quote_renderer({}, ["MSFT", "GOOG", "GOOGL", "OPTAX", "VNQ"]) # x.periodic_render(None) # x.periodic_render(None)