summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSameer Khan <57355784+skhan59bbk@users.noreply.github.com>2023-06-01 21:41:17 +0100
committerGitHub <noreply@github.com>2023-06-01 20:41:17 +0000
commitd662b69c6fc7b6f9c9e198342b78b6ac1310a33c (patch)
tree2b614f66498d7b86e299f05fd204953f983d46b9
parenteac108e74a10c5d9a0faec6b69a7cf389fdedbfd (diff)
Feature/futures curve history (#5086)
* add past contract prices to curve table * adds secondary curve to viz * includes error message when no data for selected date * linting * adds back linespace * changed as-of parameter to d and date * fixes ruff * more linting and tests * fixes for pylint test * edit the xaxis formatting * fix the tests --------- Co-authored-by: James Maslek <jmaslek11@gmail.com>
-rw-r--r--openbb_terminal/futures/futures_controller.py36
-rw-r--r--openbb_terminal/futures/yfinance_model.py16
-rw-r--r--openbb_terminal/futures/yfinance_view.py43
-rw-r--r--tests/openbb_terminal/futures/txt/test_yfinance_view/test_display_curve[ES].txt12
-rw-r--r--tests/openbb_terminal/futures/txt/test_yfinance_view/test_display_curve[YI].txt4
5 files changed, 84 insertions, 27 deletions
diff --git a/openbb_terminal/futures/futures_controller.py b/openbb_terminal/futures/futures_controller.py
index a06aca857b0..cfe9fdc435c 100644
--- a/openbb_terminal/futures/futures_controller.py
+++ b/openbb_terminal/futures/futures_controller.py
@@ -237,6 +237,15 @@ class FuturesController(BaseController):
metavar="TICKER",
choices=self.all_tickers,
)
+ parser.add_argument(
+ "-d",
+ "--date",
+ dest="date",
+ type=valid_date,
+ help="Include the curve as of a previous date with format YYYY-MM-DD",
+ metavar="DATE",
+ default=None,
+ )
if other_args and "-" not in other_args[0][0]:
other_args.insert(0, "-t")
ns_parser = self.parse_known_args_and_warn(
@@ -247,11 +256,22 @@ class FuturesController(BaseController):
)
if ns_parser:
- yfinance_view.display_curve(
- symbol=ns_parser.ticker.upper(),
- raw=ns_parser.raw,
- export=ns_parser.export,
- sheet_name=" ".join(ns_parser.sheet_name)
- if ns_parser.sheet_name
- else None,
- )
+ if ns_parser.date:
+ yfinance_view.display_curve(
+ symbol=ns_parser.ticker.upper(),
+ date=ns_parser.date.strftime("%Y-%m-%d"),
+ raw=ns_parser.raw,
+ export=ns_parser.export,
+ sheet_name=" ".join(ns_parser.sheet_name)
+ if ns_parser.sheet_name
+ else None,
+ )
+ else:
+ yfinance_view.display_curve(
+ symbol=ns_parser.ticker.upper(),
+ raw=ns_parser.raw,
+ export=ns_parser.export,
+ sheet_name=" ".join(ns_parser.sheet_name)
+ if ns_parser.sheet_name
+ else None,
+ )
diff --git a/openbb_terminal/futures/yfinance_model.py b/openbb_terminal/futures/yfinance_model.py
index 67185614a6d..69ae0d818ff 100644
--- a/openbb_terminal/futures/yfinance_model.py
+++ b/openbb_terminal/futures/yfinance_model.py
@@ -153,6 +153,7 @@ def get_historical_futures(
@log_start_end(log=logger)
def get_curve_futures(
symbol: str = "",
+ date: Optional[str] = "",
) -> pd.DataFrame:
"""Get curve futures [Source: Yahoo Finance]
@@ -160,6 +161,8 @@ def get_curve_futures(
----------
symbol: str
symbol to get forward curve
+ date: str
+ optionally include historical price for each contract
Returns
-------
@@ -174,9 +177,10 @@ def get_curve_futures(
futures_index = list()
futures_curve = list()
+ historical_curve = list()
i = 0
empty_count = 0
- # Loop through until we find 12 consecutive empty years
+ # Loop through until we find 12 consecutive empty months
while empty_count < 12:
future = today + relativedelta(months=i)
future_symbol = (
@@ -192,10 +196,20 @@ def get_curve_futures(
empty_count = 0
futures_index.append(future.strftime("%b-%Y"))
futures_curve.append(data["Adj Close"].values[-1])
+ if date != "":
+ historical_curve.append(data["Adj Close"].get(date, None))
i += 1
if not futures_index:
return pd.DataFrame()
+ if historical_curve:
+ if None in historical_curve:
+ console.print("[yellow]No pricing data for selected date.[/yellow]")
+ return pd.DataFrame(
+ index=futures_index,
+ data=zip(futures_curve, historical_curve),
+ columns=["Last Price", date],
+ )
return pd.DataFrame(index=futures_index, data=futures_curve, columns=["Last Price"])
diff --git a/openbb_terminal/futures/yfinance_view.py b/openbb_terminal/futures/yfinance_view.py
index c788d496ee6..4cf1005b07e 100644
--- a/openbb_terminal/futures/yfinance_view.py
+++ b/openbb_terminal/futures/yfinance_view.py
@@ -5,6 +5,8 @@ import logging
import os
from typing import List, Optional
+import pandas as pd
+
from openbb_terminal import OpenBBFigure
from openbb_terminal.decorators import log_start_end
from openbb_terminal.futures import yfinance_model
@@ -191,6 +193,7 @@ def display_historical(
@log_start_end(log=logger)
def display_curve(
symbol: str,
+ date: Optional[str] = "",
raw: bool = False,
export: str = "",
sheet_name: Optional[str] = None,
@@ -202,8 +205,10 @@ def display_curve(
----------
symbol: str
Curve future symbol to display
+ date: str
+ Optionally include historical futures prices for each contract
raw: bool
- Display futures timeseries in raw format
+ Display futures prices in raw format
sheet_name: str
Optionally specify the name of the sheet the data is exported to.
export: str
@@ -214,7 +219,11 @@ def display_curve(
if symbol not in yfinance_model.FUTURES_DATA["Ticker"].unique().tolist():
return console.print(f"[red]'{symbol}' is not a valid symbol[/red]")
- df = yfinance_model.get_curve_futures(symbol)
+ df = (
+ yfinance_model.get_curve_futures(symbol)
+ if date == ""
+ else yfinance_model.get_curve_futures(symbol, date)
+ )
if df.empty:
return console.print("[red]No future data found to generate curve.[/red]\n")
@@ -225,15 +234,29 @@ def display_curve(
"Description"
].values[0]
- fig.add_scatter(
- x=df.index,
- y=df.iloc[:, 0],
- mode="lines+markers",
- name=name,
- line=dict(dash="dash", width=4),
- marker=dict(size=10),
- )
+ df.index = pd.to_datetime(df.index, format="%b-%Y")
+
+ if date == "":
+ fig.add_scatter(
+ x=df.index,
+ y=df.iloc[:, 0],
+ mode="lines+markers",
+ name=name,
+ line=dict(dash="dash", width=4),
+ marker=dict(size=10),
+ )
+ else:
+ for col in df.columns.tolist():
+ fig.add_scatter(
+ x=df.index,
+ y=df[col],
+ mode="lines+markers",
+ name=col,
+ line=dict(dash="dash", width=4),
+ marker=dict(size=10),
+ )
fig.set_title(name)
+ fig.update_layout(xaxis=dict(tickformat="%b-%Y"))
export_data(
export,
diff --git a/tests/openbb_terminal/futures/txt/test_yfinance_view/test_display_curve[ES].txt b/tests/openbb_terminal/futures/txt/test_yfinance_view/test_display_curve[ES].txt
index 1c60fb81cff..29367d6e6ee 100644
--- a/tests/openbb_terminal/futures/txt/test_yfinance_view/test_display_curve[ES].txt
+++ b/tests/openbb_terminal/futures/txt/test_yfinance_view/test_display_curve[ES].txt
@@ -1,7 +1,7 @@
- Last Price
-Jun-2023 4137.75
-Sep-2023 4173.50
-Dec-2023 4207.50
-Mar-2024 4242.00
-Jun-2024 4273.00
+ Last Price
+2023-06-01 4137.75
+2023-09-01 4173.50
+2023-12-01 4207.50
+2024-03-01 4242.00
+2024-06-01 4273.00
diff --git a/tests/openbb_terminal/futures/txt/test_yfinance_view/test_display_curve[YI].txt b/tests/openbb_terminal/futures/txt/test_yfinance_view/test_display_curve[YI].txt
index 0113985068f..3cad2274599 100644
--- a/tests/openbb_terminal/futures/txt/test_yfinance_view/test_display_curve[YI].txt
+++ b/tests/openbb_terminal/futures/txt/test_yfinance_view/test_display_curve[YI].txt
@@ -1,3 +1,3 @@
- Last Price
-Jul-2023 22.577999
+ Last Price
+2023-07-01 22.577999