Tín dụng 10 — Dữ liệu & phân tích danh mục tín dụng

13 thg 7, 2026 2 lượt xem
#banking
#sql
#data
#analytics
#credit
#vintage
#roll-rate

Khép lại series: dữ liệu là nền của mọi rủi ro tín dụng

Suốt series này, chúng ta đã đi qua từng lớp của quản trị rủi ro tín dụng: cách chấm điểm và xây scorecard để quyết định ai được vay, cách trích lập dự phòng theo IFRS 9 để đo tổn thất kỳ vọng, cách quản trị hạn mức và danh mục để kiểm soát rủi ro tập trung, và cách cảnh báo sớm (EWS) để phát hiện dấu hiệu xấu trước khi vỡ nợ. Điều mà tất cả các bài đó ngầm định — và bài này làm rõ — là: mọi mô hình, mọi chỉ số, mọi cảnh báo đều chỉ tốt bằng dữ liệu nuôi nó.

Scorecard cần lịch sử hành vi trả nợ để huấn luyện và backtest. Mô hình ECL cần chuỗi thời gian đủ dài để ước lượng PD, LGD, EAD. Basel cần dữ liệu chuẩn hoá để tính RWA. EWS cần dữ liệu tươi để kịp báo động. Nếu dữ liệu bị thiếu, sai định nghĩa, hoặc không có chiều lịch sử, toàn bộ tầng phân tích bên trên sụp đổ theo kiểu "rác vào, rác ra". Vì vậy bài cuối này không nói về một kỹ thuật rủi ro mới — nó nói về cái móng: dữ liệu tín dụng trông như thế nào, các phân tích trụ cột khai thác nó ra sao, và làm sao chạy được chúng bằng SQL.

Dữ liệu tín dụng đến từ đâu

Dữ liệu tín dụng trong một ngân hàng không nằm ở một chỗ. Nó là hợp lưu của nhiều hệ thống nguồn, mỗi hệ thống nắm một mảnh sự thật:

  • LOS (Loan Origination System): hồ sơ khởi tạo khoản vay — thông tin thẩm định, thu nhập khai báo, mục đích vay, điểm scorecard tại thời điểm phê duyệt. Đây là "ảnh chụp lúc sinh ra" của khoản vay.
  • Core banking (T24, v.v.): sổ cái sống của khoản vay sau giải ngân — dư nợ gốc, lãi dồn tích, lịch trả nợ, ngày quá hạn (DPD — days past due), phân loại nhóm nợ.
  • CIC (Trung tâm Thông tin Tín dụng): dữ liệu tín dụng ngoài ngân hàng — khách hàng có vay ở đâu khác không, có nợ xấu ở tổ chức khác không. Nguồn quan trọng để nhìn tổng exposure của một khách.
  • Hệ thống TSBĐ (tài sản bảo đảm): giá trị định giá, loại tài sản, tỷ lệ LTV, ngày định giá lại — đầu vào cho LGD (xem Tài sản bảo đảm).
  • Hệ thống thu hồi / xử lý nợ (collection & recovery): lịch sử nhắc nợ, cam kết trả, số tiền thu hồi thực tế — nền để ước lượng recovery rate.

Nhiệm vụ của đội dữ liệu là kéo các nguồn này về một kho tập trung, chuẩn hoá, và giữ lại lịch sử. Chính chữ "lịch sử" mới là chìa khoá — mà chúng ta sẽ thấy ngay ở phần mô hình dữ liệu.

Mô hình dữ liệu tín dụng

Trái tim của một kho dữ liệu tín dụng là loan/account fact — bảng sự kiện ở cấp khoản vay. Nhưng khác với nhiều fact table thông thường, fact tín dụng bắt buộc phải có chiều thời gian dạng snapshot: ta không chỉ lưu trạng thái hiện tại của khoản vay, mà lưu một bản chụp mỗi tháng (hoặc mỗi ngày với các chỉ số nóng). Không có snapshot lịch sử thì không thể làm vintage, không thể làm roll rate, không thể backtest — vì tất cả các phân tích này bản chất là "so sánh cùng một khoản vay qua nhiều mốc thời gian".

Một mô hình tối giản nhưng đủ dùng gồm các thực thể sau:

  • loan_fact / account_snapshot (bảng sự kiện, một dòng cho mỗi khoản vay × tháng): loan_id, snapshot_month, outstanding_balance (dư nợ), dpd (số ngày quá hạn), npl_group (nhóm nợ 1–5 theo phân loại NHNN), interest_rate, disbursement_date (ngày giải ngân), maturity_date (ngày đáo hạn), product_code.
  • customer_dim (chiều khách hàng): customer_id, ngành nghề, khu vực, phân khúc, thông tin nhận diện nhóm liên quan.
  • collateral (tài sản bảo đảm): collateral_id, loan_id, loại tài sản, giá trị định giá, LTV.
  • payment / transaction (giao dịch trả nợ): payment_id, loan_id, số tiền, loại (gốc/lãi/phí), ngày giao dịch.

Điểm cần khắc sâu: snapshot_month biến một khoản vay thành nhiều dòng. Một khoản vay 5 năm sẽ có tới 60 dòng snapshot — mỗi dòng ghi lại dư nợ và nhóm nợ tại cuối tháng đó. Đây chính là cấu trúc cho phép ta trả lời câu hỏi "khoản này tháng trước ở nhóm 1, tháng này nhảy lên nhóm 3" — nền tảng của roll rate.

Các phân tích trụ cột

Vintage analysis — chất lượng theo "đợt giải ngân"

Vintage analysis (còn gọi là cohort analysis) nhóm các khoản vay theo tháng giải ngân (vintage), rồi theo dõi tỷ lệ xấu của từng nhóm theo tuổi khoản vay (months on book — MOB), thay vì theo thời gian lịch. Ý tưởng cốt lõi: một khoản vay giải ngân tháng 1/2024 và một khoản giải ngân tháng 6/2024, khi so ở "tháng thứ 6 sau giải ngân" của mỗi khoản, ta đang so quả táo với quả táo — cùng độ chín, khác đợt.

Bảng vintage điển hình có hàng là vintage (tháng giải ngân) và cột là MOB (tuổi 3, 6, 9, 12 tháng...), ô là tỷ lệ nợ xấu tích luỹ. Đọc bảng này theo cột dọc, ta thấy ngay: nếu cột "MOB 6" của các vintage gần đây cao hơn hẳn các vintage cũ, tức là chất lượng khách vay mới đang xấu đi — có thể do nới lỏng tiêu chuẩn cấp tín dụng. Đây là công cụ mạnh nhất để tách bạch "khoản vay xấu vì chính sách cấp tín dụng" khỏi "khoản vay xấu vì môi trường kinh tế xấu chung".

Roll rate / transition matrix — xác suất chuyển bucket

Roll rate theo dõi việc một khoản vay chuyển giữa các trạng thái quá hạn qua từng tháng: Current → 30 DPD → 60 DPD → 90 DPD → default; hoặc theo nhóm nợ 1→2→3→4→5. "Roll rate 30-to-60" là tỷ lệ các khoản đang ở bucket 30 DPD tháng này lăn xuống 60 DPD tháng sau. Tập hợp tất cả các tỷ lệ chuyển này thành một ma trận là transition matrix (ma trận chuyển trạng thái): phần tử (i, j) là xác suất một khoản ở trạng thái i chuyển sang trạng thái j trong một kỳ.

Transition matrix cực kỳ hữu dụng vì nó vừa dự báo (nhân ma trận với phân bố hiện tại để ước lượng phân bố tháng sau, làm đầu vào cho forecast NPL và collection) vừa là input trực tiếp cho ECL — chính từ chuỗi transition này người ta ước lượng PD theo từng nhóm. Lưu ý: ma trận nên được ước lượng riêng cho từng phân khúc/sản phẩm, và tốt nhất là hiệu chỉnh theo tuổi khoản vay, vì hành vi lăn nợ của khoản mới và khoản lâu năm khác nhau.

Migration / rating migration

Migration là góc nhìn rộng hơn roll rate: thay vì bucket quá hạn, ta theo dõi khoản vay (hoặc khách hàng) chuyển giữa các hạng xếp hạng nội bộ (internal rating) — ví dụ từ hạng A xuống B, B xuống C. Rating migration matrix cho thấy xu hướng suy giảm chất lượng của cả danh mục theo hạng, và là đầu vào để tính PD theo rating trong khung Basel IRB. Cả hai — roll rate và rating migration — bổ trợ nhau: một cái bắt tín hiệu ngắn hạn (lăn nợ), một cái bắt xu hướng chất lượng dài hạn (xuống hạng).

Các chỉ số danh mục: NPL, PAR, coverage, cost of risk

Đây là những con số xuất hiện trong mọi báo cáo HĐQT và báo cáo NHNN:

  • NPL ratio (tỷ lệ nợ xấu) = dư nợ nhóm 3+4+5 / tổng dư nợ. Thước đo trực tiếp nhất về chất lượng tài sản. (Định nghĩa nhóm nợ theo quy định phân loại của NHNN — cần đối chiếu thông tư hiện hành.)
  • PAR (Portfolio at Risk) = dư nợ của các khoản quá hạn trên X ngày / tổng dư nợ. Thường dùng PAR 30, PAR 90. Khác NPL ở chỗ PAR đo theo ngày quá hạn chứ không theo nhóm nợ phân loại, phổ biến trong microfinance và báo cáo quản trị nội bộ.
  • Coverage ratio (tỷ lệ bao phủ nợ xấu) = dự phòng đã trích / dư nợ xấu. Cho biết ngân hàng đã "để dành" đủ để hấp thụ tổn thất chưa. Nối trực tiếp với IFRS 9 ECL.
  • Cost of risk (CoR) = chi phí dự phòng trong kỳ / dư nợ bình quân. Đo "giá của rủi ro" mà danh mục phải trả mỗi năm, thường biểu thị bằng điểm cơ bản (bps).

Phân tích theo sản phẩm / ngành / vùng — góc concentration

Mọi chỉ số trên đều nên được cắt lát (slice) theo sản phẩm, ngành, vùng địa lý, phân khúc khách. Một NPL toàn hàng 2% có thể che giấu một ngành đang 12% và kéo cả danh mục xuống. Đây chính là góc nhìn dữ liệu cho rủi ro tập trung đã bàn ở Hạn mức & danh mục: dữ liệu là công cụ để nhìn thấy các ổ tập trung trước khi chúng phát nổ.

Ví dụ SQL trên sandbox (PROXY minh hoạ khái niệm)

Lưu ý quan trọng: SQL sandbox là PostgreSQL và chỉ chạy một câu SELECT/WITH/EXPLAIN. Schema mẫu (customers, accounts, transactions, employees, departments) không phải dữ liệu khoản vay thật. Ở đây ta dùng nó làm proxy để minh hoạ cơ chế các phân tích: coi accounts.balance như "dư nợ", transactions như "giao dịch trả nợ". Kết quả không mang ý nghĩa tín dụng thật — chỉ để bạn thấy pattern SQL. Quan hệ khoá: accounts.customer_id → customers.id, transactions.account_id → accounts.id. Không có cột customer_name (tên khách nằm ở customers.full_name).

1) "Dư nợ" (proxy = balance) theo thành phố — cắt lát danh mục theo vùng, giống cách ta cắt NPL theo địa lý:

▶ Chạy được trong SQL Builder

SELECT c.city,
       COUNT(a.id)          AS so_tai_khoan,
       SUM(a.balance)       AS tong_du_no_proxy,
       ROUND(AVG(a.balance), 2) AS du_no_binh_quan
FROM customers c
JOIN accounts a ON a.customer_id = c.id
GROUP BY c.city
ORDER BY tong_du_no_proxy DESC;

2) Phân nhóm dư nợ bằng NTILE — chia danh mục thành 4 phần bằng nhau theo quy mô dư nợ. Đây chính là cơ chế phía sau việc bucketing khách hàng theo mức exposure (ví dụ để soi nhóm dư nợ lớn nhất):

▶ Chạy được trong SQL Builder

SELECT a.id,
       a.account_no,
       a.balance,
       NTILE(4) OVER (ORDER BY a.balance DESC) AS nhom_tu_lon_den_nho
FROM accounts a
ORDER BY a.balance DESC;

3) "Giao dịch trả nợ" theo tháng — đếm và tổng giao dịch theo YYYY-MM. Cùng khuôn mẫu này dùng để dựng chuỗi thời gian snapshot theo tháng — nền của vintage và roll rate:

▶ Chạy được trong SQL Builder

SELECT to_char(t.created_at, 'YYYY-MM') AS thang,
       t.kind                           AS loai_giao_dich,
       COUNT(*)                         AS so_giao_dich,
       SUM(t.amount)                    AS tong_tien
FROM transactions t
GROUP BY to_char(t.created_at, 'YYYY-MM'), t.kind
ORDER BY thang, t.kind;

4) Top khách hàng theo tổng "dư nợ" — giống báo cáo large exposure, tìm các khách chiếm tỷ trọng dư nợ lớn nhất (góc rủi ro tập trung single obligor):

▶ Chạy được trong SQL Builder

SELECT c.id,
       c.full_name,
       c.city,
       SUM(a.balance) AS tong_du_no_proxy
FROM customers c
JOIN accounts a ON a.customer_id = c.id
GROUP BY c.id, c.full_name, c.city
ORDER BY tong_du_no_proxy DESC
LIMIT 10;

5) Tỷ trọng dư nợ theo thành phố bằng WITH + window — minh hoạ cách tính tỷ lệ tập trung (mỗi vùng chiếm bao nhiêu % tổng danh mục), pattern y hệt khi tính NPL ratio hay tỷ trọng ngành:

▶ Chạy được trong SQL Builder

WITH theo_thanh_pho AS (
    SELECT c.city,
           SUM(a.balance) AS du_no_vung
    FROM customers c
    JOIN accounts a ON a.customer_id = c.id
    GROUP BY c.city
)
SELECT city,
       du_no_vung,
       ROUND(100.0 * du_no_vung / SUM(du_no_vung) OVER (), 2) AS ty_trong_pct
FROM theo_thanh_pho
ORDER BY ty_trong_pct DESC;

Năm câu trên đều là một câu SELECT/WITH, chạy được trực tiếp trên Postgres. Trong một kho tín dụng thật, bạn chỉ cần thay accounts.balance bằng outstanding_balance, thêm snapshot_month, và GROUP BY theo vintage hoặc theo npl_group — cấu trúc câu lệnh gần như không đổi.

Ứng dụng: dữ liệu tín dụng dùng để làm gì

  • Theo dõi chất lượng tài sản: NPL, PAR, coverage, CoR cập nhật hàng tháng, cắt lát theo mọi chiều — bức tranh sức khoẻ danh mục.
  • Cảnh báo sớm: roll rate tăng bất thường ở một bucket, một ngành có vintage xấu đi nhanh — đều là tín hiệu feed thẳng vào hệ thống EWS.
  • Backtest scorecard & ECL: so điểm scorecard tại thời điểm cấp với hành vi vỡ nợ thực tế sau đó (nhờ có snapshot lịch sử) để kiểm định scorecard; so PD/LGD dự báo với thực tế để hiệu chỉnh mô hình ECL.
  • Báo cáo HĐQT & NHNN: các chỉ số danh mục chuẩn hoá, kèm phân tích xu hướng.
  • Dashboard & BI: trực quan hoá vintage heatmap, transition matrix, NPL trend bằng Power BI (hoặc Looker) để lãnh đạo tự khám phá số liệu.
  • Nền tảng dữ liệu: kho phân tích thường đặt trên BigQuery, với lớp mô hình hoá và versioning bằng dbt — nơi các bảng snapshot, vintage, transition matrix được định nghĩa dưới dạng model có kiểm thử.

Use case thực tế: dùng vintage để so chất lượng các đợt giải ngân

Một ngân hàng đẩy mạnh cho vay tiêu dùng tín chấp trong năm 2024. Cuối năm, NPL toàn danh mục vẫn thấp — 1,8% — và ban lãnh đạo yên tâm. Nhưng đội phân tích dựng bảng vintage: nhóm các khoản theo tháng giải ngân, đo tỷ lệ nợ 90+ DPD tại MOB 6 của từng vintage.

Kết quả gây giật mình. Vintage tháng 1–3/2024 có tỷ lệ nợ 90+ tại MOB 6 khoảng 1,2%. Nhưng vintage tháng 7–9/2024 — những khoản mới nên chưa đủ già để hiện lên trong con số NPL tổng — đã chạm 3,5% tại cùng MOB 6. Lý do tỷ lệ NPL tổng vẫn thấp chỉ vì các khoản mới còn quá trẻ, chưa kịp "chín" thành nợ xấu; con số tổng đang bị pha loãng bởi khối lượng giải ngân mới khổng lồ.

Vintage đã bóc tách điều mà chỉ số tổng che giấu: tiêu chuẩn cấp tín dụng đã bị nới lỏng từ giữa năm để chạy chỉ tiêu tăng trưởng. Đội rủi ro siết lại scorecard, và tránh được một làn sóng nợ xấu sẽ chỉ lộ ra 6–9 tháng sau đó — khi đã quá muộn để không giải ngân. Đây là giá trị điển hình của phân tích dữ liệu tín dụng: nhìn thấy vấn đề khi nó còn nhỏ, thay vì khi nó đã thành con số trên báo cáo.

Chất lượng dữ liệu & những khó khăn thực tế

Phân tích tín dụng đẹp trên slide nhưng khó trong thực tế, chủ yếu vì dữ liệu:

  • Chiều lịch sử thiếu: nếu ngân hàng chỉ mới bắt đầu chụp snapshot tháng gần đây, không có cách nào dựng vintage cho các khoản cũ. Chuỗi lịch sử là tài sản không thể mua lại — phải bắt đầu lưu càng sớm càng tốt.
  • Định nghĩa "default" không nhất quán: nhóm nợ theo NHNN, "default" theo Basel, "stage 3" theo IFRS 9, và "90+ DPD" trong PAR — không hoàn toàn trùng nhau. Nếu mỗi báo cáo dùng một định nghĩa ngầm khác nhau, các con số sẽ mâu thuẫn. Cần một tầng định nghĩa chuẩn (chuẩn hoá trong dbt là nơi lý tưởng).
  • Snapshot lệch điểm chốt: ảnh chụp cuối tháng của core và LOS có thể lệch ngày, gây sai lệch khi join. Cần khoá điểm chốt rõ ràng.
  • Restructure & tất toán sớm làm dư nợ nhảy bất thường, dễ bị hiểu nhầm là "chuyển bucket" — phải gắn cờ (flag) các sự kiện này.

Ghi nhớ

  • Dữ liệu là móng của cả series: scoring, ECL, Basel, EWS đều ăn cùng một kho dữ liệu tín dụng. Không có snapshot lịch sử theo tháng thì không có vintage, roll rate hay backtest.
  • Mô hình dữ liệu cốt lõi = loan_fact snapshot theo tháng (dư nợ, DPD, nhóm nợ, ngày giải ngân/đáo hạn) + dim khách hàng + collateral + payment.
  • Bốn phân tích trụ cột: vintage (chất lượng theo tuổi & đợt giải ngân), roll rate/transition matrix (xác suất chuyển bucket), rating migration (xu hướng xuống hạng), và bộ chỉ số danh mục (NPL, PAR, coverage, cost of risk).
  • Vintage tách "vấn đề chính sách cấp tín dụng" khỏi "vấn đề kinh tế vĩ mô" — và nhìn thấy nợ xấu tương lai trước khi nó hiện lên trong NPL tổng.
  • Định nghĩa default nhất quánchuỗi lịch sử đầy đủ là hai điều kiện sống còn; giải quyết chúng ở tầng chuẩn hoá (dbt) trên nền kho (BigQuery), rồi trực quan hoá bằng Power BI.
  • Trong SQL sandbox, schema mẫu chỉ là proxy — cấu trúc câu lệnh (GROUP BY, NTILE, window, WITH) giống hệt cái bạn dùng trên kho tín dụng thật; chỉ cần đổi cột và thêm chiều snapshot_month.

Sources: ListenData — Vintage Analysis, ListenData — Roll Rate Analysis, Roll Rate & Vintage Analysis in IFRS 9

Bài viết liên quan

Dòng chảy dữ liệu core -> ODS -> DWH -> BI, mô hình dữ liệu cốt lõi và bộ ví dụ SQL thực hành chạy được.

13 thg 7, 2026 7

Bản chất kinh doanh của ngân hàng: trung gian tài chính, bảng cân đối, NIM và vì sao dữ liệu quan trọng.

13 thg 7, 2026 5

Kiến trúc core banking, CIF, các phân hệ và xử lý online vs batch/EOD.

13 thg 7, 2026 5

Nguyên lý hạch toán kép, Nợ/Có, hệ thống tài khoản và cách mọi giao dịch ngân hàng luôn cân sổ.

13 thg 7, 2026 5