mirror of
https://gitlab.com/simple-stock-bots/simple-stock-bot.git
synced 2025-07-22 06:01:40 +00:00
Resolve "Add Options from MarketData.app"
This commit is contained in:
@@ -2,7 +2,9 @@ import datetime as dt
|
||||
import logging
|
||||
import os
|
||||
from typing import Dict
|
||||
from collections import OrderedDict
|
||||
|
||||
import humanize
|
||||
import pandas as pd
|
||||
import pytz
|
||||
import requests as r
|
||||
@@ -286,3 +288,58 @@ class MarketData:
|
||||
return df
|
||||
|
||||
return pd.DataFrame()
|
||||
|
||||
def options_reply(self, request: str) -> str:
|
||||
"""Undocumented API Usage!"""
|
||||
|
||||
options_data = self.get(f"options/quotes/{request}")
|
||||
|
||||
for key in options_data.keys():
|
||||
options_data[key] = options_data[key][0]
|
||||
|
||||
options_data["underlying"] = "$" + options_data["underlying"]
|
||||
|
||||
options_data["updated"] = humanize.naturaltime(dt.datetime.now() - dt.datetime.fromtimestamp(options_data["updated"]))
|
||||
|
||||
options_data["expiration"] = humanize.naturaltime(
|
||||
dt.datetime.now() - dt.datetime.fromtimestamp(options_data["expiration"])
|
||||
)
|
||||
|
||||
options_data["firstTraded"] = humanize.naturaltime(
|
||||
dt.datetime.now() - dt.datetime.fromtimestamp(options_data["firstTraded"])
|
||||
)
|
||||
|
||||
rename = {
|
||||
"optionSymbol": "Option Symbol",
|
||||
"underlying": "Underlying",
|
||||
"expiration": "Expiration",
|
||||
"side": "side",
|
||||
"strike": "strike",
|
||||
"firstTraded": "First Traded",
|
||||
"updated": "Last Updated",
|
||||
"bid": "bid",
|
||||
"bidSize": "bidSize",
|
||||
"mid": "mid",
|
||||
"ask": "ask",
|
||||
"askSize": "askSize",
|
||||
"last": "last",
|
||||
"openInterest": "Open Interest",
|
||||
"volume": "Volume",
|
||||
"inTheMoney": "inTheMoney",
|
||||
"intrinsicValue": "Intrinsic Value",
|
||||
"extrinsicValue": "Extrinsic Value",
|
||||
"underlyingPrice": "Underlying Price",
|
||||
"iv": "Implied Volatility",
|
||||
"delta": "delta",
|
||||
"gamma": "gamma",
|
||||
"theta": "theta",
|
||||
"vega": "vega",
|
||||
"rho": "rho",
|
||||
}
|
||||
|
||||
options_cleaned = OrderedDict()
|
||||
for old, new in rename.items():
|
||||
if old in options_data:
|
||||
options_cleaned[new] = options_data[old]
|
||||
|
||||
return options_cleaned
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import pandas as pd
|
||||
import logging
|
||||
|
||||
import pandas as pd
|
||||
|
||||
|
||||
class Symbol:
|
||||
"""
|
||||
|
@@ -1,6 +1,7 @@
|
||||
requests==2.31.0
|
||||
pandas==2.1.1
|
||||
schedule==1.2.1
|
||||
mplfinance==0.12.10b0
|
||||
markdownify==0.11.6
|
||||
cachetools==5.3.1
|
||||
humanize==4.8.0
|
||||
markdownify==0.11.6
|
||||
mplfinance==0.12.10b0
|
||||
pandas==2.1.1
|
||||
requests==2.31.0
|
||||
schedule==1.2.1
|
||||
|
@@ -5,6 +5,7 @@ import datetime
|
||||
import logging
|
||||
import random
|
||||
import re
|
||||
from typing import Dict
|
||||
|
||||
import pandas as pd
|
||||
import schedule
|
||||
@@ -14,8 +15,6 @@ from common.cg_Crypto import cg_Crypto
|
||||
from common.MarketData import MarketData
|
||||
from common.Symbol import Coin, Stock, Symbol
|
||||
|
||||
from typing import Dict
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -38,7 +37,7 @@ class Router:
|
||||
t_copy = self.trending_count.copy()
|
||||
for key in t_copy.keys():
|
||||
if t_copy[key] < 0.01:
|
||||
# This just makes sure were not keeping around keys that havent been called in a very long time.
|
||||
# Prune Keys
|
||||
dead_keys.append(key)
|
||||
else:
|
||||
t_copy[key] = t_copy[key] * decay
|
||||
@@ -48,7 +47,7 @@ class Router:
|
||||
self.trending_count = t_copy.copy()
|
||||
log.info("Decayed trending symbols.")
|
||||
|
||||
def find_symbols(self, text: str, *, trending_weight: int = 1) -> list[Stock | Symbol]:
|
||||
def find_symbols(self, text: str, *, trending_weight: int = 1) -> list[Stock | Coin]:
|
||||
"""Finds stock tickers starting with a dollar sign, and cryptocurrencies with two dollar signs
|
||||
in a blob of text and returns them in a list.
|
||||
|
||||
@@ -66,6 +65,8 @@ class Router:
|
||||
|
||||
symbols: list[Symbol] = []
|
||||
stock_matches = set(re.findall(self.STOCK_REGEX, text))
|
||||
coin_matches = set(re.findall(self.CRYPTO_REGEX, text))
|
||||
|
||||
for stock_match in stock_matches:
|
||||
# Market data lacks tools to check if a symbol is valid.
|
||||
if stock_info := self.stock.symbol_id(stock_match):
|
||||
@@ -73,11 +74,10 @@ class Router:
|
||||
else:
|
||||
log.info(f"{stock_match} is not in list of stocks")
|
||||
|
||||
coins = set(re.findall(self.CRYPTO_REGEX, text))
|
||||
for coin in coins:
|
||||
sym = self.crypto.symbol_list[self.crypto.symbol_list["symbol"].str.fullmatch(coin.lower(), case=False)]
|
||||
for coin_match in coin_matches:
|
||||
sym = self.crypto.symbol_list[self.crypto.symbol_list["symbol"].str.fullmatch(coin_match.lower(), case=False)]
|
||||
if sym.empty:
|
||||
log.info(f"{coin} is not in list of coins")
|
||||
log.info(f"{coin_match} is not in list of coins")
|
||||
else:
|
||||
symbols.append(Coin(sym))
|
||||
if symbols:
|
||||
@@ -396,3 +396,12 @@ class Router:
|
||||
replies = replies + self.crypto.batch_price(coins)
|
||||
|
||||
return replies
|
||||
|
||||
def options(self, request: str, symbols: list[Symbol]) -> Dict:
|
||||
request = request.lower()
|
||||
if len(symbols) == 1:
|
||||
symbol = symbols[0]
|
||||
request = request.replace(symbol.tag.lower(), symbol.symbol.lower())
|
||||
return self.stock.options_reply(request)
|
||||
else:
|
||||
return self.stock.options_reply(request)
|
||||
|
Reference in New Issue
Block a user