diff options
author | Sameer Khan <57355784+skhan59bbk@users.noreply.github.com> | 2023-06-01 21:41:17 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-01 20:41:17 +0000 |
commit | d662b69c6fc7b6f9c9e198342b78b6ac1310a33c (patch) | |
tree | 2b614f66498d7b86e299f05fd204953f983d46b9 | |
parent | eac108e74a10c5d9a0faec6b69a7cf389fdedbfd (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>
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 |