Risk05.04.2026schedule3 min read

Portföy Volatilitesini Ölçmek: ATR ve Beta

ATR ile bireysel hisse riskini, beta ile piyasa duyarlılığını Python'da hesaplıyoruz. BIST'te volatilite rejimlerini tanıma ve portföy risk skorlaması dahil.

Risk yönetimini ciddiye almaya başlamadan önce şöyle düşünürdüm: "iyi hisse alırsan zaten risk az." Yanlış. İyi hisse bile yanlış volatilite rejiminde, yanlış büyüklükte tutulursa portföyü mahvedebilir. ATR ve beta bu dersi öğrettikten sonra her yeni pozisyon açmadan önce mutlaka baktığım iki gösterge oldu.

Portföy Risk Analizi

Neden İki Farklı Ölçüt?

ATR (Average True Range) mutlak volatiliteyi ölçer — hissenin kaç TL oynadığını. Pozisyon büyüklüğü hesaplarken ve stop-loss yerleştirirken kullanılır.

Beta ise göreli volatiliteyi ölçer — hissenin piyasaya (XU100) göre ne kadar oynadığını. Beta 1.5 olan hisse, endeks %10 düştüğünde ortalamada %15 düşer.

İkisi farklı soruları yanıtlıyor: ATR "bu hisse ne kadar oynar?" derken beta "piyasa düşünce bu hisse ne kadar acıtır?" diyor.

Adım 1: Veri Hazırlığı

!pip install yfinance --quiet

import yfinance as yf
import pandas as pd
import numpy as np
import plotly.graph_objects as go

semboller = ["THYAO.IS", "GARAN.IS", "ASELS.IS", "EREGL.IS", "SISE.IS"]
benchmark = "XU100.IS"

ham = yf.download(semboller + [benchmark],
                  start="2022-01-01", end="2025-01-01", progress=False)

kapanis = ham["Close"].copy()
kapanis.columns = [c.replace(".IS", "") for c in kapanis.columns]

high = ham["High"].copy()
low = ham["Low"].copy()
high.columns = [c.replace(".IS", "") for c in high.columns]
low.columns = [c.replace(".IS", "") for c in low.columns]

kapanis = kapanis[kapanis > 0].ffill().dropna()
high = high[high > 0].ffill().dropna()
low = low[low > 0].ffill().dropna()

print(f"Veri hazır: {len(kapanis)} gün, {len(semboller)} hisse + benchmark")

Adım 2: ATR Hesaplama ve Normalize Etme

def atr_hesapla(yuksek, dusuk, kapanis, period=14):
    tr1 = yuksek - dusuk
    tr2 = (yuksek - kapanis.shift(1)).abs()
    tr3 = (dusuk - kapanis.shift(1)).abs()

    true_range = pd.concat(
        [tr1.stack(), tr2.stack(), tr3.stack()], axis=1
    ).max(axis=1).unstack()

    atr = true_range.ewm(alpha=1/period, adjust=False).mean()
    atr_pct = atr / kapanis * 100

    return atr, atr_pct

hisse_adlari = [s.replace(".IS", "") for s in semboller]
atr, atr_pct = atr_hesapla(high[hisse_adlari], low[hisse_adlari], kapanis[hisse_adlari])

print("\nGüncel ATR Değerleri:")
for hisse in hisse_adlari:
    son_atr_pct = atr_pct[hisse].iloc[-1]
    seviye = "Yüksek" if son_atr_pct > 2.5 else ("Orta" if son_atr_pct > 1.5 else "Düşük")
    print(f"  {hisse:<10} ATR%: {son_atr_pct:.2f}%  ({seviye})")

Volatilite ve Risk Yönetimi

Adım 3: Beta Hesaplama

def beta_hesapla(hisse_getiri, piyasa_getiri, pencere=60):
    kovaryans = hisse_getiri.rolling(pencere).cov(piyasa_getiri)
    varyans = piyasa_getiri.rolling(pencere).var()
    beta = kovaryans / varyans
    return beta

getiriler = kapanis[hisse_adlari].pct_change().dropna()
bm_getiri = kapanis["XU100"].pct_change().dropna()

beta_df = pd.DataFrame(index=getiriler.index)
for hisse in hisse_adlari:
    beta_df[hisse] = beta_hesapla(getiriler[hisse], bm_getiri)

print("\nGüncel Beta Değerleri (son 60 gün):")
for hisse in hisse_adlari:
    son_beta = beta_df[hisse].iloc[-1]
    if son_beta > 1.3:
        yorum = "Agresif"
    elif son_beta > 0.8:
        yorum = "Normal"
    else:
        yorum = "Savunmacı"
    print(f"  {hisse:<10} Beta: {son_beta:.2f}  ({yorum})")

Adım 4: Portföy Risk Skoru ve Görselleştirme

risk_skoru = atr_pct[hisse_adlari].iloc[-20:].mean() * beta_df[hisse_adlari].iloc[-20:].mean()
risk_skoru = risk_skoru.sort_values(ascending=False)

fig = go.Figure()

for hisse in hisse_adlari:
    son_atr_pct = atr_pct[hisse].iloc[-1]
    son_beta = beta_df[hisse].iloc[-1]
    boyut = risk_skoru[hisse] * 20

    fig.add_trace(go.Scatter(
        x=[son_beta], y=[son_atr_pct],
        mode="markers+text",
        name=hisse, text=[hisse], textposition="top center",
        marker=dict(size=max(boyut, 15), opacity=0.7)
    ))

fig.add_vline(x=1.0, line_dash="dash", line_color="gray", line_width=1)
fig.add_hline(y=2.0, line_dash="dash", line_color="gray", line_width=1)

fig.update_layout(
    title="Portföy Risk Haritası: ATR% vs Beta",
    xaxis_title="Beta (Piyasa Duyarlılığı)",
    yaxis_title="ATR% (Mutlak Volatilite)",
    plot_bgcolor="#fff", paper_bgcolor="#f8f9fa",
    showlegend=False, height=450
)
fig.show()

Sonuç

  • ATR ve beta farklı risk boyutlarını ölçüyor; ikisini birlikte kullanmak çok daha bütünlüklü bir tablo veriyor.
  • BIST'te volatilite çok değişken — 2021 kur krizi döneminde ATR% iki-üç katına çıkmıştı.
  • Bu analizin sınırı: korelasyon ihmal edildi. İki yüksek beta hisse portföyde aynı anda düşerse risk toplamak değil, katlamak demektir.

Bu yazıdaki kodlar eğitim amaçlıdır; yatırım tavsiyesi değildir.