TCPDashboard/dashboard/components/indicator_modal.py
Vasily.onl b49e39dcb4 Implement multi-timeframe support for indicators
- Enhanced the `UserIndicator` class to include an optional `timeframe` attribute for custom indicator timeframes.
- Updated the `get_indicator_data` method in `MarketDataIntegrator` to fetch and calculate indicators based on the specified timeframe, ensuring proper data alignment and handling.
- Modified the `ChartBuilder` to pass the correct DataFrame for plotting indicators with different timeframes.
- Added UI elements in the indicator modal for selecting timeframes, improving user experience.
- Updated relevant JSON templates to include the new `timeframe` field for all indicators.
- Refactored the `prepare_chart_data` function to ensure it returns a DataFrame with a `DatetimeIndex` for consistent calculations.

This commit enhances the flexibility and usability of the indicator system, allowing users to analyze data across various timeframes.
2025-06-06 15:06:17 +08:00

141 lines
6.8 KiB
Python

"""
Indicator modal component for creating and editing indicators.
"""
from dash import html, dcc
import dash_bootstrap_components as dbc
def create_indicator_modal():
"""Create the indicator modal dialog for adding/editing indicators."""
return html.Div([
dcc.Store(id='edit-indicator-store', data=None),
dbc.Modal([
dbc.ModalHeader(dbc.ModalTitle("📊 Add New Indicator", id="modal-title")),
dbc.ModalBody([
# Basic Settings
html.H5("Basic Settings"),
dbc.Row([
dbc.Col(dbc.Label("Indicator Name:"), width=12),
dbc.Col(dcc.Input(id='indicator-name-input', type='text', placeholder='e.g., "SMA 30 Custom"', className="w-100"), width=12)
], className="mb-3"),
dbc.Row([
dbc.Col(dbc.Label("Indicator Type:"), width=12),
dbc.Col(dcc.Dropdown(
id='indicator-type-dropdown',
options=[
{'label': 'Simple Moving Average (SMA)', 'value': 'sma'},
{'label': 'Exponential Moving Average (EMA)', 'value': 'ema'},
{'label': 'Relative Strength Index (RSI)', 'value': 'rsi'},
{'label': 'MACD', 'value': 'macd'},
{'label': 'Bollinger Bands', 'value': 'bollinger_bands'}
],
placeholder='Select indicator type',
), width=12)
], className="mb-3"),
dbc.Row([
dbc.Col(dbc.Label("Timeframe (Optional):"), width=12),
dbc.Col(dcc.Dropdown(
id='indicator-timeframe-dropdown',
options=[
{'label': 'Chart Timeframe', 'value': ''},
{'label': "1 Second", 'value': '1s'},
{'label': "5 Seconds", 'value': '5s'},
{'label': "15 Seconds", 'value': '15s'},
{'label': "30 Seconds", 'value': '30s'},
{'label': '1 Minute', 'value': '1m'},
{'label': '5 Minutes', 'value': '5m'},
{'label': '15 Minutes', 'value': '15m'},
{'label': '1 Hour', 'value': '1h'},
{'label': '4 Hours', 'value': '4h'},
{'label': '1 Day', 'value': '1d'},
],
value='',
placeholder='Defaults to chart timeframe'
), width=12),
], className="mb-3"),
dbc.Row([
dbc.Col(dbc.Label("Description (Optional):"), width=12),
dbc.Col(dcc.Textarea(
id='indicator-description-input',
placeholder='Brief description of this indicator configuration...',
style={'width': '100%', 'height': '60px'}
), width=12)
], className="mb-3"),
html.Hr(),
# Parameters Section
html.H5("Parameters"),
html.Div(
id='indicator-parameters-message',
children=[html.P("Select an indicator type to configure parameters", className="text-muted fst-italic")]
),
# Parameter fields (SMA, EMA, etc.)
create_parameter_fields(),
html.Hr(),
# Styling Section
html.H5("Styling"),
dbc.Row([
dbc.Col([
dbc.Label("Color:"),
dcc.Input(id='indicator-color-input', type='text', value='#007bff', className="w-100")
], width=6),
dbc.Col([
dbc.Label("Line Width:"),
dcc.Slider(id='indicator-line-width-slider', min=1, max=5, step=1, value=2, marks={i: str(i) for i in range(1, 6)})
], width=6)
], className="mb-3"),
]),
dbc.ModalFooter([
html.Div(id='save-indicator-feedback', className="me-auto"),
dbc.Button("Cancel", id="cancel-indicator-btn", color="secondary"),
dbc.Button("Save Indicator", id="save-indicator-btn", color="primary")
])
], id='indicator-modal', size="lg", is_open=False),
])
def create_parameter_fields():
"""Helper function to create parameter input fields for all indicator types."""
return html.Div([
# SMA Parameters
html.Div([
dbc.Label("Period:"),
dcc.Input(id='sma-period-input', type='number', value=20, min=1, max=200),
dbc.FormText("Number of periods for Simple Moving Average calculation")
], id='sma-parameters', style={'display': 'none'}, className="mb-3"),
# EMA Parameters
html.Div([
dbc.Label("Period:"),
dcc.Input(id='ema-period-input', type='number', value=12, min=1, max=200),
dbc.FormText("Number of periods for Exponential Moving Average calculation")
], id='ema-parameters', style={'display': 'none'}, className="mb-3"),
# RSI Parameters
html.Div([
dbc.Label("Period:"),
dcc.Input(id='rsi-period-input', type='number', value=14, min=2, max=50),
dbc.FormText("Number of periods for RSI calculation (typically 14)")
], id='rsi-parameters', style={'display': 'none'}, className="mb-3"),
# MACD Parameters
html.Div([
dbc.Row([
dbc.Col([dbc.Label("Fast Period:"), dcc.Input(id='macd-fast-period-input', type='number', value=12)], width=4),
dbc.Col([dbc.Label("Slow Period:"), dcc.Input(id='macd-slow-period-input', type='number', value=26)], width=4),
dbc.Col([dbc.Label("Signal Period:"), dcc.Input(id='macd-signal-period-input', type='number', value=9)], width=4),
]),
dbc.FormText("MACD periods: Fast EMA, Slow EMA, and Signal line")
], id='macd-parameters', style={'display': 'none'}, className="mb-3"),
# Bollinger Bands Parameters
html.Div([
dbc.Row([
dbc.Col([dbc.Label("Period:"), dcc.Input(id='bb-period-input', type='number', value=20)], width=6),
dbc.Col([dbc.Label("Standard Deviation:"), dcc.Input(id='bb-stddev-input', type='number', value=2.0, step=0.1)], width=6),
]),
dbc.FormText("Period for middle line (SMA) and standard deviation multiplier")
], id='bb-parameters', style={'display': 'none'}, className="mb-3")
])