Skip to content

Commit

Permalink
Refactor stocks/options/voi,vol,oi,chains (#4017)
Browse files Browse the repository at this point in the history
  • Loading branch information
hjoaquim authored Jan 26, 2023
1 parent 719ad75 commit cc2fa38
Show file tree
Hide file tree
Showing 68 changed files with 92,289 additions and 3,600 deletions.
2 changes: 1 addition & 1 deletion openbb_terminal/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def wrapper_decorator(*args, **kwargs):
undefined_apis_name = ", ".join(undefined_apis)
console.print(
f"[red]{undefined_apis_name} not defined. "
"Set API Keys in ~/.openbb_terminal/.env or under keys menu.[/red]\n"
"Set API Keys in ~/.openbb_terminal/.env or under keys menu.[/red]"
) # pragma: allowlist secret
return None
return func(*args, **kwargs)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
stocks
options
# screen
# view
# view high_IV
# set high_IV
# scr
# q
# unu -l 2 -s Strike -a -c
# unu -l 2 -s Vol
# calc
# load ${ticker=aapl}
# exp 0
# pcr
# info
# chains
# oi
# vol
# voi
# hist 100
# grhist 100
# greeks
# plot -x ltd -y iv
# parity -p -m 150 -M 175
# binom -s 150
# load spy
# vsurf
# load ${ticker=NDX} --source Nasdaq
# exp 0 --source Nasdaq
# chains --source Nasdaq
# oi --source Nasdaq
# vol --source Nasdaq
# voi --source Nasdaq
screen
view
view --preset high_IV.ini
set --preset high_IV.ini
scr
q
unu -l 2 -s Strike -r -c
unu -l 2 -s Vol
calc
load aapl
exp 0
pcr
info
chains
oi
vol
voi
hist 100
grhist 100
greeks
plot -x ltd -y iv
parity -p -m 150 -M 175
binom -s 150
load spy
vsurf
load NDX --source Nasdaq
exp 0
chains --source Nasdaq
oi
vol
voi
exit
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
stocks
options
load ${ticker=aapl}
load aapl
exp 0
payoff
list
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
stocks
options
load ${ticker=aapl}
load aapl
exp 0
pricing
add 150 -c 3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ stocks
options
screen
view
view high_IV
set high_IV
view high_IV.ini
set high_IV.ini
scr
ca
historical
Expand Down
4 changes: 4 additions & 0 deletions openbb_terminal/miscellaneous/library/trail_map.csv
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,10 @@ stocks.options.grhist,openbb_terminal.stocks.options.screen.syncretism_model.get
stocks.options.screen.screener_output,openbb_terminal.stocks.options.screen.syncretism_model.get_screener_output,openbb_terminal.stocks.options.screen.syncretism_view.view_screener_output
stocks.options.hist,openbb_terminal.stocks.options.options_sdk_helper.hist,
stocks.options.chains,openbb_terminal.stocks.options.options_sdk_helper.get_full_option_chain,
stocks.options.price,openbb_terminal.stocks.options.options_sdk_helper.get_option_current_price,
stocks.options.vol,openbb_terminal.stocks.options.options_view.plot_vol,
stocks.options.oi,openbb_terminal.stocks.options.options_view.plot_oi,
stocks.options.voi,openbb_terminal.stocks.options.options_view.plot_voi,
stocks.options.last_price,openbb_terminal.stocks.options.tradier_model.last_price,
stocks.options.expirations,openbb_terminal.stocks.options.options_sdk_helper.get_option_expirations,
stocks.options.process_chains,openbb_terminal.stocks.options.tradier_model.process_chains,
Expand Down
172 changes: 68 additions & 104 deletions openbb_terminal/stocks/options/nasdaq_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
__docformat__ = "numpy"

import logging
from datetime import datetime
from datetime import datetime, timedelta
from typing import List

import numpy as np
Expand All @@ -11,12 +11,38 @@

from openbb_terminal.decorators import log_start_end
from openbb_terminal.rich_config import console
from openbb_terminal.stocks.options.op_helpers import get_dte_from_expiration as get_dte

logger = logging.getLogger(__name__)
# pylint: disable=unsupported-assignment-operation


@log_start_end(log=logger)
def get_dte_from_expiration(date: str) -> float:
"""
Converts a date to total days until the option would expire.
This assumes that the date is in the form %B %d, %Y such as January 11, 2023
This calculates time from 'now' to 4 PM the date of expiration
This is particularly a helper for nasdaq results.
Parameters
----------
date: str
Date in format %B %d, %Y
Returns
-------
float
Days to expiration as a decimal
"""
# Get the date as a datetime and add 16 hours (4PM)
expiration_time = datetime.strptime(date, "%B %d, %Y") + timedelta(hours=16)
# Find total seconds from now
time_to_now = (expiration_time - datetime.now()).total_seconds()
# Convert to days
time_to_now /= 60 * 60 * 24
return time_to_now


@log_start_end(log=logger)
def get_full_option_chain(symbol: str) -> pd.DataFrame:
"""Get the full option chain for symbol over all expirations
Expand Down Expand Up @@ -45,50 +71,53 @@ def get_full_option_chain(symbol: str) -> pd.DataFrame:
" AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6 Safari/605.1.15"
},
).json()

if response_json["status"]["rCode"] == 200:
df = pd.DataFrame(response_json["data"]["table"]["rows"]).drop(
columns=["c_colour", "p_colour", "drillDownURL"]
)
df["expirygroup"] = (
df["expirygroup"].replace("", np.nan).fillna(method="ffill")
)
# Make numeric
columns_w_types = {
"c_Last": float,
"c_Change": float,
"c_Bid": float,
"c_Ask": float,
"c_Volume": int,
"c_Openinterest": int,
"strike": float,
"p_Last": float,
"p_Change": float,
"p_Bid": float,
"p_Ask": float,
"p_Volume": int,
"p_Openinterest": int,
}

for key, _ in columns_w_types.items():
df[key] = df[key].replace(",", "", regex=True)

df = (
df.fillna(np.nan)
.dropna(axis=0)
.replace("--", 0)
.astype(columns_w_types)
)
df["DTE"] = df["expirygroup"].apply(lambda t: get_dte(t))
df = df[df.DTE > 0]
df = df.drop(columns=["DTE"])
return df
return process_response(response_json)

console.print(f"[red]{symbol} Option Chain not found.[/red]\n")
return pd.DataFrame()


def process_response(response_json):
df = pd.DataFrame(response_json["data"]["table"]["rows"]).drop(
columns=["c_colour", "p_colour", "drillDownURL"]
)
df["expirygroup"] = df["expirygroup"].replace("", np.nan).fillna(method="ffill")
# Make numeric
columns_w_types = {
"c_Last": float,
"c_Change": float,
"c_Bid": float,
"c_Ask": float,
"c_Volume": int,
"c_Openinterest": int,
"strike": float,
"p_Last": float,
"p_Change": float,
"p_Bid": float,
"p_Ask": float,
"p_Volume": int,
"p_Openinterest": int,
}

for key, _ in columns_w_types.items():
df[key] = df[key].replace(",", "", regex=True)

df = df.fillna(np.nan).dropna(axis=0).replace("--", 0).astype(columns_w_types)
df["DTE"] = df["expirygroup"].apply(lambda t: get_dte_from_expiration(t))
df = df[df.DTE > 0]
df = df.drop(columns=["DTE"])

df["expiration"] = pd.to_datetime(
df["expirygroup"], format="%B %d, %Y"
).dt.strftime("%Y-%m-%d")

return df


@log_start_end(log=logger)
def get_expirations(symbol: str) -> List[str]:
def option_expirations(symbol: str) -> List[str]:
"""Get available expirations
Parameters
Expand All @@ -110,71 +139,6 @@ def get_expirations(symbol: str) -> List[str]:
return [datetime.strptime(exp, "%B %d, %Y").strftime("%Y-%m-%d") for exp in exps]


@log_start_end(log=logger)
def get_chain_given_expiration(symbol: str, expiration: str) -> pd.DataFrame:
"""Get option chain for symbol at a given expiration
Parameters
----------
symbol: str
Symbol to get chain for
expiration: str
Expiration to get chain for
Returns
-------
pd.DataFrame
Dataframe of option chain
"""
for asset in ["stocks", "index", "etf"]:
url = (
f"https://api.nasdaq.com/api/quote/{symbol}/option-chain?assetclass={asset}&"
f"fromdate={expiration}&todate={expiration}&excode=oprac&callput=callput&money=all&type=all"
)

response_json = requests.get(
url,
headers={
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"
" AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6 Safari/605.1.15"
},
).json()
if response_json["status"]["rCode"] == 200:
df = (
pd.DataFrame(
response_json.get("data", {}).get("table", {}).get("rows", {})
)
.drop(columns=["c_colour", "p_colour", "drillDownURL", "expirygroup"])
.fillna(np.nan)
.dropna(axis=0)
)
# Make numeric
columns_w_types = {
"c_Last": float,
"c_Change": float,
"c_Bid": float,
"c_Ask": float,
"c_Volume": int,
"c_Openinterest": int,
"strike": float,
"p_Last": float,
"p_Change": float,
"p_Bid": float,
"p_Ask": float,
"p_Volume": int,
"p_Openinterest": int,
}

for key, _ in columns_w_types.items():
df[key] = df[key].replace(",", "", regex=True)

df = df.replace("--", 0).astype(columns_w_types)
return df

console.print(f"[red]{symbol} Option Chain not found.[/red]\n")
return pd.DataFrame()


@log_start_end(log=logger)
def get_last_price(symbol: str) -> float:
"""Get the last price from nasdaq
Expand Down
Loading

0 comments on commit cc2fa38

Please sign in to comment.