2024-10-23 18:58:31 +00:00
|
|
|
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
|
2024-10-28 17:52:46 +00:00
|
|
|
from datetime import datetime, timedelta
|
|
|
|
from pandas import DataFrame, Series
|
|
|
|
from typing import Callable, List, Dict
|
2024-10-23 18:58:31 +00:00
|
|
|
|
|
|
|
from ohlc import ohlc
|
|
|
|
from plotting import CandlestickChart, figure_with_subplots
|
|
|
|
|
2024-10-29 13:30:16 +00:00
|
|
|
from strategies import cumulative_rsi
|
2024-10-29 14:01:41 +00:00
|
|
|
from strategies import double_5s
|
2024-10-31 16:38:12 +00:00
|
|
|
from strategies import down_days_in_a_row
|
2024-10-28 17:52:46 +00:00
|
|
|
from strategies import end_of_month
|
2024-10-28 18:27:47 +00:00
|
|
|
from strategies import internal_bar_strength
|
2024-10-31 07:17:26 +00:00
|
|
|
from strategies import lower_lows
|
2024-10-30 07:24:00 +00:00
|
|
|
from strategies import trin
|
2024-11-08 18:54:35 +00:00
|
|
|
from strategies import turnaround
|
2024-10-28 18:34:08 +00:00
|
|
|
from strategies import two_period_rsi
|
2024-11-10 13:57:00 +00:00
|
|
|
from strategies import vix_reversal_1
|
2024-10-29 19:57:58 +00:00
|
|
|
from strategies import vix_rsi
|
2024-10-28 17:52:46 +00:00
|
|
|
from stylesheets import grid_stylesheet, theme_stylesheet
|
2024-10-23 18:58:31 +00:00
|
|
|
|
2024-10-28 17:52:46 +00:00
|
|
|
app = Dash(__name__, external_stylesheets = [theme_stylesheet, grid_stylesheet])
|
2024-10-23 18:58:31 +00:00
|
|
|
app.title = 'Swing Trading Dashboard'
|
|
|
|
|
2024-10-28 17:52:46 +00:00
|
|
|
load_figure_template('lux_dark')
|
2024-10-23 18:58:31 +00:00
|
|
|
|
2024-10-28 17:52:46 +00:00
|
|
|
SignalFunction = Callable[[DataFrame], Series]
|
|
|
|
|
|
|
|
signal_functions: List[Dict[str, SignalFunction]] = [
|
2024-10-28 18:34:08 +00:00
|
|
|
{'strategy': '2-Period RSI', 'function': two_period_rsi.signals},
|
2024-10-29 13:30:16 +00:00
|
|
|
{'strategy': 'Cumulative RSI', 'function': cumulative_rsi.signals},
|
2024-10-29 14:01:41 +00:00
|
|
|
{'strategy': 'Double 5\'s', 'function': double_5s.signals},
|
2024-10-31 16:38:12 +00:00
|
|
|
{'strategy': 'Down Days in a Row', 'function': down_days_in_a_row.signals},
|
2024-10-28 17:52:46 +00:00
|
|
|
{'strategy': 'End of Month', 'function': end_of_month.signals},
|
2024-10-29 19:57:58 +00:00
|
|
|
{'strategy': 'Internal Bar Strength', 'function': internal_bar_strength.signals},
|
2024-10-31 07:17:26 +00:00
|
|
|
{'strategy': 'Lower Lows', 'function': lower_lows.signals},
|
2024-10-30 07:24:00 +00:00
|
|
|
{'strategy': 'TRIN', 'function': trin.signals},
|
2024-11-08 18:54:35 +00:00
|
|
|
{'strategy': 'Turnaround', 'function': turnaround.signals},
|
2024-11-10 13:57:00 +00:00
|
|
|
{'strategy': 'VIX Reversal 1', 'function': vix_reversal_1.signals},
|
2024-10-29 19:57:58 +00:00
|
|
|
{'strategy': 'VIX RSI', 'function': vix_rsi.signals}
|
2024-10-23 18:58:31 +00:00
|
|
|
]
|
|
|
|
|
2024-10-28 17:52:46 +00:00
|
|
|
symbol = 'SPY'
|
2024-10-28 18:04:43 +00:00
|
|
|
today = datetime.today()
|
2024-10-28 18:25:04 +00:00
|
|
|
data = ohlc(symbol = symbol, start_date = today - timedelta(days = 365), end_date = today)
|
2024-10-23 18:58:31 +00:00
|
|
|
|
2024-10-28 18:04:43 +00:00
|
|
|
def calculate_signals(days: int = 12) -> DataFrame:
|
2024-10-28 17:52:46 +00:00
|
|
|
signal_data = []
|
|
|
|
|
|
|
|
for signal_info in signal_functions:
|
|
|
|
signal_dict = {'Strategy': signal_info['strategy']}
|
2024-10-28 18:04:43 +00:00
|
|
|
|
|
|
|
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']]
|
2024-10-28 17:52:46 +00:00
|
|
|
for date, signal in zip(dates, signals):
|
|
|
|
signal_dict[date] = signal
|
2024-10-28 18:04:43 +00:00
|
|
|
|
2024-10-28 17:52:46 +00:00
|
|
|
signal_data.append(signal_dict)
|
|
|
|
|
|
|
|
return DataFrame(signal_data)
|
|
|
|
|
|
|
|
def load_chart() -> dict:
|
2024-10-28 18:25:04 +00:00
|
|
|
chart_data = data.tail(180)
|
2024-10-23 18:58:31 +00:00
|
|
|
candlestick_chart = CandlestickChart(
|
2024-10-28 18:25:04 +00:00
|
|
|
x = chart_data['Date'],
|
|
|
|
opens = chart_data['Open'],
|
|
|
|
highs = chart_data['High'],
|
|
|
|
lows = chart_data['Low'],
|
|
|
|
closes = chart_data['Close']
|
2024-10-23 18:58:31 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
return figure_with_subplots([[candlestick_chart]])
|
|
|
|
|
2024-10-28 18:04:43 +00:00
|
|
|
signal_data = calculate_signals()
|
2024-10-28 17:52:46 +00:00
|
|
|
|
2024-10-23 18:58:31 +00:00
|
|
|
app.layout = dbc.Container(
|
|
|
|
[
|
|
|
|
dcc.Graph(
|
|
|
|
id = 'candlestick-chart',
|
|
|
|
config = {'displayModeBar': False},
|
|
|
|
figure = load_chart(),
|
|
|
|
),
|
|
|
|
html.Div(
|
|
|
|
AgGrid(
|
|
|
|
columnDefs = [
|
2024-10-28 17:52:46 +00:00
|
|
|
{'field': col, 'flex': 3} if col == 'Strategy' else {'field': col, 'flex': 1, 'cellRenderer': 'SignalRenderer'}
|
|
|
|
for col in signal_data.columns
|
2024-10-23 18:58:31 +00:00
|
|
|
],
|
2024-10-28 17:52:46 +00:00
|
|
|
rowData = signal_data.to_dict(orient = 'records'),
|
2024-10-23 18:58:31 +00:00
|
|
|
defaultColDef = {'flex': 1, 'sortable': False, 'resizable': False},
|
|
|
|
dashGridOptions = {'domLayout': 'autoHeight'},
|
|
|
|
style = {'height': None}
|
|
|
|
),
|
|
|
|
className = 'dbc dbc-ag-grid'
|
|
|
|
)
|
|
|
|
],
|
2024-10-28 17:52:46 +00:00
|
|
|
style = {'maxWidth': '1200px', 'margin': '0 auto'},
|
2024-10-23 18:58:31 +00:00
|
|
|
fluid = True
|
|
|
|
)
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
app.run_server(debug = False)
|