Chapter 34 Exercises: Banking and Payment Systems

Tier 1: Recall and Recognition (Exercises 1-8)

Exercise 1: Core Banking Components

Match each core banking component with its primary function:

Component Function
a) Customer Information File (CIF) 1) Stores account balances and attributes
b) Account Master File 2) Handles debit/credit posting to accounts
c) Transaction Processing Engine 3) Generates CTRs and SARs
d) General Ledger Interface 4) Master database of customer data
e) Payment Processing Systems 5) Ensures double-entry bookkeeping balance
f) Regulatory Reporting 6) Handles ACH, wire, check, and card flows

Solution: a-4, b-1, c-2, d-5, e-6, f-3.

Exercise 2: Transaction Lifecycle Ordering

Place the following transaction lifecycle stages in the correct order:

  • Settlement
  • Final Posting
  • Authorization
  • Reconciliation
  • Memo Posting
  • Origination

Solution: 1. Origination 2. Authorization 3. Memo Posting 4. Final Posting 5. Settlement 6. Reconciliation

Exercise 3: Account Status Codes

Given the following COBOL condition-name definitions, answer the questions below:

       10  ACCT-STATUS-CODE       PIC X(01).
           88  ACCT-ACTIVE        VALUE 'A'.
           88  ACCT-CLOSED        VALUE 'C'.
           88  ACCT-FROZEN        VALUE 'F'.
           88  ACCT-DORMANT       VALUE 'D'.

a) Which status code allows all transaction types? b) Which status code allows deposits but blocks withdrawals? c) Which status code blocks all transactions? d) After how many months of no customer-initiated activity does an account typically become dormant? e) Why are closed account records retained rather than deleted?

Solution: a) 'A' (Active) -- all transactions permitted. b) 'F' (Frozen) -- deposits may be accepted but debits are blocked. c) 'C' (Closed) -- no transactions permitted. d) Typically 12-24 months, depending on state law. e) Closed records are retained for regulatory and audit purposes, typically for seven to ten years, as required by banking regulations.

Exercise 4: COMP-3 Storage Calculation

Calculate the storage requirements for the following packed decimal fields used in an account master record:

a) PIC S9(11)V99 COMP-3 (ledger balance) b) PIC S9(07)V99 COMP-3 (daily withdrawal limit) c) PIC S9(09)V99 COMP-3 (interest paid year-to-date) d) PIC 9V9(06) in DISPLAY format (interest rate)

Solution: COMP-3 formula: (number of digits + 1) / 2, rounded up. a) 13 digits + sign = 14 nibbles = 7 bytes. b) 9 digits + sign = 10 nibbles = 5 bytes. c) 11 digits + sign = 12 nibbles = 6 bytes. d) DISPLAY format: 7 bytes (one byte per digit, no sign).

Exercise 5: ACH Transaction Codes

Fill in the missing transaction codes and their meanings:

Code Account Type Direction
22 ____ ____
27 ____ ____
32 ____ ____
37 ____ ____
23 ____ ____
28 ____ ____

Solution: | Code | Account Type | Direction | |---|---|---| | 22 | Checking | Credit (deposit) | | 27 | Checking | Debit (withdrawal) | | 32 | Savings | Credit (deposit) | | 37 | Savings | Debit (withdrawal) | | 23 | Checking | Credit prenote (zero-dollar test) | | 28 | Checking | Debit prenote (zero-dollar test) |

Exercise 6: NACHA Record Types

Identify each NACHA record type by its record type code:

a) Record Type 1 b) Record Type 5 c) Record Type 6 d) Record Type 8 e) Record Type 9

What is the fixed record length for all NACHA records?

Solution: a) File Header Record. b) Batch Header Record. c) Entry Detail Record. d) Batch Control Record. e) File Control Record. All NACHA records are exactly 94 bytes long.

Exercise 7: ABA Routing Number Validation

Validate the following routing number using the ABA weighted modulus 10 algorithm: 011401533.

The weights are: 3, 7, 1, 3, 7, 1, 3, 7, 1.

Show your work step by step.

Solution:

Digits:   0  1  1  4  0  1  5  3  3
Weights:  3  7  1  3  7  1  3  7  1
Products: 0+ 7+ 1+12+ 0+ 1+15+21+ 3 = 60
60 mod 10 = 0 --> VALID

The routing number 011401533 is valid because the weighted sum (60) is evenly divisible by 10.

Exercise 8: Posting Order

A bank processes the following transactions in its nightly batch cycle for account 1001234567. The opening balance is $500.00, with no overdraft protection. List the order in which these transactions should be posted and the resulting balance after each:

Transaction Type Amount
T1 Check (debit) $200.00
T2 ACH Payroll (credit) $1,500.00
T3 Debit card (debit) $450.00
T4 ATM withdrawal (debit) $100.00
T5 Wire transfer in (credit) $300.00

Solution: Credits are posted before debits. Within debits, posting order follows bank policy (here, largest first).

Order Transaction Type Amount Balance
1 T2 Credit $1,500.00 | $2,000.00
2 T5 Credit $300.00 | $2,300.00
3 T3 Debit $450.00 | $1,850.00
4 T1 Debit $200.00 | $1,650.00
5 T4 Debit $100.00 | $1,550.00

All transactions post successfully. The final balance is $1,550.00.


Tier 2: Comprehension and Application (Exercises 9-16)

Exercise 9: Available Balance Calculation

Write a COBOL paragraph named 2500-CALC-AVAILABLE-BALANCE that computes the available balance using the following formula:

Available Balance = Ledger Balance - Hold Amount + Pending Credits - Pending Debits

Use the account master record layout from the chapter. After computing the available balance, check whether it is negative, and if so, display a warning message that includes the account number and the negative available balance amount.

Solution:

       2500-CALC-AVAILABLE-BALANCE.
           COMPUTE ACCT-AVAIL-BAL =
               ACCT-LEDGER-BAL
             - ACCT-HOLD-AMT
             + ACCT-PENDING-CR
             - ACCT-PENDING-DR
           END-COMPUTE

           IF ACCT-AVAIL-BAL < ZEROES
               DISPLAY 'WARNING: NEGATIVE AVAILABLE BALANCE'
               DISPLAY '  ACCOUNT: ' ACCT-NUMBER
               DISPLAY '  AVAILABLE: ' ACCT-AVAIL-BAL
           END-IF
           .

Exercise 10: Luhn Algorithm Implementation

Write a COBOL paragraph named 3000-VALIDATE-CARD-NUMBER that implements the Luhn (Mod 10) algorithm to validate a 16-digit credit card number stored in WS-CARD-NUMBER PIC X(16). The paragraph should:

  1. Redefine the card number as an array of 16 individual digits.
  2. Process from right to left, doubling every second digit.
  3. If the doubled value exceeds 9, subtract 9.
  4. Sum all digits.
  5. Set WS-CARD-VALID to TRUE if the sum is divisible by 10, FALSE otherwise.

Solution:

       WORKING-STORAGE SECTION.
       01  WS-CARD-NUMBER          PIC X(16).
       01  WS-CARD-DIGITS REDEFINES WS-CARD-NUMBER.
           05  WS-CARD-DIGIT       PIC 9(01) OCCURS 16 TIMES.
       01  WS-LUHN-SUM             PIC 9(03) VALUE ZEROS.
       01  WS-DOUBLED              PIC 9(02) VALUE ZEROS.
       01  WS-IDX                  PIC 9(02) VALUE ZEROS.
       01  WS-POSITION-FROM-RIGHT  PIC 9(02) VALUE ZEROS.
       01  WS-CARD-STATUS          PIC X(01) VALUE SPACES.
           88  WS-CARD-VALID       VALUE 'Y'.
           88  WS-CARD-INVALID     VALUE 'N'.

       3000-VALIDATE-CARD-NUMBER.
           MOVE ZEROS TO WS-LUHN-SUM
           PERFORM VARYING WS-IDX FROM 16 BY -1
               UNTIL WS-IDX < 1
               ADD 1 TO WS-POSITION-FROM-RIGHT
               IF FUNCTION MOD(WS-POSITION-FROM-RIGHT 2) = 0
                   COMPUTE WS-DOUBLED =
                       WS-CARD-DIGIT(WS-IDX) * 2
                   IF WS-DOUBLED > 9
                       SUBTRACT 9 FROM WS-DOUBLED
                   END-IF
                   ADD WS-DOUBLED TO WS-LUHN-SUM
               ELSE
                   ADD WS-CARD-DIGIT(WS-IDX)
                       TO WS-LUHN-SUM
               END-IF
           END-PERFORM
           MOVE ZEROS TO WS-POSITION-FROM-RIGHT

           IF FUNCTION MOD(WS-LUHN-SUM 10) = 0
               SET WS-CARD-VALID TO TRUE
           ELSE
               SET WS-CARD-INVALID TO TRUE
           END-IF
           .

Exercise 11: Transaction Validation

Write a COBOL paragraph named 2000-VALIDATE-TRANSACTION that performs the following checks on an incoming transaction, using the record layouts from the chapter:

  1. Verify the account exists (READ with INVALID KEY).
  2. Reject if the account is closed.
  3. Reject debits (but not deposits) if the account is frozen.
  4. For debit transactions, verify sufficient funds including overdraft limit.
  5. For withdrawals and transfers out, verify the daily withdrawal limit has not been exceeded.
  6. Write rejection reasons to an error file for any failed validation.

Set a flag WS-TRAN-VALID to TRUE only if all checks pass.

Solution:

       2000-VALIDATE-TRANSACTION.
           SET WS-TRAN-VALID TO TRUE

           READ ACCT-MASTER-FILE INTO ACCT-MASTER-RECORD
               KEY IS TRAN-ACCT-NUMBER
               INVALID KEY
                   MOVE 'ACCOUNT NOT FOUND' TO WS-REJECT-REASON
                   PERFORM 9100-WRITE-REJECT
                   SET WS-TRAN-INVALID TO TRUE
                   GO TO 2000-VALIDATE-EXIT
           END-READ

           IF ACCT-CLOSED
               MOVE 'ACCOUNT IS CLOSED' TO WS-REJECT-REASON
               PERFORM 9100-WRITE-REJECT
               SET WS-TRAN-INVALID TO TRUE
               GO TO 2000-VALIDATE-EXIT
           END-IF

           IF ACCT-FROZEN
               IF NOT TRAN-DEPOSIT
                   MOVE 'ACCOUNT IS FROZEN' TO WS-REJECT-REASON
                   PERFORM 9100-WRITE-REJECT
                   SET WS-TRAN-INVALID TO TRUE
                   GO TO 2000-VALIDATE-EXIT
               END-IF
           END-IF

           IF TRAN-WITHDRAWAL OR TRAN-TRANSFER-OUT
              OR TRAN-PAYMENT OR TRAN-FEE
               IF TRAN-AMOUNT > ACCT-AVAIL-BAL
                   IF ACCT-OD-LIMIT > ZEROES
                       IF TRAN-AMOUNT >
                          (ACCT-AVAIL-BAL + ACCT-OD-LIMIT)
                           MOVE 'EXCEEDS OVERDRAFT LIMIT'
                               TO WS-REJECT-REASON
                           PERFORM 9100-WRITE-REJECT
                           SET WS-TRAN-INVALID TO TRUE
                           GO TO 2000-VALIDATE-EXIT
                       END-IF
                   ELSE
                       MOVE 'INSUFFICIENT FUNDS'
                           TO WS-REJECT-REASON
                       PERFORM 9100-WRITE-REJECT
                       SET WS-TRAN-INVALID TO TRUE
                       GO TO 2000-VALIDATE-EXIT
                   END-IF
               END-IF
           END-IF

           IF TRAN-WITHDRAWAL OR TRAN-TRANSFER-OUT
               ADD TRAN-AMOUNT TO ACCT-DAILY-W-USED
               IF ACCT-DAILY-W-USED > ACCT-DAILY-W-LIMIT
                   SUBTRACT TRAN-AMOUNT FROM ACCT-DAILY-W-USED
                   MOVE 'DAILY WITHDRAWAL LIMIT EXCEEDED'
                       TO WS-REJECT-REASON
                   PERFORM 9100-WRITE-REJECT
                   SET WS-TRAN-INVALID TO TRUE
                   GO TO 2000-VALIDATE-EXIT
               END-IF
           END-IF
           .

       2000-VALIDATE-EXIT.
           EXIT.

Exercise 12: Interest Accrual Program

Write a complete COBOL program that performs daily interest accrual on savings and money market accounts. The program should:

  1. Read the account master file sequentially.
  2. For each active savings or money market account with a positive ledger balance, calculate daily interest as: Balance * (Annual Rate / 365).
  3. Use ROUNDED on the COMPUTE statement.
  4. Add the daily interest to the accrued interest field.
  5. REWRITE the updated record.
  6. Display a summary at the end: total accounts processed, total accounts accrued, total daily interest accrued.

Use COMP-3 for all monetary working-storage fields.

Solution:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. INTACCRL.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT ACCT-MASTER-FILE
               ASSIGN TO ACCTMAST
               ORGANIZATION IS INDEXED
               ACCESS MODE IS SEQUENTIAL
               RECORD KEY IS ACCT-NUMBER
               FILE STATUS IS WS-ACCT-STATUS.

       DATA DIVISION.
       FILE SECTION.
       FD  ACCT-MASTER-FILE
           RECORD CONTAINS 300 CHARACTERS.
       01  ACCT-MASTER-RECORD.
           05  ACCT-NUMBER             PIC X(12).
           05  FILLER                  PIC X(64).
           05  ACCT-TYPE-CODE          PIC X(03).
               88  ACCT-SAVINGS        VALUE 'SAV'.
               88  ACCT-MONEY-MARKET   VALUE 'MMA'.
           05  FILLER                  PIC X(03).
           05  ACCT-STATUS-CODE        PIC X(01).
               88  ACCT-ACTIVE         VALUE 'A'.
           05  FILLER                  PIC X(24).
           05  ACCT-LEDGER-BAL         PIC S9(11)V99
                                       USAGE COMP-3.
           05  FILLER                  PIC X(28).
           05  ACCT-INT-RATE           PIC 9V9(06).
           05  ACCT-INT-ACCRUED        PIC S9(09)V99
                                       USAGE COMP-3.
           05  FILLER                  PIC X(150).

       WORKING-STORAGE SECTION.
       01  WS-ACCT-STATUS             PIC XX.
       01  WS-EOF-FLAG                PIC X(01) VALUE 'N'.
           88  WS-EOF                  VALUE 'Y'.
       01  WS-DAILY-INTEREST          PIC S9(07)V99
                                      USAGE COMP-3.
       01  WS-DAYS-IN-YEAR            PIC 9(03) VALUE 365.
       01  WS-TOTAL-PROCESSED         PIC 9(09) VALUE ZEROS.
       01  WS-TOTAL-ACCRUED           PIC 9(09) VALUE ZEROS.
       01  WS-TOTAL-INTEREST          PIC S9(11)V99
                                      USAGE COMP-3 VALUE ZEROS.

       PROCEDURE DIVISION.
       0000-MAIN.
           OPEN I-O ACCT-MASTER-FILE
           PERFORM 1000-PROCESS-ACCOUNTS
               UNTIL WS-EOF
           PERFORM 9000-DISPLAY-SUMMARY
           CLOSE ACCT-MASTER-FILE
           STOP RUN
           .

       1000-PROCESS-ACCOUNTS.
           READ ACCT-MASTER-FILE
               AT END SET WS-EOF TO TRUE
           END-READ
           IF NOT WS-EOF
               ADD 1 TO WS-TOTAL-PROCESSED
               IF ACCT-ACTIVE AND
                  (ACCT-SAVINGS OR ACCT-MONEY-MARKET)
                   IF ACCT-LEDGER-BAL > ZEROES
                       PERFORM 2000-ACCRUE-INTEREST
                   END-IF
               END-IF
           END-IF
           .

       2000-ACCRUE-INTEREST.
           COMPUTE WS-DAILY-INTEREST ROUNDED =
               ACCT-LEDGER-BAL *
               (ACCT-INT-RATE / WS-DAYS-IN-YEAR)
           END-COMPUTE
           ADD WS-DAILY-INTEREST TO ACCT-INT-ACCRUED
           REWRITE ACCT-MASTER-RECORD
           ADD 1 TO WS-TOTAL-ACCRUED
           ADD WS-DAILY-INTEREST TO WS-TOTAL-INTEREST
           .

       9000-DISPLAY-SUMMARY.
           DISPLAY 'INTEREST ACCRUAL SUMMARY'
           DISPLAY '  ACCOUNTS PROCESSED: ' WS-TOTAL-PROCESSED
           DISPLAY '  ACCOUNTS ACCRUED:   ' WS-TOTAL-ACCRUED
           DISPLAY '  TOTAL DAILY INT:    ' WS-TOTAL-INTEREST
           .

Exercise 13: CTR Detection Logic

Write a COBOL paragraph named 5000-CHECK-CTR-THRESHOLD that examines a customer's daily cash transactions and determines whether a Currency Transaction Report is required. The paragraph should:

  1. Accept a customer ID and aggregate all cash deposits and cash withdrawals for the day from a working-storage table of up to 100 daily transactions.
  2. If the total cash deposits exceed $10,000, flag for CTR filing with indicator 'D' (deposit).
  3. If the total cash withdrawals exceed $10,000, flag for CTR filing with indicator 'W' (withdrawal).
  4. If both exceed $10,000, flag with indicator 'B' (both).
  5. Write a CTR trigger record to the CTR output file when any threshold is met.

Solution:

       01  WS-DAILY-TRAN-TABLE.
           05  WS-DAILY-TRAN-ENTRY OCCURS 100 TIMES.
               10  WS-DT-CUST-ID      PIC X(10).
               10  WS-DT-TYPE         PIC X(03).
               10  WS-DT-CASH-IND     PIC X(01).
                   88  WS-DT-IS-CASH   VALUE 'Y'.
               10  WS-DT-AMOUNT       PIC S9(11)V99 COMP-3.
       01  WS-TRAN-COUNT              PIC 9(03).
       01  WS-CASH-DEP-TOTAL          PIC S9(11)V99 COMP-3.
       01  WS-CASH-WDR-TOTAL          PIC S9(11)V99 COMP-3.
       01  WS-CTR-THRESHOLD           PIC S9(07)V99 COMP-3
                                      VALUE 10000.00.
       01  WS-CTR-INDICATOR           PIC X(01).
       01  WS-SEARCH-CUST-ID          PIC X(10).
       01  WS-IDX                     PIC 9(03).

       5000-CHECK-CTR-THRESHOLD.
           MOVE ZEROS TO WS-CASH-DEP-TOTAL
                         WS-CASH-WDR-TOTAL

           PERFORM VARYING WS-IDX FROM 1 BY 1
               UNTIL WS-IDX > WS-TRAN-COUNT
               IF WS-DT-CUST-ID(WS-IDX) = WS-SEARCH-CUST-ID
                  AND WS-DT-IS-CASH(WS-IDX)
                   IF WS-DT-TYPE(WS-IDX) = 'DEP'
                       ADD WS-DT-AMOUNT(WS-IDX)
                           TO WS-CASH-DEP-TOTAL
                   END-IF
                   IF WS-DT-TYPE(WS-IDX) = 'WDR'
                       ADD WS-DT-AMOUNT(WS-IDX)
                           TO WS-CASH-WDR-TOTAL
                   END-IF
               END-IF
           END-PERFORM

           MOVE SPACES TO WS-CTR-INDICATOR

           IF WS-CASH-DEP-TOTAL > WS-CTR-THRESHOLD
               IF WS-CASH-WDR-TOTAL > WS-CTR-THRESHOLD
                   MOVE 'B' TO WS-CTR-INDICATOR
               ELSE
                   MOVE 'D' TO WS-CTR-INDICATOR
               END-IF
           ELSE
               IF WS-CASH-WDR-TOTAL > WS-CTR-THRESHOLD
                   MOVE 'W' TO WS-CTR-INDICATOR
               END-IF
           END-IF

           IF WS-CTR-INDICATOR NOT = SPACES
               PERFORM 5100-WRITE-CTR-TRIGGER
           END-IF
           .

Exercise 14: NACHA File Header Parsing

Write a COBOL record layout (01-level with subordinate fields) that maps to the 94-byte NACHA File Header Record (Record Type 1). Include all fields from position 1 through position 94 as defined in the NACHA specification. Then write a paragraph that validates the following fields:

  • Record Type Code must be '1'.
  • Priority Code must be '01'.
  • Record Size must be '094'.
  • Blocking Factor must be '10'.
  • Format Code must be '1'.

Solution:

       01  NACHA-FILE-HEADER.
           05  NH-RECORD-TYPE          PIC X(01).
           05  NH-PRIORITY-CODE        PIC X(02).
           05  NH-IMMED-DEST           PIC X(10).
           05  NH-IMMED-ORIGIN         PIC X(10).
           05  NH-FILE-CREATE-DATE     PIC X(06).
           05  NH-FILE-CREATE-TIME     PIC X(04).
           05  NH-FILE-ID-MODIFIER     PIC X(01).
           05  NH-RECORD-SIZE          PIC X(03).
           05  NH-BLOCKING-FACTOR      PIC X(02).
           05  NH-FORMAT-CODE          PIC X(01).
           05  NH-IMMED-DEST-NAME      PIC X(23).
           05  NH-IMMED-ORIGIN-NAME    PIC X(23).
           05  NH-REFERENCE-CODE       PIC X(08).

       VALIDATE-FILE-HEADER.
           SET WS-HEADER-VALID TO TRUE

           IF NH-RECORD-TYPE NOT = '1'
               DISPLAY 'INVALID RECORD TYPE: ' NH-RECORD-TYPE
               SET WS-HEADER-INVALID TO TRUE
           END-IF

           IF NH-PRIORITY-CODE NOT = '01'
               DISPLAY 'INVALID PRIORITY CODE: '
                       NH-PRIORITY-CODE
               SET WS-HEADER-INVALID TO TRUE
           END-IF

           IF NH-RECORD-SIZE NOT = '094'
               DISPLAY 'INVALID RECORD SIZE: ' NH-RECORD-SIZE
               SET WS-HEADER-INVALID TO TRUE
           END-IF

           IF NH-BLOCKING-FACTOR NOT = '10'
               DISPLAY 'INVALID BLOCKING FACTOR: '
                       NH-BLOCKING-FACTOR
               SET WS-HEADER-INVALID TO TRUE
           END-IF

           IF NH-FORMAT-CODE NOT = '1'
               DISPLAY 'INVALID FORMAT CODE: ' NH-FORMAT-CODE
               SET WS-HEADER-INVALID TO TRUE
           END-IF
           .

Exercise 15: Wire Transfer Fee Calculation

Write a COBOL paragraph that calculates wire transfer fees based on the following schedule used by a commercial bank:

Transfer Type Amount Range Fee
Domestic outgoing $0 - $5,000 $25.00
Domestic outgoing $5,001 - $50,000 $30.00
Domestic outgoing Over $50,000 | $35.00
International outgoing $0 - $5,000 $45.00
International outgoing $5,001 - $50,000 $50.00
International outgoing Over $50,000 | $65.00
Incoming (any) Any $15.00

The paragraph should accept WS-WIRE-TYPE ('D' = domestic, 'I' = international), WS-WIRE-DIRECTION ('O' = outgoing, 'I' = incoming), and WS-WIRE-AMOUNT, and set WS-WIRE-FEE.

Solution:

       3500-CALCULATE-WIRE-FEE.
           IF WS-WIRE-DIRECTION = 'I'
               MOVE 15.00 TO WS-WIRE-FEE
           ELSE
               EVALUATE TRUE
                   WHEN WS-WIRE-TYPE = 'D'
                       AND WS-WIRE-AMOUNT <= 5000.00
                       MOVE 25.00 TO WS-WIRE-FEE

                   WHEN WS-WIRE-TYPE = 'D'
                       AND WS-WIRE-AMOUNT <= 50000.00
                       MOVE 30.00 TO WS-WIRE-FEE

                   WHEN WS-WIRE-TYPE = 'D'
                       AND WS-WIRE-AMOUNT > 50000.00
                       MOVE 35.00 TO WS-WIRE-FEE

                   WHEN WS-WIRE-TYPE = 'I'
                       AND WS-WIRE-AMOUNT <= 5000.00
                       MOVE 45.00 TO WS-WIRE-FEE

                   WHEN WS-WIRE-TYPE = 'I'
                       AND WS-WIRE-AMOUNT <= 50000.00
                       MOVE 50.00 TO WS-WIRE-FEE

                   WHEN WS-WIRE-TYPE = 'I'
                       AND WS-WIRE-AMOUNT > 50000.00
                       MOVE 65.00 TO WS-WIRE-FEE

                   WHEN OTHER
                       MOVE ZEROS TO WS-WIRE-FEE
                       DISPLAY 'UNKNOWN WIRE TYPE: '
                               WS-WIRE-TYPE
               END-EVALUATE
           END-IF
           .

Exercise 16: Overdraft Processing

Write a COBOL paragraph named 4000-PROCESS-OVERDRAFT that handles an overdraft situation after a debit transaction has caused a negative available balance. The paragraph should:

  1. Check whether the account has overdraft protection linked to another account (WS-OD-LINK-ACCT).
  2. If linked, attempt to transfer sufficient funds from the linked account to cover the overdraft plus a $10.00 transfer fee.
  3. If the linked account also has insufficient funds, assess an overdraft fee of $35.00 against the original account.
  4. If no overdraft protection, assess the $35.00 overdraft fee directly.
  5. Generate a fee transaction record for any fees assessed.

Solution:

       4000-PROCESS-OVERDRAFT.
           MOVE 35.00 TO WS-OD-FEE-AMOUNT
           MOVE 10.00 TO WS-OD-TRANSFER-FEE

           IF WS-OD-LINK-ACCT NOT = SPACES
               COMPUTE WS-OD-TRANSFER-NEEDED =
                   (ACCT-AVAIL-BAL * -1) + WS-OD-TRANSFER-FEE
               PERFORM 4100-CHECK-LINKED-ACCT
               IF WS-LINKED-HAS-FUNDS
                   PERFORM 4200-TRANSFER-FROM-LINKED
                   MOVE WS-OD-TRANSFER-FEE
                       TO WS-FEE-TO-ASSESS
                   PERFORM 4500-ASSESS-FEE
               ELSE
                   MOVE WS-OD-FEE-AMOUNT
                       TO WS-FEE-TO-ASSESS
                   PERFORM 4500-ASSESS-FEE
               END-IF
           ELSE
               MOVE WS-OD-FEE-AMOUNT
                   TO WS-FEE-TO-ASSESS
               PERFORM 4500-ASSESS-FEE
           END-IF

           ADD 1 TO WS-OVERDRAFT-COUNT
           .

       4500-ASSESS-FEE.
           SUBTRACT WS-FEE-TO-ASSESS FROM ACCT-LEDGER-BAL
           SUBTRACT WS-FEE-TO-ASSESS FROM ACCT-AVAIL-BAL
           MOVE 'FEE' TO TRAN-TYPE-CODE
           MOVE WS-FEE-TO-ASSESS TO TRAN-AMOUNT
           MOVE 'OVERDRAFT FEE' TO TRAN-DESCRIPTION
           MOVE 'P' TO TRAN-STATUS
           PERFORM 9200-WRITE-TRAN-RECORD
           .

Tier 3: Analysis and Problem Solving (Exercises 17-24)

Exercise 17: Debugging a Transaction Posting Program

The following COBOL paragraph posts transactions but has three bugs that will cause incorrect balance updates. Identify each bug and explain how to fix it.

       3000-POST-TRANSACTION.
           EVALUATE TRUE
               WHEN TRAN-DEPOSIT
               WHEN TRAN-TRANSFER-IN
                   ADD TRAN-AMOUNT TO ACCT-LEDGER-BAL
                   ADD 1 TO WS-CREDIT-COUNT
                   ADD TRAN-AMOUNT TO WS-CREDIT-TOTAL

               WHEN TRAN-WITHDRAWAL
               WHEN TRAN-TRANSFER-OUT
               WHEN TRAN-FEE
                   SUBTRACT TRAN-AMOUNT FROM ACCT-LEDGER-BAL
                   ADD 1 TO WS-DEBIT-COUNT
                   ADD TRAN-AMOUNT TO WS-DEBIT-TOTAL

               WHEN TRAN-INTEREST
                   ADD TRAN-AMOUNT TO ACCT-INT-ACCRUED
           END-EVALUATE

           MOVE WS-CURRENT-DATE TO ACCT-LAST-ACTIVITY
           REWRITE ACCT-MASTER-RECORD
           .

Solution:

Bug 1: The available balance (ACCT-AVAIL-BAL) is never updated. Both ledger and available balances must be adjusted. For credits, ADD TRAN-AMOUNT TO ACCT-AVAIL-BAL. For debits, SUBTRACT TRAN-AMOUNT FROM ACCT-AVAIL-BAL.

Bug 2: Interest posting (TRAN-INTEREST) adds to ACCT-INT-ACCRUED instead of adding to both ACCT-LEDGER-BAL and ACCT-AVAIL-BAL. Interest accrual adds to the accrued field; interest posting should move accrued interest into the balance. As written, interest transactions should be treated like credits.

Bug 3: The TRAN-PAYMENT condition is missing from the debit cases. The WHEN TRAN-PAYMENT line must be added alongside the other debit transaction types. Without it, payment transactions fall through to the default (no action) and the balance is not updated.

Exercise 18: ACH Batch Control Validation

Write a COBOL paragraph that validates an ACH Batch Control Record (Record Type 8) against accumulated totals from processing the Entry Detail records in the batch. The paragraph should verify:

  1. The entry/addenda count matches the number of Entry Detail and Addenda records processed.
  2. The entry hash matches the sum of all Receiving DFI Identification fields (positions 4-11) in the Entry Detail records, using only the last 10 digits.
  3. The total debit dollar amount matches the sum of all debit entries.
  4. The total credit dollar amount matches the sum of all credit entries.

Report each discrepancy found.

Solution:

       01  WS-ACCUM-ENTRY-COUNT    PIC 9(06) VALUE ZEROS.
       01  WS-ACCUM-HASH           PIC 9(10) VALUE ZEROS.
       01  WS-ACCUM-DEBIT-TOTAL    PIC 9(12)V99 VALUE ZEROS.
       01  WS-ACCUM-CREDIT-TOTAL   PIC 9(12)V99 VALUE ZEROS.
       01  WS-BATCH-ERRORS         PIC 9(03) VALUE ZEROS.

       01  NACHA-BATCH-CONTROL.
           05  BC-RECORD-TYPE      PIC X(01).
           05  BC-SVC-CLASS-CODE   PIC X(03).
           05  BC-ENTRY-COUNT      PIC 9(06).
           05  BC-ENTRY-HASH       PIC 9(10).
           05  BC-TOTAL-DEBIT      PIC 9(12)V99.
           05  BC-TOTAL-CREDIT     PIC 9(12)V99.
           05  BC-COMPANY-ID       PIC X(10).
           05  FILLER              PIC X(25).
           05  BC-ODFI-ID          PIC X(08).
           05  BC-BATCH-NUMBER     PIC 9(07).

       6000-VALIDATE-BATCH-CONTROL.
           MOVE ZEROS TO WS-BATCH-ERRORS

           IF BC-ENTRY-COUNT NOT = WS-ACCUM-ENTRY-COUNT
               DISPLAY 'ENTRY COUNT MISMATCH: '
                   'CONTROL=' BC-ENTRY-COUNT
                   ' ACTUAL=' WS-ACCUM-ENTRY-COUNT
               ADD 1 TO WS-BATCH-ERRORS
           END-IF

           IF BC-ENTRY-HASH NOT = WS-ACCUM-HASH
               DISPLAY 'ENTRY HASH MISMATCH: '
                   'CONTROL=' BC-ENTRY-HASH
                   ' ACTUAL=' WS-ACCUM-HASH
               ADD 1 TO WS-BATCH-ERRORS
           END-IF

           IF BC-TOTAL-DEBIT NOT = WS-ACCUM-DEBIT-TOTAL
               DISPLAY 'DEBIT TOTAL MISMATCH: '
                   'CONTROL=' BC-TOTAL-DEBIT
                   ' ACTUAL=' WS-ACCUM-DEBIT-TOTAL
               ADD 1 TO WS-BATCH-ERRORS
           END-IF

           IF BC-TOTAL-CREDIT NOT = WS-ACCUM-CREDIT-TOTAL
               DISPLAY 'CREDIT TOTAL MISMATCH: '
                   'CONTROL=' BC-TOTAL-CREDIT
                   ' ACTUAL=' WS-ACCUM-CREDIT-TOTAL
               ADD 1 TO WS-BATCH-ERRORS
           END-IF

           IF WS-BATCH-ERRORS > 0
               DISPLAY 'BATCH ' BC-BATCH-NUMBER
                       ' FAILED VALIDATION WITH '
                       WS-BATCH-ERRORS ' ERRORS'
               ADD 1 TO WS-REJECTED-BATCHES
           ELSE
               ADD 1 TO WS-ACCEPTED-BATCHES
           END-IF
           .

Exercise 19: Statement Running Balance Error

A bank customer reports that the running balance on their monthly statement is incorrect starting from the fifth transaction. Here is the transaction detail from the statement:

Date Description Debit Credit Balance
03/01 Opening Balance $2,500.00
03/02 Payroll Deposit $3,200.00 | $5,700.00
03/03 Electric Bill $185.50 | | $5,514.50
03/05 ATM Withdrawal $200.00 | | $5,314.50
03/07 Transfer Out $1,000.00 | | $4,514.50
03/10 Check #1042 $450.00 | | $3,864.50
03/15 Monthly Fee $12.00 | | $3,852.50

The customer claims the balance after the check (#1042) should be $3,864.50 but the statement shows it correctly. However, the customer says the ATM withdrawal was actually $300.00, not $200.00. If the customer is correct, recalculate the running balance from the ATM withdrawal onward and determine the correct closing balance. Then explain what COBOL logic error could cause a statement to use the wrong transaction amount.

Solution:

If the ATM withdrawal was actually $300.00 (not $200.00), the corrected running balance is:

Date Description Debit Credit Balance
03/05 ATM Withdrawal $300.00 | | $5,214.50
03/07 Transfer Out $1,000.00 | | $4,214.50
03/10 Check #1042 $450.00 | | $3,764.50
03/15 Monthly Fee $12.00 | | $3,752.50

The correct closing balance is $3,752.50, which is $100.00 less than the reported $3,852.50. A possible COBOL logic error: the statement program may be reading the memo-posted authorization amount ($200.00) rather than the final posted amount ($300.00). This occurs when the program reads from the authorization hold file instead of the completed transaction history, or when a partial reversal/adjustment to the original memo post was not properly reflected in the statement extract.

Exercise 20: Regulation CC Hold Period Determination

Write a COBOL paragraph named 3500-DETERMINE-HOLD-PERIOD that implements Regulation CC hold rules. Given a check deposit, the paragraph should determine the hold period and the date funds become available based on these rules:

Condition Hold Period
Cash deposit Next business day
U.S. Treasury check Next business day
Local check, existing account 2 business days
Non-local check 5 business days
New account (open < 30 days) 9 business days
Large deposit (> $5,525) | 7 business days on amount over $5,525
Account with repeated overdrafts 7 business days

The input fields are WS-DEPOSIT-TYPE ('C'=cash, 'T'=treasury, 'L'=local check, 'N'=non-local check), WS-DEPOSIT-AMOUNT, WS-ACCOUNT-OPEN-DAYS, and WS-OVERDRAFT-HISTORY ('Y'/'N'). Set WS-HOLD-DAYS with the appropriate number of business days.

Solution:

       3500-DETERMINE-HOLD-PERIOD.
           EVALUATE WS-DEPOSIT-TYPE
               WHEN 'C'
                   MOVE 1 TO WS-HOLD-DAYS
               WHEN 'T'
                   MOVE 1 TO WS-HOLD-DAYS
               WHEN 'L'
                   MOVE 2 TO WS-HOLD-DAYS
               WHEN 'N'
                   MOVE 5 TO WS-HOLD-DAYS
               WHEN OTHER
                   MOVE 5 TO WS-HOLD-DAYS
           END-EVALUATE

           IF WS-ACCOUNT-OPEN-DAYS < 30
               MOVE 9 TO WS-HOLD-DAYS
           END-IF

           IF WS-OVERDRAFT-HISTORY = 'Y'
               IF WS-HOLD-DAYS < 7
                   MOVE 7 TO WS-HOLD-DAYS
               END-IF
           END-IF

           IF WS-DEPOSIT-AMOUNT > 5525.00
               IF WS-HOLD-DAYS < 7
                   MOVE 7 TO WS-HOLD-DAYS
               END-IF
               COMPUTE WS-IMMEDIATE-AVAIL =
                   5525.00
               COMPUTE WS-HELD-AMOUNT =
                   WS-DEPOSIT-AMOUNT - 5525.00
           ELSE
               MOVE WS-DEPOSIT-AMOUNT
                   TO WS-IMMEDIATE-AVAIL
               MOVE ZEROS TO WS-HELD-AMOUNT
           END-IF
           .

Exercise 21: End-of-Day Reconciliation

Write a COBOL paragraph that performs end-of-day reconciliation by comparing the following control totals:

  1. The sum of all beginning balances plus all credits minus all debits should equal the sum of all ending balances.
  2. The number of transactions posted plus the number of transactions rejected should equal the total number of transactions received.
  3. The net change in the GL cash account should equal the net settlement amount reported by the payment networks.

For any discrepancy, write a reconciliation exception record that includes the control being checked, the expected value, the actual value, and the difference.

Solution:

       7000-END-OF-DAY-RECON.
           MOVE ZEROS TO WS-RECON-EXCEPTIONS

           COMPUTE WS-EXPECTED-END-BAL =
               WS-TOTAL-BEG-BAL
             + WS-TOTAL-CREDITS
             - WS-TOTAL-DEBITS

           IF WS-EXPECTED-END-BAL NOT = WS-TOTAL-END-BAL
               MOVE 'BALANCE RECONCILIATION'
                   TO WS-RECON-CONTROL-NAME
               MOVE WS-EXPECTED-END-BAL
                   TO WS-RECON-EXPECTED
               MOVE WS-TOTAL-END-BAL
                   TO WS-RECON-ACTUAL
               COMPUTE WS-RECON-DIFFERENCE =
                   WS-EXPECTED-END-BAL - WS-TOTAL-END-BAL
               PERFORM 7900-WRITE-EXCEPTION
               ADD 1 TO WS-RECON-EXCEPTIONS
           END-IF

           COMPUTE WS-EXPECTED-TRAN-COUNT =
               WS-POSTED-COUNT + WS-REJECTED-COUNT
           IF WS-EXPECTED-TRAN-COUNT NOT = WS-RECEIVED-COUNT
               MOVE 'TRANSACTION COUNT'
                   TO WS-RECON-CONTROL-NAME
               MOVE WS-RECEIVED-COUNT
                   TO WS-RECON-EXPECTED
               MOVE WS-EXPECTED-TRAN-COUNT
                   TO WS-RECON-ACTUAL
               COMPUTE WS-RECON-DIFFERENCE =
                   WS-RECEIVED-COUNT
                 - WS-EXPECTED-TRAN-COUNT
               PERFORM 7900-WRITE-EXCEPTION
               ADD 1 TO WS-RECON-EXCEPTIONS
           END-IF

           IF WS-GL-CASH-NET-CHANGE NOT =
              WS-SETTLEMENT-NET-AMOUNT
               MOVE 'SETTLEMENT RECONCILIATION'
                   TO WS-RECON-CONTROL-NAME
               MOVE WS-SETTLEMENT-NET-AMOUNT
                   TO WS-RECON-EXPECTED
               MOVE WS-GL-CASH-NET-CHANGE
                   TO WS-RECON-ACTUAL
               COMPUTE WS-RECON-DIFFERENCE =
                   WS-SETTLEMENT-NET-AMOUNT
                 - WS-GL-CASH-NET-CHANGE
               PERFORM 7900-WRITE-EXCEPTION
               ADD 1 TO WS-RECON-EXCEPTIONS
           END-IF

           IF WS-RECON-EXCEPTIONS = 0
               DISPLAY 'EOD RECONCILIATION: ALL CONTROLS BALANCED'
           ELSE
               DISPLAY 'EOD RECONCILIATION: '
                       WS-RECON-EXCEPTIONS ' EXCEPTIONS FOUND'
               MOVE 8 TO RETURN-CODE
           END-IF
           .

Exercise 22: ACH Return Processing

An ACH return file contains entries that could not be posted by the receiving bank. Each return has a return reason code. Write a COBOL paragraph that processes ACH returns and takes the appropriate action based on the return reason code:

Code Reason Action
R01 Insufficient Funds Reverse the debit, assess $25 return fee
R02 Account Closed Reverse the entry, flag account for review
R03 No Account/Unable to Locate Reverse the entry, generate exception report
R04 Invalid Account Number Reverse the entry, notify originator
R08 Payment Stopped Reverse the entry, no fee
R10 Customer Advises Not Authorized Reverse the entry, initiate investigation

Solution:

       6500-PROCESS-ACH-RETURN.
           EVALUATE WS-RETURN-CODE
               WHEN 'R01'
                   PERFORM 6510-REVERSE-ENTRY
                   MOVE 25.00 TO WS-RETURN-FEE
                   PERFORM 6520-ASSESS-RETURN-FEE
                   ADD 1 TO WS-R01-COUNT

               WHEN 'R02'
                   PERFORM 6510-REVERSE-ENTRY
                   MOVE 'Y' TO WS-REVIEW-FLAG
                   PERFORM 6530-FLAG-FOR-REVIEW
                   ADD 1 TO WS-R02-COUNT

               WHEN 'R03'
                   PERFORM 6510-REVERSE-ENTRY
                   PERFORM 6540-WRITE-EXCEPTION-RPT
                   ADD 1 TO WS-R03-COUNT

               WHEN 'R04'
                   PERFORM 6510-REVERSE-ENTRY
                   PERFORM 6550-NOTIFY-ORIGINATOR
                   ADD 1 TO WS-R04-COUNT

               WHEN 'R08'
                   PERFORM 6510-REVERSE-ENTRY
                   ADD 1 TO WS-R08-COUNT

               WHEN 'R10'
                   PERFORM 6510-REVERSE-ENTRY
                   PERFORM 6560-INITIATE-INVESTIGATION
                   ADD 1 TO WS-R10-COUNT

               WHEN OTHER
                   PERFORM 6510-REVERSE-ENTRY
                   DISPLAY 'UNHANDLED RETURN CODE: '
                           WS-RETURN-CODE
                   ADD 1 TO WS-OTHER-RETURN-COUNT
           END-EVALUATE

           ADD 1 TO WS-TOTAL-RETURNS
           .

       6510-REVERSE-ENTRY.
           IF WS-ORIG-TRAN-CODE = '27' OR '37'
               ADD WS-RETURN-AMOUNT TO ACCT-LEDGER-BAL
               ADD WS-RETURN-AMOUNT TO ACCT-AVAIL-BAL
           ELSE
               SUBTRACT WS-RETURN-AMOUNT FROM ACCT-LEDGER-BAL
               SUBTRACT WS-RETURN-AMOUNT FROM ACCT-AVAIL-BAL
           END-IF
           MOVE 'R' TO TRAN-STATUS
           REWRITE ACCT-MASTER-RECORD
           .

Exercise 23: Structuring Detection

Write a COBOL program section that detects potential cash structuring -- the practice of deliberately keeping cash transactions below the $10,000 CTR threshold. The program should flag a customer as potentially structuring if:

  1. The customer has 3 or more cash transactions in a single day.
  2. Each individual transaction is below $10,000.
  3. The total exceeds $10,000.
  4. At least two transactions occurred at different branches.

Describe the data structures needed, write the detection logic, and generate a suspicious activity trigger record.

Solution:

       01  WS-STRUCTURING-WORK.
           05  WS-CUST-CASH-COUNT      PIC 9(03) VALUE ZEROS.
           05  WS-CUST-CASH-TOTAL      PIC S9(11)V99
                                       COMP-3 VALUE ZEROS.
           05  WS-ALL-BELOW-10K        PIC X(01) VALUE 'Y'.
               88  WS-ALL-UNDER-LIMIT  VALUE 'Y'.
           05  WS-BRANCH-TABLE.
               10  WS-BRANCH-ENTRY OCCURS 10 TIMES.
                   15  WS-BRANCH-CODE  PIC X(04).
           05  WS-BRANCH-COUNT         PIC 9(02) VALUE ZEROS.
           05  WS-UNIQUE-BRANCHES      PIC 9(02) VALUE ZEROS.
           05  WS-IS-DUPLICATE-BR      PIC X(01) VALUE 'N'.
           05  WS-BR-IDX               PIC 9(02) VALUE ZEROS.

       7500-CHECK-STRUCTURING.
           IF WS-CUST-CASH-COUNT >= 3
              AND WS-ALL-UNDER-LIMIT
              AND WS-CUST-CASH-TOTAL > 10000.00
              AND WS-UNIQUE-BRANCHES >= 2
               PERFORM 7510-GENERATE-SAR-TRIGGER
               ADD 1 TO WS-STRUCTURING-FLAGS
               DISPLAY 'STRUCTURING ALERT: CUSTOMER '
                       WS-CURRENT-CUST-ID
                       ' CASH TOTAL $' WS-CUST-CASH-TOTAL
                       ' IN ' WS-CUST-CASH-COUNT
                       ' TRANSACTIONS AT '
                       WS-UNIQUE-BRANCHES ' BRANCHES'
           END-IF
           .

       7510-GENERATE-SAR-TRIGGER.
           MOVE WS-CURRENT-CUST-ID TO SAR-CUSTOMER-ID
           MOVE 'STRUCTURING' TO SAR-ACTIVITY-TYPE
           MOVE WS-CUST-CASH-TOTAL TO SAR-TOTAL-AMOUNT
           MOVE WS-CUST-CASH-COUNT TO SAR-TRAN-COUNT
           MOVE WS-CURRENT-DATE TO SAR-ACTIVITY-DATE
           MOVE 'MULTIPLE CASH TRANSACTIONS BELOW CTR '
                'THRESHOLD ACROSS BRANCHES'
               TO SAR-NARRATIVE
           WRITE SAR-TRIGGER-RECORD
           .

Exercise 24: Nightly Batch Cycle JCL

Design a complete JCL job stream for the nightly batch cycle of a banking system. The job should include the following steps in order:

  1. Sort all pending transactions by account number, credits before debits.
  2. Execute the transaction posting program (TRANPOST).
  3. Execute the interest accrual program (INTACCRL).
  4. Execute the fee assessment program (FEEASSMT).
  5. Execute the reconciliation program (RECONPGM).

Each step should have appropriate DD statements, COND parameters for step-level restart capability, and SYSOUT allocation. If any step fails with a return code greater than 4, subsequent steps should not execute.

Solution:

//NIGHTLY  JOB (BANK,BATCH),'NIGHTLY CYCLE',
//             CLASS=A,MSGCLASS=X,MSGLEVEL=(1,1),
//             NOTIFY=&SYSUID
//*
//*-----------------------------------------------------------*
//*  STEP 1: SORT TRANSACTIONS - CREDITS BEFORE DEBITS        *
//*-----------------------------------------------------------*
//SORT     EXEC PGM=SORT
//SORTIN   DD DSN=BANK.DAILY.PENDING.TRANS,DISP=SHR
//SORTOUT  DD DSN=BANK.DAILY.SORTED.TRANS,
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(CYL,(50,10)),
//            DCB=(RECFM=FB,LRECL=200,BLKSIZE=0)
//SORTWK01 DD UNIT=SYSDA,SPACE=(CYL,(100,20))
//SORTWK02 DD UNIT=SYSDA,SPACE=(CYL,(100,20))
//SORTWK03 DD UNIT=SYSDA,SPACE=(CYL,(100,20))
//SYSOUT   DD SYSOUT=*
//SYSIN    DD *
  SORT FIELDS=(1,12,CH,A,18,3,CH,A)
  OPTION EQUALS
/*
//*
//*-----------------------------------------------------------*
//*  STEP 2: POST TRANSACTIONS                                *
//*-----------------------------------------------------------*
//POST     EXEC PGM=TRANPOST,COND=(4,LT)
//STEPLIB  DD DSN=BANK.PROD.LOADLIB,DISP=SHR
//TRANSIN  DD DSN=BANK.DAILY.SORTED.TRANS,DISP=SHR
//ACCTMAST DD DSN=BANK.ACCT.MASTER,DISP=SHR
//TRANSHST DD DSN=BANK.TRAN.HISTORY,DISP=MOD
//REJECTFL DD DSN=BANK.DAILY.REJECTS,
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(CYL,(5,2)),
//            DCB=(RECFM=FB,LRECL=250,BLKSIZE=0)
//SYSOUT   DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//*
//*-----------------------------------------------------------*
//*  STEP 3: ACCRUE INTEREST                                  *
//*-----------------------------------------------------------*
//INTACRL  EXEC PGM=INTACCRL,COND=(4,LT)
//STEPLIB  DD DSN=BANK.PROD.LOADLIB,DISP=SHR
//ACCTMAST DD DSN=BANK.ACCT.MASTER,DISP=SHR
//SYSOUT   DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//*
//*-----------------------------------------------------------*
//*  STEP 4: ASSESS FEES                                      *
//*-----------------------------------------------------------*
//FEES     EXEC PGM=FEEASSMT,COND=(4,LT)
//STEPLIB  DD DSN=BANK.PROD.LOADLIB,DISP=SHR
//ACCTMAST DD DSN=BANK.ACCT.MASTER,DISP=SHR
//FEESCHDL DD DSN=BANK.FEE.SCHEDULE,DISP=SHR
//FEETRANS DD DSN=BANK.DAILY.FEE.TRANS,
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(CYL,(5,2)),
//            DCB=(RECFM=FB,LRECL=200,BLKSIZE=0)
//SYSOUT   DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//*
//*-----------------------------------------------------------*
//*  STEP 5: RECONCILIATION                                   *
//*-----------------------------------------------------------*
//RECON    EXEC PGM=RECONPGM,COND=(4,LT)
//STEPLIB  DD DSN=BANK.PROD.LOADLIB,DISP=SHR
//ACCTMAST DD DSN=BANK.ACCT.MASTER,DISP=SHR
//TRANSHST DD DSN=BANK.TRAN.HISTORY,DISP=SHR
//RECONRPT DD SYSOUT=*
//EXCEPTFL DD DSN=BANK.DAILY.RECON.EXCEPT,
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(CYL,(1,1)),
//            DCB=(RECFM=FB,LRECL=200,BLKSIZE=0)
//SYSOUT   DD SYSOUT=*
//SYSPRINT DD SYSOUT=*

Tier 4: Synthesis and Design (Exercises 25-32)

Exercise 25: Complete ACH File Parser

Design and write a complete COBOL program that reads a NACHA-format ACH file and performs the following:

  1. Parse all five record types (File Header, Batch Header, Entry Detail, Batch Control, File Control).
  2. Validate each record type against its format rules.
  3. Accumulate control totals as entries are processed.
  4. At each Batch Control record, validate the batch totals against accumulated values.
  5. At the File Control record, validate the file totals.
  6. Produce a summary report showing: number of batches, number of entries, total debits, total credits, and any validation errors.

Include the complete FILE SECTION, WORKING-STORAGE SECTION, and PROCEDURE DIVISION. Provide the companion JCL.

Hint: Use an EVALUATE statement on the first byte of each record to dispatch to the appropriate parsing paragraph. Maintain separate accumulators for the current batch and the overall file.

Exercise 26: Card Authorization System

Design a CICS-callable COBOL program that processes credit card authorization requests in real time. The program should:

  1. Receive a card number, merchant ID, merchant category code, and transaction amount through a COMMAREA.
  2. Validate the card number using the Luhn algorithm.
  3. Read the card master file (VSAM KSDS) to verify the card exists, is active, and is not reported lost or stolen.
  4. Check the available credit (credit limit minus current balance minus pending authorizations).
  5. Apply merchant category restrictions (e.g., block gambling merchant codes for certain card types).
  6. Generate a 6-digit authorization code if approved.
  7. Create a memo-post record for approved transactions.
  8. Return an approval or decline response through the COMMAREA.

Provide the COMMAREA layout, the card master record layout, and the complete PROCEDURE DIVISION logic. Discuss how you would handle the situation where the card master file is unavailable.

Hint: The CICS commands you need are EXEC CICS READ, EXEC CICS WRITE, and EXEC CICS RETURN. Use RESP and RESP2 for error handling.

Exercise 27: Multi-Channel Payment Router

Design a COBOL program that acts as a payment router, receiving payment requests from multiple channels and routing them to the appropriate processing subsystem. The channels are:

  • ACH (batch, next-day settlement)
  • Fedwire (real-time, same-day settlement)
  • RTP (real-time, immediate settlement)
  • Internal transfer (real-time, same institution)

The routing rules are: - Transfers under $1,000 between accounts at the same bank: Internal transfer. - Transfers under $25,000 with next-day settlement acceptable: ACH. - Transfers between $25,000 and $1,000,000 requiring same-day settlement: Fedwire. - Transfers under $100,000 requiring immediate settlement: RTP. - All other transfers: Fedwire.

Design the input record layout, the routing logic, and the output record layouts for each channel. Include validation, error handling, and audit trail generation.

Hint: Consider edge cases: what happens when a transfer meets multiple criteria? What is the priority order? How do you handle amounts that exceed the RTP per-transaction limit?

Exercise 28: Statement Generation with Regulation E Compliance

Design a complete statement generation program that produces monthly bank statements. The program should:

  1. Extract accounts whose cycle date matches the current processing date.
  2. Pull all transactions for the statement period.
  3. Sort transactions chronologically.
  4. Calculate the running balance for each transaction.
  5. Format the statement with header, summary, transaction detail, and footer sections.
  6. Include Regulation E disclosures about error resolution rights.
  7. Handle page breaks correctly (maximum 55 detail lines per page).
  8. Generate both a print file and an electronic delivery file (PDF-ready data).

Provide the complete program design, key record layouts, and the main processing logic. Include the JCL for the statement generation batch job.

Hint: Use a working-storage line counter to track page position. Reset it after each page break. The Regulation E disclosure text should be stored in a copybook or a sequential file, not hard-coded in the program.


Tier 5: Evaluation and Creation (Exercises 29-35)

Exercise 29: Real-Time Payment Integration

A bank is implementing FedNow instant payments alongside its existing COBOL batch processing. Design the architecture for integrating real-time payments with the batch cycle. Address:

  1. How does a real-time credit post to an account without conflicting with the nightly batch cycle that also updates the same account master?
  2. How do you maintain an accurate available balance when both real-time and batch transactions affect the same account?
  3. How do you ensure that end-of-day reconciliation accounts for both real-time and batch activity?
  4. What locking strategy prevents two simultaneous real-time transactions from corrupting the account balance?

Provide COBOL code for the critical sections and a diagram showing the interaction between real-time and batch components.

Hint: Consider using a memo-post file that is separate from the account master. Real-time transactions update the memo-post file immediately; the batch cycle consolidates memo posts into the account master.

Exercise 30: Fraud Detection Engine

Design a COBOL batch program that implements rule-based fraud detection. The program should process the day's completed transactions and flag suspicious activity based on these rules:

  1. Any single transaction exceeding 3 standard deviations above the customer's average transaction amount.
  2. More than 10 transactions in a single day on a consumer account.
  3. ATM withdrawals in two different cities within 30 minutes (impossible travel).
  4. International wire transfers to countries on the bank's high-risk list.
  5. Rapid in-and-out: large credit followed by large debit within the same day.

Design the data structures for customer profiles (average transaction amount, standard deviation, typical activity patterns), the detection logic, and the alert generation process. Discuss how you would tune the rules to minimize false positives while maintaining detection sensitivity.

Hint: Customer profiles can be maintained in a VSAM file that is updated nightly. Standard deviation calculation requires maintaining a running count, sum, and sum of squares for each customer.

Exercise 31: Banking System Migration Strategy

Your bank is migrating from a VSAM-based account master file to a DB2 relational database while keeping the COBOL programs intact. Design the migration strategy, including:

  1. The DB2 table schema that maps to the current VSAM record layout.
  2. The changes required to the COBOL ENVIRONMENT DIVISION and DATA DIVISION.
  3. The strategy for handling the transition period when some programs are migrated and others are not.
  4. How to maintain referential integrity between the account master, transaction history, and customer information.
  5. Performance considerations: what changes when you move from VSAM sequential reads to SQL SELECT statements in a batch program that processes millions of records?

Provide sample EXEC SQL statements and discuss the trade-offs.

Hint: Consider using a database access module (DAM) pattern where all file I/O is encapsulated in a single subprogram. This allows the I/O implementation to change without modifying the business logic programs.

Exercise 32: Cross-Border Payment System

Design a COBOL program that processes SWIFT MT103 international wire transfer messages. The program should:

  1. Parse the tagged-field MT103 message format.
  2. Validate mandatory fields (sender, receiver, beneficiary, amount, currency).
  3. Perform OFAC screening by comparing beneficiary names and bank identifiers against a sanctions list.
  4. Convert the transfer amount from the originating currency to USD using exchange rates loaded from a rate file.
  5. Generate a Fedwire message for the domestic leg of the transfer.
  6. Create audit trail records for regulatory compliance.

Provide the MT103 parsing logic, the OFAC screening algorithm, and the currency conversion calculation. Discuss how you would handle partial name matches in OFAC screening.

Hint: OFAC screening typically uses fuzzy matching. For a COBOL implementation, consider comparing each word of the beneficiary name against each word of the SDN name, counting matches, and flagging if the match percentage exceeds a threshold (e.g., 80%).

Exercise 33: Comparative Analysis of Payment Systems

Compare and contrast ACH, Fedwire, SWIFT, and RTP across the following dimensions:

Dimension ACH Fedwire SWIFT RTP
Settlement speed
Transaction limit
Revocability
Operating hours
Message format
Typical use case
COBOL processing model

For each payment system, explain why COBOL is or is not the best choice for implementing the processing logic. Consider performance requirements, data format compatibility, and regulatory compliance.

Hint: Consider the difference between message-based systems (SWIFT) and value-transfer systems (Fedwire). Also consider how batch processing (COBOL's strength) maps to each system's settlement model.

Exercise 34: Disaster Recovery Procedures

Design a comprehensive disaster recovery plan for the nightly batch cycle. The plan should address:

  1. What happens if the transaction posting step fails midway through processing? How do you restart without double-posting?
  2. How do you handle a corrupted account master file? What backup and recovery procedures are needed?
  3. If the batch cycle cannot complete before the next business day begins, what are the business impacts and how do you mitigate them?
  4. Design a COBOL checkpoint/restart mechanism that writes a checkpoint record every 10,000 transactions, allowing the program to restart from the last checkpoint after a failure.

Provide the COBOL code for the checkpoint/restart mechanism and the JCL for a recovery job.

Hint: The checkpoint record should contain the last successfully processed account number, the transaction sequence number, and all running control totals. On restart, the program reads the checkpoint record, repositions the files, and resumes processing.

Exercise 35: End-to-End ACH Processing Pipeline

Design and implement a complete ACH processing pipeline consisting of five programs executed in sequence via JCL:

  1. ACHRECV: Receives and validates an incoming NACHA-format ACH file from the Federal Reserve.
  2. ACHPARSE: Parses entry detail records and routes them by account type (checking vs. savings).
  3. ACHPOST: Posts ACH credits and debits to the account master file with full validation.
  4. ACHRETRN: Identifies entries that cannot be posted and generates ACH return records with appropriate return reason codes.
  5. ACHREPT: Generates a comprehensive ACH processing report showing batches processed, entries posted, entries returned, and control total verification.

For each program, provide the main processing logic, key record layouts, and error handling. Provide the complete JCL job stream that executes all five programs in sequence.

Hint: Use a status file between steps to communicate which entries were successfully posted and which need to be returned. The return file must conform to the NACHA format with appropriate return reason codes.