Báo cáo NHNN 7 — Chất lượng & đối soát dữ liệu báo cáo
Tại sao chất lượng dữ liệu báo cáo là chuyện sống còn
Một báo cáo gửi lên NHNN là lời tuyên bố có ràng buộc pháp lý về tình trạng của ngân hàng: tổng dư nợ, huy động, tỷ lệ an toàn vốn, số giao dịch đáng ngờ. Người ký chịu trách nhiệm về con số đó. Vì vậy một con số sai không đơn thuần là "lỗi kỹ thuật cần sửa" — nó kéo theo:
- Rủi ro pháp lý và xử phạt hành chính: báo cáo sai lệch, chậm nộp, hoặc nộp lại nhiều lần đều bị xử lý theo quy định về chế độ báo cáo thống kê và an toàn hoạt động.
- Ra quyết định giám sát sai: báo CAR cao hơn thực tế khiến cơ quan giám sát tưởng an toàn trong khi vốn đã mỏng — khi vỡ ra hệ quả nặng hơn nhiều.
- Mất uy tín: khi thanh tra phát hiện số báo cáo không khớp sổ cái, mọi con số khác lập tức bị nghi ngờ. Uy tín dữ liệu mất nhanh, xây lại rất chậm.
- Chi phí đối soát ngược: một break (chênh lệch) phát hiện muộn, sau khi đã nộp, buộc điều tra ngược qua nhiều lớp pipeline — tốn kém gấp bội so với chặn từ đầu.
Điểm mấu chốt: báo cáo đúng không phải kết quả của một phép tính đúng, mà của một hệ thống kiểm soát bao quanh phép tính đó. Bài này đi qua hệ thống ấy: các loại đối soát, bốn chiều chất lượng, các control và quy trình xử lý sai lệch. Xem tổng quan chuỗi tại reg-01-overview, nền tảng data mart tại reg-06-regulatory-data-mart, và nguyên lý chất lượng dữ liệu chung tại gov-03-data-quality.
Bốn chiều chất lượng dữ liệu báo cáo
Trước khi nói đến đối soát, cần thống nhất "chất lượng" nghĩa là gì. Với dữ liệu báo cáo, có bốn chiều đo được:
| Chiều | Câu hỏi kiểm tra | Ví dụ lỗi điển hình |
|---|---|---|
| Completeness (đầy đủ) | Có đủ tất cả bản ghi cần có không? Có trường bắt buộc nào bị NULL? | Thiếu 3 chi nhánh chưa upload; 200 tài khoản không có thông tin thành phố/địa bàn |
| Accuracy (chính xác) | Con số có khớp nguồn sự thật (sổ cái) không? | Tổng dư nợ báo cáo lệch 1,2 tỷ so với GL |
| Consistency (nhất quán) | Cùng một đại lượng ở các biểu mẫu khác nhau có khớp nhau không? | Tổng huy động ở biểu A khác tổng huy động ở biểu B |
| Timeliness (kịp thời) | Dữ liệu có về đúng hạn, đúng kỳ (as-of date) không? | Số liệu cuối tháng bị trộn giao dịch của ngày đầu tháng sau |
Bốn chiều không độc lập: pipeline chậm (timeliness kém) thường kéo theo dữ liệu thiếu (completeness kém), rồi lệch tổng (accuracy kém). Kiểm soát tốt là đo cả bốn chiều tự động, có ngưỡng rõ ràng, và chặn báo cáo nếu vi phạm.
Ba loại đối soát (reconciliation)
Reconciliation là việc so hai (hoặc nhiều) nguồn số liệu độc lập để chứng minh chúng khớp nhau. Trong quy trình báo cáo có ba loại đối soát chính, xếp theo thứ tự "gần nguồn → gần đích":
Recon 1 — Báo cáo ↔ Sổ cái (GL reconciliation)
Đây là đối soát quan trọng nhất, cũng là câu hỏi đầu tiên thanh tra hỏi: "Số này có khớp sổ cái không?" Sổ cái (General Ledger) là nguồn sự thật kế toán. Mọi báo cáo an toàn/thống kê rốt cuộc phải khớp tổng với GL trên các đại lượng chủ chốt:
- Tổng dư nợ cho vay trong báo cáo = tổng dư nợ trên các tài khoản GL nhóm cho vay.
- Tổng huy động trong báo cáo = tổng số dư tiền gửi trên GL.
- Tổng tài sản/nguồn vốn phải khớp cân đối (assets = liabilities + equity).
Cơ chế: lấy tổng từ hệ thống nghiệp vụ (subledger, ví dụ hệ thống Loan) và tổng từ GL rồi so sánh. Chênh lệch (break) phải bằng 0 hoặc trong ngưỡng dung sai làm tròn; nếu không, phải giải thích từng đồng. Nguyên nhân break điển hình: bút toán treo chưa hạch toán, lệch tỷ giá quy đổi, khoản mục có ở GL nhưng chưa về subledger (hoặc ngược lại).
Recon 2 — Giữa các biểu mẫu (cross-report consistency)
Nhiều biểu mẫu cùng chứa một đại lượng và chúng phải bằng nhau. Ví dụ: "tổng dư nợ theo ngành kinh tế" khi cộng lại phải bằng "tổng dư nợ theo kỳ hạn" và bằng "tổng dư nợ" ở biểu cân đối. Nếu ba con số lệch nhau, chắc chắn có bản ghi bị phân loại thiếu/trùng ở ít nhất một biểu.
Cross-report recon là rào chắn tự nhiên chống lỗi phân loại: một khoản vay bị bỏ sót khỏi "phân theo ngành" làm tổng theo ngành nhỏ hơn tổng cân đối → lộ ra ngay. Đây là lý do nên xây tất cả biểu từ cùng một data mart thay vì mỗi biểu query một nguồn riêng.
Recon 3 — Nguồn ↔ Đích trong pipeline (source-to-target)
Trong pipeline ETL, mỗi bước có thể làm mất/nhân đôi bản ghi (join sai, filter nhầm, duplicate). Recon nguồn↔đích kiểm tra ở từng chặng:
- Row count reconciliation: số bản ghi vào một bước = số bản ghi ra (có tính đến filter đã biết trước). Rớt 5.000 dòng không giải thích được là báo động.
- Control total reconciliation: tổng một cột số (ví dụ
SUM(amount)) trước và sau bước phải khớp — trừ khi bước đó cố ý loại trừ, và phần loại trừ phải đo được. - Referential integrity: mọi khoá ngoại ở bảng con phải trỏ tới bản ghi tồn tại ở bảng cha (ví dụ mọi tài khoản phải thuộc một khách hàng có thật).
Các kiểm soát (controls) cụ thể
Đối soát trả lời "có khớp không". Control là cơ chế phát hiện khi không khớp và không cho đi tiếp. Bốn control cốt lõi:
1. Control total
Chọn vài đại lượng "signature" (tổng số dư theo loại tiền, tổng dư nợ, số bản ghi) và tính lại ở mọi chốt kiểm soát, so với giá trị kỳ vọng. Control total rẻ, nhanh, bắt được phần lớn lỗi mất/nhân bản ghi — nên là control đầu tiên.
2. Four-eyes / ký duyệt (maker-checker)
Không ai được vừa lập vừa duyệt số của chính mình. Maker tạo/chạy báo cáo, checker rà soát và ký duyệt trước khi nộp; báo cáo trọng yếu có thể ba tầng (maker → reviewer → approver). Mọi hành động ký duyệt phải ghi log không sửa được (ai, lúc nào, duyệt phiên bản nào).
3. Ngưỡng cảnh báo biến động (variance/trend check)
So kỳ này với kỳ trước: nếu một đại lượng biến động vượt ngưỡng (ví dụ tổng huy động tăng/giảm > 15% mà không có sự kiện giải thích), hệ thống cảnh báo để xác nhận. Biến động bất thường thường là dấu hiệu lỗi dữ liệu (nạp trùng kỳ, thiếu nguồn) trước khi là biến động thật. Ngưỡng nên đặt theo từng chỉ tiêu.
4. Rule-based validation
Luật nghiệp vụ cứng: số dư huy động không âm; ngày giao dịch ≤ ngày báo cáo; tổng các phần bằng tổng chung; mã tiền tệ nằm trong danh mục hợp lệ. Vi phạm luật cứng thì chặn (block), luật mềm thì cảnh báo (warn).
Minh hoạ trên sandbox
Sandbox là PostgreSQL chỉ đọc với 5 bảng. Nó không phải hệ thống báo cáo thật, nhưng đủ để minh hoạ cơ chế của từng loại kiểm soát bằng SQL chạy được thật. Hãy đọc chúng như "khuôn mẫu" — trong thực tế thay bảng sandbox bằng bảng data mart tương ứng.
(a) Control total — tổng số dư theo loại tiền
Control total kinh điển: gộp số dư theo currency, kèm số tài khoản. Con số này là "chữ ký" để so với kỳ vọng (ví dụ tổng huy động trên GL theo từng loại tiền). Nếu SUM(balance) của VND lệch so với GL, đó là break cần giải thích.
-- ▶ Chạy được
SELECT
currency,
COUNT(*) AS so_tai_khoan,
SUM(balance) AS tong_so_du
FROM accounts
GROUP BY currency
ORDER BY currency;
Ý nghĩa: bước đầu tiên của mọi quy trình đối soát — có một tổng tin cậy, gộp đúng chiều (currency), để đối chiếu với nguồn khác.
(b) Recon nguồn↔đích — referential integrity (tài khoản không khớp khách)
Kiểm tra toàn vẹn tham chiếu: mọi tài khoản phải thuộc một khách hàng tồn tại. LEFT JOIN rồi lọc c.id IS NULL lộ ra các tài khoản "mồ côi" — dấu hiệu mất bản ghi khách hàng khi nạp (hoặc nạp tài khoản trước khi nạp khách). Trong báo cáo thật, tài khoản mồ côi làm tổng theo khách hàng bị thiếu → sai completeness và sai phân loại.
-- ▶ Chạy được
SELECT
a.id AS account_id,
a.account_no,
a.customer_id
FROM accounts a
LEFT JOIN customers c ON c.id = a.customer_id
WHERE c.id IS NULL
ORDER BY a.id;
Nếu query trả về 0 dòng: toàn vẹn tham chiếu OK. Trả về > 0 dòng: đó chính là danh sách break cần xử lý trước khi báo cáo.
(c) Completeness — trường bắt buộc bị thiếu
Kiểm tra tính đầy đủ của trường dùng để phân tổ theo địa bàn: đếm số khách hàng thiếu city. Trong báo cáo theo địa bàn, khách thiếu city rơi khỏi các dòng phân theo tỉnh/thành → tổng theo địa bàn nhỏ hơn tổng chung (một break cross-report điển hình).
-- ▶ Chạy được
SELECT
COUNT(*) AS tong_khach,
COUNT(city) AS co_city,
COUNT(*) - COUNT(city) AS thieu_city,
ROUND(100.0 * (COUNT(*) - COUNT(city)) / NULLIF(COUNT(*), 0), 2) AS ty_le_thieu_pct
FROM customers;
Lưu ý kỹ thuật: COUNT(city) chỉ đếm bản ghi có city khác NULL, nên COUNT(*) - COUNT(city) chính là số bị thiếu. NULLIF(...,0) chống chia cho 0 khi bảng rỗng. Ngưỡng chấp nhận (ví dụ thieu_city ≤ 0 hoặc ty_le_thieu_pct < 0.5) do nghiệp vụ quyết định.
(d) Phát hiện bất thường — số dư âm
Rule-based validation: theo nghiệp vụ, số dư huy động không nên âm. Query dưới liệt kê mọi tài khoản có balance < 0 — đây là các ngoại lệ cần xác minh (thấu chi hợp lệ hay lỗi dữ liệu?). Đây là mẫu cho "phát hiện giá trị vi phạm luật cứng".
-- ▶ Chạy được
SELECT
a.id AS account_id,
a.account_no,
a.currency,
a.balance
FROM accounts a
WHERE a.balance < 0
ORDER BY a.balance ASC;
Bốn query phủ đủ bốn cơ chế: control total (a), recon nguồn↔đích / referential integrity (b), completeness (c), phát hiện bất thường/rule check (d). Đều là SELECT đơn, chạy được trên sandbox; thực tế chỉ cần thay bảng sandbox bằng bảng data mart.
Quy trình xử lý sai lệch (break) và log điều chỉnh
Phát hiện break mới là một nửa. Nửa còn lại là quy trình chuẩn hoá để mỗi break đều được điều tra, phân loại và đóng có bằng chứng.
Những điểm không được bỏ:
- Break log: mỗi chênh lệch ghi: đại lượng nào, giá trị nguồn A, nguồn B, chênh lệch, kỳ báo cáo, người phát hiện, thời điểm. Không "im lặng bỏ qua".
- Adjustment log: nếu điều chỉnh số (ví dụ hạch toán bù một bút toán treo), phải ghi: điều chỉnh gì, bao nhiêu, lý do, chứng từ, ai làm, ai duyệt. Điều chỉnh không lý do và không được duyệt là "cờ đỏ" thanh tra.
- Bất biến & truy vết (audit trail): log không được sửa/xoá. Phải trả lời được "con số X trong báo cáo tháng 3 đến từ đâu, qua điều chỉnh nào, ai ký" — kể cả sau nhiều năm. Kỹ thuật tự động hoá lớp này xem reg-08-automation-governance.
- Tolerance rõ ràng: không phải chênh lệch nào cũng là lỗi (làm tròn, chênh xu). Định nghĩa ngưỡng dung sai cho từng đại lượng: dưới ngưỡng thì auto-pass có ghi nhận, trên ngưỡng thì buộc điều tra.
Hậu quả của báo cáo sai
Tóm tắt hệ quả theo mức độ, để thấy vì sao hệ thống kiểm soát trên là đáng đầu tư:
| Kịch bản | Hậu quả |
|---|---|
| Số lệch nhỏ, tự phát hiện, giải trình được | Chi phí đối soát; rủi ro thấp |
| Nộp chậm / phải nộp lại nhiều lần | Bị nhắc nhở, ảnh hưởng đánh giá tuân thủ |
| Số sai trọng yếu bị thanh tra phát hiện | Xử phạt hành chính; buộc báo cáo lại; soi kỹ mọi báo cáo khác |
| Sai lệch che giấu tình trạng thật (CAR, nợ xấu) | Rủi ro pháp lý nghiêm trọng; mất uy tín; có thể bị biện pháp giám sát đặc biệt |
Điểm chung: chi phí xử lý một lỗi tăng theo cấp số nhân theo thời gian nó tồn tại chưa bị phát hiện. Kiểm soát tại nguồn (control total, validation khi nạp) rẻ hơn nhiều lần so với điều tra ngược sau khi đã nộp.
Use case thực tế
Bối cảnh: Đóng số báo cáo cân đối cuối tháng. Chỉ tiêu "tổng huy động" trên báo cáo được dựng từ data mart, cần khớp với sổ cái (GL). Ngưỡng dung sai: chênh ≤ 1 triệu đồng (làm tròn).
Diễn biến:
- Control total (recon 1): tổng huy động từ data mart = 48.512,3 tỷ; từ GL = 48.513,5 tỷ → break 1,2 tỷ, vượt dung sai. Ghi vào break log, chặn ký duyệt.
- Recon 3 (nguồn↔đích): row-count từ hệ thống Deposit là 1.204.000 tài khoản, data mart chỉ có 1.203.850 → thiếu 150 bản ghi. Kiểm tra referential integrity (mẫu query (b)) phát hiện 150 tài khoản có
customer_idtrỏ tới khách hàng chưa nạp trong kỳ → bị một bước join loại khỏi mart. - Cross-report (recon 2): "tổng huy động theo địa bàn" nhỏ hơn tổng chung đúng bằng phần của 150 tài khoản mồ côi — hai break cùng một nguyên nhân gốc.
- Xử lý: phân loại là lỗi dữ liệu (thiếu nguồn khách hàng), không phải chênh hợp lệ → nạp lại danh mục khách hàng, chạy lại. Lần sau: control total khớp GL trong dung sai (chênh 0,3 triệu do làm tròn → auto-pass có ghi nhận).
- Ký duyệt: maker đính kèm bằng chứng recon, checker rà soát break log (đã đóng) và ký duyệt. Báo cáo cùng log được lưu trữ.
Kết quả: 1,2 tỷ chênh lệch không bao giờ đi vào báo cáo nộp NHNN. Điều cứu tình huống không phải phép tính giỏi hơn, mà là control total bắt được break và recon nguồn↔đích chỉ đúng nguyên nhân gốc trong vài phút thay vì điều tra ngược sau khi nộp. Giá trị nằm ở lớp kiểm soát bao quanh con số, không nằm ở con số.
Ghi nhớ
- Báo cáo sai không phải "lỗi kỹ thuật" mà là rủi ro pháp lý, phạt, mất uy tín — chi phí sửa tăng cấp số nhân theo thời gian lỗi tồn tại chưa bị phát hiện.
- Bốn chiều chất lượng: completeness (đầy đủ), accuracy (chính xác vs GL), consistency (nhất quán giữa biểu), timeliness (kịp thời, đúng as-of date).
- Ba loại đối soát: recon 1 báo cáo↔GL (thanh tra hỏi đầu tiên), recon 2 cross-report (chống lỗi phân loại), recon 3 nguồn↔đích (row-count, control total, referential integrity).
- Bốn control: control total, four-eyes/maker-checker, ngưỡng cảnh báo biến động kỳ này vs kỳ trước, rule-based validation (block luật cứng, warn luật mềm).
- Mọi break vào break log; mọi điều chỉnh có lý do + người duyệt trong adjustment log; audit trail bất biến, truy vết nguồn gốc từng con số; định nghĩa tolerance cho từng đại lượng.
- Xây tất cả biểu từ một data mart để cross-report recon có ý nghĩa; xem reg-06-regulatory-data-mart và gov-03-data-quality.
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.
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.
Kiến trúc core banking, CIF, các phân hệ và xử lý online vs batch/EOD.
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ổ.