mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-29 13:32:08 +00:00
93 lines
2.6 KiB
Python
93 lines
2.6 KiB
Python
"""Technical Analysis Trendline Module"""
|
|
__docformat__ = "numpy"
|
|
|
|
from pandas.core.frame import DataFrame
|
|
import yfinance as yf
|
|
from scipy.stats import linregress
|
|
|
|
|
|
def load_ticker(ticker: str, start_date: str) -> DataFrame:
|
|
"""
|
|
Loads a ticker data from Yahoo Finance, adds a data index column data_id and Open-Close High/Low columns.
|
|
|
|
Parameters
|
|
----------
|
|
ticker : str
|
|
The stock ticker.
|
|
start_date : str
|
|
Start date to load stock ticker data formatted YYYY-MM-DD.
|
|
|
|
Returns
|
|
-------
|
|
DataFrame
|
|
A Panda's data frame with columns Open, High, Low, Close, Adj Close, Volume, date_id, OC-High, OC-Low.
|
|
"""
|
|
# print(f"Start date: {start_date}")
|
|
df_data = yf.download(ticker, start=start_date, progress=False)
|
|
|
|
df_data["date_id"] = (df_data.index.date - df_data.index.date.min()).astype(
|
|
"timedelta64[D]"
|
|
)
|
|
df_data["date_id"] = df_data["date_id"].dt.days + 1
|
|
|
|
df_data["OC_High"] = df_data[["Open", "Close"]].max(axis=1)
|
|
df_data["OC_Low"] = df_data[["Open", "Close"]].min(axis=1)
|
|
|
|
return df_data
|
|
|
|
|
|
def find_trendline(df_data: DataFrame, y_key: str, high_low: str = "high") -> DataFrame:
|
|
"""Attempts to find a trend line based on y_key column from a given stock ticker data frame.
|
|
|
|
Parameters
|
|
----------
|
|
df_data : DataFrame
|
|
The stock ticker data frame with at least date_id, y_key columns.
|
|
|
|
y_key : str
|
|
Column name to base the trend line on.
|
|
|
|
high_low: str, optional
|
|
Either "high" or "low". High is the default.
|
|
|
|
Returns
|
|
-------
|
|
DataFrame
|
|
If a trend is successfully found,
|
|
An updated Panda's data frame with a trend data {y_key}_trend column.
|
|
If no trend was found,
|
|
An original Panda's data frame
|
|
"""
|
|
|
|
for iteration in [3, 4, 5, 6, 7]:
|
|
df_temp = df_data.copy()
|
|
while len(df_temp) > iteration:
|
|
reg = linregress(
|
|
x=df_temp["date_id"],
|
|
y=df_temp[y_key],
|
|
)
|
|
|
|
if high_low == "high":
|
|
df_temp = df_temp.loc[
|
|
df_temp[y_key] > reg[0] * df_temp["date_id"] + reg[1]
|
|
]
|
|
else:
|
|
df_temp = df_temp.loc[
|
|
df_temp[y_key] < reg[0] * df_temp["date_id"] + reg[1]
|
|
]
|
|
|
|
if len(df_temp) > 1:
|
|
break
|
|
|
|
if len(df_temp) == 1:
|
|
return df_data
|
|
|
|
reg = linregress(
|
|
x=df_temp["date_id"],
|
|
y=df_temp[y_key],
|
|
)
|
|
|
|
df_data[f"{y_key}_trend"] = reg[0] * df_data["date_id"] + reg[1]
|
|
|
|
return df_data
|