screener-saham-demo / app /helper_script.py
gusti-adli
revert
0a3ce35
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