Merge branch 'develop' into hotfix/issue4212

This commit is contained in:
James Maslek
2023-02-26 15:13:57 -05:00
committed by GitHub
6 changed files with 112 additions and 15 deletions

View File

@@ -1,5 +1,4 @@
# IMPORTATION STANDARD
import os
import uuid
from pathlib import Path
@@ -14,25 +13,23 @@ from openbb_terminal.core.config.paths import USER_DATA_DIRECTORY
def get_log_dir() -> Path:
"""Retrieve application's log directory."""
log_dir = USER_DATA_DIRECTORY.joinpath("logs")
log_dir = USER_DATA_DIRECTORY.joinpath("logs").absolute()
if not os.path.isdir(log_dir.absolute()):
os.mkdir(log_dir.absolute())
if not log_dir.is_dir():
log_dir.mkdir(parents=True, exist_ok=True)
log_id = log_dir.absolute().joinpath(".logid")
log_id = (log_dir / ".logid").absolute()
if not os.path.isfile(log_id.absolute()):
if not log_id.is_file():
logging_id = f"{uuid.uuid4()}"
with open(log_id.absolute(), "a") as a_file:
a_file.write(f"{logging_id}\n")
log_id.write_text(logging_id, encoding="utf-8")
else:
with open(log_id.absolute()) as a_file:
logging_id = a_file.readline().rstrip()
logging_id = log_id.read_text(encoding="utf-8").rstrip()
uuid_log_dir = log_dir.absolute().joinpath(logging_id)
uuid_log_dir = (log_dir / logging_id).absolute()
if not os.path.isdir(uuid_log_dir.absolute()):
os.mkdir(uuid_log_dir.absolute())
if not uuid_log_dir.is_dir():
uuid_log_dir.mkdir(parents=True, exist_ok=True)
return uuid_log_dir

View File

@@ -37,7 +37,8 @@ logger = logging.getLogger(__name__)
forex_data_path = os.path.join(
os.path.dirname(__file__), os.path.join("data", "polygon_tickers.csv")
)
FX_TICKERS = pd.read_csv(forex_data_path).iloc[:, 0].to_list()
tickers = pd.read_csv(forex_data_path).iloc[:, 0].to_list()
FX_TICKERS = list(set(tickers + [t[-3:] + t[:3] for t in tickers if len(t) == 6]))
class ForexController(BaseController):
@@ -73,7 +74,6 @@ class ForexController(BaseController):
if session and obbff.USE_PROMPT_TOOLKIT:
choices: dict = self.choices_default
choices["load"].update({c: {} for c in FX_TICKERS})
self.completer = NestedCompleter.from_nested_dict(choices)

View File

@@ -478,6 +478,7 @@ stocks.options.dte,openbb_terminal.stocks.options.yfinance_model.get_dte,
stocks.options.eodchain,openbb_terminal.stocks.options.intrinio_model.get_full_chain_eod,
stocks.options.expirations,openbb_terminal.stocks.options.options_sdk_helper.get_option_expirations,
stocks.options.generate_data,openbb_terminal.stocks.options.yfinance_model.generate_data,
stocks.options.greeks,openbb_terminal.stocks.options.options_sdk_helper.get_greeks,
stocks.options.grhist,openbb_terminal.stocks.options.screen.syncretism_model.get_historical_greeks,openbb_terminal.stocks.options.screen.syncretism_view.view_historical_greeks
stocks.options.hist,openbb_terminal.stocks.options.options_sdk_helper.hist,
stocks.options.info,openbb_terminal.stocks.options.barchart_model.get_options_info,openbb_terminal.stocks.options.barchart_view.print_options_data
1 trail model view
478 stocks.options.eodchain openbb_terminal.stocks.options.intrinio_model.get_full_chain_eod
479 stocks.options.expirations openbb_terminal.stocks.options.options_sdk_helper.get_option_expirations
480 stocks.options.generate_data openbb_terminal.stocks.options.yfinance_model.generate_data
481 stocks.options.greeks openbb_terminal.stocks.options.options_sdk_helper.get_greeks
482 stocks.options.grhist openbb_terminal.stocks.options.screen.syncretism_model.get_historical_greeks openbb_terminal.stocks.options.screen.syncretism_view.view_historical_greeks
483 stocks.options.hist openbb_terminal.stocks.options.options_sdk_helper.hist
484 stocks.options.info openbb_terminal.stocks.options.barchart_model.get_options_info openbb_terminal.stocks.options.barchart_view.print_options_data

View File

@@ -271,6 +271,7 @@ class StocksController(model.StocksRoot):
`eodchain`: Get full EOD option date across all expirations\n
`expirations`: Get Option Chain Expirations\n
`generate_data`: Gets x values, and y values before and after premiums\n
`greeks`: Gets the greeks for a given option\n
`grhist`: Get historical option greeks\n
`grhist_chart`: Plots historical greeks for a given option. [Source: Syncretism]\n
`hist`: Get historical option pricing.\n

View File

@@ -491,6 +491,7 @@ class StocksOptions(Category):
self.eodchain = lib.stocks_options_intrinio_model.get_full_chain_eod
self.expirations = lib.stocks_options_sdk_helper.get_option_expirations
self.generate_data = lib.stocks_options_yfinance_model.generate_data
self.greeks = lib.stocks_options_sdk_helper.get_greeks
self.grhist = lib.stocks_options_screen_syncretism_model.get_historical_greeks
self.grhist_chart = (
lib.stocks_options_screen_syncretism_view.view_historical_greeks

View File

@@ -1,6 +1,7 @@
"""Options Functions For OpenBB SDK"""
import logging
from datetime import datetime, timedelta
from typing import Optional, Union
import numpy as np
@@ -8,6 +9,7 @@ import pandas as pd
from scipy.optimize import minimize
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 import (
chartexchange_model,
@@ -17,6 +19,7 @@ from openbb_terminal.stocks.options import (
tradier_model,
yfinance_model,
)
from openbb_terminal.stocks.options.op_helpers import Option
logger = logging.getLogger(__name__)
@@ -235,3 +238,97 @@ def get_delta_neutral(symbol: str, date: str, x0: Optional[float] = None) -> flo
"Error getting delta neutral price for %s on %s: error:%s", symbol, date, e
)
return np.nan
def get_greeks(
current_price: float,
chain: pd.DataFrame,
expire: str,
div_cont: float = 0,
rf: Optional[float] = None,
) -> pd.DataFrame:
"""
Gets the greeks for a given option
Parameters
----------
current_price: float
The current price of the underlying
chain: pd.DataFrame
The dataframe with option chains
div_cont: float
The dividend continuous rate
expire: str
The date of expiration
rf: float
The risk-free rate
Returns
-------
pd.DataFrame
Dataframe with calculated option greeks
Examples
--------
>>> from openbb_terminal.sdk import openbb
>>> aapl_chain = openbb.stocks.options.chains("AAPL", source="Tradier")
>>> aapl_last_price = openbb.stocks.options.last_price("AAPL")
>>> greeks = openbb.stocks.options.greeks(aapl_last_price, aapl_chain, aapl_chain.iloc[0, 2])
"""
chain = chain.rename(columns={"iv": "impliedVolatility"})
chain_columns = chain.columns.tolist()
if not all(
col in chain_columns for col in ["strike", "impliedVolatility", "optionType"]
):
if "delta" not in chain_columns:
console.print(
"[red]It's not possible to calculate the greeks without the following "
"columns: `strike`, `impliedVolatility`, `optionType`.\n[/red]"
)
return pd.DataFrame()
risk_free = rf if rf is not None else get_rf()
expire_dt = datetime.strptime(expire, "%Y-%m-%d")
dif = (expire_dt - datetime.now() + timedelta(hours=16)).total_seconds() / (
60 * 60 * 24
)
strikes = []
for _, row in chain.iterrows():
vol = row["impliedVolatility"]
opt_type = 1 if row["optionType"] == "call" else -1
opt = Option(
current_price, row["strike"], risk_free, div_cont, dif, vol, opt_type
)
tmp = [
opt.Delta(),
opt.Gamma(),
opt.Vega(),
opt.Theta(),
opt.Rho(),
opt.Phi(),
opt.Charm(),
opt.Vanna(0.01),
opt.Vomma(0.01),
]
result = [row[col] for col in row.index.tolist()]
result += tmp
strikes.append(result)
greek_columns = [
"Delta",
"Gamma",
"Vega",
"Theta",
"Rho",
"Phi",
"Charm",
"Vanna",
"Vomma",
]
columns = chain_columns + greek_columns
df = pd.DataFrame(strikes, columns=columns)
return df