mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-28 04:52:07 +00:00
Added ChartExchange as source option (#829)
* Added chartexchange source * Fixed black * Didier updates * Updated * James changes * Small fixes * Adding updates Co-authored-by: Colin Delahunty <colindelahunty@Colins-Air.indiana.edu> Co-authored-by: Colin Delahunty <colindelahunty@Colins-MacBook-Air.local>
This commit is contained in:
60
gamestonk_terminal/options/chartexchange_model.py
Normal file
60
gamestonk_terminal/options/chartexchange_model.py
Normal file
@@ -0,0 +1,60 @@
|
||||
"""Chartexchange model"""
|
||||
__docformat__ = "numpy"
|
||||
|
||||
import requests
|
||||
import pandas as pd
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
from gamestonk_terminal.options.op_helpers import convert
|
||||
|
||||
|
||||
def get_option_history(ticker: str, date: str, call: bool, price: str) -> pd.DataFrame:
|
||||
"""Historic prices for a specific option [chartexchange]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ticker : str
|
||||
Ticker to get historical data from
|
||||
date : str
|
||||
Date as a string YYYYMMDD
|
||||
call : bool
|
||||
Whether to show a call or a put
|
||||
price : str
|
||||
Strike price for a specific option
|
||||
|
||||
Returns
|
||||
-------
|
||||
historical : pd.Dataframe
|
||||
Historic information for an option
|
||||
"""
|
||||
url = (
|
||||
f"https://chartexchange.com/symbol/opra-{ticker.lower()}{date.replace('-', '')}"
|
||||
)
|
||||
url += f"{'c' if call else 'p'}{float(price):g}/historical/"
|
||||
|
||||
data = requests.get(url, headers={"User-Agent": "test"}).content
|
||||
soup = BeautifulSoup(data, "html.parser")
|
||||
table = soup.find("div", attrs={"style": "display: table; font-size: 0.9em; "})
|
||||
rows = table.find_all("div", attrs={"style": "display: table-row;"})
|
||||
clean_rows = []
|
||||
|
||||
if rows:
|
||||
for row in rows[1:]:
|
||||
item = row.find_all("div")
|
||||
clean_rows.append([x.text for x in item])
|
||||
else:
|
||||
print("No data for this option\n")
|
||||
return pd.DataFrame()
|
||||
|
||||
df = pd.DataFrame()
|
||||
df["Date"] = [x[0] for x in clean_rows]
|
||||
df["Open"] = [convert(x[1], ",") for x in clean_rows]
|
||||
df["High"] = [convert(x[2], ",") for x in clean_rows]
|
||||
df["Low"] = [convert(x[3], ",") for x in clean_rows]
|
||||
df["Close"] = [convert(x[4], ",") for x in clean_rows]
|
||||
df["Change"] = [convert(x[5], "%") for x in clean_rows]
|
||||
df["Volume"] = [convert(x[6], ",") for x in clean_rows]
|
||||
df["Open Interest"] = [convert(x[7], ",") for x in clean_rows]
|
||||
df["Change Since"] = [convert(x[8], "%") for x in clean_rows]
|
||||
|
||||
return df
|
||||
56
gamestonk_terminal/options/chartexchange_view.py
Normal file
56
gamestonk_terminal/options/chartexchange_view.py
Normal file
@@ -0,0 +1,56 @@
|
||||
"""Chartexchange view"""
|
||||
__docformat__ = "numpy"
|
||||
|
||||
import os
|
||||
|
||||
from tabulate import tabulate
|
||||
|
||||
from gamestonk_terminal.helper_funcs import export_data
|
||||
from gamestonk_terminal import feature_flags as gtff
|
||||
from gamestonk_terminal.options import chartexchange_model
|
||||
|
||||
|
||||
def display_raw(
|
||||
export: str, ticker: str, date: str, call: bool, price: str, num: int = 20
|
||||
) -> None:
|
||||
"""Return raw stock data[chartexchange]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
export : str
|
||||
Export data as CSV, JSON, XLSX
|
||||
ticker : str
|
||||
Ticker for the given option
|
||||
date : str
|
||||
Date of expiration for the option
|
||||
call : bool
|
||||
Whether the underlying asset should be a call or a put
|
||||
price : float
|
||||
The stike of the expiration
|
||||
num : int
|
||||
Number of rows to show
|
||||
"""
|
||||
|
||||
df = chartexchange_model.get_option_history(ticker, date, call, price)
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"hist",
|
||||
df,
|
||||
)
|
||||
|
||||
if gtff.USE_TABULATE_DF:
|
||||
print(
|
||||
tabulate(
|
||||
df.head(num),
|
||||
headers=df.columns,
|
||||
tablefmt="fancy_grid",
|
||||
showindex=True,
|
||||
floatfmt=".2f",
|
||||
)
|
||||
)
|
||||
else:
|
||||
print(df.to_string(index=False))
|
||||
|
||||
print("")
|
||||
@@ -62,6 +62,26 @@ def calculate_max_pain(chain: pd.DataFrame) -> int:
|
||||
return max_pain
|
||||
|
||||
|
||||
def convert(orig: str, to: str) -> float:
|
||||
"""Convert a string to a specific type of number
|
||||
Parameters
|
||||
----------
|
||||
orig: str
|
||||
String to convert
|
||||
Returns
|
||||
-------
|
||||
number : float
|
||||
Decimal value of string
|
||||
"""
|
||||
if to == "%":
|
||||
clean = orig.replace("%", "").replace("+", "")
|
||||
return float(clean) / 100
|
||||
if to == ",":
|
||||
clean = orig.replace(",", "")
|
||||
return float(clean)
|
||||
raise ValueError("Invalid to format, please use '%' or ','.")
|
||||
|
||||
|
||||
opt_chain_cols = {
|
||||
"lastTradeDate": {"format": "date", "label": "Last Trade Date"},
|
||||
"strike": {"format": "${x:.2f}", "label": "Strike"},
|
||||
|
||||
@@ -30,7 +30,7 @@ from gamestonk_terminal.options import (
|
||||
yfinance_view,
|
||||
)
|
||||
from gamestonk_terminal.stocks import stocks_controller
|
||||
from gamestonk_terminal.options import payoff_controller
|
||||
from gamestonk_terminal.options import payoff_controller, chartexchange_view
|
||||
|
||||
|
||||
class OptionsController:
|
||||
@@ -631,7 +631,7 @@ Current Expiry: {self.selected_date or None}
|
||||
"--strike",
|
||||
dest="strike",
|
||||
type=float,
|
||||
required="--chain" not in other_args or "-h" not in other_args,
|
||||
required="--chain" not in other_args and "-h" not in other_args,
|
||||
help="Strike price to look at",
|
||||
)
|
||||
parser.add_argument(
|
||||
@@ -660,6 +660,21 @@ Current Expiry: {self.selected_date or None}
|
||||
dest="export",
|
||||
help="Export dataframe data to csv,json,xlsx file",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--source",
|
||||
dest="source",
|
||||
type=str,
|
||||
choices=["td", "ce"],
|
||||
default="ce" if TRADIER_TOKEN == "REPLACE_ME" else "td",
|
||||
help="Choose Tradier(TD) or ChartExchange (CE), only affects raw data",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-n",
|
||||
"--num",
|
||||
dest="num",
|
||||
type=int,
|
||||
help="Number of data rows to show",
|
||||
)
|
||||
|
||||
try:
|
||||
if (
|
||||
@@ -678,9 +693,21 @@ Current Expiry: {self.selected_date or None}
|
||||
if not self.selected_date:
|
||||
print("No expiry loaded. First use `exp ` \n")
|
||||
return
|
||||
if ns_parser.source.lower() == "ce":
|
||||
chartexchange_view.display_raw(
|
||||
ns_parser.export,
|
||||
self.ticker,
|
||||
self.selected_date,
|
||||
not ns_parser.put,
|
||||
ns_parser.strike,
|
||||
ns_parser.num,
|
||||
)
|
||||
return
|
||||
|
||||
if TRADIER_TOKEN == "REPLACE_ME":
|
||||
print("TRADIER TOKEN not supplied. \n")
|
||||
return
|
||||
|
||||
tradier_view.display_historical(
|
||||
ticker=self.ticker,
|
||||
expiry=self.selected_date,
|
||||
|
||||
3
website/content/options/hist/_index.md
vendored
3
website/content/options/hist/_index.md
vendored
@@ -1,5 +1,5 @@
|
||||
```
|
||||
usage: hist [-s STRIKE] [-p] [--chain CHAIN_ID] [-r,--raw] [--export {csv,json,xlsx}] [-h]
|
||||
usage: hist [-s STRIKE] [-p] [--chain CHAIN_ID] [-r,--raw] [--export {csv,json,xlsx}] [--source SOURCE] [-h]
|
||||
```
|
||||
|
||||
Gets historical quotes for given option chain
|
||||
@@ -10,6 +10,7 @@ optional arguments:
|
||||
Strike price to look at (default: None)
|
||||
-p, --put Flag for showing put option (default: False)
|
||||
--chain CHAIN_ID OCC option symbol (default: None)
|
||||
--source SOURCE Source of data (default: TradierView)
|
||||
-r,--raw Display raw data (default: False)
|
||||
--export {csv,json,xlsx}
|
||||
Export dataframe data to csv,json,xlsx file (default: )
|
||||
|
||||
Reference in New Issue
Block a user