Workshop - Understanding Bank Financial Statements
AFIN8003 Workshop
What bank accounting will get you
Understanding bank accounting is fundamental for anyone interested in finance, banking, or risk management. Banks play a unique role in the financial system, and their accounting practices differ significantly from those of non-financial firms. Through this workshop, you will:
- Gain practical insights into how banks record and report financial transactions.
- Learn how various banking activities impact the balance sheet and financial health of a bank.
- Build a strong foundation for more advanced topics in banking, regulation, and risk management.
This workshop is based on the BRMS (Bank Risk Management Simulation) Python package, which I developed for teaching and research in banking.
Real-world example
CBAβs balance sheet and income statement
Letβs see the statements of an Australian bank, Commonwealth Bank of Australia (CBA), as an example. Its financial results are publicly available at its website. However, to make our lives a bit easier, pre-compiled data are available on iLearn.
- Visit AFIN8003 course page on iLearn.
- Under Week 1, find and download the Excel spreadsheet
SPGlobal_CBA_BalanceSheet.xlsxandSPGlobal_CBA_IncomeStatement.xlsx.
Now, use the provided data and your own research, try to answer the following questions. Unless specified otherwise, use the bankβs latest data.
Some (motivating) questions
Looking at a bankβs balance sheet, what do you think a bank actually does as a business?
Why are customer deposits recorded as liabilities rather than as income?
When a bank makes a loan and holds it, what do you think happens in its accounting records and financial statements?
Simple banking book accounting
A first look at bankβs balance sheet
To begin with, a simple bank has just been established with shareholdersβ contribution of $10,000.
A new bank has just been established.
import datetime
from brms.accounting.account import AccountBalances
from brms.accounting.report import Report
from brms.accounting.statement_viewer import HTMLStatementViewer
from brms.models.bank import Bank
bank = Bank()
balances = AccountBalances(
{
bank.chart_of_accounts.cash_account: 10_000,
bank.chart_of_accounts.equity_account: 10_000,
},
)
bank.initialize(balances)
viewer = HTMLStatementViewer(jupyter=True, hide_zero_balance_accounts=True)
today = datetime.date(2026, 8, 6)
report = Report(ledger=bank.ledger, viewer=viewer, date=today)
report.print_balance_sheet()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $10,000.00 Total assets $10,000.00 ββββββββββββββββββββββββββββββββββββββββββββ Liabilities Total liabilities $0.00 ββββββββββββββββββββββββββββββββββββββββββββ Net assets $10,000.00 ββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Total shareholders' equity $10,000.00 ββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-08-06
Customer deposit
Now some customers have made some deposits, for example:
- Customer A deposits $60,000.
- Customer B deposits $40,000.
- Customer C deposits $20,000.
Notably, customer deposits are the bankβs liability. We see an increase in both the bankβs total assets and total liabilities, while total shareholdersβ equity remains unchanged.
Some customers have made deposits.
from brms.instruments.factory import InstrumentFactory
from brms.models.transaction import TransactionFactory, TransactionType
customer_A_deposit = InstrumentFactory.create_deposit(value=60_000)
customer_B_deposit = InstrumentFactory.create_deposit(value=40_000)
customer_C_deposit = InstrumentFactory.create_deposit(value=20_000)
tx_deposit1 = TransactionFactory.create_transaction(
bank=bank,
transaction_type=TransactionType.DEPOSIT_RECEIVED,
instrument=customer_A_deposit,
transaction_date=today,
description="Customer A's Deposits",
)
tx_deposit2 = TransactionFactory.create_transaction(
bank=bank,
transaction_type=TransactionType.DEPOSIT_RECEIVED,
instrument=customer_B_deposit,
transaction_date=today,
description="Customer B's Deposits",
)
tx_deposit3 = TransactionFactory.create_transaction(
bank=bank,
transaction_type=TransactionType.DEPOSIT_RECEIVED,
instrument=customer_C_deposit,
transaction_date=today,
description="Customer C's Deposits",
)
bank.process_transaction(tx_deposit1)
bank.process_transaction(tx_deposit2)
bank.process_transaction(tx_deposit3)
report = Report(ledger=bank.ledger, viewer=viewer, date=today)
report.print_balance_sheet()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $130,000.00 Total assets $130,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Liabilities Deposits and Other Public Borrowings $120,000.00 Deposits $120,000.00 Total liabilities $120,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Net assets $10,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Total shareholders' equity $10,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-08-06
Deposit withdraw
Depositors can also withdraw from the bank.
If Customer C has withdrawn all of their deposits ($20,000), we see a decrease of cash and deposits.
Customer C has withdrawn their deposits.
from brms.models.transaction import DepositWithdrawTransaction
tx_deposit_withdraw = TransactionFactory.create_transaction(
bank=bank,
transaction_type=TransactionType.DEPOSIT_WITHDRAWAL,
instrument=customer_C_deposit,
transaction_date=today,
description="Customer C withdraw",
)
bank.process_transaction(tx_deposit_withdraw)
report = Report(ledger=bank.ledger, viewer=viewer, date=today)
report.print_balance_sheet()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $110,000.00 Total assets $110,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Liabilities Deposits and Other Public Borrowings $100,000.00 Deposits $100,000.00 Total liabilities $100,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Net assets $10,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Total shareholders' equity $10,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-08-06
Loan disbursement
Of course, the typical business of a bank is to make loans. Letβs assume the bank has made an (interest-only) loan of $80,000 to some borrowers.
The bank has made some loans.
from brms.instruments.base import Instrument
from brms.instruments.mock import MockInstrument
from brms.models.transaction import LoanDisbursementTransaction
(loan := MockInstrument("A loan")).value = 80_000
# fmt: off
tx_loan = TransactionFactory.create_transaction(
bank=bank,
transaction_type=TransactionType.LOAN_DISBURSEMENT,
instrument=loan,
transaction_date=today,
description="Loan made to a borrower",
)
# fmt: on
bank.process_transaction(tx_loan)
report = Report(ledger=bank.ledger, viewer=viewer, date=today)
report.print_balance_sheet()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $30,000.00 Loans and Advances $80,000.00 Total assets $110,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Liabilities Deposits and Other Public Borrowings $100,000.00 Deposits $100,000.00 Total liabilities $100,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Net assets $10,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Total shareholders' equity $10,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-08-06
Interest paid on deposits
After some time (e.g., a month), the bank may need to pay interest on customersβ deposits, e.g., $100.
Income Statement is included given that weβd like to know the profit and loss (P&L) of the bank over the period.
If the bank has only paid interest on deposits over the monthβ¦
from brms.instruments.cash import Cash
from brms.models.transaction import InterestPaidOnDepositTransaction
today = today + datetime.timedelta(days=31)
tx_interest_paid = TransactionFactory.create_transaction(
bank=bank,
transaction_type=TransactionType.INTEREST_PAID_ON_DEPOSIT,
instrument=Cash(value=100),
transaction_date=today,
description="Interest paid on deposits",
)
bank.process_transaction(tx_interest_paid)
report = Report(ledger=bank.ledger, viewer=viewer, date=today)
report.print_balance_sheet()
report.print_income_statement()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $29,900.00 Loans and Advances $80,000.00 Total assets $109,900.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Liabilities Deposits and Other Public Borrowings $100,000.00 Deposits $100,000.00 Total liabilities $100,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Net assets $9,900.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Retained Earnings ($100.00) Total shareholders' equity $9,900.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-06
Income Statement ββββββββββββββββββββββββββββββββββ Income $0.00 ββββββββββββββββββββββββββββββββββ Expense $100.00 Interest Expense $100.00 ββββββββββββββββββββββββββββββββββ Profit ($100.00) ββββββββββββββββββββββββββββββββββ Date: 2026-09-06
Loan interest income
If the bank has only paid interest on deposits over this period, it surely has a net loss or negative profit as shown before.
However, it is more reasonable that the bank also has earned some profits during the same time, especially because it has made some loans.
Suppose that over the 1-month period, the bank has earned some interest income from the loans made earlier, e.g., for a total of $800.
Overall, the bank has a net profit of $700. We can observe that the bankβs Retained Earnings has increased by $700, too.
β¦ if it has also earned interest from loans over the month.
tx_interest_earned = TransactionFactory.create_transaction(
bank=bank,
transaction_type=TransactionType.LOAN_INTEREST_PAYMENT,
instrument=Cash(value=800),
transaction_date=today,
description="Interest earned from loans",
)
bank.process_transaction(tx_interest_earned)
report = Report(ledger=bank.ledger, viewer=viewer, date=today)
report.print_balance_sheet()
report.print_income_statement()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $30,700.00 Loans and Advances $80,000.00 Total assets $110,700.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Liabilities Deposits and Other Public Borrowings $100,000.00 Deposits $100,000.00 Total liabilities $100,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Net assets $10,700.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Retained Earnings $700.00 Total shareholders' equity $10,700.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-06
Income Statement ββββββββββββββββββββββββββββββββ Income $800.00 Interest Income $800.00 ββββββββββββββββββββββββββββββββ Expense $100.00 Interest Expense $100.00 ββββββββββββββββββββββββββββββββ Profit $700.00 ββββββββββββββββββββββββββββββββ Date: 2026-09-06
Intermediate trading book accounting
Trading Book
The transactions and non-transactions previous discussed all occur to the bankβs banking book.
However, a bank also has a trading book that holds securities for short-term trading P&L purposes.
These instruments are named Fair Value Through Profit and Loss (FVTPL).
Accounting for trading book securities is relatively easy. We consider:
- The purchase
- The marking-to-market
- The sale
FVTPL security purchase
Assume that the bank just purchased a FVTPL security for its trading book at its fair value of $10,000.
The fair value of the security is recorded on the balance sheet under the Assets at FVTPL account.
Before purchasing some FVTPL securities.
report1 = Report(ledger=bank.ledger, viewer=viewer, date=today)
report1.print_balance_sheet()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $30,700.00 Loans and Advances $80,000.00 Total assets $110,700.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Liabilities Deposits and Other Public Borrowings $100,000.00 Deposits $100,000.00 Total liabilities $100,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Net assets $10,700.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Retained Earnings $700.00 Total shareholders' equity $10,700.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-06
The bank has purchased some FVTPL securities.
from brms.models.base import BookType
fvtpl_security = MockInstrument("A FVTPL Security", BookType.TRADING_BOOK)
fvtpl_security.value = fvtpl_security_value
tx_fvtpl_purchase = TransactionFactory.create_transaction(
bank=bank,
transaction_type=TransactionType.SECURITY_PURCHASE_TRADING,
instrument=fvtpl_security,
transaction_date=today,
description="Purchase a FVTPL security",
)
bank.process_transaction(tx_fvtpl_purchase)
report2 = Report(ledger=bank.ledger, viewer=viewer, date=today)
report2.print_balance_sheet()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $20,700.00 Loans and Advances $80,000.00 Assets at FVTPL $10,000.00 Total assets $110,700.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Liabilities Deposits and Other Public Borrowings $100,000.00 Deposits $100,000.00 Total liabilities $100,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Net assets $10,700.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Retained Earnings $700.00 Total shareholders' equity $10,700.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-06
FVTPL security marking to market
- The fair value of FVTPL security is marked to market periodically, e.g., daily.
- This ensures consistency in that they are held for trading P&L in the first place.
There are two possible cases:
- Unrealized trading loss
- Unrealized trading gain
These trading gains and losses are unrealized because the securities have not yet been sold.
Unrealized trading loss - Income Statement
If the market value of the security went down by 5% ($500.0) the next day, we need to recognize this unrealized trading loss in the Income Statement.
The Income Statement before.
report2.print_income_statement()Income Statement ββββββββββββββββββββββββββββββββ Income $800.00 Interest Income $800.00 ββββββββββββββββββββββββββββββββ Expense $100.00 Interest Expense $100.00 ββββββββββββββββββββββββββββββββ Profit $700.00 ββββββββββββββββββββββββββββββββ Date: 2026-09-06
The FVTPL security has an unrealized trading loss.
from brms.instruments.mock import MockValuationVisitor
today = today + datetime.timedelta(days=1)
# Assume that the market value of the FVTPL security went down by 5%
new_fvtpl_instrument_value = fvtpl_security.value * 0.95
valuation_visitor = MockValuationVisitor(new_value=new_fvtpl_instrument_value)
tx_fvtpl_marked_down = TransactionFactory.create_transaction(
bank=bank,
transaction_type=TransactionType.SECURITY_FVTPL_MARK_TO_MARKET,
instrument=fvtpl_security,
transaction_date=today,
valuation_visitor=valuation_visitor,
description="Mark to market a FVTPL security (down)",
)
bank.process_transaction(tx_fvtpl_marked_down)
report3 = Report(ledger=bank.ledger, viewer=viewer, date=today)
report3.print_income_statement()Income Statement βββββββββββββββββββββββββββββββββββββββββββββ Income $300.00 Interest Income $800.00 Trading Income (FVTPL) ($500.00) Unrealized Trading Loss $500.00 βββββββββββββββββββββββββββββββββββββββββββββ Expense $100.00 Interest Expense $100.00 βββββββββββββββββββββββββββββββββββββββββββββ Profit $200.00 βββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-07
Unrealized trading loss - Balance Sheet
If we were to generate the balance sheet now, such net trading loss would reduce the bankβs retained earnings.
The Balance Sheet before.
report2.print_balance_sheet()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $20,700.00 Loans and Advances $80,000.00 Assets at FVTPL $10,000.00 Total assets $110,700.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Liabilities Deposits and Other Public Borrowings $100,000.00 Deposits $100,000.00 Total liabilities $100,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Net assets $10,700.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Retained Earnings $700.00 Total shareholders' equity $10,700.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-06
The FVTPL security has an unrealized trading loss.
report3.print_balance_sheet()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $20,700.00 Loans and Advances $80,000.00 Assets at FVTPL $9,500.00 Total assets $110,200.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Liabilities Deposits and Other Public Borrowings $100,000.00 Deposits $100,000.00 Total liabilities $100,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Net assets $10,200.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Retained Earnings $200.00 Total shareholders' equity $10,200.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-07
Usually, financial reports are generated at a periodβs end, such as quarterβs end or yearβs end. Whatβs shown here should be viewed as what if we close the bankβs accounting ledger at this time and generate the reports?
Unrealized trading gain - Income Statement
The day after, if the market value of the security went up by 10% ($950.0), we need to recognize this unrealized trading gain.
The Income Statement before.
report3.print_income_statement()Income Statement βββββββββββββββββββββββββββββββββββββββββββββ Income $300.00 Interest Income $800.00 Trading Income (FVTPL) ($500.00) Unrealized Trading Loss $500.00 βββββββββββββββββββββββββββββββββββββββββββββ Expense $100.00 Interest Expense $100.00 βββββββββββββββββββββββββββββββββββββββββββββ Profit $200.00 βββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-07
The FVTPL security has an unrealized trading gain.
today = today + datetime.timedelta(days=1)
# Assume that the market value of the FVTPL security went up by 10%
new_fvtpl_instrument_value = fvtpl_security.value * (1 + day2_pct_change / 100)
valuation_visitor = MockValuationVisitor(new_value=new_fvtpl_instrument_value)
tx_fvtpl_marked_up = TransactionFactory.create_transaction(
bank=bank,
transaction_type=TransactionType.SECURITY_FVTPL_MARK_TO_MARKET,
instrument=fvtpl_security,
transaction_date=today,
valuation_visitor=valuation_visitor,
description="Mark to market a FVTPL security (up)",
)
bank.process_transaction(tx_fvtpl_marked_up)
report4 = Report(ledger=bank.ledger, viewer=viewer, date=today)
report4.print_income_statement()Income Statement βββββββββββββββββββββββββββββββββββββββββββββ Income $1,250.00 Interest Income $800.00 Trading Income (FVTPL) $450.00 Unrealized Trading Gain $950.00 Unrealized Trading Loss $500.00 βββββββββββββββββββββββββββββββββββββββββββββ Expense $100.00 Interest Expense $100.00 βββββββββββββββββββββββββββββββββββββββββββββ Profit $1,150.00 βββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-08
Unrealized trading gain - Balance Sheet
Again, if we were to close the bankβs accounting ledger now and check its balance sheet, we will see changes of the bankβs retained earnings (increase by $950.0).
The Balance Sheet before.
report3.print_balance_sheet()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $20,700.00 Loans and Advances $80,000.00 Assets at FVTPL $9,500.00 Total assets $110,200.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Liabilities Deposits and Other Public Borrowings $100,000.00 Deposits $100,000.00 Total liabilities $100,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Net assets $10,200.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Retained Earnings $200.00 Total shareholders' equity $10,200.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-07
The FVTPL security has an unrealized trading gain.
report4.print_balance_sheet()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $20,700.00 Loans and Advances $80,000.00 Assets at FVTPL $10,450.00 Total assets $111,150.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Liabilities Deposits and Other Public Borrowings $100,000.00 Deposits $100,000.00 Total liabilities $100,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Net assets $11,150.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Retained Earnings $1,150.00 Total shareholders' equity $11,150.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-08
FVTPL security sale
The next day, if the bank sold the security at the prevailing market price (assumed 2% up), we recognize realized trading gain.
Tracking the P&L of this particular FVTPL security,
- On day 1, we had a loss of $500.0 ($10000 * 95% = $9500.0).
- On day 2, we had a gain of $950.0 ($9500.0 * 110% = $10450.0).
- On day 3, we had a gain of $209.0 ($10450.0 * 102% = $10659.0).
The total P&L from this security is therefore a net gain of $659.0, which shows up in the Income Statement.
Because of the sale, the unrealized trading gain/loss associated with this security must be reclassified to realized gain/loss.
FVTPL security sale - Income Statement
The Income Statement before.
report4.print_income_statement()Income Statement βββββββββββββββββββββββββββββββββββββββββββββ Income $1,250.00 Interest Income $800.00 Trading Income (FVTPL) $450.00 Unrealized Trading Gain $950.00 Unrealized Trading Loss $500.00 βββββββββββββββββββββββββββββββββββββββββββββ Expense $100.00 Interest Expense $100.00 βββββββββββββββββββββββββββββββββββββββββββββ Profit $1,150.00 βββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-08
The FVTPL security is sold.
today = today + datetime.timedelta(days=1)
# Assume that the market value of the FVTPL security went up by 2%
new_fvtpl_instrument_value = fvtpl_security.value * (1 + day3_pct_change / 100)
valuation_visitor = MockValuationVisitor(new_value=new_fvtpl_instrument_value)
tx_fvtpl_marked_up = TransactionFactory.create_transaction(
bank=bank,
transaction_type=TransactionType.SECURITY_FVTPL_MARK_TO_MARKET,
instrument=fvtpl_security,
transaction_date=today,
valuation_visitor=valuation_visitor,
description="Mark to market a FVTPL security (up)",
)
bank.process_transaction(tx_fvtpl_marked_up)
# Sale transaction should be created after the previous transaction has been processed
tx_fvtpl_sale = TransactionFactory.create_transaction(
bank=bank,
transaction_type=TransactionType.SECURITY_SALE_TRADING,
instrument=fvtpl_security,
transaction_date=today,
valuation_visitor=valuation_visitor,
description="Sale of FVTPL security (net gain)",
)
bank.process_transaction(tx_fvtpl_sale)
# fmt: on
report5 = Report(ledger=bank.ledger, viewer=viewer, date=today)
report5.print_income_statement()
# report.print_balance_sheet()Income Statement βββββββββββββββββββββββββββββββββββββββββββ Income $1,459.00 Interest Income $800.00 Trading Income (FVTPL) $659.00 Realized Trading Gain $1,159.00 Realized Trading Loss $500.00 βββββββββββββββββββββββββββββββββββββββββββ Expense $100.00 Interest Expense $100.00 βββββββββββββββββββββββββββββββββββββββββββ Profit $1,359.00 βββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-09
- Trading gain: $209.0 + $950.0 = $1159.0
- Trading loss: $500.0
- Net gain: $659.0
- Gain/loss reclassified from unrealized to realized
FVTPL security sale - Balance Sheet
Now, if we were to close the bankβs accounting ledger and produce its balance sheet, we will have:
The Balance Sheet before.
report4.print_balance_sheet()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $20,700.00 Loans and Advances $80,000.00 Assets at FVTPL $10,450.00 Total assets $111,150.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Liabilities Deposits and Other Public Borrowings $100,000.00 Deposits $100,000.00 Total liabilities $100,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Net assets $11,150.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Retained Earnings $1,150.00 Total shareholders' equity $11,150.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-08
The FVTPL security has been sold with a net gain.
report5.print_balance_sheet()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $31,359.00 Loans and Advances $80,000.00 Total assets $111,359.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Liabilities Deposits and Other Public Borrowings $100,000.00 Deposits $100,000.00 Total liabilities $100,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Net assets $11,359.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Retained Earnings $1,359.00 Total shareholders' equity $11,359.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-09
FVTPL security sale - Balance Sheet
Compared to the balance sheet before the bank purchased this FVTPL security, the retained earnings increased by exactly $659.0.
The Balance Sheet before purchasing the FVTPL security.
report1.print_balance_sheet()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $30,700.00 Loans and Advances $80,000.00 Total assets $110,700.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Liabilities Deposits and Other Public Borrowings $100,000.00 Deposits $100,000.00 Total liabilities $100,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Net assets $10,700.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Retained Earnings $700.00 Total shareholders' equity $10,700.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-06
After selling the FVTPL security with a net gain.
report5.print_balance_sheet()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $31,359.00 Loans and Advances $80,000.00 Total assets $111,359.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Liabilities Deposits and Other Public Borrowings $100,000.00 Deposits $100,000.00 Total liabilities $100,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Net assets $11,359.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Retained Earnings $1,359.00 Total shareholders' equity $11,359.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-09
Intermediate banking book accounting
Banking book
Apart from loans, a bankβs banking book contains other assets that are held mostly for interest income. However, depending on whether the bank intends to hold them until maturity, these non-loan banking book assets can be either of:
- Fair Value Through Other Comprehensive Income (FVOCI),
- At Amortized Cost or Held to Maturity (HTM).1
For example, Treasury bonds, corporate bonds, MBS, etc., are usually FVOCI or HTM banking book assets.
FVOCI security
FVOCI assets in the banking book are typically debt securities that:
- Earn interest income for the bank.
- Can be sold before maturity but are not actively traded like FVTPL securities.
- Experience fair value changes that are recorded in Accumulated Other Comprehensive Income (AOCI) instead of directly impacting net income.
- Upon sale, unrealized gains/losses from AOCI are transferred to Net Income.
FVOCI security purchase
Assume that the bank now purchased a Treasury bond at a fair value of $30,000. The bank may sell the bond before it matures, and hence classify it as a FVOCI asset on the banking book.
The Balance Sheet before purchasing the FVOCI security.
report5.print_balance_sheet()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $31,359.00 Loans and Advances $80,000.00 Total assets $111,359.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Liabilities Deposits and Other Public Borrowings $100,000.00 Deposits $100,000.00 Total liabilities $100,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Net assets $11,359.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Retained Earnings $1,359.00 Total shareholders' equity $11,359.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-09
The bank has purchased some FVOCI securities.
fvoci_security = MockInstrument("A Treasury bond (FVOCI)", BookType.BANKING_BOOK)
fvoci_security.value = 30_000
tx_fvoci_purchase = TransactionFactory.create_transaction(
bank=bank,
transaction_type=TransactionType.SECURITY_PURCHASE_FVOCI,
instrument=fvoci_security,
transaction_date=today,
description="Purchase a FVOCI security",
)
bank.process_transaction(tx_fvoci_purchase)
report6 = Report(ledger=bank.ledger, viewer=viewer, date=today)
report6.print_balance_sheet()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $1,359.00 Loans and Advances $80,000.00 Investment Securities $30,000.00 Investment Securities at FVOCI $30,000.00 Total assets $111,359.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Liabilities Deposits and Other Public Borrowings $100,000.00 Deposits $100,000.00 Total liabilities $100,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Net assets $11,359.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Retained Earnings $1,359.00 Total shareholders' equity $11,359.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-09
The fair value of the security is recorded on the balance sheet under the Investment Securities at FVOCI account.
FVOCI security marking to market
- The fair value of FVOCI security is marked to market periodically, e.g., daily.
- This is because such securities do have market values (e.g., Treasury securities).
There are two possible cases:
- Unrealized loss
- Unrealized gain
These gains and losses are unrealized because the securities have not yet been sold.
These gains and losses are not through trading.
Unrealized gain
Suppose the next day the market value of the FVOCI security went up by 2% ($600 = $30,000 Γ 2%).
It is important to note that FVOCI securityβs fair value changes affect AOCI, an equity account.
It does not affect Income Statement P&L until itβs eventually sold.
The Balance Sheet before.
report6.print_balance_sheet()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $1,359.00 Loans and Advances $80,000.00 Investment Securities $30,000.00 Investment Securities at FVOCI $30,000.00 Total assets $111,359.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Liabilities Deposits and Other Public Borrowings $100,000.00 Deposits $100,000.00 Total liabilities $100,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Net assets $11,359.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Retained Earnings $1,359.00 Total shareholders' equity $11,359.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-09
The FVOCI security has an unrealized gain.
today = today + datetime.timedelta(days=1)
# Assume that the market value of the FVOCI security went up by 2%
new_fvoci_instrument_value = fvoci_security.value * 1.02
valuation_visitor = MockValuationVisitor(new_value=new_fvoci_instrument_value)
tx_fvoci_marked_up = TransactionFactory.create_transaction(
bank=bank,
transaction_type=TransactionType.SECURITY_FVOCI_MARK_TO_MARKET,
instrument=fvoci_security,
transaction_date=today,
valuation_visitor=valuation_visitor,
description="Mark to market a FVOCI security (up)",
)
bank.process_transaction(tx_fvoci_marked_up)
report7 = Report(ledger=bank.ledger, viewer=viewer, date=today)
report7.print_balance_sheet()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $1,359.00 Loans and Advances $80,000.00 Investment Securities $30,600.00 Investment Securities at FVOCI $30,600.00 Total assets $111,959.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Liabilities Deposits and Other Public Borrowings $100,000.00 Deposits $100,000.00 Total liabilities $100,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Net assets $11,959.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Accumulated OCI $600.00 Unrealized OCI Gain $600.00 Retained Earnings $1,359.00 Total shareholders' equity $11,959.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-10
Unrealized loss
If the market value of the security went down by 2% ($612=$30,600*2%) the next day, we recognize this unrealized OCI loss of AOCI.
The Balance Sheet before.
report7.print_balance_sheet()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $1,359.00 Loans and Advances $80,000.00 Investment Securities $30,600.00 Investment Securities at FVOCI $30,600.00 Total assets $111,959.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Liabilities Deposits and Other Public Borrowings $100,000.00 Deposits $100,000.00 Total liabilities $100,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Net assets $11,959.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Accumulated OCI $600.00 Unrealized OCI Gain $600.00 Retained Earnings $1,359.00 Total shareholders' equity $11,959.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-10
The FVOCI security has an unrealized trading loss.
today = today + datetime.timedelta(days=1)
# Assume that the market value of the FVOCI security went down by 2%
new_fvoci_instrument_value = fvoci_security.value * 0.98
valuation_visitor = MockValuationVisitor(new_value=new_fvoci_instrument_value)
tx_fvoci_marked_down = TransactionFactory.create_transaction(
bank=bank,
transaction_type=TransactionType.SECURITY_FVOCI_MARK_TO_MARKET,
instrument=fvoci_security,
transaction_date=today,
valuation_visitor=valuation_visitor,
description="Mark to market a FVOCI security (down)",
)
bank.process_transaction(tx_fvoci_marked_down)
report8 = Report(ledger=bank.ledger, viewer=viewer, date=today)
report8.print_balance_sheet()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $1,359.00 Loans and Advances $80,000.00 Investment Securities $29,988.00 Investment Securities at FVOCI $29,988.00 Total assets $111,347.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Liabilities Deposits and Other Public Borrowings $100,000.00 Deposits $100,000.00 Total liabilities $100,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Net assets $11,347.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Accumulated OCI ($12.00) Unrealized OCI Gain $600.00 Unrealized OCI Loss $612.00 Retained Earnings $1,359.00 Total shareholders' equity $11,347.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-11
FVOCI, AOCI, and capital ratios
Because FVOCIβs (even unrealized) gain/loss changes AOCI, and AOCI is part of a bankβs CET1 capital, FVOCIβs fair value movement can cause volatility in the bankβs regulatory capital ratios.
CET1 is the primary or core capital of a DI.
- Common shares
- Share premium resulting from the issue of CET1 instruments
- Retained earnings
- Accumulated and other comprehensive income (AOCI)
- Other disclosed reserves
- Certain minority interests
- Regulatory adjustment applied in the calculation of CET1 Capital.
In the U.S., banks with total assets below $250 billion are permitted to exclude AOCI when reporting applicable regulatory ratios β the very opt-out that let SVBβs unrealised bond losses stay invisible to its capital ratios.
FVOCI security sale
The next day, if the bank sold the FVOCI security at the prevailing market price (assumed 2% down), we recognize realized OCI loss.
Tracking the AOCI gain/loss of this particular FVOCI security,
- On day 1, we had a gain of $600.
- On day 2, we had a loss of $612.
- On day 3, we had a loss of $599.76.
The total net loss of this security is therefore $611.76.
FVOCI security sale - Income Statement
Now that the FVOCI security is sold, its gain/loss is moved from AOCI to Income Statement as Investment Income (FVOCI).
The Income Statement before
report8.print_income_statement()Income Statement βββββββββββββββββββββββββββββββββββββββββββ Income $1,459.00 Interest Income $800.00 Trading Income (FVTPL) $659.00 Realized Trading Gain $1,159.00 Realized Trading Loss $500.00 βββββββββββββββββββββββββββββββββββββββββββ Expense $100.00 Interest Expense $100.00 βββββββββββββββββββββββββββββββββββββββββββ Profit $1,359.00 βββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-11
The FVOCI security is sold with a net loss.
from brms.models.transaction import SecuritySaleFVOCITransaction
today = today + datetime.timedelta(days=1)
# Assume that the market value of the FVOCI security went down by 2%
new_fvoci_instrument_value = fvoci_security.value * 0.98
valuation_visitor = MockValuationVisitor(new_value=new_fvoci_instrument_value)
tx_fvoci_marked_down = TransactionFactory.create_transaction(
bank=bank,
transaction_type=TransactionType.SECURITY_FVOCI_MARK_TO_MARKET,
instrument=fvoci_security,
transaction_date=today,
valuation_visitor=valuation_visitor,
description="Mark to market a FVOCI security (down)",
)
bank.process_transaction(tx_fvoci_marked_down)
# Sale transaction should be created after the previous transaction has been processed
tx_fvoci_sale = TransactionFactory.create_transaction(
bank=bank,
transaction_type=TransactionType.SECURITY_SALE_FVOCI,
instrument=fvoci_security,
transaction_date=today,
description="Sale of FVOCI security (net loss)",
)
bank.process_transaction(tx_fvoci_sale)
report9 = Report(ledger=bank.ledger, viewer=viewer, date=today)
report9.print_income_statement()Income Statement βββββββββββββββββββββββββββββββββββββββββββ Income $847.24 Interest Income $800.00 Trading Income (FVTPL) $659.00 Realized Trading Gain $1,159.00 Realized Trading Loss $500.00 Investment Income (FVOCI) ($611.76) Realized OCI Gain $600.00 Realized OCI Loss $1,211.76 βββββββββββββββββββββββββββββββββββββββββββ Expense $100.00 Interest Expense $100.00 βββββββββββββββββββββββββββββββββββββββββββ Profit $747.24 βββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-12
FVOCI security sale - Balance Sheet
When P&L accounts of income statement are closed, the net gain/loss of Investment Income (FVOCI) changes the bankβs retained earnings.
The Balance Sheet before
report8.print_balance_sheet()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $1,359.00 Loans and Advances $80,000.00 Investment Securities $29,988.00 Investment Securities at FVOCI $29,988.00 Total assets $111,347.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Liabilities Deposits and Other Public Borrowings $100,000.00 Deposits $100,000.00 Total liabilities $100,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Net assets $11,347.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Accumulated OCI ($12.00) Unrealized OCI Gain $600.00 Unrealized OCI Loss $612.00 Retained Earnings $1,359.00 Total shareholders' equity $11,347.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-11
The FVOCI security is sold with a net loss.
report9.print_balance_sheet()Balance Sheet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Assets Cash and Cash Equivalents $30,747.24 Loans and Advances $80,000.00 Total assets $110,747.24 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Liabilities Deposits and Other Public Borrowings $100,000.00 Deposits $100,000.00 Total liabilities $100,000.00 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Net assets $10,747.24 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shareholders' equity Shareholders' Equity $10,000.00 Retained Earnings $747.24 Total shareholders' equity $10,747.24 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Date: 2026-09-12
Investment securities at amortized cost
- Measurement
- Initially recorded at fair value plus transaction costs.
- Subsequently measured at amortised cost using the effective interest method.
- Carrying amount = purchase price Β± cumulative amortisation of premium/discount β impairment allowance.
- Income Recognition
- Interest income recognised in profit or loss using the effective interest rate (EIR).
- Amortisation of premiums or discounts included in interest income.
- Gains and Losses
- No recognition of unrealised fair value changes in P&L or OCI.
- Realised gains/losses recognised in P&L only upon sale or derecognition.
- Impairment
- Subject to expected credit loss (ECL) model under IFRS 9/AASB 9.
- ECL recognised in P&L and reduces the carrying amount.
Footnotes
Now called βat amortized costβ under IFRS 9 / AASB 9.β©οΈ