Risk05.04.2026schedule3 min read
Position Sizing: Ne Kadar Almalıyım?
Kelly criterion ve fixed fractional yöntemlerini karşılaştırıyor, BIST'te gerçekçi pozisyon büyüklüğü nasıl belirlenir sorusunu Python'da yanıtlıyoruz.
Yıllarca strateji geliştirmeye odaklandım ama ne kadar alacağımı düşünmedim. "Ne alacağım" sorusu kadar "ne kadar alacağım" sorusu da önemli — belki daha önemli. Doğru strateji, yanlış pozisyon büyüklüğüyle bile hesabı bitirebilir.
Neden Position Sizing Bu Kadar Kritik?
Aynı strateji, farklı pozisyon büyüklükleriyle tamamen farklı sonuçlar üretir:
- Çok küçük pozisyon — kazancınız sermayenizi anlamlı büyütmez
- Çok büyük pozisyon — tek kayıp sermayi ciddi ölçüde eritir
Adım 1: Kelly Criterion
Kelly, uzun vadede sermayeyi en hızlı büyüten teorik pozisyon oranını verir.
import numpy as np
import pandas as pd
import plotly.graph_objects as go
def kelly_criterion(win_rate, kazanc_oran, kayip_oran=1.0):
q = 1 - win_rate
b = kazanc_oran / kayip_oran
kelly = (b * win_rate - q) / b
return max(kelly, 0)
win_rate = 0.55
ortalama_kazanc = 1.8
full_kelly = kelly_criterion(win_rate, ortalama_kazanc)
half_kelly = full_kelly * 0.5
quarter_kelly = full_kelly * 0.25
print(f"Full Kelly : %{full_kelly*100:.1f} sermaye")
print(f"Half Kelly : %{half_kelly*100:.1f} sermaye")
print(f"Quarter Kelly : %{quarter_kelly*100:.1f} sermaye")
Adım 2: Fixed Fractional Yöntemi
Sermayenin sabit bir yüzdesini her işlemde riske atarsınız.
def fixed_fractional_pozisyon(sermaye, risk_yuzdesi, stop_mesafe_pct):
risk_tutari = sermaye * risk_yuzdesi
pozisyon_degeri = risk_tutari / stop_mesafe_pct
return risk_tutari, pozisyon_degeri
sermaye = 500_000
risk_pct = 0.02
stop_pct = 0.05
risk_tl, poz_degeri = fixed_fractional_pozisyon(sermaye, risk_pct, stop_pct)
print(f"Portföy Değeri : {sermaye:>12,.0f} TL")
print(f"İşlem Başı Risk : %{risk_pct*100:.0f} = {risk_tl:>8,.0f} TL")
print(f"Pozisyon Büyüklüğü : {poz_degeri:>12,.0f} TL")
print("\n--- Farklı stop-loss mesafeleri ---")
for stop in [0.02, 0.03, 0.05, 0.07, 0.10, 0.15]:
r, p = fixed_fractional_pozisyon(sermaye, risk_pct, stop)
print(f" Stop %{stop*100:<4.0f} → Pozisyon: {p:>12,.0f} TL (%{p/sermaye*100:.1f})")
Adım 3: ATR Bazlı Dinamik Pozisyon Büyüklüğü
import yfinance as yf
def atr_bazli_pozisyon(ticker, sermaye, risk_pct=0.02, atr_carpan=2, period=14):
df = yf.download(ticker, period="3mo", progress=False)
if isinstance(df.columns, pd.MultiIndex):
df.columns = df.columns.droplevel(1)
close = df["Close"].iloc[-1]
high = df["High"]
low = df["Low"]
prev = df["Close"].shift(1)
tr = pd.concat([
high - low, (high - prev).abs(), (low - prev).abs()
], axis=1).max(axis=1)
atr = tr.ewm(alpha=1/period, adjust=False).mean().iloc[-1]
stop_mesafe = atr_carpan * atr
risk_tl = sermaye * risk_pct
lot_sayisi = int(risk_tl / stop_mesafe)
poz_degeri = lot_sayisi * close
return {
"ticker": ticker, "fiyat": round(close, 2),
"atr": round(atr, 2), "lot": lot_sayisi,
"pozisyon_tl": round(poz_degeri, 0),
"poz_pct": round(poz_degeri / sermaye * 100, 1)
}
semboller = ["THYAO.IS", "GARAN.IS", "ASELS.IS"]
for s in semboller:
try:
r = atr_bazli_pozisyon(s, 500_000)
print(f"{r['ticker'].replace('.IS',''):<10} Fiyat: {r['fiyat']:>8.2f} Lot: {r['lot']:>5} Poz: {r['pozisyon_tl']:>10,.0f} TL")
except Exception as e:
print(f"{s}: {e}")
Adım 4: Kelly vs Fixed Fractional — Monte Carlo
def monte_carlo_pozisyon(n_islem, win_rate, kazanc_carpan, pozisyon_oran,
n_simulasyon=500, baslangic=100_000):
np.random.seed(42)
son_sermayeler = []
for _ in range(n_simulasyon):
sermaye = baslangic
for _ in range(n_islem):
kazanc = np.random.random() < win_rate
if kazanc:
sermaye *= (1 + pozisyon_oran * kazanc_carpan)
else:
sermaye *= (1 - pozisyon_oran)
if sermaye <= 0:
break
son_sermayeler.append(sermaye)
return np.array(son_sermayeler)
full_k = kelly_criterion(0.55, 1.8)
sonuclar_full = monte_carlo_pozisyon(200, 0.55, 1.8, full_k)
sonuclar_half = monte_carlo_pozisyon(200, 0.55, 1.8, full_k * 0.5)
sonuclar_fixed = monte_carlo_pozisyon(200, 0.55, 1.8, 0.02)
for isim, veri in [("Full Kelly", sonuclar_full),
("Half Kelly", sonuclar_half),
("Fixed %2", sonuclar_fixed)]:
sifir = (veri < 1000).sum() / len(veri) * 100
print(f"{isim:<15} Medyan: {np.median(veri)/1000:.0f}K Sıfır riski: %{sifir:.1f}")
Sonuç
- Position sizing strateji kadar önemli. İyi strateji yanlış boyutla batabilir.
- Kelly Criterion teorik optimum verir ama pratikte çok agresif. Half Kelly veya Quarter Kelly daha güvenli.
- BIST'te pratik öneri: ATR bazlı stop-loss + Fixed Fractional %1-2 kombinasyonu.
- Bir sonraki adım: maximum drawdown analizi ile birleştirmek.
Bu yazıdaki kodlar eğitim amaçlıdır; yatırım tavsiyesi değildir.