From f8fb5937f6a360b80bf8ee434f9ae867e5ca1d37 Mon Sep 17 00:00:00 2001 From: teh_coderer Date: Tue, 6 Feb 2024 11:49:48 -0500 Subject: [PATCH 1/3] Docs / only display results for current platform (#6017) * Update index.js * Update index.js * yfinance * tzcache no longer exists * fixxy * ruff --------- Co-authored-by: Henrique Joaquim Co-authored-by: James Maslek Co-authored-by: Andrew --- .../stocks/options/yfinance_model.py | 2 +- poetry.lock | 25 +++++-- tests/conftest.py | 8 -- website/src/theme/SearchBar/index.js | 73 +++++++++++-------- 4 files changed, 62 insertions(+), 46 deletions(-) diff --git a/openbb_terminal/stocks/options/yfinance_model.py b/openbb_terminal/stocks/options/yfinance_model.py index bc52bea0da1..d0ffb10c028 100644 --- a/openbb_terminal/stocks/options/yfinance_model.py +++ b/openbb_terminal/stocks/options/yfinance_model.py @@ -91,7 +91,7 @@ def get_option_chain(symbol: str, expiry: str): yf_ticker = yf.Ticker(symbol) try: - chain = yf_ticker.option_chain(expiry) + chain = yf_ticker.option_chain(expiry)[0] except Exception: console.print(f"[red]Error: Expiration {expiry} cannot be found.[/red]") chain = pd.DataFrame() diff --git a/poetry.lock b/poetry.lock index ca9c12d5fc1..89fb92596ee 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. [[package]] name = "absl-py" @@ -5674,6 +5674,16 @@ files = [ {file = "pbr-5.11.1.tar.gz", hash = "sha256:aefc51675b0b533d56bb5fd1c8c6c0522fe31896679882e1c4c63d5e4a0fccb3"}, ] +[[package]] +name = "peewee" +version = "3.17.1" +description = "a little orm" +optional = false +python-versions = "*" +files = [ + {file = "peewee-3.17.1.tar.gz", hash = "sha256:e009ac4227c4fdc0058a56e822ad5987684f0a1fbb20fed577200785102581c3"}, +] + [[package]] name = "pefile" version = "2023.2.7" @@ -8237,7 +8247,7 @@ files = [ [package.dependencies] packaging = ">=20.0" setuptools = [ - {version = "*"}, + {version = "*", optional = true, markers = "extra != \"toml\""}, {version = ">=42", optional = true, markers = "extra == \"toml\""}, ] tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} @@ -10415,13 +10425,13 @@ multidict = ">=4.0" [[package]] name = "yfinance" -version = "0.2.28" +version = "0.2.36" description = "Download market data from Yahoo! Finance API" optional = false python-versions = "*" files = [ - {file = "yfinance-0.2.28-py2.py3-none-any.whl", hash = "sha256:9697dcbc38d67d1172a905fd5787c65bf049d87e18a709be788485ad7886791c"}, - {file = "yfinance-0.2.28.tar.gz", hash = "sha256:be89cd2a4d55c0a2a6227c32915b355bde59f85c569dca9123320322445901ff"}, + {file = "yfinance-0.2.36-py2.py3-none-any.whl", hash = "sha256:700f8b8fb51d4f7ca31bcef042175be68b2f39ed680a99170163e5f54874e2a6"}, + {file = "yfinance-0.2.36.tar.gz", hash = "sha256:5367c0538cf57bb0dd393ca24866cda1ab5d4aba47e375e549760652a4a19fc2"}, ] [package.dependencies] @@ -10433,9 +10443,14 @@ lxml = ">=4.9.1" multitasking = ">=0.0.7" numpy = ">=1.16.5" pandas = ">=1.3.0" +peewee = ">=3.16.2" pytz = ">=2022.5" requests = ">=2.31" +[package.extras] +nospam = ["requests-cache (>=1.0)", "requests-ratelimiter (>=0.3.1)"] +repair = ["scipy (>=1.6.3)"] + [[package]] name = "ypy-websocket" version = "0.8.4" diff --git a/tests/conftest.py b/tests/conftest.py index 7502fbad40e..2ecc998dc59 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -11,7 +11,6 @@ import importlib_metadata import matplotlib import pandas as pd import pytest -import yfinance.utils from _pytest.capture import MultiCapture, SysCapture from _pytest.config import Config from _pytest.config.argparsing import Parser @@ -400,13 +399,6 @@ def mock_plotly(mocker): # pylint: disable=protected-access -@pytest.fixture(autouse=True) -def mock_yfinance_tzcache(mocker): - mocker.patch.object( - target=yfinance.utils, - attribute="_TzCache", - new=yfinance.utils._TzCacheDummy, - ) @pytest.fixture diff --git a/website/src/theme/SearchBar/index.js b/website/src/theme/SearchBar/index.js index e10e4c251fb..a6fca7218cb 100644 --- a/website/src/theme/SearchBar/index.js +++ b/website/src/theme/SearchBar/index.js @@ -1,9 +1,10 @@ import { DocSearchButton, useDocSearchKeyboardEvents } from "@docsearch/react"; + import BrowserOnly from "@docusaurus/BrowserOnly"; import Head from "@docusaurus/Head"; import Link from "@docusaurus/Link"; import Translate from "@docusaurus/Translate"; -import { useHistory } from "@docusaurus/router"; +import { useHistory, useLocation } from "@docusaurus/router"; import { isRegexpStringMatch } from "@docusaurus/theme-common"; import { useAlgoliaContextualFacetFilters, @@ -35,15 +36,16 @@ function mergeFacetFilters(f1, f2) { return [...normalize(f1), ...normalize(f2)]; } function DocSearch({ contextualSearch, externalUrlRegex, ...props }) { + const location = useLocation(); const { siteMetadata } = useDocusaurusContext(); const processSearchResultUrl = useSearchResultUrlProcessor(); const contextualSearchFacetFilters = useAlgoliaContextualFacetFilters(); const configFacetFilters = props.searchParameters?.facetFilters ?? []; const facetFilters = contextualSearch ? // Merge contextual search filters with config filters - mergeFacetFilters(contextualSearchFacetFilters, configFacetFilters) + mergeFacetFilters(contextualSearchFacetFilters, configFacetFilters) : // ... or use config facetFilters - configFacetFilters; + configFacetFilters; // We let user override default searchParameters if she wants to const searchParameters = { ...props.searchParameters, @@ -101,14 +103,21 @@ function DocSearch({ contextualSearch, externalUrlRegex, ...props }) { }, }).current; const transformItems = useRef((items) => - props.transformItems + (props.transformItems ? // Custom transformItems - props.transformItems(items) + props.transformItems(items) : // Default transformItems - items.map((item) => ({ - ...item, - url: processSearchResultUrl(item.url), - })) + items.map((item) => ({ + ...item, + url: processSearchResultUrl(item.url), + }))).filter((item) => { + const firstPathSegment = location.pathname.split("/")[1]; + return ( + !firstPathSegment ? true : + item.url.startsWith(`/${firstPathSegment}/`) + ); + } + ) ).current; const resultsFooterComponent = useMemo( () => @@ -157,29 +166,29 @@ function DocSearch({ contextualSearch, externalUrlRegex, ...props }) { /> - {() => isOpen && - DocSearchModal && - searchContainer.current && - createPortal( - , - searchContainer.current - )} - + {() => isOpen && + DocSearchModal && + searchContainer.current && + createPortal( + , + searchContainer.current + )} + ); } From 76e4a7b7a78187c47e27407c318e7db02d7c2725 Mon Sep 17 00:00:00 2001 From: Igor Radovanovic <74266147+IgorWounds@users.noreply.github.com> Date: Tue, 6 Feb 2024 18:06:25 +0100 Subject: [PATCH 2/3] Improve the docstrings (#6040) --- .../openbb_technical/technical_router.py | 125 +++++++++++++----- 1 file changed, 89 insertions(+), 36 deletions(-) diff --git a/openbb_platform/extensions/technical/openbb_technical/technical_router.py b/openbb_platform/extensions/technical/openbb_technical/technical_router.py index 7e3cdbf3fc7..6b3a430f60f 100644 --- a/openbb_platform/extensions/technical/openbb_technical/technical_router.py +++ b/openbb_platform/extensions/technical/openbb_technical/technical_router.py @@ -31,9 +31,15 @@ def atr( drift: NonNegativeInt = 1, offset: int = 0, ) -> OBBject[List[Data]]: - """Average True Range. + """Calculate the Average True Range. Used to measure volatility, especially volatility caused by gaps or limit moves. + The ATR metric helps understand how much the values in your data change on average, + giving insights into the stability or unpredictability during a certain period. + It's particularly useful for spotting trends of increase or decrease in variations, + without getting into technical trading details. + The method considers not just the day-to-day changes but also accounts for any + sudden jumps or drops, ensuring you get a comprehensive view of movement. Parameters ---------- @@ -84,6 +90,12 @@ def fib( ) -> OBBject[List[Data]]: """Create Fibonacci Retracement Levels. + This method draws from a classic technique to pinpoint significant price levels + that often indicate where the market might find support or resistance. + It's a tool used to gauge potential turning points in the data by applying a + mathematical approach rooted in nature's patterns. Is used to get insights into + where prices could head next, based on historical movements. + Parameters ---------- data : List[Data] @@ -138,7 +150,7 @@ def obv( index: str = "date", offset: int = 0, ) -> OBBject[List[Data]]: - """On Balance Volume (OBV). + """Calculate the On Balance Volume (OBV). Is a cumulative total of the up and down volume. When the close is higher than the previous close, the volume is added to the running total, and when the close is @@ -186,7 +198,7 @@ def fisher( length: PositiveInt = 14, signal: PositiveInt = 1, ) -> OBBject[List[Data]]: - """Fisher Transform. + """Perform the Fisher Transform. A technical indicator created by John F. Ehlers that converts prices into a Gaussian normal distribution. The indicator highlights when prices have moved to an extreme, @@ -234,7 +246,7 @@ def adosc( slow: PositiveInt = 10, offset: int = 0, ) -> OBBject[List[Data]]: - """Accumulation/Distribution Oscillator. + """Calculate the Accumulation/Distribution Oscillator. Also known as the Chaikin Oscillator. @@ -286,7 +298,7 @@ def bbands( mamode: Literal["sma", "ema", "wma", "rma"] = "sma", offset: int = 0, ) -> OBBject[List[Data]]: - """Bollinger Bands. + """Calculate the Bollinger Bands. Consist of three lines. The middle band is a simple moving average (generally 20 periods) of the typical price (TP). The upper and lower bands are F standard @@ -358,7 +370,7 @@ def zlma( length: int = 50, offset: int = 0, ) -> OBBject[List[Data]]: - """The zero lag exponential moving average (ZLEMA). + """Calculate the zero lag exponential moving average (ZLEMA). Created by John Ehlers and Ric Way. The idea is do a regular exponential moving average (EMA) calculation but @@ -415,7 +427,7 @@ def aroon( length: int = 25, scalar: int = 100, ) -> OBBject[List[Data]]: - """Aroon Indicator. + """Calculate the Aroon Indicator. The word aroon is Sanskrit for "dawn's early light." The Aroon indicator attempts to show when a new trend is dawning. The indicator consists @@ -469,7 +481,7 @@ def sma( length: int = 50, offset: int = 0, ) -> OBBject[List[Data]]: - """Simple Moving Average. + """Calculate the Simple Moving Average (SMA). Moving Averages are used to smooth the data in an array to help eliminate noise and identify trends. The Simple Moving Average is literally @@ -501,7 +513,7 @@ def sma( -------- >>> from openbb import obb >>> stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp") - >>> sma_data = obb.technical.sma(data=stock_data.results,target="close",length=50,offset=0) + >>> sma_data = obb.technical.sma(data=stock_data.results,target="close", length=50, offset=0) """ df = basemodel_to_df(data, index=index) df_target = get_target_column(df, target).to_frame() @@ -529,7 +541,13 @@ def demark( asint: bool = True, offset: int = 0, ) -> OBBject[List[Data]]: - """Demark sequential indicator. + """Calculate the Demark sequential indicator. + + This indicator offers a strategic way to spot potential reversals in market trends. + It's designed to highlight moments when the current trend may be running out of steam, + suggesting a possible shift in direction. By focusing on specific patterns in price movements, it provides + valuable insights for making informed decisions on future changes and identifies trend exhaustion points + with precision. Parameters ---------- @@ -555,7 +573,7 @@ def demark( -------- >>> from openbb import obb >>> stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp") - >>> demark_data = obb.technical.demark(data=stock_data.results,offset=0) + >>> demark_data = obb.technical.demark(data=stock_data.results, offset=0) """ df = basemodel_to_df(data, index=index) df_target = get_target_column(df, target).to_frame() @@ -575,10 +593,12 @@ def vwap( anchor: str = "D", offset: int = 0, ) -> OBBject[List[Data]]: - """The Volume Weighted Average Price. + """Calculate the Volume Weighted Average Price (VWAP). Measures the average typical price by volume. It is typically used with intraday charts to identify general direction. + It helps to understand the true average price factoring in the volume of transactions, + and serves as a benchmark for assessing the market's direction over short periods, such as a single trading day. Parameters ---------- @@ -602,7 +622,7 @@ def vwap( -------- >>> from openbb import obb >>> stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp") - >>> vwap_data = obb.technical.vwap(data=stock_data.results,anchor="D",offset=0) + >>> vwap_data = obb.technical.vwap(data=stock_data.results, anchor="D", offset=0) """ df = basemodel_to_df(data, index=index) df_target = get_target_columns(df, ["high", "low", "close", "volume"]) @@ -623,7 +643,7 @@ def macd( slow: int = 26, signal: int = 9, ) -> OBBject[List[Data]]: - """The Moving Average Convergence Divergence (MACD). + """Calculate the Moving Average Convergence Divergence (MACD). Difference between two Exponential Moving Averages. The Signal line is an Exponential Moving Average of the MACD. @@ -658,7 +678,7 @@ def macd( -------- >>> from openbb import obb >>> stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp") - >>> macd_data = obb.technical.macd(data=stock_data.results,target="close",fast=12,slow=26,signal=9) + >>> macd_data = obb.technical.macd(data=stock_data.results,target="close", fast=12, slow=26, signal=9) """ df = basemodel_to_df(data, index=index) df_target = get_target_column(df, target).to_frame() @@ -685,7 +705,7 @@ def hma( length: int = 50, offset: int = 0, ) -> OBBject[List[Data]]: - """The Hull Moving Average. + """Calculate the Hull Moving Average (HMA). Solves the age old dilemma of making a moving average more responsive to current price activity whilst maintaining curve smoothness. @@ -714,7 +734,7 @@ def hma( -------- >>> from openbb import obb >>> stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp") - >>> hma_data = obb.technical.hma(data=stock_data.results,target="close",length=50,offset=0) + >>> hma_data = obb.technical.hma(data=stock_data.results, target="close", length=50, offset=0) """ df = basemodel_to_df(data, index=index) df_target = get_target_column(df, target).to_frame() @@ -741,7 +761,7 @@ def donchian( upper_length: PositiveInt = 20, offset: int = 0, ) -> OBBject[List[Data]]: - """Donchian Channels. + """Calculate the Donchian Channels. Three lines generated by moving average calculations that comprise an indicator formed by upper and lower bands around a midrange or median band. The upper band @@ -771,7 +791,7 @@ def donchian( -------- >>> from openbb import obb >>> stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp") - >>> donchian_data = obb.technical.donchian(data=stock_data.results,lower_length=20,upper_length=20,offset=0) + >>> donchian_data = obb.technical.donchian(data=stock_data.results, lower_length=20, upper_length=20, offset=0) """ df = basemodel_to_df(data, index=index) df_target = get_target_columns(df, ["high", "low"]) @@ -797,7 +817,7 @@ def ichimoku( offset: PositiveInt = 26, lookahead: bool = False, ) -> OBBject[List[Data]]: - """The Ichimoku Cloud. + """Calculate the Ichimoku Cloud. Also known as Ichimoku Kinko Hyo, is a versatile indicator that defines support and resistance, identifies trend direction, gauges momentum and provides trading @@ -821,6 +841,17 @@ def ichimoku( Number of periods for the offset, by default 26. lookahead : bool, optional drops the Chikou Span Column to prevent potential data leak + + Returns + ------- + OBBject[List[Data]] + The calculated data. + + Examples + -------- + >>> from openbb import obb + >>> stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp") + >>> ichimoku_data = obb.technical.ichimoku(data=stock_data.results, conversion=9, base=26, lookahead=False) """ df = basemodel_to_df(data, index=index) df_target = get_target_columns(df, ["high", "low", "close"]) @@ -847,7 +878,11 @@ def clenow( target: str = "close", period: PositiveInt = 90, ) -> OBBject[List[Data]]: - """Clenow Volatility Adjusted Momentum. + """Calculate the Clenow Volatility Adjusted Momentum. + + The Clenow Volatility Adjusted Momentum is a sophisticated approach to understanding market momentum with a twist. + It adjusts for volatility, offering a clearer picture of true momentum by considering how price movements are + influenced by their volatility over a set period. It helps in identifying stronger, more reliable trends. Parameters ---------- @@ -869,7 +904,7 @@ def clenow( -------- >>> from openbb import obb >>> stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp") - >>> clenow_data = obb.technical.clenow(data=stock_data.results,period=90) + >>> clenow_data = obb.technical.clenow(data=stock_data.results, period=90) """ df = basemodel_to_df(data, index=index) df_target = get_target_column(df, target) @@ -893,7 +928,7 @@ def clenow( @router.command(methods=["POST"]) def ad(data: List[Data], index: str = "date", offset: int = 0) -> OBBject[List[Data]]: - """The Accumulation/Distribution Line. + """Calculate the Accumulation/Distribution Line. Similar to the On Balance Volume (OBV). Sums the volume times +1/-1 based on whether the close is higher than the previous @@ -925,7 +960,7 @@ def ad(data: List[Data], index: str = "date", offset: int = 0) -> OBBject[List[D -------- >>> from openbb import obb >>> stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp") - >>> ad_data = obb.technical.ad(data=stock_data.results,offset=0) + >>> ad_data = obb.technical.ad(data=stock_data.results, offset=0) """ df = basemodel_to_df(data, index=index) df_target = get_target_columns(df, ["high", "low", "close", "volume"]) @@ -945,7 +980,7 @@ def adx( scalar: float = 100.0, drift: int = 1, ) -> OBBject[List[Data]]: - """ADX. + """Calculate the Average Directional Index (ADX). The ADX is a Welles Wilder style moving average of the Directional Movement Index (DX). The values range from 0 to 100, but rarely get above 60. To interpret the ADX, consider @@ -973,7 +1008,7 @@ def adx( -------- >>> from openbb import obb >>> stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp") - >>> adx_data = obb.technical.adx(data=stock_data.results,length=50,scalar=100.0,drift=1) + >>> adx_data = obb.technical.adx(data=stock_data.results, length=50, scalar=100.0, drift=1) """ df = basemodel_to_df(data, index=index) df_target = get_target_columns(df, ["close", "high", "low"]) @@ -995,7 +1030,7 @@ def wma( length: int = 50, offset: int = 0, ) -> OBBject[List[Data]]: - """Weighted Moving Average. + """Calculate the Weighted Moving Average (WMA). A Weighted Moving Average puts more weight on recent data and less on past data. This is done by multiplying each bar's price by a weighting factor. Because of its @@ -1050,7 +1085,7 @@ def cci( length: PositiveInt = 14, scalar: PositiveFloat = 0.015, ) -> OBBject[List[Data]]: - """Commodity Channel Index (CCI). + """Calculate the Commodity Channel Index (CCI). The CCI is designed to detect beginning and ending market trends. The range of 100 to -100 is the normal trading range. CCI values outside of this @@ -1073,6 +1108,12 @@ def cci( ------- OBBject[List[Data]] The CCI data. + + Examples + -------- + >>> from openbb import obb + >>> stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp") + >>> cci_data = obb.technical.cci(data=stock_data.results, length=14, scalar=0.015) """ df = basemodel_to_df(data, index=index) df_target = get_target_columns(df, ["close", "high", "low"]) @@ -1093,7 +1134,7 @@ def rsi( scalar: float = 100.0, drift: int = 1, ) -> OBBject[List[Data]]: - """Relative Strength Index (RSI). + """Calculate the Relative Strength Index (RSI). RSI calculates a ratio of the recent upward price movements to the absolute price movement. The RSI ranges from 0 to 100. @@ -1153,7 +1194,7 @@ def stoch( slow_d_period: NonNegativeInt = 3, slow_k_period: NonNegativeInt = 3, ) -> OBBject[List[Data]]: - """Stochastic Oscillator. + """Calculate the Stochastic Oscillator. The Stochastic Oscillator measures where the close is in relation to the recent trading range. The values range from zero to 100. %D values over 75 @@ -1211,7 +1252,7 @@ def kc( mamode: Literal["ema", "sma", "wma", "hma", "zlma"] = "ema", offset: NonNegativeInt = 0, ) -> OBBject[List[Data]]: - """Keltner Channels. + """Calculate the Keltner Channels. Keltner Channels are volatility-based bands that are placed on either side of an asset's price and can aid in determining @@ -1265,7 +1306,7 @@ def kc( def cg( data: List[Data], index: str = "date", length: PositiveInt = 14 ) -> OBBject[List[Data]]: - """Center of Gravity. + """Calculate the Center of Gravity. The Center of Gravity indicator, in short, is used to anticipate future price movements and to trade on price reversals as soon as they happen. However, just like other oscillators, @@ -1322,7 +1363,19 @@ def cones( ) -> OBBject[List[Data]]: """Calculate the realized volatility quantiles over rolling windows of time. - The model for calculating volatility is selectable. + The cones indicator is designed to map out the ebb and flow of price movements through a detailed analysis of + volatility quantiles. By examining the range of volatility within specific time frames, it offers a nuanced view of + market behavior, highlighting periods of stability and turbulence. + + The model for calculating volatility is selectable and can be one of the following: + - Standard deviation + - Parkinson + - Garman-Klass + - Hodges-Tompkins + - Rogers-Satchell + - Yang-Zhang + + Read more about it in the model parameter description. Parameters ---------- @@ -1360,6 +1413,7 @@ def cones( Whether the data is crypto or not. If True, volatility is calculated for 365 days instead of 252 trading_periods : Optional[int] [default: 252] Number of trading periods in a year. + Returns ------- OBBject[List[Data]] @@ -1397,7 +1451,7 @@ def ema( length: int = 50, offset: int = 0, ) -> OBBject[List[Data]]: - """Exponential Moving Average. + """Calculate the Exponential Moving Average (EMA). EMA is a cumulative calculation, including all data. Past values have a diminishing contribution to the average, while more recent values have a greater @@ -1426,8 +1480,7 @@ def ema( -------- >>> from openbb import obb >>> stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp") - >>> ema_data = obb.technical.ema(data=stock_data.results,target="close",length=50,offset=0) - + >>> ema_data = obb.technical.ema(data=stock_data.results, target="close", length=50, offset=0) """ df = basemodel_to_df(data, index=index) df_target = get_target_column(df, target).to_frame() From 6f159655f9e944b17d3bdb34deaf158eb675da1a Mon Sep 17 00:00:00 2001 From: Igor Radovanovic <74266147+IgorWounds@users.noreply.github.com> Date: Tue, 6 Feb 2024 18:09:05 +0100 Subject: [PATCH 3/3] Improve the docstrings (#6041) Co-authored-by: Henrique Joaquim --- .../quantitative_router.py | 139 +++++++++++++++++- 1 file changed, 136 insertions(+), 3 deletions(-) diff --git a/openbb_platform/extensions/quantitative/openbb_quantitative/quantitative_router.py b/openbb_platform/extensions/quantitative/openbb_quantitative/quantitative_router.py index 2a1b32c0bc4..42c17bac503 100644 --- a/openbb_platform/extensions/quantitative/openbb_quantitative/quantitative_router.py +++ b/openbb_platform/extensions/quantitative/openbb_quantitative/quantitative_router.py @@ -51,6 +51,12 @@ def normality(data: List[Data], target: str) -> OBBject[NormalityModel]: ------- OBBject[NormalityModel] Normality tests summary. See qa_models.NormalityModel for details. + + Examples + -------- + >>> from openbb import obb + >>> stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp") + >>> obb.quantitative.normality(data=stock_data, target="close") """ from scipy import stats # pylint: disable=import-outside-toplevel @@ -76,7 +82,30 @@ def normality(data: List[Data], target: str) -> OBBject[NormalityModel]: @router.command(methods=["POST"]) def capm(data: List[Data], target: str) -> OBBject[CAPMModel]: - """Get Capital Asset Pricing Model.""" + """Get Capital Asset Pricing Model (CAPM). + + CAPM offers a streamlined way to assess the expected return on an investment while accounting for its risk relative + to the market. It's a cornerstone of modern financial theory that helps investors understand the trade-off between + risk and return, guiding more informed investment choices. + + Parameters + ---------- + data : List[Data] + Time series data. + target : str + Target column name. + + Returns + ------- + OBBject[CAPMModel] + CAPM model summary. + + Examples + -------- + >>> from openbb import obb + >>> stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp") + >>> obb.quantitative.capm(data=stock_data, target="close") + """ import statsmodels.api as sm # pylint: disable=import-outside-toplevel # type: ignore df = basemodel_to_df(data) @@ -117,6 +146,10 @@ def omega_ratio( ) -> OBBject[List[OmegaModel]]: """Calculate the Omega Ratio. + The Omega Ratio is a sophisticated metric that goes beyond traditional performance measures by considering the + probability of achieving returns above a given threshold. It offers a more nuanced view of risk and reward, + focusing on the likelihood of success rather than just average outcomes. + Parameters ---------- data : List[Data] @@ -132,6 +165,12 @@ def omega_ratio( ------- OBBject[List[OmegaModel]] Omega ratios. + + Examples + -------- + >>> from openbb import obb + >>> stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp") + >>> obb.quantitative.omega_ratio(data=stock_data, target="close") """ df = basemodel_to_df(data) series_target = get_target_column(df, target) @@ -160,6 +199,13 @@ def omega_ratio( def kurtosis(data: List[Data], target: str, window: PositiveInt) -> OBBject[List[Data]]: """Get the Kurtosis. + Kurtosis provides insights into the shape of the data's distribution, particularly the heaviness of its tails. + Kurtosis is a statistical measure that reveals whether the data points tend to cluster around the mean or if + outliers are more common than a normal distribution would suggest. A higher kurtosis indicates more data points are + found in the tails, suggesting potential volatility or risk. + This analysis is crucial for understanding the underlying characteristics of your data, helping to anticipate + extreme events or anomalies over a specified window of time. + Parameters ---------- data : List[Data] @@ -173,6 +219,12 @@ def kurtosis(data: List[Data], target: str, window: PositiveInt) -> OBBject[List ------- OBBject[List[Data]] Kurtosis. + + Examples + -------- + >>> from openbb import obb + >>> stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp") + >>> obb.quantitative.kurtosis(data=stock_data, target="close", window=252) """ import pandas_ta as ta # pylint: disable=import-outside-toplevel # type: ignore @@ -193,8 +245,13 @@ def unitroot_test( ) -> OBBject[UnitRootModel]: """Get Unit Root Test. - Augmented Dickey-Fuller test for unit root. - Kwiatkowski-Phillips-Schmidt-Shin test for unit root. + This function applies two renowned tests to assess whether your data series is stationary or if it contains a unit + root, indicating it may be influenced by time-based trends or seasonality. The Augmented Dickey-Fuller (ADF) test + helps identify the presence of a unit root, suggesting that the series could be non-stationary and potentially + unpredictable over time. On the other hand, the Kwiatkowski-Phillips-Schmidt-Shin (KPSS) test checks for the + stationarity of the series, where failing to reject the null hypothesis indicates a stable, stationary series. + Together, these tests provide a comprehensive view of your data's time series properties, essential for + accurate modeling and forecasting. Parameters ---------- @@ -211,6 +268,13 @@ def unitroot_test( ------- OBBject[UnitRootModel] Unit root tests summary. + + Examples + -------- + >>> from openbb import obb + >>> stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp") + >>> obb.quantitative.unitroot_test(data=stock_data, target="close") + >>> obb.quantitative.unitroot_test(data=stock_data, target="close", fuller_reg="ct", kpss_reg="ct") """ # pylint: disable=import-outside-toplevel from statsmodels.tsa import stattools # type: ignore @@ -244,6 +308,13 @@ def sharpe_ratio( ) -> OBBject[List[Data]]: """Get Sharpe Ratio. + This function calculates the Sharpe Ratio, a metric used to assess the return of an investment compared to its risk. + By factoring in the risk-free rate, it helps you understand how much extra return you're getting for the extra + volatility that you endure by holding a riskier asset. The Sharpe Ratio is essential for investors looking to + compare the efficiency of different investments, providing a clear picture of potential rewards in relation to their + risks over a specified period. Ideal for gauging the effectiveness of investment strategies, it offers insights into + optimizing your portfolio for maximum return on risk. + Parameters ---------- data : List[Data] @@ -259,6 +330,13 @@ def sharpe_ratio( ------- OBBject[List[Data]] Sharpe ratio. + + Examples + -------- + >>> from openbb import obb + >>> stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp") + >>> obb.quantitative.sharpe_ratio(data=stock_data, target="close") + >>> obb.quantitative.sharpe_ratio(data=stock_data, target="close", rfr=0.01, window=126) """ df = basemodel_to_df(data) series_target = get_target_column(df, target) @@ -282,6 +360,15 @@ def sortino_ratio( ) -> OBBject[List[Data]]: """Get Sortino Ratio. + The Sortino Ratio enhances the evaluation of investment returns by distinguishing harmful volatility + from total volatility. Unlike other metrics that treat all volatility as risk, this command specifically assesses + the volatility of negative returns relative to a target or desired return. + It's particularly useful for investors who are more concerned with downside risk than with overall volatility. + By calculating the Sortino Ratio, investors can better understand the risk-adjusted return of their investments, + focusing on the likelihood and impact of negative returns. + This approach offers a more nuanced tool for portfolio optimization, especially in strategies aiming + to minimize the downside. + For method & terminology see: http://www.redrockcapital.com/Sortino__A__Sharper__Ratio_Red_Rock_Capital.pdf @@ -302,6 +389,13 @@ def sortino_ratio( ------- OBBject[List[Data]] Sortino ratio. + + Examples + -------- + >>> from openbb import obb + >>> stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp") + >>> obb.quantitative.sortino_ratio(data=stock_data, target="close") + >>> obb.quantitative.sortino_ratio(data=stock_data, target="close", target_return=0.01, window=126, adjusted=True) """ df = basemodel_to_df(data) series_target = get_target_column(df, target) @@ -324,6 +418,12 @@ def sortino_ratio( def skewness(data: List[Data], target: str, window: PositiveInt) -> OBBject[List[Data]]: """Get Skewness. + Skewness is a statistical measure that reveals the degree of asymmetry of a distribution around its mean. + Positive skewness indicates a distribution with an extended tail to the right, while negative skewness shows a tail + that stretches left. Understanding skewness can provide insights into potential biases in data and help anticipate + the nature of future data points. It's particularly useful for identifying the likelihood of extreme outcomes in + financial returns, enabling more informed decision-making based on the distribution's shape over a specified period. + Parameters ---------- data : List[Data] @@ -337,6 +437,12 @@ def skewness(data: List[Data], target: str, window: PositiveInt) -> OBBject[List ------- OBBject[List[Data]] Skewness. + + Examples + -------- + >>> from openbb import obb + >>> stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp") + >>> obb.quantitative.skewness(data=stock_data, target="close", window=252) """ import pandas_ta as ta # pylint: disable=import-outside-toplevel # type: ignore @@ -357,6 +463,13 @@ def quantile( ) -> OBBject[List[Data]]: """Get Quantile. + Quantile is a statistical measure that identifies the value below which a given percentage of observations in a + group of data falls. By setting the quantile percentage, you can determine any point in the distribution, not just + the median. Whether you're interested in the median, quartiles, or any other position within your data's range, + this tool offers a precise way to understand the distribution's characteristics. + It's especially useful for identifying outliers, understanding dispersion, and setting thresholds for + decision-making based on the distribution of data over a specified period. + Parameters ---------- data : List[Data] @@ -371,6 +484,13 @@ def quantile( ------- OBBject[List[Data]] Quantile. + + Examples + -------- + >>> from openbb import obb + >>> stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp") + >>> obb.quantitative.quantile(data=stock_data, target="close", window=252, quantile_pct=0.25) + >>> obb.quantitative.quantile(data=stock_data, target="close", window=252, quantile_pct=0.75) """ import pandas_ta as ta # pylint: disable=import-outside-toplevel # type: ignore @@ -390,6 +510,13 @@ def quantile( def summary(data: List[Data], target: str) -> OBBject[SummaryModel]: """Get Summary Statistics. + The summary that offers a snapshot of its central tendencies, variability, and distribution. + This command calculates essential statistics, including mean, standard deviation, variance, + and specific percentiles, to provide a detailed profile of your target column. B + y examining these metrics, you gain insights into the data's overall behavior, helping to identify patterns, + outliers, or anomalies. The summary table is an invaluable tool for initial data exploration, + ensuring you have a solid foundation for further analysis or reporting. + Parameters ---------- data : List[Data] @@ -401,6 +528,12 @@ def summary(data: List[Data], target: str) -> OBBject[SummaryModel]: ------- OBBject[SummaryModel] Summary table. + + Examples + -------- + >>> from openbb import obb + >>> stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp") + >>> obb.quantitative.summary(data=stock_data, target="close") """ df = basemodel_to_df(data) series_target = get_target_column(df, target)