import dash_bootstrap_components as dbc from dash import Dash, dcc, html from dash_ag_grid import AgGrid from dash_bootstrap_templates import load_figure_template from datetime import datetime, timedelta from pandas import DataFrame, Series from typing import Callable, List, Dict from ohlc import ohlc from plotting import CandlestickChart, figure_with_subplots from strategies import end_of_month from strategies import internal_bar_strength from strategies import two_period_rsi from stylesheets import grid_stylesheet, theme_stylesheet app = Dash(__name__, external_stylesheets = [theme_stylesheet, grid_stylesheet]) app.title = 'Swing Trading Dashboard' load_figure_template('lux_dark') SignalFunction = Callable[[DataFrame], Series] signal_functions: List[Dict[str, SignalFunction]] = [ {'strategy': '2-Period RSI', 'function': two_period_rsi.signals}, {'strategy': 'End of Month', 'function': end_of_month.signals}, {'strategy': 'Internal Bar Strength', 'function': internal_bar_strength.signals} ] symbol = 'SPY' today = datetime.today() data = ohlc(symbol = symbol, start_date = today - timedelta(days = 365), end_date = today) def calculate_signals(days: int = 12) -> DataFrame: signal_data = [] for signal_info in signal_functions: signal_dict = {'Strategy': signal_info['strategy']} signals = signal_info['function'](data).tail(days) dates = [datetime.strptime(str(date), '%Y-%m-%d').strftime('%m/%d') for date in data.tail(days)['Date']] for date, signal in zip(dates, signals): signal_dict[date] = signal signal_data.append(signal_dict) return DataFrame(signal_data) def load_chart() -> dict: chart_data = data.tail(180) candlestick_chart = CandlestickChart( x = chart_data['Date'], opens = chart_data['Open'], highs = chart_data['High'], lows = chart_data['Low'], closes = chart_data['Close'] ) return figure_with_subplots([[candlestick_chart]]) signal_data = calculate_signals() app.layout = dbc.Container( [ dcc.Graph( id = 'candlestick-chart', config = {'displayModeBar': False}, figure = load_chart(), ), html.Div( AgGrid( columnDefs = [ {'field': col, 'flex': 3} if col == 'Strategy' else {'field': col, 'flex': 1, 'cellRenderer': 'SignalRenderer'} for col in signal_data.columns ], rowData = signal_data.to_dict(orient = 'records'), defaultColDef = {'flex': 1, 'sortable': False, 'resizable': False}, dashGridOptions = {'domLayout': 'autoHeight'}, style = {'height': None} ), className = 'dbc dbc-ag-grid' ) ], style = {'maxWidth': '1200px', 'margin': '0 auto'}, fluid = True ) if __name__ == '__main__': app.run_server(debug = False)