mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-28 21:12:16 +00:00
Merge branch 'develop' into hotfix/issue4212
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user