Spaces:
Build error
Build error
from bokeh.plotting import figure | |
from bokeh.models import ColumnDataSource, HoverTool, Arrow, NormalHead | |
from bokeh.palettes import Spectral4 | |
from bokeh.embed import components | |
import sqlite3 | |
import pandas as pd | |
def get_tickers(pattern, last_dates=1): | |
# connect to database | |
with sqlite3.connect("dataset/ihsg.db") as con: | |
# retrieve data from database | |
tickers = pd.read_sql(f""" | |
SELECT Kode | |
FROM patterns | |
WHERE Date IN ( | |
SELECT Date | |
FROM ( | |
SELECT Date, ROW_NUMBER() OVER(ORDER BY Date DESC) AS rnk | |
FROM historical | |
WHERE Kode = 'IHSG' | |
) a | |
WHERE rnk <= {last_dates + 1} | |
) | |
AND Pattern = '{pattern}' | |
ORDER BY Pattern_Score DESC, Open_Close_Change DESC, High_Low_Change DESC | |
""", | |
con=con, | |
).iloc[:, 0].to_list() | |
return tickers | |
def get_data(kode, pattern): | |
# connect to database | |
with sqlite3.connect("dataset/ihsg.db") as con: | |
# retrieve data from database | |
df = pd.read_sql(f""" | |
SELECT * | |
FROM historical | |
WHERE Kode = '{kode}' | |
ORDER BY Date | |
""", | |
con=con, | |
parse_dates=['Date'], | |
) | |
# df = pd.read_sql(f""" | |
# SELECT | |
# historical.Date, | |
# historical.Open, | |
# historical.High, | |
# historical.Low, | |
# historical.Close, | |
# patterns.Pattern_Score | |
# FROM historical | |
# LEFT JOIN ( | |
# SELECT Date, Kode, Pattern_Score | |
# FROM patterns | |
# WHERE Pattern = '{pattern}' | |
# ) AS patterns | |
# USING(Kode, Date) | |
# WHERE Kode = '{kode}' | |
# ORDER BY Date | |
# """, | |
# con=con, | |
# parse_dates=['Date'], | |
# ) | |
nama = pd.read_sql( | |
f"SELECT Nama FROM list_perusahaan WHERE Kode = '{kode}'", | |
con=con, | |
).values[0][0] | |
return df, nama | |
def plot_candlestick(df, nama, kode): | |
# calculate simple moving average | |
for period in [5,20,200]: | |
df[f'sma{period}'] = df['Close'].rolling(period, period).mean() | |
# Prepare data for plotting | |
cds = ColumnDataSource(df) | |
cds_inc = ColumnDataSource(df[df["Close"] >= df["Open"]]) | |
cds_dec = ColumnDataSource(df[df["Open"] > df["Close"]]) | |
# assign figure canvas to variable p | |
x_range = (max(len(df) - 60.5, 0), len(df)) | |
p = figure( | |
tools="pan,zoom_in,zoom_out,box_zoom,undo,redo,reset,save", | |
plot_width=600, | |
plot_height=400, | |
title = f"{kode}\t({nama})", | |
x_range= x_range, | |
y_range= ( | |
df.loc[x_range[0]//1-5:x_range[1], ["Open", "High", "Low", "Close", "sma5", "sma20", "sma200"]].min().min() * 0.875, | |
df.loc[x_range[0]//1-5:x_range[1], ["Open", "High", "Low", "Close", "sma5", "sma20", "sma200"]].max().max() * 1.125 | |
) | |
) | |
# xaxis setup | |
p.xaxis.major_label_overrides = { | |
i: date.strftime('%d %b %Y') for i, date in enumerate(df["Date"]) | |
} | |
p.xaxis.bounds = (0, df.index[-1]) | |
p.xaxis.major_label_orientation = (22/7)/4 | |
p.grid.grid_line_alpha=0.3 | |
# # plot pattern arrow | |
# for idx in df[df["Pattern_Score"].notna()].tail().index: | |
# row = df.loc[idx, ["Open", "High", "Low", "Close"]] | |
# x_start = row.min() | |
# if x_start < 200: | |
# x_start -= 2 | |
# x_end = x_start - 4 | |
# elif x_start < 500: | |
# x_start -= 4 | |
# x_end = x_start - 4 | |
# else: | |
# x_start -= 8 | |
# x_end = x_start - 6 | |
# p.add_layout(Arrow( | |
# end=NormalHead(fill_color="black"), | |
# line_color="black", | |
# x_start = x_start, | |
# x_end = x_end, | |
# y_start = idx, | |
# y_end=idx | |
# )) | |
# plot candlestick wicks with HoverTool | |
p.add_tools(HoverTool( | |
renderers=[p.segment("index", "High", "index", "Low", source=cds, color="black", line_width=1)], | |
tooltips=[ | |
("Date","@Date{%F}"), | |
("Open","@Open{0.2f}"), | |
("High", "@High{0.2f}"), | |
("Low", "@Low{0.2f}"), | |
("Close", "@Close{0.2f}"), | |
], | |
formatters={"@Date":"datetime"} | |
)) | |
# plot candlestick bars | |
for data, color in [(cds_inc, "#26a69a"), (cds_dec, "#ef5350")]: | |
p.vbar("index", 0.5, "Open", "Close", source=data, fill_color=color, line_color="black", line_width=1) | |
# plot moving average with HoverTool | |
for period, color in zip([5,20,200], Spectral4): | |
p.add_tools(HoverTool( | |
renderers=[p.line( | |
"index", | |
f"sma{period}", | |
source=cds, | |
line_width=2, | |
alpha=0.8, | |
color=color, | |
legend_label=f'SMA {period}\t')], | |
tooltips=[ | |
(f"SMA {period}", "@sma%s{0.2f}" %(period)), | |
], | |
)) | |
# legend setup | |
p.legend.location = "top_left" | |
p.legend.click_policy="hide" | |
p.legend.orientation="horizontal" | |
# generate script and div | |
script, div = components(p) | |
return script, div |