Merge branch 'develop' into feature/charting-obbject

This commit is contained in:
Henrique Joaquim
2024-02-07 11:27:31 +00:00
committed by GitHub
6 changed files with 287 additions and 85 deletions

View File

@@ -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)

View File

@@ -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()

View File

@@ -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()

25
poetry.lock generated vendored
View File

@@ -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"

View File

@@ -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

View File

@@ -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 }) {
/>
<BrowserOnly>
{() => isOpen &&
DocSearchModal &&
searchContainer.current &&
createPortal(
<DocSearchModal
onClose={onClose}
initialScrollY={window.scrollY}
initialQuery={initialQuery}
navigator={navigator}
transformItems={transformItems}
hitComponent={Hit}
transformSearchClient={transformSearchClient}
{...(props.searchPagePath && {
resultsFooterComponent,
})}
{...props}
searchParameters={searchParameters}
placeholder={translations.placeholder}
translations={translations.modal}
/>,
searchContainer.current
)}
</BrowserOnly>
{() => isOpen &&
DocSearchModal &&
searchContainer.current &&
createPortal(
<DocSearchModal
onClose={onClose}
initialScrollY={window.scrollY}
initialQuery={initialQuery}
navigator={navigator}
transformItems={transformItems}
hitComponent={Hit}
transformSearchClient={transformSearchClient}
{...(props.searchPagePath && {
resultsFooterComponent,
})}
{...props}
searchParameters={searchParameters}
placeholder={translations.placeholder}
translations={translations.modal}
/>,
searchContainer.current
)}
</BrowserOnly>
</>
);
}