diff --git a/data_sources_default.json b/data_sources_default.json index 5935c900d57..133f9dbc0d5 100644 --- a/data_sources_default.json +++ b/data_sources_default.json @@ -39,7 +39,8 @@ "options": { "load": [ "yf", - "tradier" + "tradier", + "nasdaq" ], "hist": [ "chartexchange", @@ -47,19 +48,26 @@ ], "vol": [ "yf", - "tradier" + "tradier", + "nasdaq" ], "voi": [ "yf", - "tradier" + "tradier", + "nasdaq" ], "oi": [ "yf", - "tradier" + "tradier", + "nasdaq" ], "chains": [ "yf", - "tradier" + "tradier", + "nasdaq" + ], + "greeks": [ + "yf" ] }, "disc": { diff --git a/openbb_terminal/stocks/options/alphaquery_view.py b/openbb_terminal/stocks/options/alphaquery_view.py index 974d3013798..1b35419820b 100644 --- a/openbb_terminal/stocks/options/alphaquery_view.py +++ b/openbb_terminal/stocks/options/alphaquery_view.py @@ -1,20 +1,20 @@ """AlphaQuery View""" __docforma__ = "numpy" -from typing import Optional, List import logging import os from datetime import datetime, timedelta +from typing import List, Optional import matplotlib.pyplot as plt -from openbb_terminal.config_terminal import theme from openbb_terminal.config_plot import PLOT_DPI +from openbb_terminal.config_terminal import theme from openbb_terminal.decorators import log_start_end from openbb_terminal.helper_funcs import ( export_data, - plot_autoscale, is_valid_axes_count, + plot_autoscale, ) from openbb_terminal.rich_config import console from openbb_terminal.stocks.options import alphaquery_model diff --git a/openbb_terminal/stocks/options/calculator_view.py b/openbb_terminal/stocks/options/calculator_view.py index 1fa6499aee6..8203b77d337 100644 --- a/openbb_terminal/stocks/options/calculator_view.py +++ b/openbb_terminal/stocks/options/calculator_view.py @@ -1,12 +1,12 @@ import logging -from typing import Dict, Optional, List +from typing import Dict, List, Optional from matplotlib import pyplot as plt -from openbb_terminal.config_terminal import theme from openbb_terminal.config_plot import PLOT_DPI +from openbb_terminal.config_terminal import theme from openbb_terminal.decorators import log_start_end -from openbb_terminal.helper_funcs import plot_autoscale, is_valid_axes_count +from openbb_terminal.helper_funcs import is_valid_axes_count, plot_autoscale from openbb_terminal.rich_config import console from openbb_terminal.stocks.options import calculator_model diff --git a/openbb_terminal/stocks/options/chartexchange_view.py b/openbb_terminal/stocks/options/chartexchange_view.py index f08110ef158..a0930e44f87 100644 --- a/openbb_terminal/stocks/options/chartexchange_view.py +++ b/openbb_terminal/stocks/options/chartexchange_view.py @@ -3,25 +3,23 @@ __docformat__ = "numpy" import logging import os -from typing import Optional, List +from typing import List, Optional + +import matplotlib.pyplot as plt +import mplfinance as mpf import pandas as pd -import mplfinance as mpf -import matplotlib.pyplot as plt - +from openbb_terminal.config_terminal import theme from openbb_terminal.decorators import log_start_end from openbb_terminal.helper_funcs import ( export_data, - print_rich_table, is_valid_axes_count, -) -from openbb_terminal.stocks.options import chartexchange_model -from openbb_terminal.config_terminal import theme -from openbb_terminal.rich_config import console -from openbb_terminal.helper_funcs import ( - plot_autoscale, lambda_long_number_format_y_axis, + plot_autoscale, + print_rich_table, ) +from openbb_terminal.rich_config import console +from openbb_terminal.stocks.options import chartexchange_model logger = logging.getLogger(__name__) diff --git a/openbb_terminal/stocks/options/hedge/hedge_controller.py b/openbb_terminal/stocks/options/hedge/hedge_controller.py index c2935eed01f..4d8e1e1db19 100644 --- a/openbb_terminal/stocks/options/hedge/hedge_controller.py +++ b/openbb_terminal/stocks/options/hedge/hedge_controller.py @@ -11,19 +11,13 @@ from prompt_toolkit.completion import NestedCompleter from openbb_terminal import feature_flags as obbff from openbb_terminal.decorators import log_start_end -from openbb_terminal.helper_funcs import ( - check_non_negative, - print_rich_table, -) +from openbb_terminal.helper_funcs import check_non_negative, print_rich_table from openbb_terminal.menu import session from openbb_terminal.parent_classes import BaseController -from openbb_terminal.rich_config import console, MenuText +from openbb_terminal.rich_config import MenuText, console from openbb_terminal.stocks.options.hedge import hedge_view from openbb_terminal.stocks.options.hedge.hedge_model import add_hedge_option -from openbb_terminal.stocks.options.yfinance_model import ( - get_option_chain, - get_price, -) +from openbb_terminal.stocks.options.yfinance_model import get_option_chain, get_price from openbb_terminal.stocks.options.yfinance_view import plot_payoff # pylint: disable=R0902 diff --git a/openbb_terminal/stocks/options/hedge/hedge_view.py b/openbb_terminal/stocks/options/hedge/hedge_view.py index 58b0db8a84b..a15e7bc1252 100644 --- a/openbb_terminal/stocks/options/hedge/hedge_view.py +++ b/openbb_terminal/stocks/options/hedge/hedge_view.py @@ -5,9 +5,7 @@ import logging import pandas as pd -from openbb_terminal.helper_funcs import ( - print_rich_table, -) +from openbb_terminal.helper_funcs import print_rich_table from openbb_terminal.rich_config import console from openbb_terminal.stocks.options.hedge import hedge_model diff --git a/openbb_terminal/stocks/options/nasdaq_model.py b/openbb_terminal/stocks/options/nasdaq_model.py new file mode 100644 index 00000000000..c0d8bcad3bf --- /dev/null +++ b/openbb_terminal/stocks/options/nasdaq_model.py @@ -0,0 +1,230 @@ +"""Nasdaq Model""" +__docformat__ = "numpy" + +import logging +from datetime import datetime +from typing import List + +import numpy as np +import pandas as pd +import requests + +from openbb_terminal.decorators import log_start_end +from openbb_terminal.rich_config import console + +logger = logging.getLogger(__name__) + + +@log_start_end(log=logger) +def get_full_chain(symbol: str) -> pd.DataFrame: + """Get the full option chain for symbol over all expirations + + Parameters + ---------- + symbol: str + Symbol to get options for. Can be a stock, etf or index. + + Returns + ------- + pd.DataFrame + Dataframe of option chain + """ + # Nasdaq requires an asset code, so instead of making user supply one, just loop through all + for asset in ["stocks", "index", "etf"]: + url = ( + f"https://api.nasdaq.com/api/quote/{symbol}/option-chain?assetclass={asset}&" + "fromdate=2010-09-09&todate=2030-09-09&excode=oprac&callput=callput&money=all&type=all" + ) + # I have had issues with nasdaq requests, and this user agent seems to work in US and EU + 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["data"]["table"]["rows"]).drop( + columns=["c_colour", "p_colour", "drillDownURL"] + ) + df["expirygroup"] = ( + df["expirygroup"].replace("", np.nan).fillna(method="ffill") + ) + # Make numeric + df = ( + df.fillna(np.nan) + .dropna(axis=0) + .replace("--", 0) + .astype( + { + "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, + } + ) + ) + return df + + console.print(f"[red]{symbol} Option Chain not found.[/red]\n") + return pd.DataFrame() + + +@log_start_end(log=logger) +def get_expirations(symbol: str) -> List[str]: + """Get available expirations + + Parameters + ---------- + symbol + + Returns + ------- + List[str] + List of expiration dates + """ + df = get_full_chain(symbol) + if df.empty: + return [] + # get everything that is not an empty string + exps = [exp for exp in list(df.expirygroup.unique()) if exp] + # Convert 'January 11, 1993' into '1993-01-11' + 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 + 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["data"]["table"]["rows"]) + .drop(columns=["c_colour", "p_colour", "drillDownURL", "expirygroup"]) + .fillna(np.nan) + .dropna(axis=0) + ) + # Make numeric + df = df.replace("--", 0).astype( + { + "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, + } + ) + 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 + + Parameters + ---------- + symbol: str + Symbol to get quote for + + Returns + ------- + float + Last price + """ + for asset in ["stocks", "index", "etf"]: + url = f"https://api.nasdaq.com/api/quote/{symbol}/info?assetclass={asset}" + 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: + return float( + response_json["data"]["primaryData"]["lastSalePrice"] + .strip("$") + .replace(",", "") + ) + console.print(f"[red]Last price for {symbol} not found[/red]\n") + return np.nan + + +# Ugh this doesn't get the full chain +# TODO: apply CRR binomial tree to backtrack IV for greeks +@log_start_end(log=logger) +def get_option_greeks(symbol: str, expiration: str) -> pd.DataFrame: + """Get option greeks from nasdaq + + Parameters + ---------- + symbol: str + Symbol to get + expiration: str + Option expiration + + Returns + ------- + pd.DataFrame + Dataframe with option greeks + """ + for asset in ["stocks", "index", "etf"]: + url_greeks = f"https://api.nasdaq.com/api/quote/{symbol}/option-chain/greeks?assetclass={asset}&date={expiration}" + response_json = requests.get( + url_greeks, + 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: + + greeks = pd.DataFrame(response_json["data"]["table"]["rows"]) + greeks = greeks.drop(columns="url") + return greeks + + console.print(f"[red]Greeks not found for {symbol} on {expiration}[/red].") + return pd.DataFrame() diff --git a/openbb_terminal/stocks/options/nasdaq_view.py b/openbb_terminal/stocks/options/nasdaq_view.py new file mode 100644 index 00000000000..b0877ccd32e --- /dev/null +++ b/openbb_terminal/stocks/options/nasdaq_view.py @@ -0,0 +1,333 @@ +"""Nasdaq View""" +__docformat__ = "numpy" + +import logging +import os +from typing import List, Optional + +import matplotlib.pyplot as plt + +import openbb_terminal.config_plot as cfp +from openbb_terminal.config_terminal import theme +from openbb_terminal.decorators import log_start_end +from openbb_terminal.helper_funcs import ( + export_data, + is_valid_axes_count, + plot_autoscale, + print_rich_table, +) +from openbb_terminal.stocks.options import nasdaq_model + +logger = logging.getLogger(__name__) + + +@log_start_end(log=logger) +def display_oi( + symbol: str, + expiration: str, + min_sp: float = -1, + max_sp: float = -1, + raw: bool = False, + export: str = "", + external_axes: Optional[List[plt.Axes]] = None, +): + """Plot open interest + + Parameters + ---------- + symbol: str + Ticker symbol + expiration: str + Expiry date for options + min_sp: float + Min strike to consider + max_sp: float + Max strike to consider + raw: bool + Flag to display raw data + export: str + Format to export file + external_axes : Optional[List[plt.Axes]], optional + External axes (1 axis is expected in the list), by default None + """ + option_chain = nasdaq_model.get_chain_given_expiration(symbol, expiration) + export_data( + export, + os.path.dirname(os.path.abspath(__file__)), + "oi_nasdaq", + option_chain, + ) + current_price = nasdaq_model.get_last_price(symbol) + + if min_sp == -1: + min_strike = 0.75 * current_price + else: + min_strike = min_sp + + if max_sp == -1: + max_strike = 1.25 * current_price + else: + max_strike = max_sp + + if external_axes is None: + _, ax = plt.subplots(figsize=plot_autoscale(), dpi=cfp.PLOT_DPI) + elif is_valid_axes_count(external_axes, 1): + (ax,) = external_axes + else: + return + ax.plot( + option_chain.strike, + option_chain["c_Openinterest"] / 1000, + ls="-", + marker="o", + label="Calls", + ) + ax.plot( + option_chain.strike, + option_chain["p_Openinterest"] / 1000, + ls="-", + marker="o", + label="Puts", + ) + + ax.axvline(current_price, lw=2, ls="--", label="Current Price", alpha=0.7) + ax.set_xlabel("Strike Price") + ax.set_ylabel("Open Interest (1k) ") + ax.set_xlim(min_strike, max_strike) + ax.legend(loc="best") + ax.set_title(f"Open Interest for {symbol.upper()} expiring {expiration}") + + theme.style_primary_axis(ax) + if external_axes is None: + theme.visualize_output() + + if raw: + to_print = option_chain[["c_Openinterest", "strike", "p_Openinterest"]] + + print_rich_table( + to_print[(to_print.strike < max_strike) & (to_print.strike > min_strike)], + headers=to_print.columns, + title=f"Open Interest for {symbol} expiring on {expiration}.", + ) + + +@log_start_end(log=logger) +def display_volume( + symbol: str, + expiration: str, + min_sp: float = -1, + max_sp: float = -1, + raw: bool = False, + export: str = "", + external_axes: Optional[List[plt.Axes]] = None, +): + """Plot volume + + Parameters + ---------- + symbol: str + Ticker symbol + expiration: str + Expiry date for options + min_sp: float + Min strike to consider + max_sp: float + Max strike to consider + raw:bool + Flag to display raw data + export: str + Format to export file + external_axes : Optional[List[plt.Axes]], optional + External axes (1 axis is expected in the list), by default None + """ + option_chain = nasdaq_model.get_chain_given_expiration(symbol, expiration) + export_data( + export, + os.path.dirname(os.path.abspath(__file__)), + "oi_nasdaq", + option_chain, + ) + current_price = nasdaq_model.get_last_price(symbol) + + if min_sp == -1: + min_strike = 0.75 * current_price + else: + min_strike = min_sp + + if max_sp == -1: + max_strike = 1.25 * current_price + else: + max_strike = max_sp + + if external_axes is None: + _, ax = plt.subplots(figsize=plot_autoscale(), dpi=cfp.PLOT_DPI) + elif is_valid_axes_count(external_axes, 1): + (ax,) = external_axes + else: + return + ax.plot( + option_chain.strike, + option_chain["c_Volume"] / 1000, + ls="-", + marker="o", + label="Calls", + ) + ax.plot( + option_chain.strike, + option_chain["p_Volume"] / 1000, + ls="-", + marker="o", + label="Puts", + ) + + ax.axvline(current_price, lw=2, ls="--", label="Current Price", alpha=0.7) + ax.set_xlabel("Strike Price") + ax.set_ylabel("Volume (1k) ") + ax.set_xlim(min_strike, max_strike) + ax.legend(loc="best") + ax.set_title(f"Volume for {symbol.upper()} expiring {expiration}") + + theme.style_primary_axis(ax) + if external_axes is None: + theme.visualize_output() + + if raw: + to_print = option_chain[["c_Volume", "strike", "p_Volume"]] + + print_rich_table( + to_print[(to_print.strike < max_strike) & (to_print.strike > min_strike)], + headers=to_print.columns, + title=f"Volume for {symbol} expiring on {expiration}.", + ) + + +@log_start_end(log=logger) +def display_volume_and_oi( + symbol: str, + expiration: str, + min_sp: float = -1, + max_sp: float = -1, + raw: bool = False, + export: str = "", + external_axes: Optional[List[plt.Axes]] = None, +): + """Plot volume and open interest + + Parameters + ---------- + symbol: str + Ticker symbol + expiration: str + Expiry date for options + min_sp: float + Min strike to consider + max_sp: float + Max strike to consider + raw:bool + Flag to display raw data + export: str + Format to export file + external_axes : Optional[List[plt.Axes]], optional + External axes (1 axis is expected in the list), by default None + """ + option_chain = nasdaq_model.get_chain_given_expiration(symbol, expiration) + export_data( + export, + os.path.dirname(os.path.abspath(__file__)), + "voi_nasdaq", + option_chain, + ) + current_price = nasdaq_model.get_last_price(symbol) + + if min_sp == -1: + min_strike = 0.75 * current_price + else: + min_strike = min_sp + + if max_sp == -1: + max_strike = 1.25 * current_price + else: + max_strike = max_sp + + if raw: + to_print = option_chain[ + ["c_Openinterest", "c_Volume", "strike", "p_Volume", "p_Openinterest"] + ] + + print_rich_table( + to_print[(to_print.strike < max_strike) & (to_print.strike > min_strike)], + headers=to_print.columns, + title=f"Volume and Open Interest for {symbol} expiring on {expiration}.", + ) + + option_chain = option_chain.copy()[ + ["c_Volume", "c_Openinterest", "strike", "p_Openinterest", "p_Volume"] + ] + option_chain[["p_Openinterest", "p_Volume"]] = ( + option_chain[["p_Openinterest", "p_Volume"]] * -1 / 1000 + ) + option_chain[["c_Openinterest", "c_Volume"]] = ( + option_chain[["c_Openinterest", "c_Volume"]] / 1000 + ) + + if external_axes is None: + _, ax = plt.subplots(figsize=plot_autoscale(), dpi=cfp.PLOT_DPI) + elif is_valid_axes_count(external_axes, 1): + (ax,) = external_axes + else: + return + + ax.bar( + option_chain.strike, + option_chain.c_Openinterest, + color="green", + label="Calls: OI", + ) + ax.bar( + option_chain.strike, + option_chain.c_Volume, + color="lightgreen", + label="Calls: Vol", + ) + + ax.bar( + option_chain.strike, option_chain.p_Openinterest, color="red", label="Puts: OI" + ) + ax.bar(option_chain.strike, option_chain.p_Volume, color="pink", label="Puts:Vol") + + ax.axvline( + current_price, lw=2, ls="--", label=f"Current Price: {current_price}", alpha=0.7 + ) + ax.set_xlabel("Strike Price") + ax.set_ylabel("Volume or OI (1k)") + ax.set_xlim(min_strike, max_strike) + ax.legend(loc="best") + ax.set_title(f"Volume and Open Interest for {symbol.upper()} expiring {expiration}") + + theme.style_primary_axis(ax) + if external_axes is None: + theme.visualize_output() + + +@log_start_end(log=logger) +def display_chains(symbol: str, expiration: str, export: str = ""): + """Display option chain for given expiration + + Parameters + ---------- + symbol: str + Ticker symbol + expiration: str + Expiry date for options + export: str + Format to export data + """ + option_chain = nasdaq_model.get_chain_given_expiration(symbol, expiration) + export_data( + export, + os.path.dirname(os.path.abspath(__file__)), + "chain_nasdaq", + option_chain, + ) + + print_rich_table(option_chain, headers=option_chain.columns) diff --git a/openbb_terminal/stocks/options/op_helpers.py b/openbb_terminal/stocks/options/op_helpers.py index 2af745efcd0..0b2f2c4fad3 100644 --- a/openbb_terminal/stocks/options/op_helpers.py +++ b/openbb_terminal/stocks/options/op_helpers.py @@ -1,8 +1,9 @@ """Option helper functions""" __docformat__ = "numpy" -from math import log, e +from math import e, log from typing import Union + import numpy as np import pandas as pd from scipy.stats import norm @@ -131,9 +132,23 @@ opt_chain_cols = { # pylint: disable=R0903 class Chain: - def __init__(self, df: pd.DataFrame): - self.calls = df[df["option_type"] == "call"] - self.puts = df[df["option_type"] == "put"] + def __init__(self, df: pd.DataFrame, source: str = "tradier"): + if source == "tradier": + self.calls = df[df["option_type"] == "call"] + self.puts = df[df["option_type"] == "put"] + elif source == "nasdaq": + # These guys have different column names + call_columns = ["expiryDate", "strike"] + [ + col for col in df.columns if col.startswith("c_") + ] + put_columns = ["expiryDate", "strike"] + [ + col for col in df.columns if col.startswith("p_") + ] + self.calls = df[call_columns] + self.puts = df[put_columns] + else: + self.calls = None + self.puts = None class Option: diff --git a/openbb_terminal/stocks/options/options_api.py b/openbb_terminal/stocks/options/options_api.py index a6da59f7ed3..4f3e56a4e36 100644 --- a/openbb_terminal/stocks/options/options_api.py +++ b/openbb_terminal/stocks/options/options_api.py @@ -1,31 +1,38 @@ """Options API.""" -import os -from openbb_terminal.helper_classes import ModelsNamespace as _models # flake8: noqa # pylint: disable=unused-import -# Menu commands -from .calculator_view import view_calculator as calc -from .fdscanner_view import display_options as unu + +import os + +from openbb_terminal.helper_classes import ModelsNamespace as _models + from .alphaquery_view import display_put_call_ratio as pcr from .barchart_view import print_options_data as info -from .screen.syncretism_view import view_historical_greeks as grhist + +# Menu commands +from .calculator_view import view_calculator as calc from .chartexchange_view import display_raw as hist_ce -from .tradier_view import display_historical as hist_tr +from .fdscanner_view import display_options as unu +from .screen.syncretism_view import view_historical_greeks as grhist from .tradier_view import display_chains as chains -from .tradier_view import plot_vol as vol_tr -from .yfinance_view import plot_vol as vol_yf -from .tradier_view import plot_volume_open_interest as voi_tr -from .yfinance_view import plot_volume_open_interest as voi_yf -from .tradier_view import plot_oi as oi_tr from .tradier_view import display_expirations as exp +from .tradier_view import display_historical as hist_tr +from .tradier_view import plot_oi as oi_tr +from .tradier_view import plot_vol as vol_tr +from .tradier_view import plot_volume_open_interest as voi_tr +from .yfinance_view import display_vol_surface as vsurf from .yfinance_view import plot_oi as oi_yf from .yfinance_view import plot_plot as plot -from .yfinance_view import show_parity as parity +from .yfinance_view import plot_vol as vol_yf +from .yfinance_view import plot_volume_open_interest as voi_yf from .yfinance_view import show_binom as binom from .yfinance_view import show_greeks as greeks -from .yfinance_view import display_vol_surface as vsurf +from .yfinance_view import show_parity as parity + +# flake8: noqa +# pylint: disable=unused-import # Models diff --git a/openbb_terminal/stocks/options/options_controller.py b/openbb_terminal/stocks/options/options_controller.py index 0ac88bad44a..8e82c0f817b 100644 --- a/openbb_terminal/stocks/options/options_controller.py +++ b/openbb_terminal/stocks/options/options_controller.py @@ -5,7 +5,7 @@ import argparse import logging import os from datetime import datetime, timedelta -from typing import List, Any +from typing import Any, List import pandas as pd from prompt_toolkit.completion import NestedCompleter @@ -17,8 +17,8 @@ from openbb_terminal.helper_funcs import ( EXPORT_BOTH_RAW_DATA_AND_FIGURES, EXPORT_ONLY_FIGURES_ALLOWED, EXPORT_ONLY_RAW_DATA_ALLOWED, - valid_date, get_ordered_list_sources, + valid_date, ) from openbb_terminal.menu import session from openbb_terminal.parent_classes import BaseController @@ -29,18 +29,18 @@ from openbb_terminal.stocks.options import ( calculator_view, chartexchange_view, fdscanner_view, + nasdaq_model, + nasdaq_view, + op_helpers, tradier_model, tradier_view, yfinance_model, yfinance_view, - op_helpers, ) - -from openbb_terminal.stocks.options.pricing import pricing_controller from openbb_terminal.stocks.options.hedge import hedge_controller +from openbb_terminal.stocks.options.pricing import pricing_controller from openbb_terminal.stocks.options.screen import screener_controller, syncretism_view - # pylint: disable=R1710,C0302,R0916 # TODO: HELP WANTED! This controller requires some MVC style refactoring @@ -183,10 +183,12 @@ class OptionsController(BaseController): mt.add_raw("\n") mt.add_cmd("pcr", "AlphaQuery", self.ticker and self.selected_date) mt.add_cmd("info", "Barchart", self.ticker and self.selected_date) - mt.add_cmd("chains", "Tradier", self.ticker and self.selected_date) - mt.add_cmd("oi", "Tradier/YFinance", self.ticker and self.selected_date) - mt.add_cmd("vol", "Tradier/YFinance", self.ticker and self.selected_date) - mt.add_cmd("voi", "Tradier/YFinance", self.ticker and self.selected_date) + mt.add_cmd( + "chains", "Tradier/NASDAQ/Yfinance", self.ticker and self.selected_date + ) + mt.add_cmd("oi", "Tradier/YFinance/NASDAQ", self.ticker and self.selected_date) + mt.add_cmd("vol", "Tradier/YFinance/NASDAQ", self.ticker and self.selected_date) + mt.add_cmd("voi", "Tradier/YFinance/NASDAQ", self.ticker and self.selected_date) mt.add_cmd("hist", "Tradier", self.ticker and self.selected_date) mt.add_cmd("vsurf", "Yfinance", self.ticker and self.selected_date) mt.add_cmd("grhist", "Syncretism", self.ticker and self.selected_date) @@ -539,6 +541,9 @@ class OptionsController(BaseController): if ns_parser.source == "yf": self.source = "yf" self.expiry_dates = yfinance_model.option_expirations(self.ticker) + elif ns_parser.source == "nasdaq": + self.source = "nasdaq" + self.expiry_dates = nasdaq_model.get_expirations(self.ticker) else: self.source = "tradier" self.expiry_dates = tradier_model.option_expirations(self.ticker) @@ -611,6 +616,11 @@ class OptionsController(BaseController): self.chain = yfinance_model.get_option_chain( self.ticker, self.selected_date ) + elif self.source == "nasdaq": + df = nasdaq_model.get_chain_given_expiration( + self.ticker, self.selected_date + ) + self.chain = op_helpers.Chain(df, self.source) else: df = tradier_model.get_option_chains( self.ticker, self.selected_date @@ -776,13 +786,19 @@ class OptionsController(BaseController): elif ns_parser.source == "yf": yfinance_view.display_chains( symbol=self.ticker, - expiry=self.selected_date, + expiration=self.selected_date, min_sp=ns_parser.min_sp, max_sp=ns_parser.max_sp, calls_only=ns_parser.calls, puts_only=ns_parser.puts, export=ns_parser.export, ) + elif ns_parser.source == "nasdaq": + nasdaq_view.display_chains( + symbol=self.ticker, + expiration=self.selected_date, + export=ns_parser.export, + ) else: console.print("No expiry loaded. First use `exp {expiry date}`\n") else: @@ -832,7 +848,8 @@ class OptionsController(BaseController): ns_parser = self.parse_known_args_and_warn( parser, other_args, - EXPORT_BOTH_RAW_DATA_AND_FIGURES, + export_allowed=EXPORT_BOTH_RAW_DATA_AND_FIGURES, + raw=True, ) if ns_parser: if self.ticker: @@ -850,16 +867,27 @@ class OptionsController(BaseController): puts_only=ns_parser.puts, export=ns_parser.export, ) - else: + elif ns_parser.source == "yf": yfinance_view.plot_vol( symbol=self.ticker, - expiry=self.selected_date, + expiration=self.selected_date, min_sp=ns_parser.min, max_sp=ns_parser.max, calls_only=ns_parser.calls, puts_only=ns_parser.puts, export=ns_parser.export, ) + elif ns_parser.source == "nasdaq": + nasdaq_view.display_volume( + symbol=self.ticker, + expiration=self.selected_date, + min_sp=ns_parser.min, + max_sp=ns_parser.max, + export=ns_parser.export, + raw=ns_parser.raw, + ) + else: + return else: console.print("No expiry loaded. First use `exp {expiry date}`\n") else: @@ -899,9 +927,7 @@ class OptionsController(BaseController): help="maximum strike price to consider in the plot.", ) ns_parser = self.parse_known_args_and_warn( - parser, - other_args, - EXPORT_BOTH_RAW_DATA_AND_FIGURES, + parser, other_args, EXPORT_BOTH_RAW_DATA_AND_FIGURES, raw=True ) if ns_parser: if self.ticker: @@ -918,15 +944,26 @@ class OptionsController(BaseController): min_vol=ns_parser.min_vol, export=ns_parser.export, ) - else: + elif ns_parser.source == "yf": yfinance_view.plot_volume_open_interest( symbol=self.ticker, - expiry=self.selected_date, + expiration=self.selected_date, min_sp=ns_parser.min_sp, max_sp=ns_parser.max_sp, min_vol=ns_parser.min_vol, export=ns_parser.export, ) + elif ns_parser.source == "nasdaq": + nasdaq_view.display_volume_and_oi( + symbol=self.ticker, + expiration=self.selected_date, + min_sp=ns_parser.min_sp, + max_sp=ns_parser.max_sp, + raw=ns_parser.raw, + export=ns_parser.export, + ) + else: + pass else: console.print("No expiry loaded. First use `exp {expiry date}`\n") else: @@ -977,7 +1014,8 @@ class OptionsController(BaseController): ns_parser = self.parse_known_args_and_warn( parser, other_args, - EXPORT_BOTH_RAW_DATA_AND_FIGURES, + raw=True, + export_allowed=EXPORT_BOTH_RAW_DATA_AND_FIGURES, ) if ns_parser: if self.ticker: @@ -995,16 +1033,25 @@ class OptionsController(BaseController): puts_only=ns_parser.puts, export=ns_parser.export, ) - else: + elif ns_parser.source == "yf": yfinance_view.plot_oi( symbol=self.ticker, - expiry=self.selected_date, + expiration=self.selected_date, min_sp=ns_parser.min, max_sp=ns_parser.max, calls_only=ns_parser.calls, puts_only=ns_parser.puts, export=ns_parser.export, ) + elif ns_parser.source == "nasdaq": + nasdaq_view.display_oi( + self.ticker, + expiration=self.selected_date, + min_sp=ns_parser.min, + max_sp=ns_parser.max, + export=ns_parser.export, + raw=ns_parser.raw, + ) else: console.print("No expiry loaded. First use `exp {expiry date}`\n") else: @@ -1165,7 +1212,8 @@ class OptionsController(BaseController): help="Maximum strike price to show.", ) parser.add_argument( - "-a" "--all", + "-a", + "--all", dest="all", action="store_true", default=False, @@ -1181,17 +1229,18 @@ class OptionsController(BaseController): elif not self.selected_date: console.print("No expiry loaded. First use `exp {expiry date}`\n") else: - opt_type = -1 if ns_parser.put else 1 - yfinance_view.show_greeks( - symbol=self.ticker, - div_cont=ns_parser.dividend, - expiry=self.selected_date, - rf=ns_parser.risk_free, - opt_type=opt_type, - mini=ns_parser.min, - maxi=ns_parser.max, - show_all=ns_parser.all, - ) + if ns_parser.source == "yf": + opt_type = -1 if ns_parser.put else 1 + yfinance_view.show_greeks( + symbol=self.ticker, + div_cont=ns_parser.dividend, + expiration=self.selected_date, + rf=ns_parser.risk_free, + opt_type=opt_type, + mini=ns_parser.min, + maxi=ns_parser.max, + show_all=ns_parser.all, + ) @log_start_end(log=logger) def call_parity(self, other_args: List[str]): diff --git a/openbb_terminal/stocks/options/pricing/pricing_controller.py b/openbb_terminal/stocks/options/pricing/pricing_controller.py index af31fea2938..3457a51497f 100644 --- a/openbb_terminal/stocks/options/pricing/pricing_controller.py +++ b/openbb_terminal/stocks/options/pricing/pricing_controller.py @@ -13,7 +13,7 @@ from openbb_terminal.decorators import log_start_end from openbb_terminal.helper_funcs import print_rich_table from openbb_terminal.menu import session from openbb_terminal.parent_classes import BaseController -from openbb_terminal.rich_config import console, MenuText +from openbb_terminal.rich_config import MenuText, console from openbb_terminal.stocks.options import yfinance_view logger = logging.getLogger(__name__) diff --git a/openbb_terminal/stocks/options/screen/screener_controller.py b/openbb_terminal/stocks/options/screen/screener_controller.py index d11130ecba0..c5365868ab7 100644 --- a/openbb_terminal/stocks/options/screen/screener_controller.py +++ b/openbb_terminal/stocks/options/screen/screener_controller.py @@ -10,13 +10,10 @@ from prompt_toolkit.completion import NestedCompleter from openbb_terminal import feature_flags as obbff from openbb_terminal.decorators import log_start_end -from openbb_terminal.helper_funcs import ( - EXPORT_ONLY_RAW_DATA_ALLOWED, - check_positive, -) +from openbb_terminal.helper_funcs import EXPORT_ONLY_RAW_DATA_ALLOWED, check_positive from openbb_terminal.menu import session from openbb_terminal.parent_classes import BaseController -from openbb_terminal.rich_config import console, MenuText +from openbb_terminal.rich_config import MenuText, console from openbb_terminal.stocks.comparison_analysis import ca_controller from openbb_terminal.stocks.options.screen import syncretism_view diff --git a/openbb_terminal/stocks/options/screen/syncretism_view.py b/openbb_terminal/stocks/options/screen/syncretism_view.py index ac88f9aec84..993c07dacd7 100644 --- a/openbb_terminal/stocks/options/screen/syncretism_view.py +++ b/openbb_terminal/stocks/options/screen/syncretism_view.py @@ -8,14 +8,14 @@ from typing import List, Optional import matplotlib.pyplot as plt -from openbb_terminal.config_terminal import theme from openbb_terminal import config_plot as cfp +from openbb_terminal.config_terminal import theme from openbb_terminal.decorators import log_start_end from openbb_terminal.helper_funcs import ( export_data, + is_valid_axes_count, plot_autoscale, print_rich_table, - is_valid_axes_count, ) from openbb_terminal.rich_config import console from openbb_terminal.stocks.options.screen import syncretism_model diff --git a/openbb_terminal/stocks/options/tradier_view.py b/openbb_terminal/stocks/options/tradier_view.py index b3a65c8be5a..8c46502896a 100644 --- a/openbb_terminal/stocks/options/tradier_view.py +++ b/openbb_terminal/stocks/options/tradier_view.py @@ -1,10 +1,10 @@ """Tradier options view""" __docformat__ = "numpy" -import warnings import argparse import logging import os +import warnings from bisect import bisect_left from typing import List, Optional, Tuple @@ -14,20 +14,20 @@ import numpy as np import pandas as pd import seaborn as sns -from openbb_terminal.config_terminal import theme from openbb_terminal import config_plot as cfp +from openbb_terminal import rich_config +from openbb_terminal.config_terminal import theme from openbb_terminal.decorators import log_start_end from openbb_terminal.helper_funcs import ( export_data, + is_valid_axes_count, + lambda_long_number_format_y_axis, patch_pandas_text_adjustment, plot_autoscale, print_rich_table, - lambda_long_number_format_y_axis, - is_valid_axes_count, ) from openbb_terminal.rich_config import console from openbb_terminal.stocks.options import op_helpers, tradier_model, yfinance_model -from openbb_terminal import rich_config logger = logging.getLogger(__name__) diff --git a/openbb_terminal/stocks/options/yfinance_model.py b/openbb_terminal/stocks/options/yfinance_model.py index ef7e4be642f..5149f2a7dd3 100644 --- a/openbb_terminal/stocks/options/yfinance_model.py +++ b/openbb_terminal/stocks/options/yfinance_model.py @@ -1,19 +1,19 @@ """Yfinance options model""" __docformat__ = "numpy" -import warnings import logging import math -from datetime import datetime, date, timedelta +import warnings +from datetime import date, datetime, timedelta from typing import Any, Dict, List, Tuple import pandas as pd import yfinance as yf -from openbb_terminal.stocks.options.op_helpers import Option from openbb_terminal.decorators import log_start_end from openbb_terminal.helper_funcs import get_rf from openbb_terminal.rich_config import console +from openbb_terminal.stocks.options.op_helpers import Option logger = logging.getLogger(__name__) diff --git a/openbb_terminal/stocks/options/yfinance_view.py b/openbb_terminal/stocks/options/yfinance_view.py index 26f3a2735d5..32fe712409c 100644 --- a/openbb_terminal/stocks/options/yfinance_view.py +++ b/openbb_terminal/stocks/options/yfinance_view.py @@ -3,9 +3,9 @@ __docformat__ = "numpy" import logging import os +import re from bisect import bisect_left from datetime import date, datetime, timedelta -import re from typing import Any, Dict, List, Optional import matplotlib.dates as mdates @@ -18,17 +18,17 @@ import yfinance as yf from openpyxl import Workbook from scipy.stats import binom -from openbb_terminal.config_terminal import theme -from openbb_terminal.config_plot import PLOT_DPI import openbb_terminal.config_plot as cfp +from openbb_terminal.config_plot import PLOT_DPI +from openbb_terminal.config_terminal import theme from openbb_terminal.decorators import log_start_end from openbb_terminal.helper_funcs import ( excel_columns, export_data, get_rf, + is_valid_axes_count, plot_autoscale, print_rich_table, - is_valid_axes_count, ) from openbb_terminal.rich_config import console from openbb_terminal.stocks.options import op_helpers, yfinance_model @@ -70,7 +70,7 @@ def header_fmt(header: str) -> str: @log_start_end(log=logger) def display_chains( symbol: str, - expiry: str, + expiration: str, min_sp: float = 0.0, max_sp: float = np.inf, calls_only: bool = False, @@ -83,7 +83,7 @@ def display_chains( ---------- symbol: str Stock ticker symbol - expiry: str + expiration: str Expiration for option chain min_sp: float Min strike @@ -108,7 +108,7 @@ def display_chains( put_bool = True option_chains = yfinance_model.get_full_option_chain( - symbol=symbol, expiration=expiry, calls=call_bool, puts=put_bool + symbol=symbol, expiration=expiration, calls=call_bool, puts=put_bool ).fillna("-") if option_chains.empty: console.print("[red]Option chains not found.[/red]") @@ -231,7 +231,7 @@ def display_chains( print_rich_table( option_chains, - title=f"Yahoo Option Chain (15 min delayed) for {expiry} (Greeks calculated by OpenBB)", + title=f"Yahoo Option Chain (15 min delayed) for {expiration} (Greeks calculated by OpenBB)", headers=[header_fmt(x) for x in option_chains.columns], ) export_data( @@ -245,7 +245,7 @@ def display_chains( @log_start_end(log=logger) def plot_oi( symbol: str, - expiry: str, + expiration: str, min_sp: float = -1, max_sp: float = -1, calls_only: bool = False, @@ -259,8 +259,8 @@ def plot_oi( ---------- symbol: str Ticker symbol - expiry: str - Expiry date for options + expiration: str + expiration date for options min_sp: float Min strike to consider max_sp: float @@ -274,7 +274,7 @@ def plot_oi( external_axes : Optional[List[plt.Axes]], optional External axes (1 axis is expected in the list), by default None """ - options = yfinance_model.get_option_chain(symbol, expiry) + options = yfinance_model.get_option_chain(symbol, expiration) export_data( export, os.path.dirname(os.path.abspath(__file__)), @@ -339,7 +339,7 @@ def plot_oi( ax.set_ylabel("Open Interest [1k] ") ax.set_xlim(min_strike, max_strike) ax.legend() - ax.set_title(f"Open Interest for {symbol.upper()} expiring {expiry}") + ax.set_title(f"Open Interest for {symbol.upper()} expiring {expiration}") theme.style_primary_axis(ax) @@ -350,7 +350,7 @@ def plot_oi( @log_start_end(log=logger) def plot_vol( symbol: str, - expiry: str, + expiration: str, min_sp: float = -1, max_sp: float = -1, calls_only: bool = False, @@ -364,8 +364,8 @@ def plot_vol( ---------- symbol: str Ticker symbol - expiry: str - Expiry date for options + expiration: str + expiration date for options min_sp: float Min strike to consider max_sp: float @@ -379,7 +379,7 @@ def plot_vol( external_axes : Optional[List[plt.Axes]], optional External axes (1 axis is expected in the list), by default None """ - options = yfinance_model.get_option_chain(symbol, expiry) + options = yfinance_model.get_option_chain(symbol, expiration) calls = options.calls puts = options.puts @@ -431,7 +431,7 @@ def plot_vol( ax.set_ylabel("Volume [1k] ") ax.set_xlim(min_strike, max_strike) ax.legend() - ax.set_title(f"Volume for {symbol.upper()} expiring {expiry}") + ax.set_title(f"Volume for {symbol.upper()} expiring {expiration}") theme.style_primary_axis(ax) if external_axes is None: @@ -447,7 +447,7 @@ def plot_vol( @log_start_end(log=logger) def plot_volume_open_interest( symbol: str, - expiry: str, + expiration: str, min_sp: float = -1, max_sp: float = -1, min_vol: float = -1, @@ -460,7 +460,7 @@ def plot_volume_open_interest( ---------- symbol: str Stock ticker symbol - expiry: str + expiration: str Option expiration min_sp: float Min strike price @@ -474,7 +474,7 @@ def plot_volume_open_interest( External axes (1 axis is expected in the list), by default None """ - options = yfinance_model.get_option_chain(symbol, expiry) + options = yfinance_model.get_option_chain(symbol, expiration) calls = options.calls puts = options.puts @@ -604,7 +604,7 @@ def plot_volume_open_interest( g.set_xticklabels(xlabels) ax.set_title( - f"{symbol} volumes for {expiry} \n(open interest displayed only during market hours)", + f"{symbol} volumes for {expiration} \n(open interest displayed only during market hours)", ) ax.invert_yaxis() @@ -640,7 +640,7 @@ def plot_volume_open_interest( @log_start_end(log=logger) def plot_plot( symbol: str, - expiry: str, + expiration: str, put: bool = False, x: str = "s", y: str = "iv", @@ -654,7 +654,7 @@ def plot_plot( ---------- symbol: str Stock ticker symbol - expiry: str + expiration: str Option expiration x: str variable to display in x axis, choose from: @@ -690,7 +690,7 @@ def plot_plot( x = convert[x] y = convert[y] varis = op_helpers.opt_chain_cols - chain = yfinance_model.get_option_chain(symbol, expiry) + chain = yfinance_model.get_option_chain(symbol, expiration) values = chain.puts if put else chain.calls if external_axes is None: @@ -705,7 +705,7 @@ def plot_plot( ax.plot(x_data, y_data, "--bo") option = "puts" if put else "calls" ax.set_title( - f"{varis[y]['label']} vs. {varis[x]['label']} for {symbol} {option} on {expiry}" + f"{varis[y]['label']} vs. {varis[x]['label']} for {symbol} {option} on {expiration}" ) ax.set_ylabel(varis[y]["label"]) ax.set_xlabel(varis[x]["label"]) @@ -732,7 +732,7 @@ def plot_payoff( options: List[Dict[Any, Any]], underlying: float, symbol: str, - expiry: str, + expiration: str, external_axes: Optional[List[plt.Axes]] = None, ) -> None: """Generate a graph showing the option payoff diagram""" @@ -750,7 +750,7 @@ def plot_payoff( ax.plot(x, ya, label="Payoff After Premium") else: ax.plot(x, yb, label="Payoff") - ax.set_title(f"Option Payoff Diagram for {symbol} on {expiry}") + ax.set_title(f"Option Payoff Diagram for {symbol} on {expiration}") ax.set_ylabel("Profit") ax.set_xlabel("Underlying Asset Price at Expiration") ax.legend() @@ -765,7 +765,7 @@ def plot_payoff( @log_start_end(log=logger) def show_parity( symbol: str, - expiry: str, + expiration: str, put: bool = False, ask: bool = False, mini: float = None, @@ -778,7 +778,7 @@ def show_parity( ---------- symbol : str Ticker symbol to get expirations for - expiry : str + expiration : str Expiration to use for options put : bool Whether to use puts or calls @@ -791,7 +791,7 @@ def show_parity( export : str Export data """ - r_date = datetime.strptime(expiry, "%Y-%m-%d").date() + r_date = datetime.strptime(expiration, "%Y-%m-%d").date() delta = (r_date - date.today()).days rate = ((1 + get_rf()) ** (delta / 365)) - 1 stock = get_price(symbol) @@ -809,7 +809,7 @@ def show_parity( next_div = last_div + timedelta(days=91) dividends = [] - while next_div < datetime.strptime(expiry, "%Y-%m-%d"): + while next_div < datetime.strptime(expiration, "%Y-%m-%d"): day_dif = (next_div - datetime.now()).days dividends.append((avg_div, day_dif)) next_div += timedelta(days=91) @@ -818,7 +818,7 @@ def show_parity( else: pv_dividend = 0 - chain = get_option_chain(symbol, expiry) + chain = get_option_chain(symbol, expiration) name = "ask" if ask else "lastPrice" o_type = "put" if put else "call" @@ -1050,7 +1050,7 @@ def export_binomial_calcs( @log_start_end(log=logger) def show_binom( symbol: str, - expiry: str, + expiration: str, strike: float = 0, put: bool = False, europe: bool = False, @@ -1064,7 +1064,7 @@ def show_binom( ---------- symbol : str The ticker symbol of the option's underlying asset - expiry : str + expiration : str The expiration for the option strike : float The strike price for the option @@ -1080,18 +1080,18 @@ def show_binom( The annualized volatility for the underlying asset """ up, prob_up, discount, und_vals, opt_vals, days = yfinance_model.get_binom( - symbol, expiry, strike, put, europe, vol + symbol, expiration, strike, put, europe, vol ) if export: export_binomial_calcs(up, prob_up, discount, und_vals, opt_vals, days, symbol) if plot: - plot_expected_prices(und_vals, prob_up, symbol, expiry) + plot_expected_prices(und_vals, prob_up, symbol, expiration) option = "put" if put else "call" console.print( - f"{symbol} {option} at ${strike:.2f} expiring on {expiry} is worth ${opt_vals[0][0]:.2f}\n" + f"{symbol} {option} at ${strike:.2f} expiring on {expiration} is worth ${opt_vals[0][0]:.2f}\n" ) @@ -1155,7 +1155,7 @@ def display_vol_surface( @log_start_end(log=logger) def show_greeks( symbol: str, - expiry: str, + expiration: str, div_cont: float = 0, rf: float = None, opt_type: int = 1, @@ -1172,7 +1172,7 @@ def show_greeks( The ticker symbol value of the option div_cont: float The dividend continuous rate - expiry: str + expiration: str The date of expiration, format "YYYY-MM-DD", i.e. 2010-12-31. rf: float The risk-free rate @@ -1187,7 +1187,7 @@ def show_greeks( """ df = yfinance_model.get_greeks( - symbol, expiry, div_cont, rf, opt_type, mini, maxi, show_all + symbol, expiration, div_cont, rf, opt_type, mini, maxi, show_all ) column_formatting = [ diff --git a/tests/openbb_terminal/stocks/options/test_yfinance_view.py b/tests/openbb_terminal/stocks/options/test_yfinance_view.py index f48b3338324..663a2858424 100644 --- a/tests/openbb_terminal/stocks/options/test_yfinance_view.py +++ b/tests/openbb_terminal/stocks/options/test_yfinance_view.py @@ -38,7 +38,7 @@ def test_plot_oi(calls_only, max_sp, min_sp, mocker, puts_only): yfinance_view.plot_oi( symbol="PM", - expiry="2022-01-07", + expiration="2022-01-07", min_sp=min_sp, max_sp=max_sp, calls_only=calls_only, @@ -67,7 +67,7 @@ def test_plot_vol(calls_only, max_sp, min_sp, mocker, puts_only): yfinance_view.plot_vol( symbol="PM", - expiry="2022-01-07", + expiration="2022-01-07", min_sp=min_sp, max_sp=max_sp, calls_only=calls_only, @@ -96,7 +96,7 @@ def test_plot_volume_open_interest(max_sp, min_sp, min_vol, mocker): yfinance_view.plot_volume_open_interest( symbol="PM", - expiry="2022-01-07", + expiration="2022-01-07", min_sp=min_sp, max_sp=max_sp, min_vol=min_vol, @@ -117,7 +117,7 @@ def test_plot_plot(mocker): yfinance_view.plot_plot( symbol="PM", - expiry="2022-01-07", + expiration="2022-01-07", put=True, x="c", y="v", @@ -142,7 +142,7 @@ def test_plot_payoff(mocker): options=[], underlying=0, symbol="PM", - expiry="2022-06-05", + expiration="2022-06-05", ) @@ -159,7 +159,7 @@ def test_show_parity(mocker): yfinance_view.show_parity( symbol="PM", - expiry="2022-01-07", + expiration="2022-01-07", put=True, ask=True, mini=0.0, @@ -206,7 +206,7 @@ def test_show_binom(mocker): yfinance_view.show_binom( symbol="PM", - expiry="2022-01-07", + expiration="2022-01-07", strike=90.0, put=True, europe=False, @@ -219,12 +219,12 @@ def test_show_binom(mocker): @pytest.mark.default_cassette("test_show_greeks") @pytest.mark.vcr def test_show_greeks(): - yfinance_view.show_greeks(symbol="AAPL", expiry="2022-01-28", div_cont=0) + yfinance_view.show_greeks(symbol="AAPL", expiration="2022-01-28", div_cont=0) @pytest.mark.default_cassette("test_display_chains") @pytest.mark.vcr def test_display_chains(): yfinance_view.display_chains( - symbol="AAPL", expiry="2022-07-29", min_sp=-1, max_sp=-1 + symbol="AAPL", expiration="2022-07-29", min_sp=-1, max_sp=-1 ) diff --git a/tests/openbb_terminal/stocks/options/txt/test_options_controller/test_print_help.txt b/tests/openbb_terminal/stocks/options/txt/test_options_controller/test_print_help.txt index ee34a023150..99bf0097384 100644 --- a/tests/openbb_terminal/stocks/options/txt/test_options_controller/test_print_help.txt +++ b/tests/openbb_terminal/stocks/options/txt/test_options_controller/test_print_help.txt @@ -11,10 +11,10 @@ Expiry: [unvl] pcr display put call ratio for ticker[/unvl] [AlphaQuery] [unvl] info display option information (volatility, IV rank etc)[/unvl] [Barchart] -[unvl] chains display option chains with greeks[/unvl] [Tradier] -[unvl] oi plot open interest[/unvl] [Tradier/YFinance] -[unvl] vol plot volume[/unvl] [Tradier/YFinance] -[unvl] voi plot volume and open interest[/unvl] [Tradier/YFinance] +[unvl] chains display option chains with greeks[/unvl] [Tradier/NASDAQ/Yfinance] +[unvl] oi plot open interest[/unvl] [Tradier/YFinance/NASDAQ] +[unvl] vol plot volume[/unvl] [Tradier/YFinance/NASDAQ] +[unvl] voi plot volume and open interest[/unvl] [Tradier/YFinance/NASDAQ] [unvl] hist plot option history[/unvl] [Tradier] [unvl] vsurf show 3D volatility surface[/unvl] [Yfinance] [unvl] grhist plot option greek history[/unvl] [Syncretism]