From d7ab183f412f78ef6d43452c93946b9bf0c2c6c1 Mon Sep 17 00:00:00 2001 From: William Kray Date: Sat, 5 Dec 2020 00:30:52 -0800 Subject: [PATCH] initial commit --- base-config.yaml | 5 + maubot.yaml | 11 + sample-api-output.json | 453 +++++++++++++++++++++++++++++++++++++++++ tickerbot.py | 71 +++++++ 4 files changed, 540 insertions(+) create mode 100644 base-config.yaml create mode 100644 maubot.yaml create mode 100644 sample-api-output.json create mode 100644 tickerbot.py diff --git a/base-config.yaml b/base-config.yaml new file mode 100644 index 0000000..c0406c0 --- /dev/null +++ b/base-config.yaml @@ -0,0 +1,5 @@ +# api key to use for https://rapidapi.com/apidojo/api/yahoo-finance1 +apiKey: mYsUp3rs3CretKEY12345 + +stocktrigger: stonks +cryptotrigger: hodl diff --git a/maubot.yaml b/maubot.yaml new file mode 100644 index 0000000..f348878 --- /dev/null +++ b/maubot.yaml @@ -0,0 +1,11 @@ +maubot: 0.1.0 +id: org.jobmachine.tickerbot +version: 0.0.1 +license: MIT +modules: +- tickerbot +main_class: TickerBot +database: false + +extra_files: +- base-config.yaml diff --git a/sample-api-output.json b/sample-api-output.json new file mode 100644 index 0000000..1c28756 --- /dev/null +++ b/sample-api-output.json @@ -0,0 +1,453 @@ +{ + "quoteResponse": { + "result": [ + { + "language": "en-US", + "region": "US", + "quoteType": "EQUITY", + "quoteSourceName": "Delayed Quote", + "triggerable": true, + "quoteSummary": { + "earnings": { + "maxAge": 86400, + "earningsChart": { + "quarterly": [ + { + "date": "4Q2019", + "actual": 0.41, + "estimate": 0.34 + }, + { + "date": "1Q2020", + "actual": 0.23, + "estimate": -0.05 + }, + { + "date": "2Q2020", + "actual": 0.44, + "estimate": -0.03 + }, + { + "date": "3Q2020", + "actual": 0.76, + "estimate": 0.59 + } + ], + "currentQuarterEstimate": 0.87, + "currentQuarterEstimateDate": "4Q", + "currentQuarterEstimateYear": 2020, + "earningsDate": [ + 1611705600, + 1612137600 + ] + }, + "financialsChart": { + "yearly": [ + { + "date": 2016, + "revenue": 7000132000, + "earnings": -674914000 + }, + { + "date": 2017, + "revenue": 11759000000, + "earnings": -1962000000 + }, + { + "date": 2018, + "revenue": 21461000000, + "earnings": -976000000 + }, + { + "date": 2019, + "revenue": 24578000000, + "earnings": -862000000 + } + ], + "quarterly": [ + { + "date": "4Q2019", + "revenue": 7384000000, + "earnings": 105000000 + }, + { + "date": "1Q2020", + "revenue": 5985000000, + "earnings": 16000000 + }, + { + "date": "2Q2020", + "revenue": 6036000000, + "earnings": 104000000 + }, + { + "date": "3Q2020", + "revenue": 8771000000, + "earnings": 331000000 + } + ] + }, + "financialCurrency": "USD" + } + }, + "currency": "USD", + "firstTradeDateMilliseconds": 1277818200000, + "priceHint": 2, + "totalCash": 14531000300, + "floatShares": 759524420, + "ebitda": 4019000064, + "shortRatio": 1.57, + "preMarketChange": -1.88, + "preMarketChangePercent": -0.31683, + "preMarketTime": 1607092166, + "targetPriceHigh": 780, + "targetPriceLow": 40, + "targetPriceMean": 375.66, + "targetPriceMedian": 400, + "preMarketPrice": 591.5, + "heldPercentInsiders": 20.02, + "heldPercentInstitutions": 42.46, + "postMarketChangePercent": 0.12687129, + "postMarketTime": 1607122355, + "postMarketPrice": 599.8, + "postMarketChange": 0.76000977, + "regularMarketChange": 5.659973, + "regularMarketChangePercent": 0.953853, + "regularMarketTime": 1607115602, + "regularMarketPrice": 599.04, + "regularMarketDayHigh": 599.04, + "regularMarketDayRange": "585.5 - 599.04", + "regularMarketDayLow": 585.5, + "regularMarketVolume": 28140697, + "sharesShort": 47898025, + "sharesShortPrevMonth": 52955116, + "shortPercentFloat": 6.3, + "regularMarketPreviousClose": 593.38, + "bid": 599.2, + "ask": 598.88, + "bidSize": 18, + "askSize": 22, + "exchange": "NMS", + "market": "us_market", + "messageBoardId": "finmb_27444752", + "fullExchangeName": "NasdaqGS", + "shortName": "Tesla, Inc.", + "longName": "Tesla, Inc.", + "regularMarketOpen": 591.01, + "averageDailyVolume3Month": 50945714, + "averageDailyVolume10Day": 47675014, + "beta": 2.151181, + "fiftyTwoWeekLowChange": 532.086, + "fiftyTwoWeekLowChangePercent": 7.947038, + "fiftyTwoWeekRange": "66.954 - 607.8", + "fiftyTwoWeekHighChange": -8.76001, + "fiftyTwoWeekHighChangePercent": -0.014412652, + "fiftyTwoWeekLow": 66.954, + "fiftyTwoWeekHigh": 607.8, + "components": [ + "^NQDMXJPLMAUD", + "^NQUSBLM", + "^NQNA3000LMJPY", + "^NQNA3300LMGBP", + "^NQNA3300LM", + "^QIV", + "^NQDXUSMLTCGN", + "^NQUS500LCGN", + "^NQUSB3000LMJPY", + "^NQDM3000LM", + "^NQGS", + "^NQNALMEURN", + "^NQUSB3300LMGBP", + "^NQUSBLMCAD", + "^NQDMXKRJPYN", + "^NQDMXKRLMAUDN", + "^NQUSB3000LMEUR", + "^NQUSB3000LMCAD", + "^NQDMXJPLMAUDN", + "^NQDMXKRLMAUD", + "^NQUSBLMJPY", + "^NDXCHF", + "^NQDM3300LMCAD", + "^NQDM3300LMEUR", + "^NQGXGBLMN", + "^NQDMXKRLCJPY", + "^WEALTHGN", + "^NQDXUSLCEUR", + "^NQG3000LMEUR", + "^WEALTHGL", + "^NQDM3000LMCADN", + "^NQDXUSLCG", + "^NQUSB3000LMGBPN", + "^NQDMXKRAUD", + "^NQG3000LMGBPN", + "^NQDMXKRLMGBPN", + "^NQGXGBLMGBPN", + "^NQDM3000LMAUD", + "^NQGXJPLMJPYN", + "^NQNALMCADN", + "^NQUSBLMEUR", + "^NQNALMJPY", + "^NQNA3000LMCADN", + "^NDX", + "^NQGXGBLMJPY", + "^QCRD", + "^NQDM3300LMCADN", + "^NQG3300LMGBPN", + "^NQGXJPLMJPY", + "^NQUSB3300LMCADN", + "^NQDMXKR", + "^NQDMXGBLMCADN", + "^NQDMXKRLCN", + "^NQGXGBLMEURN", + "^NQGXJPLMCAD", + "^NQUSB3300LMGBPN", + "^NQGXJPLMEUR", + "^XNDXNNRCHF", + "^NQG3000LMAUDN", + "^NQDMXJPLMGBPN", + "^NQDMXJPLMN", + "^NQDMXKRLCJPYN", + "^NQDMXKRLMCADN", + "^NQG3300LMJPY", + "^NQDMXKRLCEUR", + "^NQDXUSLC", + "^NQGXGBLMJPYN", + "^NQG3000LMJPY", + "^NQUSBLMEURN", + "^NQDM3000LMGBPN", + "^INDS", + "^NQDMXKRJPY", + "^NQDMXKRLCCAD", + "^NQDMXKRLCEURN", + "^NQUSMLTCG", + "^NQDM3000LMJPY", + "^NQNA3300LMCADN", + "^NQGXJPLMGBPN", + "^NQUSB3000LMCADN", + "^QMI", + "^NQNA3000LM", + "^IXIC", + "^NQNALM", + "^NQUS500LC", + "^NQDMXGBLMJPY", + "^NQDM3300LMGBPN", + "^NQNALMAUD", + "^NQNA3300LMAUD", + "^NQDXUSLCN", + "^NQGXGBLMAUD", + "^NQG3000LMCAD", + "^NQUSBLMN", + "^NQDMXJPLMGBP", + "^NQG3300LMCADN", + "^NQSSTR", + "^NQFGSL", + "^NQG3300LMCAD", + "^NQUSB3300LMAUD", + "^NQDMXKRLMEUR", + "^NQG3300LMEUR", + "^MNX1", + "^NQDM3300LMN", + "^NQNALMAUDN", + "^NQDM3300LMAUDN", + "^NQNA3300LMJPYN", + "^NQUSB3300LMN", + "^NQG3300LMAUDN", + "^NQDMXKRLMCAD", + "^NQUSB3300LMAUDN", + "^NQDMXGBLM", + "^NQNA3300LMEURN", + "^NQDM3300LMJPY", + "^NQDMXGBLMJPYN", + "^NQG3000LMCADN", + "^NQSSTRN", + "^NQUSB3300LM", + "^NQNA3000LMEURN", + "^NQG3300LM", + "^NQDMXKRLMJPY", + "^NQUSB3000LMAUDN", + "^NQUSBLMJPYN", + "^NQNA3000LMAUD", + "^NQNA3000LMJPYN", + "^NQDMXGBLMCAD", + "^XNDXNNRGBP", + "^NQUSLG", + "^NQDMXGBLMEURN", + "^NQDMXKRGBPN", + "^NQDMXGBLMEUR", + "^XNDXNNR", + "^NQDM3000LMAUDN", + "^NQUSB3300LMJPY", + "^NQDMXKRAUDN", + "^NQDMXKRLMJPYN", + "^NQUSBLMCADN", + "^NQNA3000LMGBP", + "^NQDMXGBLMN", + "^NQDM3000LMN", + "^NQG3000LM", + "^NQUSB3000LMJPYN", + "^NQNALMGBPN", + "^NQGXGBLMCADN", + "^NQNA3300LMGBPN", + "^NQDMXKRLCCADN", + "^NQG3300LMN", + "^NQGXJPLMCADN", + "^QAUTO", + "^NQUSB3000LMGBP", + "^NQGXJPLM", + "^NQUSB3000LMEURN", + "^NQG3300LMEURN", + "^NQDM3300LMAUD", + "^NQUSBLMGBP", + "^NQNALMN", + "^RCH", + "^NQG3300LMJPYN", + "^NQNA3300LMN", + "^NQUSLGN", + "^NQNA3000LMGBPN", + "^NQGXJPLMAUDN", + "^NQUSB3000LMAUD", + "^NQNA3300LMEUR", + "^NQNA3300LMAUDN", + "^NQDMXKRLCGBP", + "^NQDMXKRLM", + "^NQUSMLTCGN", + "^NQDMXKRLC", + "^NQG3000LMAUD", + "^NQNALMGBP", + "^NDXEUR", + "^NDXHKD", + "^NQDMXJPLMJPYN", + "^NQGXGBLM", + "^NQNA3300LMCAD", + "^NQDMXKRN", + "^XQC", + "^NQCRDN", + "^NQDMXJPLMEURN", + "^NDXCAD", + "^NQDXUSMLTCG", + "^NQDMXJPLM", + "^NQDMXKREUR", + "^NQGXJPLMGBP", + "^NQDMXKRLMEURN", + "^NQUSBLMAUD", + "^NQGXGBLMGBP", + "^NQDM3000LMEUR", + "^NQDMXKRCAD", + "^NQNA3300LMJPY", + "^XQO", + "^GRNUS", + "^NQG3000LMEURN", + "^NQDM3000LMCAD", + "^NQDXUSLCEURN", + "^NQNA3000LMAUDN", + "^NQDMXKRLCAUD", + "^XCQ", + "^NQNALMCAD", + "^NQG3000LMGBP", + "^CELS", + "^NQGXJPLMEURN", + "^GRNTRN", + "^NQG3300LMGBP", + "^NQDXUSLCGBP", + "^NQG3000LMJPYN", + "^NQUSB3000LMN", + "^NQGXJPLMN", + "^NQNALMEUR", + "^NDXGBP", + "^NQGXGBLMEUR", + "^NQDMXKRGBP", + "^NQDM3000LMGBP", + "^XNDXNNRHKD", + "^NQDMXGBLMGBPN", + "^XNDXNNREUR", + "^NQCRD", + "^NQDMXKRCADN", + "^NQGXGBLMCAD", + "^NQDMXGBLMGBP", + "^NQDMXKRLCAUDN", + "^XNDXNNRCAD", + "^NQDXUSLCGBPN", + "^NQNA3000LMN", + "^NQDM3300LM", + "^NQUSBLMGBPN", + "^NQDMXKRLMN", + "^NQFGSLN", + "^NQGXJPLMAUD", + "^NQUSB3000LM", + "^NQDMXGBLMAUDN", + "^QGREEN", + "^NQDMXJPLMJPY", + "^NQUSB3300LMJPYN", + "^NQDMXKRLCGBPN", + "^NDXX", + "^NQDXUSLCGN", + "^NQUS500LCG", + "^NQDM3000LMEURN", + "^NDXE", + "^NQDMXKREURN", + "^NQUSB3300LMEUR", + "^NQNA3000LMCAD", + "^NQNALMJPYN", + "^NQG3300LMAUD", + "^NQNA3000LMEUR", + "^NQDMXJPLMCADN", + "^RCHNTR", + "^NQG3000LMN", + "^NQDM3000LMJPYN", + "^NQDMXGBLMAUD", + "^NQUSBLMAUDN", + "^NQDM3300LMGBP", + "^NQUSB3300LMEURN", + "^NQDM3300LMJPYN", + "^NQDMXJPLMCAD", + "^NQUSB3300LMCAD", + "^NQDMXJPLMEUR", + "^NQDMXKRLMGBP", + "^NQGXGBLMAUDN", + "^NQUS500LCN", + "^NQDM3300LMEURN" + ], + "earningsTimestamp": 1603296436, + "earningsTimestampStart": 1611745140, + "earningsTimestampEnd": 1612180800, + "trailingPE": 1145.392, + "pegRatio": 0.74, + "dividendsPerShare": 0, + "revenue": 28175999000, + "priceToSales": 20.152988, + "marketState": "POST", + "epsTrailingTwelveMonths": 0.523, + "epsForward": 3.9, + "epsCurrentYear": 2.26, + "epsNextQuarter": 0.84, + "priceEpsCurrentYear": 265.06195, + "priceEpsNextQuarter": 713.1429, + "sharesOutstanding": 947900992, + "bookValue": 16.91, + "fiftyDayAverage": 460.55542, + "fiftyDayAverageChange": 138.48456, + "fiftyDayAverageChangePercent": 0.30069032, + "twoHundredDayAverage": 348.84998, + "twoHundredDayAverageChange": 250.19, + "twoHundredDayAverageChangePercent": 0.7171851, + "marketCap": 567830577152, + "forwardPE": 153.59999, + "priceToBook": 35.42519, + "sourceInterval": 15, + "exchangeDataDelayedBy": 0, + "exchangeTimezoneName": "America/New_York", + "exchangeTimezoneShortName": "EST", + "pageViews": { + "midTermTrend": "UP", + "longTermTrend": "UP", + "shortTermTrend": "DOWN" + }, + "gmtOffSetMilliseconds": -18000000, + "esgPopulated": false, + "tradeable": false, + "symbol": "TSLA" + } + ], + "error": null + } +} diff --git a/tickerbot.py b/tickerbot.py new file mode 100644 index 0000000..0316bf9 --- /dev/null +++ b/tickerbot.py @@ -0,0 +1,71 @@ +from typing import Optional, Type + +from mautrix.util.config import BaseProxyConfig, ConfigUpdateHelper +from maubot import Plugin, MessageEvent +from maubot.handlers import command + +import requests +import json + +class Config(BaseProxyConfig): + def do_update(self, helper: ConfigUpdateHelper) -> None: + helper.copy("apiKey") + helper.copy("stocktrigger") + helper.copy("cryptotrigger") + +class TickerBot(Plugin): + async def start(self) -> None: + await super().start() + self.config.load_and_update() + + @classmethod + def get_config_class(cls) -> Type[BaseProxyConfig]: + return Config + + @command.new(name=lambda self: self.config["stocktrigger"], + help="Look up information about a stock by its ticker symbol") + @command.argument("ticker", pass_raw=True, required=True) + async def handler(self, evt: MessageEvent, ticker: str) -> None: + await evt.mark_read() + + tickerUpper = ticker.upper() + url = "https://apidojo-yahoo-finance-v1.p.rapidapi.com/market/v2/get-quotes" + querystring = {"symbols":tickerUpper} + headers = { + 'x-rapidapi-key': self.config["apiKey"], + 'x-rapidapi-host': "apidojo-yahoo-finance-v1.p.rapidapi.com" + } + + try: + response = requests.request("GET", url, headers=headers, params=querystring) + except Exception as e: + evt.respond(f"request failed: {e.message}") + return None + try: + jsonresponse = response.json()['quoteResponse']['result'][0] + openDifference = f"{jsonresponse['regularMarketPrice'] - jsonresponse['regularMarketOpen']:.2f}" + openPercentDiff = f"{(float(openDifference) / jsonresponse['regularMarketOpen'] * 100):.2f}%" + except Exception as e: + evt.respond("No results, double check that you've chosen a real ticker symbol") + self.log.exception(e) + return None + + if float(openDifference) < 0: + color = "red" + arrow = "\U000025BC" + else: + color = "green" + arrow = "\U000025B2" + + prettyMessage = "
".join( + [ + f"Current data for {tickerUpper}:" , + f"", + f"Price: ${str(jsonresponse['regularMarketPrice'])}, \ + {arrow}{openPercentDiff} from market open @ ${str(jsonresponse['regularMarketOpen'])}", + f"52 Week High: ${str(jsonresponse['fiftyTwoWeekHigh'])}", + f"52 Week Low: ${str(jsonresponse['fiftyTwoWeekLow'])}" + ] + ) + + await evt.respond(prettyMessage, allow_html=True)