from datetime import datetime
print(f'Päivitetty {datetime.now().date()} / Aki Taanila')
Päivitetty 2024-03-25 / Aki Taanila
Seuraavassa tarvitaan yfinance-kirjastoa, joka ei kuulu Anacondan vakioasennukseen. Voit asentaa sen komentoriviltä (Windows: Anaconda Prompt, macOS: Terminal/Pääte) komennolla conda install -c conda-forge yfinance
.
pandas_ta-kirjaston voit asentaa komentoriviltä komennolla conda install -c conda-forge pandas-ta
.
Lisätietoa RSI:stä: https://www.investopedia.com/terms/r/rsi.asp
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import yfinance as yf
import pandas_ta as ta
sns.set_style('whitegrid')
rsi0 noudattaa laskennassa sivun https://www.macroption.com/rsi-calculation/ ohjetta (keskiarvojen laskenta yksinkertaisena liukuvana keskiarvona).
# Keskiarvot yksinkertaisena liukuvana
def rsi0(stock, span):
muutos = stock['Close'].diff()
u = muutos.clip(lower = 0) # positiiviset muutokset
d = muutos.clip(upper = 0).abs() # negatiiviset muutokset
avgu = u.rolling(span).mean() # positiivisten muutosten liukuva keskiarvo
avgd = d.rolling(span).mean() # negatiivisten muutosten liukuva keskiarvo
rs = avgu/avgd # suhteellinen voima (relative strength)
stock['RSI'] = (100 - (100/(1 + rs))) # suhteellinen voimaindeksi (RSI)
# Kaavio
stock['RSI'].plot(figsize = (12, 5), label = 'yksinkertainen liukuva', legend = True)
plt.ylim(0, 100)
plt.axhline(30, color = 'r', linestyle = '--')
plt.axhline(70, color = 'r', linestyle = '--')
plt.ylabel('RSI')
rsi1 noudattaa laskennassa sivun https://www.macroption.com/rsi-calculation/ ohjetta (keskiarvojen laskenta eksponentiaalisella tasoituksella).
# Keskiarvot eksponentiaalisella tasoituksella
def rsi1(stock, span):
muutos = stock['Close'].diff()
u = muutos.clip(lower = 0) # positiiviset muutokset
d = muutos.clip(upper = 0).abs() # negatiiviset muutokset
avgu = u.ewm(span = span, adjust = False).mean() # positiivisten muutosten liukuva keskiarvo
avgd = d.ewm(span = span, adjust = False).mean() # negatiivisten muutosten liukuva keskiarvo
rs = avgu/avgd # suhteellinen voima (relative strength)
stock['RSI'] = (100 - (100/(1 + rs))) # suhteellinen voimaindeksi (RSI)
# Kaavio
stock['RSI'].plot(figsize = (12, 5), label = 'eksponentiaalinen', legend = True)
plt.ylim(0, 100)
plt.axhline(30, color = 'r', linestyle = '--')
plt.axhline(70, color = 'r', linestyle = '--')
plt.ylabel('RSI')
rs2 on kuten rs1, mutta keskiarvojen laskentaan tehty sivun https://stackoverflow.com/questions/37924377/does-pandas-calculate-ewm-wrong suosittelemat korjaukset.
# Keskiarvot eksponentiaalisella tasoituksella, alkupäähän korjaus
def rsi2(stock, span):
muutos = stock['Close'].diff()
u = muutos.clip(lower = 0) # positiiviset muutokset
u_sma = u.rolling(window=span, min_periods=span).mean()[:span]
u_rest = u[span:]
u = pd.concat([u_sma, u_rest])
d = muutos.clip(upper = 0).abs() # negatiiviset muutokset
d_sma = d.rolling(window=span, min_periods=span).mean()[:span]
d_rest = d[span:]
d = pd.concat([d_sma, d_rest])
avgu = u.ewm(span = span, adjust = False, min_periods=span).mean() # positiivisten muutosten liukuva keskiarvo
avgd = d.ewm(span = span, adjust = False, min_periods=span).mean() # negatiivisten muutosten liukuva keskiarvo
rs = avgu/avgd # suhteellinen voima (relative strength)
stock['RSI'] = (100 - (100/(1 + rs))) # suhteellinen voimaindeksi (RSI)
# Kaavio
stock['RSI'].plot(figsize = (12, 5), label = 'eksponentiaalinen korj.', legend = True)
plt.ylim(0, 100)
plt.axhline(30, color = 'r', linestyle = '--')
plt.axhline(70, color = 'r', linestyle = '--')
plt.ylabel('RSI')
rsi3 noudattaa laskennassa sivun https://www.macroption.com/rsi-calculation/ ohjetta (keskiarvojen laskenta Wilderin tasoituksella).
# Keskiarvot Wilderin tasoituksella
def rsi3(stock, span):
muutos = stock['Close'].diff()
u = muutos.clip(lower = 0) # positiiviset muutokset
d = muutos.clip(upper = 0).abs() # negatiiviset muutokset
avgu = u.ewm(alpha = 1/span, adjust = False).mean() # positiivisten muutosten liukuva keskiarvo
avgd = d.ewm(alpha = 1/span, adjust = False).mean() # negatiivisten muutosten liukuva keskiarvo
rs = avgu/avgd # suhteellinen voima (relative strength)
stock['RSI'] = (100 - (100/(1 + rs))) # suhteellinen voimaindeksi (RSI)
# Kaavio
stock['RSI'].plot(figsize = (12, 5), label = 'Wilder', legend = True)
plt.ylim(0, 100)
plt.axhline(30, color = 'r', linestyle = '--')
plt.axhline(70, color = 'r', linestyle = '--')
plt.ylabel('RSI')
# pandas_ta-kirjaston rsi-toiminnolla (käyttää Wilderin tasoitusta)
def rsi4(stock, span):
stock['RSI'] = ta.rsi(stock['Close'], length = 14)
# Kaavio
stock['RSI'].plot(figsize = (12, 5), label = 'Wilder (pandas_ta)', legend = True)
plt.ylim(0, 100)
plt.axhline(30, color = 'r', linestyle = '--')
plt.axhline(70, color = 'r', linestyle = '--')
plt.ylabel('RSI')
stock = yf.download('ELISA.HE', start = '2023-1-1')
[*********************100%%**********************] 1 of 1 completed
rsi0(stock, 14)
rsi1(stock, 14)
rsi2(stock, 14)
rsi3(stock, 14)
rsi4(stock, 14)
rsi0(stock, 14)
rsi1(stock, 14)
rsi3(stock, 14)
rsi1(stock, 14)
rsi2(stock, 14)
rsi3(stock, 14)
rsi4(stock, 14)