mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-28 13:01:38 +00:00
Improves load and candle relation + 3 bonus READMEs (#908)
* stocks/ba * stocks/disc * stocks/dps * Improve load and candle relation * refactor trendline file * change --plotly to --it
This commit is contained in:
@@ -68,14 +68,6 @@ gamestonk\_terminal.common.technical\_analysis.trend\_indicators\_view module
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
gamestonk\_terminal.common.technical\_analysis.trendline\_api module
|
||||
--------------------------------------------------------------------
|
||||
|
||||
.. automodule:: gamestonk_terminal.common.technical_analysis.trendline_api
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
gamestonk\_terminal.common.technical\_analysis.volatility\_model module
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
"""Technical Analysis Trendline Module"""
|
||||
__docformat__ = "numpy"
|
||||
|
||||
from typing import Union
|
||||
from datetime import datetime
|
||||
|
||||
import yfinance as yf
|
||||
from pandas.core.frame import DataFrame
|
||||
from scipy.stats import linregress
|
||||
|
||||
|
||||
def load_ticker(ticker: str, start_date: Union[str, datetime]) -> 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 : Union[str,datetime]
|
||||
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
|
||||
@@ -7,7 +7,7 @@ from datetime import datetime, timedelta
|
||||
import pandas as pd
|
||||
import mplfinance as mpf
|
||||
|
||||
from gamestonk_terminal.common.technical_analysis import trendline_api as trend
|
||||
from gamestonk_terminal.stocks import stocks_helper
|
||||
|
||||
|
||||
# pylint: disable=too-many-arguments
|
||||
@@ -48,20 +48,20 @@ def draw_graph(
|
||||
if os.path.isfile(df_stock_cache):
|
||||
df_stock = pd.read_pickle(df_stock_cache)
|
||||
else:
|
||||
df_stock = trend.load_ticker(
|
||||
df_stock = stocks_helper.load_ticker(
|
||||
ticker,
|
||||
(datetime.now() - timedelta(days=time_delta)).strftime("%Y-%m-%d"),
|
||||
)
|
||||
df_stock = trend.find_trendline(df_stock, "OC_High", "high")
|
||||
df_stock = trend.find_trendline(df_stock, "OC_Low", "how")
|
||||
df_stock = stocks_helper.find_trendline(df_stock, "OC_High", "high")
|
||||
df_stock = stocks_helper.find_trendline(df_stock, "OC_Low", "how")
|
||||
df_stock.to_pickle(df_stock_cache)
|
||||
|
||||
else:
|
||||
df_stock = trend.load_ticker(
|
||||
df_stock = stocks_helper.load_ticker(
|
||||
ticker, (datetime.now() - timedelta(days=time_delta)).strftime("%Y-%m-%d")
|
||||
)
|
||||
df_stock = trend.find_trendline(df_stock, "OC_High", "high")
|
||||
df_stock = trend.find_trendline(df_stock, "OC_Low", "how")
|
||||
df_stock = stocks_helper.find_trendline(df_stock, "OC_High", "high")
|
||||
df_stock = stocks_helper.find_trendline(df_stock, "OC_Low", "how")
|
||||
|
||||
mc = mpf.make_marketcolors(
|
||||
up="green", down="red", edge="black", wick="black", volume="in", ohlc="i"
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
# BEHAVIOURAL ANALYSIS
|
||||
|
||||
Check all features [HERE](https://gamestonkterminal.github.io/GamestonkTerminal/common/behavioural_analysis/).
|
||||
# Behavioural Analysis [>>](https://gamestonkterminal.github.io/GamestonkTerminal/common/behavioural_analysis/)
|
||||
|
||||
Command|Description|Source
|
||||
----|----|----
|
||||
@@ -11,6 +9,7 @@ Command|Description|Source
|
||||
`popular` |show popular tickers|[Reddit](https://reddit.com)
|
||||
`spac_c` |show other users spacs announcements from subreddit SPACs community|[Reddit](https://reddit.com)
|
||||
`spac` |show other users spacs announcements from other subs|[Reddit](https://reddit.com)
|
||||
`getdd` |gets due diligence from another user's post|[Reddit](https://reddit.com)
|
||||
`bullbear` |estimate quick sentiment from last 30 messages on board|[Stocktwits](https://stocktwits.com/)
|
||||
`messages` |output up to the 30 last messages on the board|[Stocktwits](https://stocktwits.com/)
|
||||
`trending` |trending stocks|[Stocktwits](https://stocktwits.com/)
|
||||
@@ -21,6 +20,8 @@ Command|Description|Source
|
||||
`regions` |regions that show highest interest in stock|[Google](https://google.com/)
|
||||
`queries` |top related queries with this stock|[Google](https://google.com/)
|
||||
`rise` |top rising related queries with stock|[Google](https://google.com/)
|
||||
`popularsi` |show most popular stocks on social media right now|[Sentiment Investor](https://sentimentinvestor.com)
|
||||
`emerging` |show stocks that are being talked about more than usual|[Sentiment Investor](https://sentimentinvestor.com)
|
||||
`metrics` |core social sentiment metrics for this stock|[Sentiment Investor](https://sentimentinvestor.com)
|
||||
`social` |social media figures for stock popularity|[Sentiment Investor](https://sentimentinvestor.com)
|
||||
`historical` |plot the past week of data for a selected metric|[Sentiment Investor](https://sentimentinvestor.com)
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# DARK POOL SHORTS
|
||||
# Dark Pool and Short Data [>>](https://gamestonkterminal.github.io/GamestonkTerminal/stocks/dark_pool_shorts)
|
||||
|
||||
Check all features [HERE](https://gamestonkterminal.github.io/GamestonkTerminal/stocks/dark_pool_shorts).
|
||||
|
||||
**TODO**
|
||||
Command|Description|Source
|
||||
---|---|---
|
||||
`shorted` |show most shorted stocks |[Yahoo Finance](https://finance.yahoo.com/)
|
||||
`hsi` |show top high short interest stocks of over 20% ratio |[High Short Interest](https://www.highshortinterest.com/)
|
||||
`prom` |promising tickers based on dark pool shares regression |[FINRA](https://www.finra.org)
|
||||
`pos` |dark pool short position|[Stockgrid](https://stockgrid.io)
|
||||
`sidtc` |short interest and days to cover |[Stockgrid](https://stockgrid.io)
|
||||
`dpotc` |dark pools (ATS) vs OTC data |[FINRA](https://www.finra.org)
|
||||
`ftd` |fails-to-deliver data|[SEC](https://sec.report)
|
||||
`spos` |net short vs position |[Stockgrid](https://stockgrid.io)
|
||||
`psi` |price vs short interest volume |[Stockgrid](https://stockgrid.io) or [Quandl](https://data.nasdaq.com)
|
||||
|
||||
37
gamestonk_terminal/stocks/discovery/README.md
vendored
37
gamestonk_terminal/stocks/discovery/README.md
vendored
@@ -1,29 +1,22 @@
|
||||
# DISCOVER STOCKS
|
||||
|
||||
Check all features [HERE](https://gamestonkterminal.github.io/GamestonkTerminal/stocks/discovery/).
|
||||
# Discovery [>>](https://gamestonkterminal.github.io/GamestonkTerminal/stocks/discovery/)
|
||||
|
||||
Command|Description|Source
|
||||
---|---|---
|
||||
`ipo` |past and future IPOs |[Finnhub](https://finnhub.io)
|
||||
`map` |S&P500 index stocks map |[Finviz](https://finviz.com)
|
||||
`rtp_sectors` |real-time performance sectors |[Alpha Vantage](www.alphavantage.co)
|
||||
`rtearn` | realtime earnings from and expected moves | [Geek of Wall St](https://thegeekofwallstreet.com)
|
||||
`pipo` |past IPOs dates |[Finnhub](https://finnhub.io)
|
||||
`fipo` |future IPOs dates |[Finnhub](https://finnhub.io)
|
||||
`gainers` |show latest top gainers |[Yahoo Finance](https://finance.yahoo.com/)
|
||||
`losers` |show latest top losers |[Yahoo Finance](https://finance.yahoo.com/)
|
||||
`orders` |orders by Fidelity Customers |[Fidelity](https://www.fidelity.com/)
|
||||
`ark_orders` |orders by ARK Investment Management LLC | [Cathiesark](https://www.cathiesark.com)
|
||||
`up_earnings` |upcoming earnings release dates |[Seeking Alpha](https://seekingalpha.com/)
|
||||
`high_short` |show top high short interest stocks of over 20% ratio |[High Short Interest](https://www.highshortinterest.com/)
|
||||
`low_float` |show low float stocks under 10M shares float |[Low Float](https://www.lowfloat.com/)
|
||||
`simply_wallst` |Simply Wall St. research data |[Simply Wall St.](https://simplywall.st/about)
|
||||
`spachero` |great website for SPACs research |[SpacHero](https://www.spachero.com/)
|
||||
`uwhales` |good website for SPACs research |[UnusualWhales](https://unusualwhales.com/)
|
||||
`valuation` |valuation of sectors, industry, country |[Finviz](https://finviz.com)
|
||||
`performance` |performance of sectors, industry, country |[Finviz](https://finviz.com)
|
||||
`spectrum` |spectrum of sectors, industry, country |[Finviz](https://finviz.com)
|
||||
`ugs` |undervalued stocks with revenue and earnings growth in excess of 25% |[Yahoo Finance](https://finance.yahoo.com/)
|
||||
`gtech` |tech stocks with revenue and earnings growth more than 25% |[Yahoo Finance](https://finance.yahoo.com/)
|
||||
`active` |most active stocks by intraday trade volume |[Yahoo Finance](https://finance.yahoo.com/)
|
||||
`ulc` |potentially undervalued large cap stocks |[Yahoo Finance](https://finance.yahoo.com/)
|
||||
`asc` |small cap stocks with earnings growth rates better than 25% |[Yahoo Finance](https://finance.yahoo.com/)
|
||||
`ford` |orders by Fidelity Customers |[Fidelity](https://www.fidelity.com/)
|
||||
`arkord` |orders by ARK Investment Management LLC | [Cathiesark](https://www.cathiesark.com)
|
||||
`upcoming` |upcoming earnings release dates |[Seeking Alpha](https://seekingalpha.com/)
|
||||
`latest` |latest news |[Seeking Alpha](https://seekingalpha.com/)
|
||||
`trending` |trending news |[Seeking Alpha](https://seekingalpha.com/)
|
||||
`darkpool` |dark pool tickers with growing activity |[FINRA](https://www.finra.org)
|
||||
`darkshort` |dark pool short position|[Stockgrid](https://stockgrid.io)
|
||||
`shortvol` |short interest and days to cover |[Stockgrid](https://stockgrid.io)
|
||||
`popular` |show most popular stocks on social media right now|[Sentiment Investor](https://sentimentinvestor.com)
|
||||
`emerging` |show stocks that are being talked about more than usual|[Sentiment Investor](https://sentimentinvestor.com)
|
||||
`low_float` |show low float stocks under 10M shares float |[Low Float](https://www.lowfloat.com/)
|
||||
`hotpenny` |today's hot penny stocks |[hotpenny](https://pennystockflow.com)
|
||||
`fds` |advanced Equities search based on country, sector, industry, name and/or description |[FinanceDatabase](https://github.com/JerBouma/FinanceDatabase)
|
||||
|
||||
@@ -16,7 +16,12 @@ from gamestonk_terminal.helper_funcs import (
|
||||
parse_known_args_and_warn,
|
||||
)
|
||||
from gamestonk_terminal.menu import session
|
||||
from gamestonk_terminal.stocks.stocks_helper import display_candle, load, quote
|
||||
from gamestonk_terminal.stocks.stocks_helper import (
|
||||
display_candle,
|
||||
load,
|
||||
quote,
|
||||
process_candle,
|
||||
)
|
||||
|
||||
from gamestonk_terminal.helper_funcs import (
|
||||
valid_date,
|
||||
@@ -214,14 +219,22 @@ Market {('CLOSED', 'OPEN')[b_is_stock_market_open()]}
|
||||
)
|
||||
parser.add_argument(
|
||||
"-s",
|
||||
"--start_date",
|
||||
"--start",
|
||||
dest="s_start",
|
||||
type=valid_date,
|
||||
default=(datetime.now() - timedelta(days=366)).strftime("%Y-%m-%d"),
|
||||
default=self.stock.index[0],
|
||||
help="Start date for candle data",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--plotly",
|
||||
"-e",
|
||||
"--end",
|
||||
dest="s_end",
|
||||
type=valid_date,
|
||||
default=self.stock.index[-1],
|
||||
help="End date for candle data",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--it",
|
||||
dest="plotly",
|
||||
action="store_true",
|
||||
default=False,
|
||||
@@ -280,7 +293,7 @@ Market {('CLOSED', 'OPEN')[b_is_stock_market_open()]}
|
||||
if not ns_parser:
|
||||
return
|
||||
if not self.ticker:
|
||||
print("No ticker loaded. First use `load {ticker}`\n")
|
||||
print("No ticker loaded. First use `load {ticker}`\n")
|
||||
return
|
||||
|
||||
if ns_parser.raw:
|
||||
@@ -293,11 +306,11 @@ Market {('CLOSED', 'OPEN')[b_is_stock_market_open()]}
|
||||
)
|
||||
|
||||
else:
|
||||
df_stock = process_candle(self.stock)
|
||||
|
||||
display_candle(
|
||||
s_ticker=self.ticker + "." + self.suffix
|
||||
if self.suffix
|
||||
else self.ticker,
|
||||
s_start=ns_parser.s_start,
|
||||
s_ticker=self.ticker,
|
||||
df_stock=df_stock,
|
||||
plotly=ns_parser.plotly,
|
||||
)
|
||||
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
__docformat__ = "numpy"
|
||||
import argparse
|
||||
from datetime import datetime, timedelta
|
||||
from typing import List
|
||||
|
||||
from typing import List, Union
|
||||
import warnings
|
||||
from scipy import stats
|
||||
import matplotlib.pyplot as plt
|
||||
import mplfinance as mpf
|
||||
import pandas as pd
|
||||
@@ -19,13 +20,13 @@ from tabulate import tabulate
|
||||
from gamestonk_terminal import config_plot as cfgPlot
|
||||
from gamestonk_terminal import config_terminal as cfg
|
||||
from gamestonk_terminal import feature_flags as gtff
|
||||
from gamestonk_terminal.common.technical_analysis import trendline_api as trend
|
||||
from gamestonk_terminal.helper_funcs import (
|
||||
parse_known_args_and_warn,
|
||||
plot_autoscale,
|
||||
valid_date,
|
||||
)
|
||||
|
||||
warnings.simplefilter("ignore")
|
||||
# pylint: disable=no-member,too-many-branches,C0302
|
||||
|
||||
|
||||
@@ -139,6 +140,14 @@ def load(
|
||||
dest="s_start_date",
|
||||
help="The starting date (format YYYY-MM-DD) of the stock",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-e",
|
||||
"--end",
|
||||
type=valid_date,
|
||||
default=datetime.now().strftime("%Y-%m-%d"),
|
||||
dest="s_end_date",
|
||||
help="The ending date (format YYYY-MM-DD) of the stock",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-i",
|
||||
"--interval",
|
||||
@@ -209,12 +218,17 @@ def load(
|
||||
df_stock_candidate.sort_index(ascending=True, inplace=True)
|
||||
|
||||
# Slice dataframe from the starting date YYYY-MM-DD selected
|
||||
df_stock_candidate = df_stock_candidate[ns_parser.s_start_date :]
|
||||
df_stock_candidate = df_stock_candidate[
|
||||
ns_parser.s_start_date : ns_parser.s_end_date
|
||||
]
|
||||
|
||||
# Yahoo Finance Source
|
||||
elif ns_parser.source == "yf":
|
||||
df_stock_candidate = yf.download(
|
||||
ns_parser.s_ticker, start=ns_parser.s_start_date, progress=False
|
||||
ns_parser.s_ticker,
|
||||
start=ns_parser.s_start_date,
|
||||
end=ns_parser.s_end_date,
|
||||
progress=False,
|
||||
)
|
||||
|
||||
# Check that loading a stock was not successful
|
||||
@@ -252,7 +266,9 @@ def load(
|
||||
df_stock_candidate.sort_index(ascending=True, inplace=True)
|
||||
|
||||
# Slice dataframe from the starting date YYYY-MM-DD selected
|
||||
df_stock_candidate = df_stock_candidate[ns_parser.s_start_date :]
|
||||
df_stock_candidate = df_stock_candidate[
|
||||
ns_parser.s_start_date : ns_parser.s_end_date
|
||||
]
|
||||
|
||||
# Check if start time from dataframe is more recent than specified
|
||||
if df_stock_candidate.index[0] > pd.to_datetime(ns_parser.s_start_date):
|
||||
@@ -290,7 +306,9 @@ def load(
|
||||
df_stock_candidate.sort_index(ascending=True, inplace=True)
|
||||
|
||||
# Slice dataframe from the starting date YYYY-MM-DD selected
|
||||
df_stock_candidate = df_stock_candidate[ns_parser.s_start_date :]
|
||||
df_stock_candidate = df_stock_candidate[
|
||||
ns_parser.s_start_date : ns_parser.s_end_date
|
||||
]
|
||||
|
||||
# Check if start time from dataframe is more recent than specified
|
||||
if df_stock_candidate.index[0] > pd.to_datetime(ns_parser.s_start_date):
|
||||
@@ -376,7 +394,9 @@ def load(
|
||||
df_stock_candidate.index.name = "date"
|
||||
|
||||
# Slice dataframe from the starting date YYYY-MM-DD selected
|
||||
df_stock_candidate = df_stock_candidate[ns_parser.s_start_date :]
|
||||
df_stock_candidate = df_stock_candidate[
|
||||
ns_parser.s_start_date : ns_parser.s_end_date
|
||||
]
|
||||
|
||||
# Check if start time from dataframe is more recent than specified
|
||||
if df_stock_candidate.index[0] > pd.to_datetime(ns_parser.s_start_date):
|
||||
@@ -407,27 +427,23 @@ def load(
|
||||
return [s_ticker, s_start, s_interval, df_stock]
|
||||
|
||||
|
||||
def display_candle(s_ticker: str, s_start: datetime, plotly: bool):
|
||||
"""Shows candle plot of loaded ticker
|
||||
def display_candle(s_ticker: str, df_stock: pd.DataFrame, plotly: bool):
|
||||
"""Shows candle plot of loaded ticker. [Source: Yahoo Finance, IEX Cloud or Alpha Vantage]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
df_stock: pd.DataFrame
|
||||
Stock dataframe
|
||||
s_ticker: str
|
||||
Ticker to display
|
||||
s_start: datetime
|
||||
Starting date for candle
|
||||
Ticker name
|
||||
plotly: bool
|
||||
Flag to show interactive plotly chart
|
||||
|
||||
"""
|
||||
# TODO: Add option to customize plot even further
|
||||
print(type(s_start))
|
||||
df_stock = trend.load_ticker(s_ticker, s_start)
|
||||
df_stock["ma20"] = df_stock["Close"].rolling(20).mean().fillna(method="bfill")
|
||||
df_stock["ma50"] = df_stock["Close"].rolling(50).mean().fillna(method="bfill")
|
||||
|
||||
df_stock = trend.find_trendline(df_stock, "OC_High", "high")
|
||||
df_stock = trend.find_trendline(df_stock, "OC_Low", "low")
|
||||
df_stock = find_trendline(df_stock, "OC_High", "high")
|
||||
df_stock = find_trendline(df_stock, "OC_Low", "low")
|
||||
if not plotly:
|
||||
mc = mpf.make_marketcolors(
|
||||
up="green",
|
||||
@@ -460,7 +476,7 @@ def display_candle(s_ticker: str, s_start: datetime, plotly: bool):
|
||||
type="candle",
|
||||
mav=(20, 50),
|
||||
volume=True,
|
||||
title=f"\n{s_ticker} - Starting {s_start.strftime('%Y-%m-%d')}",
|
||||
title=f"\nStock {s_ticker}",
|
||||
addplot=ap0,
|
||||
xrotation=10,
|
||||
style=s,
|
||||
@@ -812,3 +828,120 @@ def plot_view_stock(df: pd.DataFrame, symbol: str, interval: str):
|
||||
|
||||
plt.show()
|
||||
print("")
|
||||
|
||||
|
||||
def load_ticker(
|
||||
ticker: str, start_date: Union[str, datetime], end_date: Union[str, datetime] = ""
|
||||
) -> pd.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 : Union[str,datetime]
|
||||
Start date to load stock ticker data formatted YYYY-MM-DD.
|
||||
end_date : Union[str,datetime]
|
||||
End 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.
|
||||
"""
|
||||
if end_date:
|
||||
df_data = yf.download(ticker, start=start_date, end=end_date, progress=False)
|
||||
else:
|
||||
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 process_candle(df_data: pd.DataFrame) -> pd.DataFrame:
|
||||
"""Process DataFrame into candle style plot
|
||||
|
||||
Parameters
|
||||
----------
|
||||
df_data : DataFrame
|
||||
Stock dataframe.
|
||||
|
||||
Returns
|
||||
-------
|
||||
DataFrame
|
||||
A Panda's data frame with columns Open, High, Low, Close, Adj Close, Volume, date_id, OC-High, OC-Low.
|
||||
"""
|
||||
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: pd.DataFrame, y_key: str, high_low: str = "high"
|
||||
) -> pd.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 = stats.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 = stats.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
|
||||
|
||||
Reference in New Issue
Block a user