我是 Pandas 新手。计算 Pandas RSI指标中相对强度部分的最佳方法是什么?到目前为止,我得到了以下信息:
from pylab import *
import pandas as pd
import numpy as np
def Datapull(Stock):
try:
df = (pd.io.data.DataReader(Stock,'yahoo',start='01/01/2010'))
return df
print 'Retrieved', Stock
time.sleep(5)
except Exception, e:
print 'Main Loop', str(e)
def RSIfun(price, n=14):
delta = price['Close'].diff()
#-----------
dUp=
dDown=
RolUp=pd.rolling_mean(dUp, n)
RolDown=pd.rolling_mean(dDown, n).abs()
RS = RolUp / RolDown
rsi= 100.0 - (100.0 / (1.0 + RS))
return rsi
Stock='AAPL'
df=Datapull(Stock)
RSIfun(df)
到目前为止,我做得对吗?我在等式的差异部分遇到问题,您将向上和向下的计算分开
最佳答案
请务必注意,定义 RSI 的方法有多种。它通常至少以两种方式定义:使用上述简单移动平均线 (SMA),或使用指数移动平均线 (EMA)。这是一个代码片段,它计算 RSI 的各种定义并绘制它们以进行比较。我在取差后丢弃了第一行,因为根据定义它总是 NaN。
请注意,使用 EMA 时必须小心:因为它包含一个可以追溯到数据开头的内存,所以结果取决于您从哪里开始!出于这个原因,通常人们会在开始时添加一些数据,比如 100 个时间步长,然后切断前 100 个 RSI 值。
在下图中,可以看到使用 SMA 和 EMA 计算的 RSI 之间的差异:SMA 往往更敏感。请注意,基于 EMA 的 RSI 在第一个时间步(这是原始周期的第二个时间步,由于丢弃了第一行)具有其第一个有限值,而基于 SMA 的 RSI 在第一个时间步具有其第一个有限值第 14 个时间步。这是因为默认情况下 rolling_mean() 仅在有足够的值填充窗口时才返回有限值。
import datetime
from typing import Callable
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import pandas_datareader.data as web
# Window length for moving average
length = 14
# Dates
start, end = '2010-01-01', '2013-01-27'
# Get data
data = web.DataReader('AAPL', 'yahoo', start, end)
# Get just the adjusted close
close = data['Adj Close']
# Define function to calculate the RSI
def calc_rsi(over: pd.Series, fn_roll: Callable) -> pd.Series:
# Get the difference in price from previous step
delta = over.diff()
# Get rid of the first row, which is NaN since it did not have a previous row to calculate the differences
delta = delta[1:]
# Make the positive gains (up) and negative gains (down) Series
up, down = delta.clip(lower=0), delta.clip(upper=0).abs()
roll_up, roll_down = fn_roll(up), fn_roll(down)
rs = roll_up / roll_down
rsi = 100.0 - (100.0 / (1.0 + rs))
# Avoid division-by-zero if `roll_down` is zero
# This prevents inf and/or nan values.
rsi[:] = np.select([roll_down == 0, roll_up == 0, True], [100, 0, rsi])
rsi.name = 'rsi'
# Assert range
valid_rsi = rsi[length - 1:]
assert ((0 <= valid_rsi) & (valid_rsi <= 100)).all()
# Note: rsi[:length - 1] is excluded from above assertion because it is NaN for SMA.
return rsi
# Calculate RSI using MA of choice
# Reminder: Provide ≥ `1 + length` extra data points!
rsi_ema = calc_rsi(close, lambda s: s.ewm(span=length).mean())
rsi_sma = calc_rsi(close, lambda s: s.rolling(length).mean())
rsi_rma = calc_rsi(close, lambda s: s.ewm(alpha=1 / length).mean()) # Approximates TradingView.
# Compare graphically
plt.figure(figsize=(8, 6))
rsi_ema.plot(), rsi_sma.plot(), rsi_rma.plot()
plt.legend(['RSI via EMA/EWMA', 'RSI via SMA', 'RSI via RMA/SMMA/MMA (TradingView)'])
plt.show()
关于python - python pandas中的相对强度指数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20526414/