Skip to content
All library documents

Z-Score Normalization Does Not Bound Indicators to a Fixed Range

Article Quant Q&A · Author: mllamazares

Summary

The discussion addresses why combining a commodity channel index, momentum, and price distance from a moving average with a row-wise standardization formula does not yield values confined to minus one and one. It explains that standardization centers observations around zero and rescales them by standard deviation, making variables with different scales more comparable; it does not impose fixed bounds.

A scaling example shows that multiplying a variable by a positive constant leaves its z-scores unchanged, because both the centered values and standard deviation scale together. Thus the displayed out-of-range values are compatible with normalization. The response answers the range question but does not assess whether the proposed row-wise calculation is a sound way to combine indicators into a trading signal, nor does it compare alternatives such as bounded transforms or historical rolling normalization.

Key ideas

  • Z-score normalization subtracts a mean and divides by standard deviation.
  • Standardized values are centered and scale-comparable but are not constrained to minus one and one.
  • Multiplying a variable by a positive constant does not change its z-scores.
  • The explanation does not validate the trading usefulness of combining the indicators row by row.

Tags

Full text
# How to normalize various indicators into one column?


# How to normalize various indicators into one column?












I've seen this video which talks about how to compress different indicators into a sin

https://www.youtube.com/watch?v=sDu6CudKa0Q

I tried to do the same by this way:

```
data_hist['sma10']  = talib.SMA(data_hist['close'].values, 10)  
data_hist['difsma'] = data_hist['close'] - data_hist['sma10']  
data_hist['cci10']  = talib.CCI(data_hist['high'].values, data_hist['low'].values, data_hist['close'].values, 10)  
data_hist['mom5']   = talib.MOM(data_hist['close'].values, 5)

data_hist.dropna(inplace=True)  

cols = ['cci10', 'mom5', 'difsma']  
data_hist['norm'] = ( data_hist[cols].sum(axis=1) - data_hist[cols].mean(axis=1) ) / data_hist[cols].std(axis=1)
```

But this is an example of output data (it's not between -1 and 1...)

```
2013-09-11 00:00:00+00:00   -1.557247
2013-09-12 00:00:00+00:00   -1.686368
2013-09-13 00:00:00+00:00   -2.160459
2013-09-16 00:00:00+00:00   -2.805381
2013-09-17 00:00:00+00:00   -2.770916
2013-09-18 00:00:00+00:00   -1.726371
2013-09-19 00:00:00+00:00   -1.610760
2013-09-20 00:00:00+00:00   -1.645410
2013-09-23 00:00:00+00:00    2.143846
2013-09-24 00:00:00+00:00    1.863802
2013-09-25 00:00:00+00:00    1.847545
2013-09-26 00:00:00+00:00    1.956981
2013-09-27 00:00:00+00:00    2.507031
2013-09-30 00:00:00+00:00   -0.856816
2013-10-01 00:00:00+00:00    1.422277
2013-10-02 00:00:00+00:00    1.604809
```

What am I missing out? Any alternative to compress various indicators in a single column?

## Answer by SRKX (score 1, accepted)

https://quant.stackexchange.com/a/32406

Normalized data are not supposed to be in $[-1,1]$, but they're supposed to be "centered" around 0 (because you subtract the mean of the sample) and with values spread from 0 in a way which makes it comparable between different variable size (because you divide by the standard deviation of the sample).

A quick example is let's say you compare two random sample $X$ and $Y=7 \cdot X$. It could be somewhat "difficult" to see that the points in $X$ and $Y$ are in fact distributed in a same way but for a scaling factor, just by looking at the values.

But the normalized data will show that they're actually exactly the same:

$$X_\text{normalized} = \frac{X-\mu_X}{\sigma_X}$$ $$\begin{align} Y_\text{normalized} &= \frac{Y-\mu_Y}{\sigma_Y} \\ &= \frac{7X-7\mu_X}{7\sigma_X} \\ &= \frac{X-\mu_X}{\sigma_X} \\ & = X_\text{normalized} \end{align}$$

This, however, does not imply it will be contained between -1 and 1.

Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.