Source code for backtrader.bokeh.utils.helpers
#!/usr/bin/env python
"""
Helper utility functions.
"""
import re
from typing import List
from backtrader.utils.log_message import get_logger
logger = get_logger(__name__)
[docs]
def get_datanames(strategy):
"""Get names of all data sources in strategy.
Args:
strategy: Strategy instance
Returns:
list: List of data source names
"""
datanames: List[str] = []
if strategy is None or not hasattr(strategy, "datas"):
return datanames
for i, data in enumerate(strategy.datas):
if hasattr(data, "_name") and data._name:
datanames.append(data._name)
else:
datanames.append(f"Data{i}")
return datanames
[docs]
def get_strategy_label(strategy):
"""Get strategy label.
Args:
strategy: Strategy instance
Returns:
str: Strategy label
"""
if strategy is None:
return "Unknown Strategy"
return strategy.__class__.__name__
[docs]
def sanitize_source_name(name):
"""Sanitize data source name, remove illegal characters.
Args:
name: Original name
Returns:
str: Sanitized name
"""
if name is None:
return "unnamed"
# Remove non-alphanumeric and underscore characters
sanitized = re.sub(r"[^a-zA-Z0-9_]", "_", str(name))
# Ensure it doesn't start with a digit
if sanitized and sanitized[0].isdigit():
sanitized = "_" + sanitized
return sanitized or "unnamed"
[docs]
def get_indicator_label(indicator):
"""Get indicator label.
Args:
indicator: Indicator instance
Returns:
str: Indicator label
"""
if indicator is None:
return "Unknown Indicator"
label = indicator.__class__.__name__
# Add parameter info (if available)
if hasattr(indicator, "params"):
params = []
for name in dir(indicator.params):
if not name.startswith("_"):
try:
value = getattr(indicator.params, name)
if not callable(value):
params.append(f"{name}={value}")
except Exception as e:
logger.debug("Failed to get indicator param '%s': %s", name, e)
if params:
label += f" ({', '.join(params[:3])})" # Show max 3 parameters
return label
[docs]
def get_color_from_value(value, up_color="#26a69a", down_color="#ef5350", neutral_color="#666666"):
"""Get color based on value.
Args:
value: Numeric value
up_color: Color for positive values
down_color: Color for negative values
neutral_color: Color for zero values
Returns:
str: Color value
"""
if value is None:
return neutral_color
try:
val = float(value)
if val > 0:
return up_color
if val < 0:
return down_color
return neutral_color
except (ValueError, TypeError):
return neutral_color