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ı.

İnteraktif Grafik Geliştirme

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)

Plotly Candlestick Grafik

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.