Как рассчитать индекс относительной силы (RSI) и экспоненциальную скользящую среднюю (EMA) из списка в pandas

Я создал фрейм данных pandas (называемый df) следующим образом:

import pandas as pd
import numpy as np

ds = {'col1' : [[10,23,45],[54,67,65],[76,43,21]]}

df = pd.DataFrame(data=ds)

Кадр данных выглядит следующим образом:

print(df)

           col1
0  [10, 23, 45]
1  [54, 67, 65]
2  [76, 43, 21]

Мне нужно создать два новых столбца:

  • столбец под названием RSI_2, который показывает индекс относительной силы (RSI) с 2 периодами из списка, содержащегося в col1 (так что столбец RSI_2 будет содержать 2-периодный RSI 10,23,45, а затем 2-периодный RSI 54,67,65 и т.д.)
  • столбец с именем EMA_2, который показывает экспоненциальную скользящую среднюю (EMA) с 2 периодами из списка, содержащегося в col1 (так что столбец EMA_2 будет содержать EMA с 2 периодами 10,23,45, а затем EMA с 2 периодами 54,67,65 и т.д.)

Не все знакомы с RSI 2 и EMA_2. Было бы полезно опубликовать ожидаемый результат.

Serge de Gosson de Varennes 16.04.2024 12:03
1
1
87
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Один из возможных способов сделать это — определить две функции. Один для расчета RSI и один для расчета EMA (обратите внимание, что в этом случае я выбрал прейод 2, как вы и требовали, но при необходимости его можно изменить).

Несколько советов. В будущем добавьте немного контекста и, возможно, объяснений того, к чему вы стремитесь. Это увеличит ваши шансы на ответ. Не все привыкли к фондовым рынкам.

Учитывая ваши данные, это будет:

import pandas as pd
import numpy as np

ds = {'col1': [[10, 23, 45], [54, 67, 65], [76, 43, 21]]}
df = pd.DataFrame(data=ds)

def calculate_rsi(values):
    gains = []
    losses = []
    for i in range(1, len(values)):
        difference = values[i] - values[i-1]
        if difference > 0:
            gains.append(difference)
        else:
            losses.append(abs(difference))
    
    average_gain = np.mean(gains) if gains else 0
    average_loss = np.mean(losses) if losses else 0
    
    if average_loss == 0:  
        return 100
    else:
        rs = average_gain / average_loss
        rsi = 100 - (100 / (1 + rs))
        return rsi

def calculate_ema(values, periods=2):
    weights = np.exp(np.linspace(-1., 0., periods))
    weights /= weights.sum()
    ema = np.convolve(values, weights, mode='full')[:len(values)]
    ema[:periods] = ema[periods]  
    return ema[-1]

df['RSI_2'] = df['col1'].apply(calculate_rsi)
df['EMA_2'] = df['col1'].apply(lambda x: calculate_ema(x, 2))

print(df)

Что возвращается:

           col1       RSI_2      EMA_2
0  [10, 23, 45]  100.000000  28.916711
1  [54, 67, 65]   86.666667  66.462117
2  [76, 43, 21]    0.000000  37.083289

Привет Серж, спасибо за ответ и за предложение! Действительно очень полезно! Ваше здоровье.

Giampaolo Levorato 16.04.2024 12:20

Другие вопросы по теме