---
# System prepended metadata

title: RSI

---

# RSI
## rsi_1
```python=
import numpy as np
import pandas as pd
import mplfinance as mpf
import matplotlib.pyplot as plt
from datetime import datetime

#整理檔案
dataname = '1722_2020.csv'
SData = pd.read_csv(dataname, index_col = 'Date')
SData.index = pd.DatetimeIndex(SData.index)

#收盤價
close = SData.Close

#每日漲跌
change = close - close.shift(1)

#上漲幅度,nan以0填滿
change_p = pd.Series(index = change.index,data = change[change>0])
change_p = change_p.fillna(0)

#下跌幅度,nan以0填滿,取正值所以加-號
change_n = pd.Series(index = change.index,data = -change[change<0])
change_n = change_n.fillna(0)

'''
計算n日平均漲跌幅
RSIn = 100 × 前n日漲幅的平均值 ÷ ( 前n日漲幅的平均值 + 前n日跌幅的平均值 )
'''
n = 9

#平均漲幅
up_mean = [0]*(n)
#平均跌幅
down_mean = [0]*(n)

#第一天沒有漲跌幅
for i in range(n+1,len(change)+1):
    up_mean.append(np.mean(change_p.values[i-n:i]))
    down_mean.append(np.mean(change_n.values[i-n:i]))


#計算RSI
rsi_n= []
for i in range(len(up_mean)):
    if (up_mean[i] + down_mean[i]) == 0:
        rsi_n.append(0)
    else:
        rsi_n.append(100 * up_mean[i] / (up_mean[i] + down_mean[i]))

rsi_n_series = pd.Series(index = close.index, data = rsi_n)
rsi_n_series = rsi_n_series.fillna(0)

#設定策略
buyp = 30
sellp = 80

#訊號
signal = []

#庫存，只會是 0 or 1
stock = 0
cost = 0
benifit = 0

#偵測RSI訊號
for i in range(len(rsi_n_series)):
    if rsi_n_series[i] > sellp and stock ==1:
        stock -= 1
        signal.append(-1)
        cost = benifit + close[i] * (1+0.001425)
    elif rsi_n_series[i] < buyp and stock == 0:
        stock += 1
        signal.append(1)
        benifit = cost + close[i] * (1-0.004425)
    else:
        signal.append(0)
rsi_sig = pd.Series(index = rsi_n_series.index, data = signal)

#return
print('cost:',cost)
print('benifit:',benifit)
n_income = benifit - cost
n_return = n_income / cost
print('return',n_return)

```
## rsi_2
```python=
import numpy as np
import pandas as pd
import mplfinance as mpf
import matplotlib.pyplot as plt
from datetime import datetime

def rsi(close,n):
    change = close - close.shift(1)
    #上漲幅度,nan以0填滿
    change_p = pd.Series(index = change.index,data = change[change>0])
    change_p = change_p.fillna(0)
    #下跌幅度,nan以0填滿,取正值所以加-號
    change_n = pd.Series(index = change.index,data = -change[change<0])
    change_n = change_n.fillna(0)
    #平均漲幅
    up_mean_n = []
    #平均跌幅
    down_mean_n = []
    #第一天沒有漲跌幅，計算平均漲跌幅
    for i in range(n+1,len(change)+1):
        up_mean_n.append(np.mean(change_p.values[i-n:i]))
        down_mean_n.append(np.mean(change_n.values[i-n:i]))
    #計算RSI
    rsi_n = [0]*n
    for i in range(len(up_mean_n)):
        rsi_n.append(100 * up_mean_n[i] / (up_mean_n[i] + down_mean_n[i]))

    rsi_n_series = pd.Series(index = close.index, data = rsi_n)
    
    return rsi_n_series

#整理資料
dataname = "0050_2020.csv"
SData = pd.read_csv(dataname, index_col = 'Date')
SData.index = pd.DatetimeIndex(SData.index)
#收盤價
close = SData.Close

rsi_fast = rsi(close,2)
rsi_slow = rsi(close,14)

'''
策略:RSI_fast向上穿破RSI_slow買進，RSI_fast向下穿破RSI_slow賣出
'''
#訊號
signal = []
#庫存，只會是 0 or 1
stock = 0
#成本、獲益
cost = 0
benifit = 0

std = 50

#偵測RSI訊號
for i in range(len(close)):
    #buy
    if stock == 0:
        if (rsi_fast[i-1] < rsi_slow[i-1]) and (rsi_fast[i] > rsi_slow[i]) and (rsi_slow[i-1] > std):
            stock += 1
            signal.append(1)
            cost = benifit + close[i] * (1+0.001425)
        else:
            signal.append(0)
    #sell
    elif stock == 1:
        if (rsi_fast[i-1] > rsi_slow[i-1]) and (rsi_fast[i] < rsi_slow[i]) and (rsi_slow[i-1] < std):
            stock -= 1
            signal.append(-1)
            benifit = cost + close[i] * (1-0.004425)
        else:
            signal.append(0)

rsi_sig = pd.Series(index = SData.index, data = signal)

return_final = (benifit - cost) / cost
print("cost:",cost)
print("benifit:",benifit)
print("return:",return_final)

#plot
from matplotlib import gridspec

fig = plt.figure(figsize=(15,10))
gs = gridspec.GridSpec(2, 1, height_ratios=[2, 1])

ax0 = plt.subplot(gs[0])
ax0.plot(rsi_fast)
ax0.plot(rsi_slow)
ax0.axhline(y=50, color='red')

ax1 = plt.subplot(gs[1], sharex = ax0)
ax1.plot(rsi_sig)

```