The gap tolerance algorithm now looks through small intermediate blocks
to find the first LARGE block (> gap_tolerance) in each direction.
This ensures small isolated rating intervals are merged into the
correct dominant block, not just the nearest neighbor.
Example: NORMAL(large) HIGH(1) NORMAL(1) HIGH(large)
Before: HIGH at 05:45 merged into NORMAL (wrong - nearest neighbor)
After: NORMAL at 06:00 merged into HIGH (correct - dominant block)
Also collects all merge decisions BEFORE applying them, preventing
order-dependent outcomes when multiple small blocks are adjacent.
Impact: Rating transitions now appear at visually logical positions
where prices actually change direction, not at arbitrary boundaries.
Fixed multiple calculation issues with negative prices (Norway/Germany
renewable surplus scenarios):
Bug #6: Rating threshold validation with dead code
- Added threshold validation (low >= high) with warning
- Returns NORMAL as fallback for misconfigured thresholds
Bug #7: Min/Max functions returning 0.0 instead of None
- Changed default from 0.0 to None when window is empty
- Prevents misinterpretation (0.0 looks like price with negatives)
Bug #9: Period price diff percentage wrong sign with negative reference
- Use abs(ref_price) in percentage calculation
- Correct percentage direction for negative prices
Bug #10: Trend diff percentage wrong sign with negative current price
- Use abs(current_interval_price) in percentage calculation
- Correct trend direction when prices cross zero
Bug #11: later_half_diff calculation failed for negative prices
- Changed condition from `if current_interval_price > 0` to `!= 0`
- Use abs(current_interval_price) for percentage
Changes:
- utils/price.py: Add threshold validation, use abs() in percentages
- utils/average.py: Return None instead of 0.0 for empty windows
- period_statistics.py: Use abs() for reference prices
- trend.py: Use abs() for current prices, fix zero-check condition
- tests: 95+ new tests covering negative/zero/mixed price scenarios
Impact: All calculations work correctly with negative electricity prices.
Percentages show correct direction regardless of sign.