Summary
The ADX formula divides by di_plus + di_minus with no guard. At the start of a series before directional movement accumulates, both values are zero, producing inf. The subsequent ewm call propagates inf through the entire ADX series. fillna(0) does not remove inf, so it enters the feature tensor.
Evidence
src/features/regime_features.py line 128:
dx = 100 * np.abs(di_plus - di_minus) / (di_plus + di_minus)
No zero-division guard. di_plus and di_minus are both zero on the first period bars.
Fix
denom = di_plus + di_minus
dx = np.where(denom > 0, 100 * np.abs(di_plus - di_minus) / denom, 0.0)
Then proceed with pd.Series(dx).ewm(...).
Summary
The ADX formula divides by
di_plus + di_minuswith no guard. At the start of a series before directional movement accumulates, both values are zero, producinginf. The subsequentewmcall propagatesinfthrough the entire ADX series.fillna(0)does not removeinf, so it enters the feature tensor.Evidence
src/features/regime_features.pyline 128:No zero-division guard.
di_plusanddi_minusare both zero on the firstperiodbars.Fix
Then proceed with
pd.Series(dx).ewm(...).