skyte/relative-strength

Incorrect RS formula with negative index returns

Closed this issue · 1 comments

Hi,

today the output rank for NFLX on rs_stocks.csv is 92, on IBD it is 6.

The reason for such a high value is the formula being used for the relative strength doesn't take into account the index could have a negative return. This gives stocks with huge negative returns a fantastic relative strength and therefore fantastic rating.

By changing the formula to a relative value centered around 1, we get the correct rank ordering as per IDB.

rs = (1 + stock_return) / (1 + index_return)

for full example:

rs_list = []
for i in [1, 2, 3, 4]:
    l = min(len(stock_closes), 63 * i)
    stock_return = (stock_closes[-1] - stock_closes[-l]) / stock_closes[-l]
    index_return = (index_closes[-1] - index_closes[-l]) / index_closes[-l]
    rs_period = (1 + stock_return) / (1 + index_return)
    rs_list.append(rs_period )

relative_strength = (rs_list[0] * 0.4) + (rs_list[1] * 0.2) + (rs_list[2] * 0.2) + (rs_list[3] * 0.2)

and then after adding the data to a dataframe, rank is

df['rank'] = df['rs'].rank(pct=True) * 100

Comparing the results to IBD gives a very high level of similarity (using 12000 tickers) and gradually gets looser using less tickers. However the order of the rank remains consistent.

Additionally, the formula currently sums the quarterly strengths of the stock, and divides by the sum of the quarterly strengths of the index.

(stock_rs1 + stock_rs2 + stock_rs3 + stock_rs4) / (index_rs1 + index_rs2 + index_rs3 + index_rs4)

The normal formula quoted has the relative strength of the stock and index per quarter multiplied by that periods factor, and then summed.

(stock_rs1/index_rs1) + (stock_rs2/index_rs2) + (stock_rs3/index_rs3) + (stock_rs4/index_rs4)

Hope this helps.

skyte commented

Thank you, I adjusted the formula for the negative index returns.