1. Şirketin sorusu ve brif
Kim soruyor? Küçük bir finansman şirketinin risk yöneticisi. Kurul toplantısından önce portföyün 31.12.2024 itibarıyla fotoğrafını istiyor.
Hangi karar? 2025’te hangi segmentte yeni kredi verilmeye devam edilecek, hangisinde koşullar sıkılaştırılacak? Brifin soruları:
- Her kredinin aylık taksiti ne, taksitin ne kadarı faiz, ne kadarı anapara?
- Rapor tarihinde portföyde ne kadar bakiye var?
- Gecikme ve takip (30+ ve 90+ gün) bakiyenin yüzde kaçı; segmentlere göre fark var mı?
- Portföy ne getiriyor? Riskli krediler hesaba katılınca getiri ne olur?
- Bir krediye tıklayınca açılan, o kredinin ödeme planını gösteren bir detay sayfası.
Paranın zaman değeri ve PMT fonksiyonunun mantığı Finansal raporlama: gelir tablosu, bütçe sapması, oranlar ve finansal fonksiyonlar dersinde anlatıldı; burada tekrar etmiyoruz, onu bir portföye uyguluyoruz.
2. Veri ve model
Krediler =
DATATABLE(
"KrediNo", STRING, "Segment", STRING, "Tutar", CURRENCY, "YillikFaiz", DOUBLE,
"Vade", INTEGER, "Baslangic", DATETIME, "GecikmeGun", INTEGER,
{
{"K01", "KOBİ", 400000, 0.42, 24, "2024-01-15", 0},
{"K02", "KOBİ", 250000, 0.45, 12, "2024-06-01", 45},
{"K03", "Bireysel", 120000, 0.48, 36, "2023-09-01", 0},
{"K04", "Bireysel", 80000, 0.50, 24, "2024-03-01", 120},
{"K05", "Kurumsal", 1000000, 0.38, 36, "2023-04-01", 0},
{"K06", "Kurumsal", 600000, 0.40, 24, "2024-09-01", 0},
{"K07", "KOBİ", 300000, 0.44, 18, "2023-12-01", 0},
{"K08", "Bireysel", 60000, 0.52, 12, "2024-02-01", 35},
{"K09", "KOBİ", 150000, 0.46, 24, "2024-04-01", 95},
{"K10", "Kurumsal", 450000, 0.39, 12, "2024-07-01", 0}
}
)
| Sütun | Anlamı |
|---|---|
Tutar, YillikFaiz, Vade | Kullandırılan anapara, yıllık sözleşme faizi, ay cinsinden vade. Eşit taksitli (anüite) kredi. |
Baslangic | Kullandırım tarihi; ilk taksit bir ay sonra. |
GecikmeGun | Rapor tarihinde en eski ödenmemiş taksitin gecikme günü. 30+ “gecikmede”, 90+ “takipte”. |
Modelde ikinci tablo ödeme planıdır: her kredi için her ay bir satır. Krediler ile ödeme planı arasında bire-çok ilişki kurulur (KrediNo), plandaki ödeme tarihi de tarih tablosuna bağlanır.
Veri sınırları:
- Sözleşme bakiyesi: bakiyeyi ödeme planına göre hesaplıyoruz, yani her taksitin zamanında ödendiğini varsayıyoruz. Gecikmedeki kredilerde gerçek bakiye daha yüksektir (ödenmeyen taksitler ve gecikme faizi). Gerçek işte tahsilat tablosu ayrıca gelir.
- Tarih tablosu kısa: uygulamanın
Tarihtablosu 31.12.2024’te bitiyor; portföyün son taksiti ise Eylül 2026’da. 222 taksitin 123’ü 2024’ten sonra. Modelde ödeme planını tarih tablosuna bağlayacaksan tarih tablosunu vadelerin sonuna kadar uzat.
3. Analiz adımları
Adım 1: Ödeme planı (amortisman tablosu). Aylık faiz i = yıllık faiz ÷ 12, taksit A = PMT(i, Vade, -Tutar). k. taksitten sonra kalan bakiye için kapalı formül: Bk = P·(1+i)k − A·((1+i)k − 1) ÷ i. k. taksitin faizi bir önceki bakiyenin faizidir: Bk−1 × i; anapara = A − faiz. GENERATE her kredi satırı için GENERATESERIES(1, Vade) ile taksit satırlarını üretir:
Ödeme Planı =
GENERATE(
Krediler,
VAR i = [YillikFaiz] / 12
VAR A = PMT(i, [Vade], -[Tutar])
VAR P0 = [Tutar]
VAR Bas = [Baslangic]
RETURN
SELECTCOLUMNS(
GENERATESERIES(1, [Vade]),
"TaksitNo", [Value],
"OdemeTarihi", EDATE(Bas, [Value]),
"Taksit", A,
"Faiz", (P0 * POWER(1 + i, [Value] - 1) - A * (POWER(1 + i, [Value] - 1) - 1) / i) * i,
"Kalan", P0 * POWER(1 + i, [Value]) - A * (POWER(1 + i, [Value]) - 1) / i
)
)
Uygulamanın motorunda Krediler modelde olmadığı için aynı tabloyu sorguda değişkenle deneriz. Önce tek bir kredi (K03):
EVALUATE
VAR Krediler =
DATATABLE(
"KrediNo", STRING, "Tutar", CURRENCY, "YillikFaiz", DOUBLE, "Vade", INTEGER, "Baslangic", DATETIME,
{{"K03", 120000, 0.48, 36, "2023-09-01"}}
)
VAR Plan = GENERATE(
Krediler,
VAR i = [YillikFaiz] / 12
VAR A = PMT(i, [Vade], -[Tutar])
VAR P0 = [Tutar]
VAR Bas = [Baslangic]
RETURN
SELECTCOLUMNS(
GENERATESERIES(1, [Vade]),
"TaksitNo", [Value],
"OdemeTarihi", EDATE(Bas, [Value]),
"Taksit", A,
"Faiz", (P0 * POWER(1 + i, [Value] - 1) - A * (POWER(1 + i, [Value] - 1) - 1) / i) * i,
"Kalan", P0 * POWER(1 + i, [Value]) - A * (POWER(1 + i, [Value]) - 1) / i
)
)
RETURN
SELECTCOLUMNS(
FILTER(Plan, [TaksitNo] <= 2 || [TaksitNo] = 15 || [TaksitNo] = 36),
"Taksit No", [TaksitNo], "Tarih", [OdemeTarihi], "Taksit", [Taksit],
"Faiz", [Faiz], "Anapara", [Taksit] - [Faiz], "Kalan", [Kalan]
)
| K03 taksit | Tarih | Taksit | Faiz | Anapara | Kalan bakiye |
|---|---|---|---|---|---|
| 1 | 01.10.2023 | 6.346,43 ₺ | 4.800,00 ₺ | 1.546,43 ₺ | 118.453,57 ₺ |
| 2 | 01.11.2023 | 6.346,43 ₺ | 4.738,14 ₺ | 1.608,28 ₺ | 116.845,29 ₺ |
| 15 | 01.12.2024 | 6.346,43 ₺ | 3.668,52 ₺ | 2.677,91 ₺ | 89.035,02 ₺ |
| 36 | 01.09.2026 | 6.346,43 ₺ | 244,09 ₺ | 6.102,33 ₺ | 0,00 ₺ |
Bulgu: Taksit sabit, içeriği değişiyor. K03’ün ilk taksitinin %76’sı faiz; son taksitin %96’sı anapara. Kredi boyunca toplam 228.471 ₺ ödenecek; bunun 108.471 ₺’si faiz. Son satırda kalan bakiyenin tam 0 çıkması planın doğru kurulduğunun testidir; bu kontrolü her kredi için yap.
Adım 2: Rapor tarihinde kalan bakiye ve 2024 faiz geliri. Her kredi için rapor tarihine kadar vadesi gelen taksitleri sayar, son taksitten sonraki bakiyeyi alırız. Henüz taksiti gelmemiş kredinin bakiyesi tutarın kendisidir.
DEFINE
VAR Krediler = DATATABLE(
"KrediNo", STRING, "Segment", STRING, "Tutar", CURRENCY, "YillikFaiz", DOUBLE,
"Vade", INTEGER, "Baslangic", DATETIME, "GecikmeGun", INTEGER,
{
{"K01", "KOBİ", 400000, 0.42, 24, "2024-01-15", 0},
{"K02", "KOBİ", 250000, 0.45, 12, "2024-06-01", 45},
{"K03", "Bireysel", 120000, 0.48, 36, "2023-09-01", 0},
{"K04", "Bireysel", 80000, 0.50, 24, "2024-03-01", 120},
{"K05", "Kurumsal", 1000000, 0.38, 36, "2023-04-01", 0},
{"K06", "Kurumsal", 600000, 0.40, 24, "2024-09-01", 0},
{"K07", "KOBİ", 300000, 0.44, 18, "2023-12-01", 0},
{"K08", "Bireysel", 60000, 0.52, 12, "2024-02-01", 35},
{"K09", "KOBİ", 150000, 0.46, 24, "2024-04-01", 95},
{"K10", "Kurumsal", 450000, 0.39, 12, "2024-07-01", 0}
}
)
VAR Plan = GENERATE(
Krediler,
VAR i = [YillikFaiz] / 12
VAR A = PMT(i, [Vade], -[Tutar])
VAR P0 = [Tutar]
VAR Bas = [Baslangic]
RETURN
SELECTCOLUMNS(
GENERATESERIES(1, [Vade]),
"TaksitNo", [Value],
"OdemeTarihi", EDATE(Bas, [Value]),
"Taksit", A,
"Faiz", (P0 * POWER(1 + i, [Value] - 1) - A * (POWER(1 + i, [Value] - 1) - 1) / i) * i,
"Kalan", P0 * POWER(1 + i, [Value]) - A * (POWER(1 + i, [Value]) - 1) / i
)
)
VAR Rapor = DATE(2024, 12, 31)
EVALUATE
ADDCOLUMNS(
Krediler,
"Durum", SWITCH(TRUE(), [GecikmeGun] >= 90, "Takipte", [GecikmeGun] >= 30, "Gecikmede", "Düzenli"),
"Odenen", VAR k = [KrediNo] RETURN COUNTROWS(FILTER(Plan, [KrediNo] = k && [OdemeTarihi] <= Rapor)) + 0,
"Bakiye",
VAR k = [KrediNo]
VAR t = [Tutar]
VAR p = FILTER(Plan, [KrediNo] = k && [OdemeTarihi] <= Rapor)
RETURN IF(ISEMPTY(p), t, MINX(p, [Kalan])),
"Faiz2024", VAR k = [KrediNo] RETURN SUMX(FILTER(Plan, [KrediNo] = k && YEAR([OdemeTarihi]) = 2024), [Faiz]),
"Tahsilat2025", VAR k = [KrediNo] RETURN SUMX(FILTER(Plan, [KrediNo] = k && YEAR([OdemeTarihi]) = 2025), [Taksit])
)
| Kredi | Segment | Tutar | Durum | Ödenen taksit | Kalan bakiye | 2024 faiz |
|---|---|---|---|---|---|---|
| K01 | KOBİ | 400.000 ₺ | Düzenli | 11 / 24 | 256.632 ₺ | 130.633 ₺ |
| K02 | KOBİ | 250.000 ₺ | Gecikmede (45) | 6 / 12 | 138.749 ₺ | 46.268 ₺ |
| K03 | Bireysel | 120.000 ₺ | Düzenli | 15 / 36 | 89.035 ₺ | 50.019 ₺ |
| K04 | Bireysel | 80.000 ₺ | Takipte (120) | 9 / 24 | 58.652 ₺ | 26.683 ₺ |
| K05 | Kurumsal | 1.000.000 ₺ | Düzenli | 20 / 36 | 582.299 ₺ | 282.409 ₺ |
| K06 | Kurumsal | 600.000 ₺ | Düzenli | 3 / 24 | 548.172 ₺ | 58.310 ₺ |
| K07 | KOBİ | 300.000 ₺ | Düzenli | 12 / 18 | 122.209 ₺ | 98.934 ₺ |
| K08 | Bireysel | 60.000 ₺ | Gecikmede (35) | 10 / 12 | 12.234 ₺ | 17.408 ₺ |
| K09 | KOBİ | 150.000 ₺ | Takipte (95) | 8 / 24 | 114.086 ₺ | 41.453 ₺ |
| K10 | Kurumsal | 450.000 ₺ | Düzenli | 5 / 12 | 283.204 ₺ | 62.630 ₺ |
Bulgu: 3.410.000 ₺ kullandırılmış, rapor tarihinde 2.205.272 ₺ bakiye var. 2024’te vadesi gelen taksitlerin faiz kısmı 814.747 ₺, anapara kısmı 1.063.190 ₺: tahsil edilmesi gerekenin %43’ü faiz. 2025’te planlanan tahsilat 2.189.223 ₺; bunun 350.646 ₺’si (%16) 30 gün ve üstü gecikmedeki kredilerden.
Adım 3: Segmentlere göre risk ve getiri. Gecikme oranını kredi sayısıyla değil bakiyeyle ölçeriz: küçük bir kredinin gecikmesi büyük bir kredininkiyle aynı ağırlığı taşımamalı. Getiri için iki ölçü: sözleşme getirisi (bakiye ağırlıklı faiz) ve takipteki kredileri getirisiz sayan riskten arındırılmış getiri.
DEFINE
VAR Krediler = DATATABLE(
"KrediNo", STRING, "Segment", STRING, "Tutar", CURRENCY, "YillikFaiz", DOUBLE,
"Vade", INTEGER, "Baslangic", DATETIME, "GecikmeGun", INTEGER,
{
{"K01", "KOBİ", 400000, 0.42, 24, "2024-01-15", 0},
{"K02", "KOBİ", 250000, 0.45, 12, "2024-06-01", 45},
{"K03", "Bireysel", 120000, 0.48, 36, "2023-09-01", 0},
{"K04", "Bireysel", 80000, 0.50, 24, "2024-03-01", 120},
{"K05", "Kurumsal", 1000000, 0.38, 36, "2023-04-01", 0},
{"K06", "Kurumsal", 600000, 0.40, 24, "2024-09-01", 0},
{"K07", "KOBİ", 300000, 0.44, 18, "2023-12-01", 0},
{"K08", "Bireysel", 60000, 0.52, 12, "2024-02-01", 35},
{"K09", "KOBİ", 150000, 0.46, 24, "2024-04-01", 95},
{"K10", "Kurumsal", 450000, 0.39, 12, "2024-07-01", 0}
}
)
VAR Plan = GENERATE(
Krediler,
VAR i = [YillikFaiz] / 12
VAR A = PMT(i, [Vade], -[Tutar])
VAR P0 = [Tutar]
VAR Bas = [Baslangic]
RETURN
SELECTCOLUMNS(
GENERATESERIES(1, [Vade]),
"TaksitNo", [Value],
"OdemeTarihi", EDATE(Bas, [Value]),
"Taksit", A,
"Faiz", (P0 * POWER(1 + i, [Value] - 1) - A * (POWER(1 + i, [Value] - 1) - 1) / i) * i,
"Kalan", P0 * POWER(1 + i, [Value]) - A * (POWER(1 + i, [Value]) - 1) / i
)
)
VAR Rapor = DATE(2024, 12, 31)
VAR Ozet = ADDCOLUMNS(
Krediler,
"Durum", SWITCH(TRUE(), [GecikmeGun] >= 90, "Takipte", [GecikmeGun] >= 30, "Gecikmede", "Düzenli"),
"Odenen", VAR k = [KrediNo] RETURN COUNTROWS(FILTER(Plan, [KrediNo] = k && [OdemeTarihi] <= Rapor)) + 0,
"Bakiye",
VAR k = [KrediNo]
VAR t = [Tutar]
VAR p = FILTER(Plan, [KrediNo] = k && [OdemeTarihi] <= Rapor)
RETURN IF(ISEMPTY(p), t, MINX(p, [Kalan])),
"Faiz2024", VAR k = [KrediNo] RETURN SUMX(FILTER(Plan, [KrediNo] = k && YEAR([OdemeTarihi]) = 2024), [Faiz]),
"Tahsilat2025", VAR k = [KrediNo] RETURN SUMX(FILTER(Plan, [KrediNo] = k && YEAR([OdemeTarihi]) = 2025), [Taksit])
)
EVALUATE
ADDCOLUMNS(
DISTINCT(SELECTCOLUMNS(Krediler, "Segment", [Segment])),
"Bakiye", VAR s = [Segment] RETURN SUMX(FILTER(Ozet, [Segment] = s), [Bakiye]),
"Gecikme 30+ %", VAR s = [Segment]
RETURN DIVIDE(SUMX(FILTER(Ozet, [Segment] = s && [GecikmeGun] >= 30), [Bakiye]), SUMX(FILTER(Ozet, [Segment] = s), [Bakiye])) + 0,
"Takip 90+ %", VAR s = [Segment]
RETURN DIVIDE(SUMX(FILTER(Ozet, [Segment] = s && [GecikmeGun] >= 90), [Bakiye]), SUMX(FILTER(Ozet, [Segment] = s), [Bakiye])) + 0,
"Sözleşme Getirisi", VAR s = [Segment]
RETURN DIVIDE(SUMX(FILTER(Ozet, [Segment] = s), [Bakiye] * [YillikFaiz]), SUMX(FILTER(Ozet, [Segment] = s), [Bakiye])),
"Riskten Arındırılmış", VAR s = [Segment]
RETURN DIVIDE(SUMX(FILTER(Ozet, [Segment] = s && [GecikmeGun] < 90), [Bakiye] * [YillikFaiz]), SUMX(FILTER(Ozet, [Segment] = s), [Bakiye]))
)
| Segment | Kredi | Bakiye (pay) | Gecikme 30+ | Takip 90+ | Sözleşme getirisi | Riskten arındırılmış |
|---|---|---|---|---|---|---|
| Kurumsal | 3 | 1.413.675 ₺ (%64,1) | %0 | %0 | %39,0 | %39,0 |
| KOBİ | 4 | 631.677 ₺ (%28,6) | %40,0 | %18,1 | %43,8 | %35,5 |
| Bireysel | 3 | 159.921 ₺ (%7,3) | %44,3 | %36,7 | %49,0 | %30,7 |
| Portföy | 10 | 2.205.272 ₺ | %14,7 | %7,8 | %41,1 | %37,4 |
Bulgu: Kâğıt üzerinde en kârlı segment Bireysel (%49,0), ama takipteki K04 hesaba katılınca getirisi %30,7’ye iniyor ve en düşük segment oluyor. Kurumsal hiç gecikme olmadan %39,0 getiriyor. Yüksek faiz riskin bedelidir; risk gerçekleşince getiri kaybolur. Portföy düzeyinde takip oranı %7,8 ve bu bakiye 2024 faizinin 68.136 ₺’sini oluşturuyor; bu faiz büyük olasılıkla tahsil edilemeyecek.
Adım 4: Model ölçüleri ve kredi detay sayfası. Gerçek modelde Krediler ve Ödeme Planı iki tablodur; ölçüler ilişki üzerinden çalışır. Kalan bakiye yarı toplanabilir bir değerdir: krediler üzerinden toplanır ama aylar üzerinden toplanmaz (Yarı toplanabilir ölçüler: stok, bakiye, nüfus).
Kalan Bakiye =
VAR Rapor = MAX(Tarih[Tarih])
RETURN
SUMX(
VALUES(Krediler[KrediNo]),
VAR Son = CALCULATE(MIN('Ödeme Planı'[Kalan]), REMOVEFILTERS(Tarih), 'Ödeme Planı'[OdemeTarihi] <= Rapor)
RETURN IF(ISBLANK(Son), CALCULATE(SUM(Krediler[Tutar])), Son)
)
Gecikme 30+ % =
DIVIDE(CALCULATE([Kalan Bakiye], Krediler[GecikmeGun] >= 30), [Kalan Bakiye])
Kredi Başlığı =
VAR No = SELECTEDVALUE(Krediler[KrediNo])
VAR Gun = SELECTEDVALUE(Krediler[GecikmeGun])
VAR Durum = SWITCH(TRUE(), Gun >= 90, "Takipte", Gun >= 30, "Gecikmede", "Düzenli")
RETURN
IF(
ISBLANK(No), "Bir kredi seçin",
No & " · " & SELECTEDVALUE(Krediler[Segment]) & " · " & FORMAT(SELECTEDVALUE(Krediler[Tutar]), "#,##0") & " ₺ · yıllık %"
& FORMAT(SELECTEDVALUE(Krediler[YillikFaiz]) * 100, "0") & " · " & Durum & IF(Gun > 0, " (" & Gun & " gün)")
)
Portföy sayfasındaki kredi tablosunda bir satıra sağ tıklayıp Detaya git denince Kredi detayı sayfası açılır; detay alanı Krediler[KrediNo]. K04 için başlık “K04 · Bireysel · 80.000 ₺ · yıllık %50 · Takipte (120 gün)” olur. Sayfada ödeme planı tablosu (taksit no, tarih, faiz, anapara, kalan), faiz ve anaparayı yığılmış sütunla gösteren grafik ve rapor tarihini işaretleyen bir sabit çizgi bulunur.
4. Rapor sayfası taslağı
| Sayfa / konum | Görsel | Alanlar |
|---|---|---|
| Portföy, üst şerit | 4 kart | Kalan bakiye (2.205.272 ₺), Gecikme 30+ % (%14,7), Takip 90+ % (%7,8), Riskten arındırılmış getiri (%37,4) |
| Portföy, sol | Kümelenmiş çubuk | Segment; Sözleşme getirisi ve riskten arındırılmış getiri yan yana |
| Portföy, sağ | Yığılmış sütun | 2025 ayları; planlanan tahsilat, Durum’a göre renkli (Düzenli / Gecikmede / Takipte) |
| Portföy, alt | Tablo | Kredi; Segment, Tutar, Ödenen taksit, Kalan bakiye, Durum (koşullu ikon) |
| Kredi detayı | Detay sayfası | Başlık: Kredi Başlığı; ödeme planı tablosu; faiz/anapara yığılmış sütunu; “Geri” düğmesi |
5. Bulgu özeti ve öneri
- Portföyün %14,7’si 30 gün ve üstü gecikmede, %7,8’i takipte. Takipteki iki kredi (K04, K09) için yapılandırma ya da hukuki takip kararı ve karşılık ayrılması gerekiyor.
- Bireysel segmentte koşulları sıkılaştır: en yüksek sözleşme faizine (%49,0) rağmen riskten arındırılmış getiri en düşük (%30,7). Faizi artırmak yerine kredi onay kriterlerini gözden geçir.
- Kurumsal segment portföyün bel kemiği: bakiyenin %64,1’i, gecikme yok, getiri %39,0. Büyüme bu segmentte daha güvenli; ama tek bir kredinin (K05) bakiyenin %26’sı olduğu yoğunlaşma riski not edilmeli.
- 2025 nakit planını riske göre ayır: planlanan 2.189.223 ₺ tahsilatın 350.646 ₺’si gecikmedeki kredilerden; nakit planında bu kısmı ayrı satırda ve iskontolu göster.
- Modeli tamamla: gerçek tahsilat tablosu ve vadelerin sonuna kadar uzanan tarih tablosu olmadan bakiye sözleşme varsayımına dayanır.