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 |