3 from typing import Dict, List, Optional, Tuple
4 import yfinance as yf # type: ignore
10 class stock_quote_renderer(renderer.debuggable_abstaining_renderer):
11 """Render the stock prices page."""
15 name_to_timeout_dict: Dict[str, int],
17 display_subs: Dict[str, str] = None,
19 super(stock_quote_renderer, self).__init__(name_to_timeout_dict, False)
20 self.symbols = symbols
21 self.display_subs = display_subs
23 def debug_prefix(self) -> str:
27 def get_ticker_name(ticker: yf.ticker.Ticker) -> str:
28 """Get friendly name of a ticker."""
29 info = ticker.get_info()
30 if "shortName" in info:
31 return info["shortName"]
35 def get_price(ticker: yf.ticker.Ticker) -> Optional[float]:
36 """Get most recent price of a ticker."""
45 info = ticker.get_info()
47 if key in info and info[key] is not None and info[key] != 0.0:
48 print(f"Price: picked {key}, ${info[key]}.")
49 return float(info[key])
53 def get_change_and_delta(
54 ticker: yf.ticker.Ticker, price: float
55 ) -> Tuple[float, float]:
56 """Given the current price, look up opening price and compute delta."""
61 info = ticker.get_info()
63 if key in info and info[key] is not None:
64 print(f"Change: picked {key}, ${info[key]}.")
65 old_price = float(info[key])
66 delta = price - old_price
67 return (delta / old_price * 100.0, delta)
70 def periodic_render(self, key: str) -> bool:
71 """Write an up-to-date stock page."""
72 with file_writer.file_writer("stock_3_86400.html") as f:
73 f.write("<H1>Stock Quotes</H1><HR>")
74 f.write("<TABLE WIDTH=99%>")
76 for symbol in self.symbols:
77 ticker = yf.Ticker(symbol)
78 # print(ticker.get_info())
80 self.debug_print(f"Unknown symbol {symbol} -- ignored.")
82 name = stock_quote_renderer.get_ticker_name(ticker)
83 price = stock_quote_renderer.get_price(ticker)
85 self.debug_print(f"No price information for {symbol} -- skipped.")
87 (percent_change, delta) = stock_quote_renderer.get_change_and_delta(
90 # print(f"delta: {delta}, change: {percent_change}")
91 cell_color = "#b00000" if percent_change < 0 else "#009000"
92 if symbols_finished % 4 == 0:
93 if symbols_finished > 0:
97 if self.display_subs is not None and symbol in self.display_subs:
98 symbol = self.display_subs[symbol]
101 <TD WIDTH=20% HEIGHT=150 BGCOLOR="{cell_color}">
103 <DIV style="position:relative;
105 <!-- Symbol {symbol} -->
106 <DIV style="position:absolute;
109 -webkit-transform:rotate(-90deg);
111 font-family: helvetica, arial, sans-serif;
113 -webkit-text-stroke: 2px black;
117 <!-- Current price, Change today and percent change today, name -->
118 <DIV style="position:absolute;
122 font-family: helvetica, arial, sans-serif;
125 <I>({percent_change:.1f}%)</I><BR>
131 f.write("</TR></TABLE>")
135 #x = stock_quote_renderer({}, ["MSFT", "GOOG", "BTC-USD", "OPTAX", "GC=F", "VNQ"], { "BTC-USD": "BTC", "GC=F": "GOLD" })
136 #x.periodic_render(None)