Python05.04.2026schedule3 min read
Plotly ile İnteraktif Borsa Grafikleri
Candlestick, hacim, RSI ve MACD'yi Plotly ile interaktif hale getiriyoruz. Zoom'layabileceğiniz, hover'da değer gören, indirilebilir BIST grafikleri.
Matplotlib grafikleri güzel ama statik. Plotly'yi ilk kullandığımda grafiğin üzerinde serbestçe gezebilmek, herhangi bir muma hover edince OHLCV değerlerini görebilmek benim için gerçek bir verimlilik farkı yarattı.
Neden Plotly?
plotly Python için en olgun interaktif grafik kütüphanesi. Finansal grafikler için özel go.Candlestick komponenti var, Colab'da direkt render oluyor ve HTML olarak export edilebiliyor.
Adım 1: Kurulum ve Veri Hazırlığı
!pip install yfinance plotly --quiet
import yfinance as yf
import pandas as pd
import numpy as np
import plotly.graph_objects as go
from plotly.subplots import make_subplots
ticker = "THYAO.IS"
df = yf.download(ticker, start="2023-01-01", end="2025-01-01", progress=False)
if isinstance(df.columns, pd.MultiIndex):
df.columns = df.columns.droplevel(1)
df = df[df["Volume"] > 0].ffill().dropna()
df.index = pd.to_datetime(df.index)
print(f"Veri hazır: {len(df)} gün")
Adım 2: Temel İndikatör Hesaplama
def rsi(close, period=14):
delta = close.diff()
kazanc = delta.clip(lower=0).ewm(alpha=1/period, adjust=False).mean()
kayip = (-delta).clip(lower=0).ewm(alpha=1/period, adjust=False).mean()
return 100 - (100 / (1 + kazanc / kayip))
def macd(close, h=12, y=26, s=9):
macd_line = close.ewm(span=h, adjust=False).mean() - close.ewm(span=y, adjust=False).mean()
sinyal_line = macd_line.ewm(span=s, adjust=False).mean()
return macd_line, sinyal_line, macd_line - sinyal_line
def bollinger(close, period=20, std=2):
orta = close.rolling(period).mean()
bant = close.rolling(period).std()
return orta, orta + std * bant, orta - std * bant
df["RSI"] = rsi(df["Close"])
df["MACD"], df["MACDSinyal"], df["MACDHist"] = macd(df["Close"])
df["BB_Orta"], df["BB_Ust"], df["BB_Alt"] = bollinger(df["Close"])
Adım 3: Ana Grafik — Candlestick + Bollinger
fig = make_subplots(
rows=4, cols=1,
shared_xaxes=True,
vertical_spacing=0.03,
row_heights=[4, 1.5, 1.5, 1.5],
subplot_titles=("Fiyat + Bollinger", "Hacim", "RSI", "MACD")
)
fig.add_trace(go.Candlestick(
x=df.index,
open=df["Open"], high=df["High"],
low=df["Low"], close=df["Close"],
name="OHLC",
increasing_line_color="#26a69a",
decreasing_line_color="#ef5350"
), row=1, col=1)
fig.add_trace(go.Scatter(
x=df.index, y=df["BB_Ust"],
line=dict(color="rgba(100,100,200,0.3)", width=1),
name="BB Üst", showlegend=False
), row=1, col=1)
fig.add_trace(go.Scatter(
x=df.index, y=df["BB_Alt"],
fill="tonexty",
fillcolor="rgba(100,100,200,0.05)",
line=dict(color="rgba(100,100,200,0.3)", width=1),
name="BB Alan", showlegend=False
), row=1, col=1)
Adım 4: Hacim, RSI ve MACD Panelleri
hacim_renk = ["#26a69a" if c >= o else "#ef5350"
for c, o in zip(df["Close"], df["Open"])]
fig.add_trace(go.Bar(
x=df.index, y=df["Volume"],
marker_color=hacim_renk, opacity=0.7,
name="Hacim"
), row=2, col=1)
fig.add_trace(go.Scatter(
x=df.index, y=df["RSI"],
line=dict(color="#7b1fa2", width=1),
name="RSI"
), row=3, col=1)
for seviye, renk in [(70, "rgba(239,83,80,0.4)"), (30, "rgba(38,166,154,0.4)")]:
fig.add_hline(y=seviye, line_dash="dash",
line_color=renk, line_width=1, row=3, col=1)
fig.add_trace(go.Scatter(
x=df.index, y=df["MACD"],
line=dict(color="#1565c0", width=1), name="MACD"
), row=4, col=1)
fig.add_trace(go.Scatter(
x=df.index, y=df["MACDSinyal"],
line=dict(color="#f57c00", width=1), name="Sinyal"
), row=4, col=1)
hist_renk = ["#26a69a" if v >= 0 else "#ef5350" for v in df["MACDHist"]]
fig.add_trace(go.Bar(
x=df.index, y=df["MACDHist"],
marker_color=hist_renk, opacity=0.6,
name="Histogram"
), row=4, col=1)
Adım 5: Düzen ve Export
fig.update_layout(
title=dict(text=f"{ticker} — İnteraktif Teknik Analiz", font=dict(size=16)),
height=900,
showlegend=True,
legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1),
xaxis_rangeslider_visible=False,
plot_bgcolor="#ffffff",
paper_bgcolor="#f8f9fa",
hovermode="x unified"
)
fig.update_yaxes(range=[0, 100], row=3, col=1)
fig.show()
fig.write_html(f"{ticker.replace('.IS','')}_grafik.html")
print("Grafik HTML olarak kaydedildi.")
Sonuç
- Plotly interaktif grafikleri analiz verimliliğini ciddi artırıyor. Zoom, pan, hover — statik grafiklerde olmayan değerli özellikler.
- HTML export özelliği sayesinde grafikleri sunucu gerektirmeden paylaşabilirsiniz.
- Bu yapının sınırı: gerçek zamanlı güncelleme yok. Plotly Dash ile bunu çözmek mümkün ama ayrı bir konu.
- Bir sonraki adım: bu grafik altyapısını backtest sonuçlarıyla birleştirmek.
Bu yazıdaki kodlar eğitim amaçlıdır; yatırım tavsiyesi değildir.