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