傳知單與庫存對帳演算法

G1234 vs ABC123

核心對帳邏輯:一場 Transaction Flow 與 Position Snapshot 的實戰

Day 23 教育訓練課程

Agenda 課程大綱

  1. 名詞定義:何謂明細流與庫存報表?
  2. 核心痛點:為何需要 Cross-Join 交叉校驗?
  3. 演算法解析:對帳的核心數學模型
  4. 實作三部曲:資料正規化、聚合與比對
  1. 極端值處理:T+N 延遲與小數點誤差
  2. 自動化架構:從批次抓取到異常發報
  3. 實戰案例:報表解析與對帳除錯
  4. Q & A

什麼是 G1234?

Transaction Flow (明細流/傳知單)

G1234 代表的是「動態的交易行為」。它記錄了系統中每一筆資金或資產的進出軌跡。

  • 資料特性: 連續性、時間序列、增量資料 (Incremental)。
  • 關鍵欄位: 交易時間、帳號、交易代碼 (申購/贖回/配息)、異動金額/單位數。
  • 常見格式: 系統匯出的 .csv 交易明細檔或 .txt 傳票紀錄。

類比: 就像你銀行存摺裡,每一筆提款和存款的紀錄。

什麼是 ABC123?

Position Snapshot (庫存/餘額報表)

ABC123 代表的是「靜態的結果切片」。它反映了在特定時間點(通常是日終 EOD),資產的最終狀態。

  • 資料特性: 靜態性、特定時間點 (Snapshot)、絕對數值。
  • 關鍵欄位: 結算日期、帳號、資產代碼、最終持有單位數、最終帳戶餘額。
  • 常見格式: 系統批次產生的日終 .pdf 餘額表或庫存文字檔。

類比: 就像你銀行存摺翻到最後一頁,本子下方印著的「目前總餘額」。

核心痛點:為何需要校驗?

在複雜的金融系統環境中,前台交易(明細)與後台結算(庫存)往往由不同模組甚至不同主機處理。資料不一致是必然面臨的風險。

常見的斷鏈原因

  • 網路延遲: 明細已寫入,但批次庫存未更新。
  • 人為介入: 傳知單人工改帳,未同步後台。
  • 小數點捨入: 累加明細與直接算庫存的匯率/單位數尾差。
  • 系統當機: 批次檔轉檔 (Batch Job) 失敗。

對帳核心演算法

Cross-Join 校驗的本質,在於驗證「動態」推導出的結果,是否等於「靜態」的現況。

昨日 ABC123 餘額
+
Σ (本日 G1234 交易明細)
===
本日 ABC123 餘額

如果等式不成立,代表發生 Out of Balance (帳務不平),需要觸發異常警報。

Step 1: 資料正規化 (Normalization)

在進行運算前,必須先透過自動化工具讀取各式異質報表,將文字檔轉換為結構化數據。

  • 解析 G1234: 去除傳知單表頭、表尾,攔截區別碼 (如 `1`:首筆, `2`:明細, `3`:尾筆)。
  • 解析 ABC123: 讀取報表底稿,轉換半形/全形空白,將字串轉型為浮點數 (Float)。
  • 統一鍵值 (Key): 將「分行代號 + 客戶帳號 + 資產 ISIN Code」組合為唯一 Hash Key

Step 2: 聚合運算 (Aggregation)

G1234 是明細,同一個帳戶一天內可能有多次申購與贖回。必須先執行 GROUP BY 運算。

SQL 邏輯思維

SELECT 
    帳號, ISIN_Code,
    SUM(CASE WHEN 交易碼 = '申購' THEN 單位數 ELSE 0 END) AS 總買入,
    SUM(CASE WHEN 交易碼 = '贖回' THEN -單位數 ELSE 0 END) AS 總賣出
FROM G1234_明細流
WHERE 交易日 = '今日'
GROUP BY 帳號, ISIN_Code;
                        

產出結果:該帳戶本日的「淨異動量 (Net Change)」

Step 3: Cross-Join 交叉校驗

將「聚合後的 G1234」與「昨日/今日 ABC123」進行 Left Join / Full Outer Join。

Hash Key (帳號_資產) (A) 昨餘額 (B) 淨異動 (C) 今餘額 Diff (A+B-C) 狀態
8801_US_APPL 1,000 +500 1,500 0 MATCH
8801_TW_2330 5,000 -2,000 3,000 0 MATCH
8802_US_TSLA 200 0 250 -50 ERROR

解析異常 (Error Handling)

Diff ≠ 0 時,程式不應只是報錯,而應具備基本的錯誤特徵辨識能力。

  • 情境一:淨異動有值,但昨餘與今餘不變。
    研判: G1234 交易已成立,但 ABC123 批次落檔失敗(無庫存更新)。
  • 情境二:無淨異動,但今餘額突然減少。
    研判: 可能發生了「系統自動扣收手續費/管理費」,未出現在一般交易明細中。
  • 情境三:Diff 極小 (例如 0.0001)。
    研判: 浮點數精度問題或匯率換算尾差。

極端值挑戰:T+N 延遲問題

許多海外基金或債券,其申贖交易日 (T) 與實際撥轉入庫日 (T+N) 存在時間差。這會破壞 昨餘 + 異動 = 今餘 的等式。

解決方案:Transit 狀態池

針對 G1234 的明細,依照「交割日 (Value Date)」進行打標。
交割日大於今日的交易,放入 「在途庫存 (Transit Position)」 運算池,不立刻計入本日 ABC123 校驗。

修正後公式:今餘額 = 昨餘額 + T日到期之在途明細

極端值挑戰:手續費與退單重打

實務上操作手冊常提到:必須考慮「手續費拆分」與「改帳」等異常流程。

  • 退單重打 (Reversal):
    同一日若發生沖正 (一筆正值、一筆負值同金額),在 G1234 聚合時需互相抵銷,確保不產生虛假異動。
  • 外幣結匯問題:
    明細若為原幣,報表若為台幣等值,對帳前必須抓取「月底結帳匯率 / 牌告匯率」進行統一基準換算 (Normalize to Base Currency)。

實作:系統自動化對帳模組

運用 VBA、Python 或 RPA 工具,將繁瑣的對帳流程自動化。

  1. 排程觸發器 (Cron Job): 每日 02:00 AM 等待核心主機產出 txt/csv。
  2. 資料匯入器 (Importer): 讀取檔案,處理編碼 (BIG5/UTF8),轉存關聯式資料庫。
  3. 校驗引擎 (Recon Engine): 執行 Cross-Join 演算法,產出差異明細。
  4. 通知模組 (Notifier): 將結果寫入 Excel 工作底稿,並自動透過 SMTP 發送 HTML 格式的警告信件給業務單位。

實戰案例:抓出幽靈庫存

問題描述

連續三天,某特定系列資產的 ABC123 庫存總量未增加,但 G1234 顯示每日有大量申購。

演算法診斷結果

Cross-Join 後發現 Diff 呈現線性擴大。

根本原因 (Root Cause)

上游主機在寫入該系列資產時,遺漏了特定的 ISIN Code 前綴,導致批次更新庫存時找不到對應帳號,直接跳過 (Skip) 且未亮紅燈。

Best Practices (最佳實務)

建構健全的對帳演算法,應具備以下精神:

  • Idempotency (冪等性): 程式重複執行多次,不應造成重複扣帳或累加。必須具備防呆機制(清除舊暫存)。
  • Immutable Logs (不可變日誌): 任何比對過程中發現的 Diff,都必須寫入 Log,不可直接手動從後台資料庫 `UPDATE` 抹平。
  • 容錯區間 (Tolerance Threshold): 設定合理的容許誤差值(如 ±1 元內視為匯率尾差,自動歸入調整科目)。

Trust, but Verify.

沒有完美的交易系統,只有嚴謹的對帳演算法。
掌握 G1234 與 ABC123 的邏輯,就是掌握資產安全的最後防線。

Q & A

開放現場提問

```eof