hass.tibber_prices/custom_components/tibber_prices/period_utils
Julian Pawlowski 07517660e3 refactor(volatility): migrate to coefficient of variation calculation
Replaced absolute volatility thresholds (ct/øre) with relative coefficient
of variation (CV = std_dev / mean * 100%) for scale-independent volatility
measurement that works across all price levels.

Changes to volatility calculation:
- price_utils.py: Rewrote calculate_volatility_level() to accept price list
  instead of spread value, using statistics.mean() and statistics.stdev()
- sensor.py: Updated volatility sensors to pass price lists (not spread)
- services.py: Modified _get_price_stats() to calculate CV from prices
- period_statistics.py: Extract prices for CV calculation in period summaries
- const.py: Updated default thresholds to 15%/30%/50% (was 5/15/30 ct)
  with comprehensive documentation explaining CV-based approach

Dead code removal:
- period_utils/core.py: Removed filter_periods_by_volatility() function
  (86 lines of code that was never actually called)
- period_utils/__init__.py: Removed dead function export
- period_utils/relaxation.py: Simplified callback signature from
  Callable[[str|None, str|None], bool] to Callable[[str|None], bool]
- coordinator.py: Updated lambda callbacks to match new signature
- const.py: Replaced RELAXATION_VOLATILITY_ANY with RELAXATION_LEVEL_ANY

Bug fix:
- relaxation.py: Added int() conversion for max_relaxation_attempts
  (line 435: attempts = max(1, int(max_relaxation_attempts)))
  Fixes TypeError when config value arrives as float

Configuration UI:
- config_flow.py: Changed volatility threshold unit display from "ct" to "%"

Translations (all 5 languages):
- Updated volatility descriptions to explain coefficient of variation
- Changed threshold labels from "spread ≥ value" to "CV ≥ percentage"
- Languages: de, en, nb, nl, sv

Documentation:
- period-calculation.md: Removed volatility filter section (dead feature)

Impact: Breaking change for users with custom volatility thresholds.
Old absolute values (e.g., 5 ct) will be interpreted as percentages (5%).
However, new defaults (15%/30%/50%) are more conservative and work
universally across all currencies and price levels. No data migration
needed - existing configs continue to work with new interpretation.
2025-11-14 01:12:47 +00:00
..
__init__.py refactor(volatility): migrate to coefficient of variation calculation 2025-11-14 01:12:47 +00:00
core.py refactor(volatility): migrate to coefficient of variation calculation 2025-11-14 01:12:47 +00:00
level_filtering.py Feature/adaptive defaults (#22) 2025-11-13 23:51:29 +01:00
outlier_filtering.py feat(relaxation): make tail handling smarter and attempts configurable 2025-11-14 00:07:12 +00:00
period_building.py fix(build_periods): improve comment clarity for smoothing impact on interval qualification 2025-11-13 23:00:26 +00:00
period_merging.py Feature/adaptive defaults (#22) 2025-11-13 23:51:29 +01:00
period_statistics.py refactor(volatility): migrate to coefficient of variation calculation 2025-11-14 01:12:47 +00:00
relaxation.py refactor(volatility): migrate to coefficient of variation calculation 2025-11-14 01:12:47 +00:00
types.py Feature/adaptive defaults (#22) 2025-11-13 23:51:29 +01:00