Files
OpenBB/bots/stocks/candle.py
Colin Delahunty fae93c67ad Refactor Bot (#1326)
* First commit

* Renamed to bot

* change from discordbot to bots imports

* refractor cmds

+ autocomplete helpers
+ updated dps plots/candle
+ quote cmd

* isort fix

* Update helpers.py

* Added first refactor

* Added commands and refactor

* Added description handler

* Through grains

* ta + image border helper

* Added indices

* merged

* Finished econ

* options refactor

* dark_pool_shorts, candle, quote done

* pagination/dropdown logic to helpers + fixes

* dd/disc/insider done + add image logic to helpers

* linting

* removed plt style

* Almost done with Gov

* fixing conflicts

* Finished gov (excpect ones mentioned)

* screener done

* Test bug refactor

* Store changes to switch

* Finished refactor

* Fixed error

* Delete ::40

* Fixed issue

* Fixed black

* finished

* fixes

Co-authored-by: teh_coderer <me@tehcoderer.com>
Co-authored-by: didierlopes.eth <dro.lopes@campus.fct.unl.pt>
2022-02-20 10:36:59 -05:00

210 lines
5.9 KiB
Python

from datetime import datetime, timedelta
import plotly.graph_objects as go
import yfinance as yf
from plotly.subplots import make_subplots
import bots.config_discordbot as cfg
from bots.config_discordbot import logger
from bots import helpers
from gamestonk_terminal.common.technical_analysis import overlap_model
def candle_command(
ticker: str = "",
interval: int = 15,
past_days: int = 1,
start="",
end="",
):
"""Shows candle plot of loaded ticker. [Source: Yahoo Finance, IEX Cloud or Alpha Vantage]
Parameters
----------
ticker: str
Ticker name
interval: int
chart mins or daily
past_days: int
Display the past * days. Default: 1(Not for Daily)
start: str
start date format YYYY-MM-DD
end: str
end date format YYYY-MM-DD
"""
logger.info("candle %s %s %s %s", ticker, interval, start, end)
if start == "":
start = datetime.now() - timedelta(days=365)
else:
start = datetime.strptime(start, cfg.DATE_FORMAT)
if end == "":
end = datetime.now()
else:
end = datetime.strptime(end, cfg.DATE_FORMAT)
futures = "=F" or "^"
crypto = "-USD"
if interval == 1440:
df_stock_candidate = yf.download(
ticker,
start=start,
end=end,
progress=False,
)
# Check that loading a stock was not successful
if df_stock_candidate.empty:
raise Exception(f"No data found for {ticker.upper()}")
df_stock_candidate.index.name = "date"
else:
s_int = str(interval) + "m"
d_granularity = {
"1m": past_days,
"5m": past_days,
"15m": past_days,
"30m": past_days,
"60m": past_days,
}
s_start_dt = datetime.utcnow() - timedelta(days=d_granularity[s_int])
s_date_start = s_start_dt.strftime("%Y-%m-%d")
df_stock_candidate = yf.download(
ticker,
start=s_date_start if s_start_dt > start else start.strftime("%Y-%m-%d"),
progress=False,
interval=s_int,
prepost=True,
)
# Check that loading a stock was not successful
if df_stock_candidate.empty:
raise Exception(f"No data found for {ticker.upper()}.")
df_stock_candidate.index = df_stock_candidate.index.tz_localize(None)
df_stock_candidate.index.name = "date"
df_stock = df_stock_candidate
price_df = df_stock.loc[(df_stock.index >= start) & (df_stock.index < end)]
df_vwap = overlap_model.vwap(price_df, 0)
plt_title = [f"{ticker.upper()} Intraday {interval}min", "Volume"]
title = f"Intraday {interval}min Chart for {ticker.upper()}"
if interval == 1440:
plt_title = [f"{ticker.upper()} Daily", "Volume"]
title = f"Daily Chart for {ticker.upper()}"
fig = make_subplots(
shared_xaxes=True,
vertical_spacing=0.09,
subplot_titles=plt_title,
specs=[[{"secondary_y": True}]],
)
fig.add_trace(
go.Candlestick(
x=df_stock.index,
open=df_stock.Open,
high=df_stock.High,
low=df_stock.Low,
close=df_stock.Close,
name="OHLC",
showlegend=False,
),
secondary_y=True,
)
fig.add_trace(
go.Bar(
x=df_stock.index,
y=df_stock.Volume,
name="Volume",
yaxis="y2",
marker_color="#d81aea",
opacity=0.4,
showlegend=False,
),
secondary_y=False,
)
if interval != 1440:
fig.add_trace(
go.Scatter(
name="VWAP",
x=df_stock.index,
y=df_vwap["VWAP_D"],
opacity=0.65,
line=dict(color="#fdc708", width=2),
showlegend=True,
),
secondary_y=True,
)
fig.update_xaxes(showspikes=True, spikesnap="cursor", spikemode="across")
fig.update_yaxes(showspikes=True, spikethickness=2)
fig.update_layout(
margin=dict(l=0, r=0, t=40, b=20),
template=cfg.PLT_CANDLE_STYLE_TEMPLATE,
yaxis2_title="Price ($)",
yaxis_title="Volume",
yaxis=dict(
showgrid=False,
fixedrange=False,
side="left",
titlefont=dict(color="#d81aea"),
tickfont=dict(color="#d81aea"),
nticks=20,
),
yaxis2=dict(
side="right",
fixedrange=False,
anchor="x",
layer="above traces",
overlaying="y",
nticks=20,
),
xaxis=dict(
rangeslider=dict(visible=False),
type="date",
showspikes=True,
),
legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1),
dragmode="pan",
hovermode="x unified",
spikedistance=1000,
hoverdistance=100,
)
if futures in ticker.upper():
fig.update_xaxes(
rangebreaks=[
dict(bounds=["sat", "sun"]),
dict(bounds=[17, 17.50], pattern="hour"),
],
)
elif crypto not in ticker.upper() and interval != 1440:
fig.update_xaxes(
rangebreaks=[
dict(bounds=["sat", "mon"]),
dict(bounds=[20, 9.50], pattern="hour"),
],
)
config = dict({"scrollZoom": True})
imagefile = "candle.png"
# Check if interactive settings are enabled
plt_link = ""
if cfg.INTERACTIVE:
html_ran = helpers.uuid_get()
fig.write_html(f"in/candle_{html_ran}.html", config=config)
plt_link = f"[Interactive]({cfg.INTERACTIVE_URL}/candle_{html_ran}.html)"
fig.update_layout(
width=800,
height=500,
)
imagefile = helpers.image_border(imagefile, fig=fig)
return {
"title": title,
"description": plt_link,
"imagefile": imagefile,
}