- Introduced dynamic generation of parameter fields and callback handling for indicators, enhancing modularity and maintainability. - Updated `config_utils.py` with new utility functions to load indicator templates and generate dynamic outputs and states for parameter fields. - Refactored `indicators.py` to utilize these utilities, streamlining the callback logic and improving user experience by reducing hardcoded elements. - Modified `indicator_modal.py` to create parameter fields dynamically based on JSON templates, eliminating the need for manual updates when adding new indicators. - Added documentation outlining the new data-driven architecture for indicators, improving clarity and guidance for future development. These changes significantly enhance the flexibility and scalability of the indicator system, aligning with project goals for maintainability and performance.
23 KiB
Chart Configuration System
The Chart Configuration System provides comprehensive management of chart settings, indicator definitions, and trading strategy configurations. It includes schema validation, default presets, and extensible configuration patterns.
Table of Contents
- Overview
- Indicator Definitions
- Default Configurations
- Strategy Configurations
- Validation System
- Configuration Files
- Usage Examples
- Extension Guide
Overview
The configuration system is built around three core concepts:
- Indicator Definitions - Schema and validation for technical indicators
- Default Configurations - Pre-built indicator presets organized by category
- Strategy Configurations - Complete chart setups for trading strategies
Architecture
components/charts/config/
├── indicator_defs.py # Core schemas and validation
├── defaults.py # Default indicator presets
├── strategy_charts.py # Strategy configurations
├── validation.py # Validation system
├── example_strategies.py # Real-world examples
└── __init__.py # Package exports
Indicator Definitions
The indicator definitions are now primarily managed through JSON template files located in config/indicators/templates/. These JSON files define the schema, default parameters, display properties, and styling for each technical indicator. This approach allows for easy addition and modification of indicators without requiring code changes.
Core Schema Fields (defined in JSON templates)
Each indicator JSON template includes the following key fields:
name: Display name of the indicator (e.g., "Simple Moving Average")description: Brief explanation of the indicator.type: Unique identifier for the indicator (e.g., "sma", "ema"). This is used for internal mapping.display_type: How the indicator is rendered on the chart ("overlay" or "subplot").timeframe: Optional default timeframe for the indicator (can be null for chart timeframe).default_parameters: Default values for the indicator's calculation parameters.parameter_schema: Defines the type, validation rules (min/max), default values, and descriptions for each parameter.default_styling: Default color, line width, and other visual properties.
Example JSON Template (config/indicators/templates/sma_template.json):
{
"name": "Simple Moving Average",
"description": "Simple Moving Average indicator",
"type": "sma",
"display_type": "overlay",
"timeframe": null,
"default_parameters": {
"period": 20
},
"parameter_schema": {
"period": {
"type": "int",
"min": 1,
"max": 200,
"default": 20,
"description": "Period for SMA calculation"
},
"timeframe": {
"type": "string",
"default": null,
"description": "Indicator timeframe (e.g., '1h', '4h'). Null for chart timeframe."
}
},
"default_styling": {
"color": "#007bff",
"line_width": 2
}
}
ChartIndicatorConfig (Python representation)
The ChartIndicatorConfig Python dataclass in components/charts/config/indicator_defs.py serves as the runtime representation of an indicator's configuration, parsed from the JSON templates.
@dataclass
class ChartIndicatorConfig:
name: str
indicator_type: str
parameters: Dict[str, Any]
display_type: str # 'overlay', 'subplot'
color: str
line_style: str = 'solid' # 'solid', 'dash', 'dot'
line_width: int = 2
opacity: float = 1.0
visible: bool = True
subplot_height_ratio: float = 0.3 # For subplot indicators
Enums (for internal type safety)
Enums like IndicatorType, DisplayType, LineStyle are still used internally for type safety and consistent value representation within the Python codebase.
IndicatorType
class IndicatorType(str, Enum):
SMA = "sma"
EMA = "ema"
RSI = "rsi"
MACD = "macd"
BOLLINGER_BANDS = "bollinger_bands"
VOLUME = "volume"
# ... new indicator types should be added here for internal consistency
DisplayType
class DisplayType(str, Enum):
OVERLAY = "overlay" # Overlaid on price chart
SUBPLOT = "subplot" # Separate subplot
HISTOGRAM = "histogram" # Histogram display
LineStyle
class LineStyle(str, Enum):
SOLID = "solid"
DASHED = "dash"
DOTTED = "dot"
DASH_DOT = "dashdot"
PriceColumn
class PriceColumn(str, Enum):
OPEN = "open"
HIGH = "high"
LOW = "low"
CLOSE = "close"
VOLUME = "volume"
Schema Validation (driven by JSON templates)
The validation system now primarily reads parameter schemas from the JSON templates. The IndicatorParameterSchema and IndicatorSchema dataclasses are used for internal representation when parsing and validating these JSON definitions.
IndicatorParameterSchema
Defines validation rules for indicator parameters:
@dataclass
class IndicatorParameterSchema:
name: str
type: type
required: bool = True
default: Any = None
min_value: Optional[Union[int, float]] = None
max_value: Optional[Union[int, float]] = None
description: str = ""
IndicatorSchema
Complete schema for an indicator type:
@dataclass
class IndicatorSchema:
indicator_type: IndicatorType
display_type: DisplayType
required_parameters: List[IndicatorParameterSchema]
optional_parameters: List[IndicatorParameterSchema] = field(default_factory=list)
min_data_points: int = 1
description: str = ""
Schema Definitions (now loaded dynamically)
The INDICATOR_SCHEMAS dictionary is now populated dynamically at runtime by loading and parsing the JSON template files. Manual definitions in indicator_defs.py are deprecated.
Utility Functions
Validation Functions
# Validate individual indicator configuration
def validate_indicator_configuration(config: ChartIndicatorConfig) -> tuple[bool, List[str]]
# Create indicator configuration with validation
def create_indicator_config(
name: str,
indicator_type: str,
parameters: Dict[str, Any],
display_type: Optional[str] = None,
color: str = "#007bff",
**display_options
) -> tuple[Optional[ChartIndicatorConfig], List[str]]
# Get schema for indicator type
def get_indicator_schema(indicator_type: str) -> Optional[IndicatorSchema]
# Get available indicator types
def get_available_indicator_types() -> List[str]
# Validate parameters for specific type
def validate_parameters_for_type(
indicator_type: str,
parameters: Dict[str, Any]
) -> tuple[bool, List[str]]
Default Configurations
Organization
Default configurations are organized by category and trading strategy:
Categories
class IndicatorCategory(str, Enum):
TREND = "trend"
MOMENTUM = "momentum"
VOLATILITY = "volatility"
VOLUME = "volume"
SUPPORT_RESISTANCE = "support_resistance"
Trading Strategies
class TradingStrategy(str, Enum):
SCALPING = "scalping"
DAY_TRADING = "day_trading"
SWING_TRADING = "swing_trading"
POSITION_TRADING = "position_trading"
MOMENTUM = "momentum"
MEAN_REVERSION = "mean_reversion"
Indicator Presets
IndicatorPreset
Container for pre-configured indicators:
@dataclass
class IndicatorPreset:
name: str
config: ChartIndicatorConfig
category: IndicatorCategory
description: str
recommended_timeframes: List[str]
suitable_strategies: List[TradingStrategy]
notes: List[str] = field(default_factory=list)
Available Presets
Trend Indicators (13 presets)
sma_5,sma_10,sma_20,sma_50,sma_100,sma_200ema_5,ema_12,ema_21,ema_26,ema_50,ema_100,ema_200
Momentum Indicators (9 presets)
rsi_7,rsi_14,rsi_21macd_5_13_4,macd_8_17_6,macd_12_26_9,macd_19_39_13
Volatility Indicators (4 presets)
bb_10_15,bb_20_15,bb_20_20,bb_50_20
Color Schemes
Organized color palettes by category:
CATEGORY_COLORS = {
IndicatorCategory.TREND: {
"primary": "#2E86C1", # Blue
"secondary": "#5DADE2", # Light Blue
"accent": "#1F618D" # Dark Blue
},
IndicatorCategory.MOMENTUM: {
"primary": "#E74C3C", # Red
"secondary": "#F1948A", # Light Red
"accent": "#C0392B" # Dark Red
},
# ... more colors
}
Access Functions
# Get all default indicators
def get_all_default_indicators() -> Dict[str, IndicatorPreset]
# Filter by category
def get_indicators_by_category(category: IndicatorCategory) -> Dict[str, IndicatorPreset]
# Filter by timeframe
def get_indicators_for_timeframe(timeframe: str) -> Dict[str, IndicatorPreset]
# Get strategy-specific indicators
def get_strategy_indicators(strategy: TradingStrategy) -> Dict[str, IndicatorPreset]
# Create custom preset
def create_custom_preset(
name: str,
indicator_type: IndicatorType,
parameters: Dict[str, Any],
category: IndicatorCategory,
**kwargs
) -> tuple[Optional[IndicatorPreset], List[str]]
Strategy Configurations
Core Classes
StrategyChartConfig
Complete chart configuration for a trading strategy:
@dataclass
class StrategyChartConfig:
strategy_name: str
strategy_type: TradingStrategy
description: str
timeframes: List[str]
# Chart layout
layout: ChartLayout = ChartLayout.MAIN_WITH_SUBPLOTS
main_chart_height: float = 0.7
# Indicators
overlay_indicators: List[str] = field(default_factory=list)
subplot_configs: List[SubplotConfig] = field(default_factory=list)
# Style
chart_style: ChartStyle = field(default_factory=ChartStyle)
# Metadata
created_at: Optional[datetime] = None
updated_at: Optional[datetime] = None
version: str = "1.0"
tags: List[str] = field(default_factory=list)
SubplotConfig
Configuration for chart subplots:
@dataclass
class SubplotConfig:
subplot_type: SubplotType
height_ratio: float = 0.3
indicators: List[str] = field(default_factory=list)
title: Optional[str] = None
y_axis_label: Optional[str] = None
show_grid: bool = True
show_legend: bool = True
background_color: Optional[str] = None
ChartStyle
Comprehensive chart styling:
@dataclass
class ChartStyle:
theme: str = "plotly_white"
background_color: str = "#ffffff"
grid_color: str = "#e6e6e6"
text_color: str = "#2c3e50"
font_family: str = "Arial, sans-serif"
font_size: int = 12
candlestick_up_color: str = "#26a69a"
candlestick_down_color: str = "#ef5350"
volume_color: str = "#78909c"
show_volume: bool = True
show_grid: bool = True
show_legend: bool = True
show_toolbar: bool = True
Default Strategy Configurations
Pre-built strategy configurations for common trading approaches:
-
Scalping Strategy
- Ultra-fast indicators (EMA 5, 12, 21)
- Fast RSI (7) and MACD (5,13,4)
- 1m-5m timeframes
-
Day Trading Strategy
- Balanced indicators (SMA 20, EMA 12/26, BB 20,2.0)
- Standard RSI (14) and MACD (12,26,9)
- 5m-1h timeframes
-
Swing Trading Strategy
- Longer-term indicators (SMA 50, EMA 21/50, BB 20,2.0)
- Standard momentum indicators
- 1h-1d timeframes
Configuration Functions
# Create default strategy configurations
def create_default_strategy_configurations() -> Dict[str, StrategyChartConfig]
# Create custom strategy
def create_custom_strategy_config(
strategy_name: str,
strategy_type: TradingStrategy,
description: str,
timeframes: List[str],
overlay_indicators: List[str],
subplot_configs: List[Dict[str, Any]],
**kwargs
) -> tuple[Optional[StrategyChartConfig], List[str]]
# JSON import/export
def load_strategy_config_from_json(json_data: Union[str, Dict[str, Any]]) -> tuple[Optional[StrategyChartConfig], List[str]]
def export_strategy_config_to_json(config: StrategyChartConfig) -> str
# Access functions
def get_strategy_config(strategy_name: str) -> Optional[StrategyChartConfig]
def get_all_strategy_configs() -> Dict[str, StrategyChartConfig]
def get_available_strategy_names() -> List[str]
Validation System
Validation Rules
The system includes 10 comprehensive validation rules:
- REQUIRED_FIELDS - Validates essential configuration fields
- HEIGHT_RATIOS - Ensures chart height ratios sum correctly
- INDICATOR_EXISTENCE - Checks indicator availability
- TIMEFRAME_FORMAT - Validates timeframe patterns
- CHART_STYLE - Validates styling options
- SUBPLOT_CONFIG - Validates subplot configurations
- STRATEGY_CONSISTENCY - Checks strategy-timeframe alignment
- PERFORMANCE_IMPACT - Warns about performance issues
- INDICATOR_CONFLICTS - Detects redundant indicators
- RESOURCE_USAGE - Estimates resource consumption
Validation Classes
ValidationReport
Comprehensive validation results:
@dataclass
class ValidationReport:
is_valid: bool
errors: List[ValidationIssue] = field(default_factory=list)
warnings: List[ValidationIssue] = field(default_factory=list)
info: List[ValidationIssue] = field(default_factory=list)
debug: List[ValidationIssue] = field(default_factory=list)
validation_time: Optional[datetime] = None
rules_applied: Set[ValidationRule] = field(default_factory=set)
ValidationIssue
Individual validation issue:
@dataclass
class ValidationIssue:
level: ValidationLevel
rule: ValidationRule
message: str
field_path: str = ""
suggestion: Optional[str] = None
auto_fix: Optional[str] = None
context: Dict[str, Any] = field(default_factory=dict)
Validation Usage
from components.charts.config import validate_configuration
# Comprehensive validation
report = validate_configuration(config)
# Check results
if report.is_valid:
print("✅ Configuration is valid")
else:
print("❌ Configuration has errors:")
for error in report.errors:
print(f" • {error}")
# Handle warnings
if report.warnings:
print("⚠️ Warnings:")
for warning in report.warnings:
print(f" • {warning}")
Configuration Files
File Structure
components/charts/config/
├── __init__.py # Package exports and public API
├── indicator_defs.py # Core indicator schemas and validation
├── defaults.py # Default indicator presets and categories
├── strategy_charts.py # Strategy configuration classes and defaults
├── validation.py # Validation system and rules
└── example_strategies.py # Real-world trading strategy examples
Key Exports
From __init__.py:
# Core classes
from .indicator_defs import (
IndicatorType, DisplayType, LineStyle, PriceColumn,
IndicatorParameterSchema, IndicatorSchema, ChartIndicatorConfig
)
# Default configurations
from .defaults import (
IndicatorCategory, TradingStrategy, IndicatorPreset,
get_all_default_indicators, get_indicators_by_category
)
# Strategy configurations
from .strategy_charts import (
ChartLayout, SubplotType, SubplotConfig, ChartStyle, StrategyChartConfig,
create_default_strategy_configurations
)
# Validation system
from .validation import (
ValidationLevel, ValidationRule, ValidationIssue, ValidationReport,
validate_configuration
)
# Utility functions from indicator_defs
from .indicator_defs import (
create_indicator_config, get_indicator_schema, get_available_indicator_types
)
Usage Examples
Example 1: Creating Custom Indicator
from components.charts.config import (
create_indicator_config, IndicatorType
)
# Create custom EMA configuration
config, errors = create_indicator_config(
name="EMA 21",
indicator_type=IndicatorType.EMA,
parameters={"period": 21, "price_column": "close"},
color="#2E86C1",
line_width=2
)
if config:
print(f"Created: {config.name}")
else:
print(f"Errors: {errors}")
Example 2: Using Default Presets
from components.charts.config import (
get_all_default_indicators,
get_indicators_by_category,
IndicatorCategory
)
# Get all available indicators
all_indicators = get_all_default_indicators()
print(f"Available indicators: {len(all_indicators)}")
# Get trend indicators only
trend_indicators = get_indicators_by_category(IndicatorCategory.TREND)
for name, preset in trend_indicators.items():
print(f"{name}: {preset.description}")
Example 3: Strategy Configuration
from components.charts.config import (
create_custom_strategy_config,
TradingStrategy
)
# Create custom momentum strategy
config, errors = create_custom_strategy_config(
strategy_name="Custom Momentum",
strategy_type=TradingStrategy.MOMENTUM,
description="Fast momentum trading strategy",
timeframes=["5m", "15m"],
overlay_indicators=["ema_8", "ema_21"],
subplot_configs=[{
"subplot_type": "rsi",
"height_ratio": 0.2,
"indicators": ["rsi_7"]
}]
)
if config:
print(f"Created strategy: {config.strategy_name}")
is_valid, validation_errors = config.validate()
if is_valid:
print("Strategy is valid!")
else:
print(f"Validation errors: {validation_errors}")
Example 4: Comprehensive Validation
from components.charts.config import (
validate_configuration,
ValidationRule
)
# Validate with specific rules
rules = {ValidationRule.REQUIRED_FIELDS, ValidationRule.HEIGHT_RATIOS}
report = validate_configuration(config, rules=rules)
# Detailed error handling
for error in report.errors:
print(f"ERROR: {error.message}")
if error.suggestion:
print(f" Suggestion: {error.suggestion}")
if error.auto_fix:
print(f" Auto-fix: {error.auto_fix}")
# Performance warnings
performance_issues = report.get_issues_by_rule(ValidationRule.PERFORMANCE_IMPACT)
if performance_issues:
print(f"Performance concerns: {len(performance_issues)}")
Extension Guide
Adding New Indicators
-
Define Indicator Type
- Add to
IndicatorTypeenum (if not already present)
- Add to
-
Create JSON Template
- Create a new JSON file in
config/indicators/templates/(e.g.,stochastic_template.json) - Define the indicator's name, type, display type, default parameters, parameter schema, and default styling.
- Example (
stochastic_template.json):{ "name": "Stochastic Oscillator", "description": "Stochastic momentum oscillator indicator", "type": "stochastic", "display_type": "subplot", "timeframe": null, "default_parameters": { "k_period": 14, "d_period": 3, "smooth_k": 1 }, "parameter_schema": { "k_period": { "type": "int", "min": 2, "max": 50, "default": 14, "description": "Period for %K calculation" }, "d_period": { "type": "int", "min": 1, "max": 20, "default": 3, "description": "Period for %D (moving average of %K)" }, "smooth_k": { "type": "int", "min": 1, "max": 10, "default": 1, "description": "Smoothing factor for %K" }, "timeframe": { "type": "string", "default": null, "description": "Indicator timeframe (e.g., '1h', '4h'). Null for chart timeframe." } }, "default_styling": { "color": "#e83e8c", "line_width": 2 } }
- Create a new JSON file in
-
Create Default Presets
# Add to defaults.py def create_momentum_indicators(): # ... existing indicators indicators["stoch_14"] = IndicatorPreset( name="stoch_14", config=create_indicator_config( IndicatorType.STOCHASTIC, {"k_period": 14, "d_period": 3}, display_name="Stochastic %K(14,%D(3))", color=CATEGORY_COLORS[IndicatorCategory.MOMENTUM]["primary"] )[0], category=IndicatorCategory.MOMENTUM, description="Standard Stochastic oscillator", recommended_timeframes=["15m", "1h", "4h"], suitable_strategies=[TradingStrategy.SWING_TRADING] )
Adding New Validation Rules
-
Define Rule
# Add to ValidationRule enum class ValidationRule(str, Enum): # ... existing rules CUSTOM_RULE = "custom_rule" -
Implement Validation
# Add to ConfigurationValidator def _validate_custom_rule(self, config: StrategyChartConfig, report: ValidationReport) -> None: # Custom validation logic if some_condition: report.add_issue(ValidationIssue( level=ValidationLevel.WARNING, rule=ValidationRule.CUSTOM_RULE, message="Custom validation message", suggestion="Suggested fix" )) -
Add to Validator
# Add to validate_strategy_config method if ValidationRule.CUSTOM_RULE in self.enabled_rules: self._validate_custom_rule(config, report)
Adding New Strategy Types
-
Define Strategy Type
# Add to TradingStrategy enum class TradingStrategy(str, Enum): # ... existing strategies GRID_TRADING = "grid_trading" -
Create Strategy Configuration
# Add to create_default_strategy_configurations() strategy_configs["grid_trading"] = StrategyChartConfig( strategy_name="Grid Trading Strategy", strategy_type=TradingStrategy.GRID_TRADING, description="Grid trading with support/resistance levels", timeframes=["1h", "4h"], overlay_indicators=["sma_20", "sma_50"], # ... complete configuration ) -
Add Example Strategy
# Create in example_strategies.py def create_grid_trading_strategy() -> StrategyExample: config = StrategyChartConfig(...) return StrategyExample( config=config, description="Grid trading strategy description...", difficulty="Intermediate", risk_level="Medium" )
The configuration system is designed to be highly extensible while maintaining type safety and comprehensive validation. All additions should follow the established patterns and include appropriate tests.