It's those darn NaNs.
The following seems like it should return a factor with all zeros.
weight_1yr = 0
score_1yr = weight_1yr * returns_1yr * er_1y
This is true EXCEPT in the case of NaN values. Wherever there is a NaN in either of the factors 'returns_1yr' or 'er_1y', the value will be NaN and NOT zero.
This is the same when all the factors are summed.
score_1 = score_5d + score_21d + score_63d + score_126d + score_1yr
score_2 = score_21d
Wherever there is a NaN in the factors then the result will be NaN. Since there can be some NaN values in the factors there may be cases where a perfectly non-NaN value in 'score_21d' becomes a NaN. Therefore, the two factors, score_1 and score_2, may not always return the same results. There could be more NaNs in score_1.
So, take the second backtest above and add the following code
no_nans = score_5d.notnan() & score_21d.notnan() & score_63d.notnan() & score_126d.notnan() & score_1yr.notnan()
score_rank = score.rank(ascending=False, mask = no_nans)
This filters out any assets that have NaN values. This is effectively what was happening when all the factors were summed because the '.rank' method ignores NaN (ie filters them). Using a filter and a mask just makes it more straightforward.
Attached is algo number 2 with this filter. The results are the same as algo 1 and algo 3.
Hope that helps.