LabHub

Blog

Investment Banking Systems Architecture — From Deal Pipeline to Syndication

한국어English日本語

Introduction

When people talk about banking IT, most material focuses on retail banking — deposits, lending, the core banking ledger. Investment banking (IB) systems look completely different. Instead of millions of accounts, you handle dozens of deals; instead of thousands of transactions per second, you handle workflows that span months. Transaction volume is tiny, but a single deal can be worth hundreds of millions to billions of dollars, and material non-public information (MNPI) flows through these systems — so the cost of a control failure is enormous.

This article is for engineers who are designing or maintaining IB division systems for the first time. It assembles the business domain map, the deal lifecycle, conflict checks, the technical implementation of Chinese walls (information barriers), bookbuilding, syndicated loan administration, document management, and regulatory reporting into a single picture. We also cover the Korean capital markets context (the Financial Investment Services and Capital Markets Act and related regulations).

Note that this article is a technical resource from a systems design perspective. It is not investment or legal advice. Always confirm regulatory matters with your compliance department.

The IB Business Domain Map

The IB division can be divided into five broad domains.

+---------------------------------------------------------------+
|                     Investment Banking Division                |
|                                                               |
|  +-----------+  +-----------+  +-----------+                  |
|  |   ECM     |  |   DCM     |  |   M&A     |                  |
|  | Equity    |  | Debt      |  | Advisory  |                  |
|  | Capital   |  | Capital   |  | buy-side/ |                  |
|  | Markets:  |  | Markets:  |  | sell-side |                  |
|  | IPO/FO/CB |  | bonds/ABS |  | fairness  |                  |
|  +-----------+  +-----------+  +-----------+                  |
|                                                               |
|  +------------------+  +---------------------------+          |
|  | Acquisition      |  | Loan Syndication          |          |
|  | Finance          |  | (arranging/participation) |          |
|  | LBO/bridge loans |  | Arranger / Agent bank     |          |
|  +------------------+  +---------------------------+          |
|                                                               |
|  Shared infra: deal pipeline / conflict check / Chinese wall   |
|               document mgmt / insider lists / reg reporting    |
|               / CRM                                            |
+---------------------------------------------------------------+

Comparing the system requirements of each domain:

DomainKey deliverablesCore system capabilitiesLifecycle length
ECMIPOs, follow-ons, convertiblesBookbuilding, demand forecasting, allocation3 to 12 months
DCMCorporate bonds, ABS, MTN programsIssuance calendar, pricing, demand capture1 to 6 months
M&ABuy/sell-side advisory, valuationDeal room (VDR), document management, conflict checks6 to 18 months
Acquisition financeLBO loans, bridge loansLimit/exposure management, credit approval workflow3 to 9 months
SyndicationSyndicated loan arrangementParticipant management, fee distribution, agency functionsYears, to loan maturity

The biggest difference from retail is that everything revolves around the deal. The first-class object in the system is not the account but the deal, and teams, documents, approvals, and information access rights all hang off it.

The Deal Lifecycle and Pipeline Management

A deal typically passes through these phases.

[Origination]      [Execution]                    [Closing]      [Post-Close]
     |                  |                             |               |
 idea/pitch  -->  mandate won --> due diligence --> marketing/   --> pricing
     |             |                |              bookbuilding      |
     v             v                v                 |              v
 conflict check  engagement      deal room open    insider list   allocation,
 (pre-screening) letter signed   (VDR/documents)   expanded       settlement,
                                                                  fee billing
                                                                     |
                                                                     v
                                                          post-close / league tables

The core requirements of a deal pipeline management system:

Enforcing stage transitions in code matters. Manage the pipeline in spreadsheets and you will, without fail, end up with deals that bypassed the conflict check.

Conflict Checks — Block It Before You Take the Deal

A conflict check verifies, before accepting a new mandate, that it does not conflict with existing deals and client relationships. For example, if you are pitching to advise on the sale of Company A while already advising Company B on acquiring Company A, you cannot take both sides.

From a systems perspective, the conflict check is a gate in the deal creation workflow.

-- The core conflict query: detect active deals that touch
-- the same or related target companies
SELECT d.deal_id,
       d.deal_type,
       d.stage,
       c.company_name,
       r.relation_type        -- TARGET / ACQUIRER / ISSUER / SPONSOR
FROM   deal d
JOIN   deal_company_rel r ON r.deal_id = d.deal_id
JOIN   company c          ON c.company_id = r.company_id
WHERE  d.stage NOT IN ('CLOSED', 'DEAD')
AND    c.company_group_id IN (
         -- expand to the corporate group of the new target
         SELECT company_group_id FROM company
         WHERE  company_id = :new_deal_target_id
       );

Practical points:

Implementing the Chinese Wall in Systems

The Chinese wall is the control that blocks information flow between the IB division (the private side, which holds MNPI) and research or sales and trading (the public side). In Korea, information barrier requirements are mandated under the Capital Markets Act conflict-of-interest provisions. Technically it is implemented in three layers.

Layer 1 — Entitlements (access control)

Deal information is deny-all by default and opens only through deal team membership.

# Example deal-level access policy (policy engine input)
policy:
  resource: deal/PRJ-FALCON
  default: deny
  rules:
    - effect: allow
      subjects:
        - group: deal-team/PRJ-FALCON        # deal team members
        - group: compliance-surveillance      # compliance (standing access)
      actions: [read, write]
    - effect: allow
      subjects:
        - group: ib-management                # division management
      actions: [read-summary]                 # summary only, no documents
    - effect: deny
      subjects:
        - group: research                     # research explicitly blocked
        - group: sales-trading
      actions: [read, write, read-summary]
      override: true                          # takes precedence over allow

Key design principles:

Layer 2 — Watermarking

Deal documents must be traceable to their source if leaked. Apply per-user dynamic watermarks at view or download time.

# Applying a dynamic watermark at document view time (conceptual)
from pypdf import PdfReader, PdfWriter
from reportlab.pdfgen import canvas
from io import BytesIO
import datetime

def apply_watermark(src_pdf: bytes, user_id: str, deal_code: str) -> bytes:
    stamp_buf = BytesIO()
    c = canvas.Canvas(stamp_buf)
    text = f"{deal_code} / {user_id} / {datetime.datetime.utcnow().isoformat()}"
    c.setFont("Helvetica", 7)
    c.setFillColorRGB(0.6, 0.6, 0.6, alpha=0.4)
    # repeated diagonal watermark
    c.saveState()
    c.translate(300, 400)
    c.rotate(45)
    for y in range(-400, 400, 60):
        c.drawString(-250, y, text)
    c.restoreState()
    c.save()
    stamp_buf.seek(0)

    stamp = PdfReader(stamp_buf).pages[0]
    reader = PdfReader(BytesIO(src_pdf))
    writer = PdfWriter()
    for page in reader.pages:
        page.merge_page(stamp)
        writer.add_page(page)
    out = BytesIO()
    writer.write(out)
    return out.getvalue()

Some institutions combine visible watermarks with invisible ones based on metadata or steganography. What matters is that every watermarking event is tied back to the access log.

Layer 3 — Logging and surveillance

MNPI Management and Insider Lists

An insider list is the register of people who accessed MNPI for a specific deal. The EU Market Abuse Regulation explicitly obliges issuers and advisers to maintain insider lists, and Korean firms operate equivalent controls to address the insider trading provisions of the Capital Markets Act (Article 174).

CREATE TABLE insider_list_entry (
    entry_id        BIGINT PRIMARY KEY,
    deal_id         BIGINT NOT NULL REFERENCES deal(deal_id),
    person_id       BIGINT NOT NULL REFERENCES person(person_id),
    reason          VARCHAR(200) NOT NULL,   -- registration reason (team, wall cross, external adviser)
    obtained_at     TIMESTAMP NOT NULL,      -- when MNPI access began
    notified_at     TIMESTAMP,               -- when the person was formally notified
    removed_at      TIMESTAMP,               -- when removed from the list
    removed_reason  VARCHAR(200),
    created_by      VARCHAR(50) NOT NULL,
    created_at      TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

-- Insider lists must preserve correction history, so no UPDATEs:
-- changes are handled as new rows plus invalidation of prior rows
-- (bitemporal pattern)
CREATE INDEX idx_insider_deal ON insider_list_entry (deal_id, obtained_at);
CREATE INDEX idx_insider_person ON insider_list_entry (person_id, obtained_at);

Operational points:

The Bookbuilding System — Demand Capture and Allocation

The highlight of ECM/DCM deals is bookbuilding. You collect demand (price, quantity) from institutional investors, construct the demand curve, set the issue price, and allocate the offering. In Korean IPOs, the institutional demand forecast process is governed by Korea Financial Investment Association rules.

The core models of a bookbuilding system are the order and the allocation.

# Simplified allocation engine (conceptual)
# Real allocation combines qualitative review (anchor investors,
# long-term holding profile); this shows only the pro-rata skeleton.
from dataclasses import dataclass

@dataclass
class Order:
    investor_id: str
    quantity: int          # requested quantity
    limit_price: int       # limit price; market orders treated as top of range
    investor_grade: str    # internal grade: ANCHOR / LONG_ONLY / HEDGE / RETAIL_INST

GRADE_WEIGHT = {"ANCHOR": 1.5, "LONG_ONLY": 1.2, "HEDGE": 0.8, "RETAIL_INST": 1.0}

def build_demand_curve(orders, price_grid):
    """Cumulative demand per price level: sum of orders at or above the price"""
    return {
        p: sum(o.quantity for o in orders if o.limit_price >= p)
        for p in price_grid
    }

def allocate(orders, final_price, total_shares):
    eligible = [o for o in orders if o.limit_price >= final_price]
    weighted = sum(o.quantity * GRADE_WEIGHT[o.investor_grade] for o in eligible)
    allocations = {}
    remaining = total_shares
    for o in sorted(eligible, key=lambda x: GRADE_WEIGHT[x.investor_grade], reverse=True):
        share = int(total_shares * o.quantity * GRADE_WEIGHT[o.investor_grade] / weighted)
        share = min(share, o.quantity, remaining)
        allocations[o.investor_id] = share
        remaining -= share
    # leftover shares get redistributed under explicit rounding rules (omitted)
    return allocations, remaining

What matters in the system design:

Syndicated Loan Administration — A Multi-Year Operations System

A syndicated loan is a structure where multiple financial institutions jointly lend to one borrower. The arranger organizes the deal, and the agent bank handles interest calculation, principal and interest distribution, and notices between borrower and participants for the life of the loan. LMA (Europe) and LSTA (US) standard documentation are the de facto industry standards.

The core data the system must manage:

AreaContent
Facility structureTranches such as Term Loan A/B, RCF, and their limits
Participant sharesCommitment amounts per institution, assignment history
Drawdowns/repaymentsDrawdown requests, interest periods, repayment schedules
Interest and feesBase rate plus margin, commitment fees, arrangement fees, agency fees
DistributionPro-rata calculation and payment of interest, principal, and fees per participant

A fee distribution calculation example:

# Distribution per participant at end of interest period (conceptual)
from decimal import Decimal, ROUND_HALF_UP

def distribute_interest(total_interest: Decimal, participations: dict) -> dict:
    """participations: {institution_id: outstanding_amount}"""
    total_outstanding = sum(participations.values())
    result = {}
    allocated = Decimal("0")
    items = sorted(participations.items())
    for inst, amount in items[:-1]:
        share = (total_interest * amount / total_outstanding).quantize(
            Decimal("0.01"), rounding=ROUND_HALF_UP)
        result[inst] = share
        allocated += share
    # The last institution absorbs the rounding residue — totals must match
    last_inst = items[-1][0]
    result[last_inst] = total_interest - allocated
    assert sum(result.values()) == total_interest
    return result

The trickiest operational areas:

Acquisition Finance Limits and Exposure Management

Acquisition finance (LBO financing, bridge loans) puts the bank balance sheet directly at risk, so limit management is central.

Exposure aggregation concept:
  Total exposure (corporate group G)
    = sum of drawn balances (all borrowers in the group)
    + sum of undrawn commitments x credit conversion factor (CCF)
    + sum of underwriting positions (unsold portion)
  Limit checks run both at new-deal approval and in the daily batch

Deal Document Management — Versions and Signatures

In M&A and syndication, documents are nearly the entire deliverable. Requirements:

Regulatory Reporting and the Korean Capital Markets Context

In Korea, IB business is governed by the Financial Investment Services and Capital Markets Act and the Financial Investment Business Regulations. From a systems perspective, the reporting and disclosure duties you meet most often include the following (exact requirements vary by timing and institution type — always confirm with compliance):

The design implication is clear. Do not defer regulatory reporting to a separate system later — the deal system data model itself must be report-ready (immutable history, point-in-time queries).

CRM Integration

IB CRM differs from sales CRM. Coverage bankers manage meetings with client executives, pitch history, and deal opportunities. Integration points:

Example Data Model

The relationships among core entities as an ERD:

+--------------+        +-------------------+        +--------------+
|   COMPANY    |        |       DEAL        |        |    PERSON    |
+--------------+        +-------------------+        +--------------+
| company_id PK|---+    | deal_id PK        |    +---| person_id PK |
| group_id     |   |    | code_name UQ      |    |   | dept         |
| lei          |   +--<-| deal_type         |    |   | side (pub/pr)|
| name         |        | stage             |    |   +--------------+
+--------------+        | expected_fee      |    |
       ^                | probability       |    |
       |                +-------------------+    |
       |                  |       |      |       |
+------+--------+         |       |      +-------+----------+
| DEAL_COMPANY_ |---------+       |              |          |
| REL           |        +--------+-----+  +-----+------+  +-+----------+
| (TARGET/      |        | DEAL_DOCUMENT|  | DEAL_TEAM  |  | INSIDER_   |
|  ACQUIRER/    |        +--------------+  +------------+  | LIST_ENTRY |
|  ISSUER...)   |        | doc_id PK    |  | deal_id FK |  +------------+
+---------------+        | deal_id FK   |  | person_id  |  | deal_id FK |
                         | version      |  | role       |  | person_id  |
+---------------+        | status       |  | granted_at |  | obtained_at|
| ORDER (book)  |        | sha256       |  | revoked_at |  | removed_at |
+---------------+        +--------------+  +------------+  +------------+
| order_id PK   |
| deal_id FK    |        +-----------------+   +----------------------+
| investor_id   |        | FACILITY (loan) |   | PARTICIPATION        |
| qty / price   |        +-----------------+   +----------------------+
| superseded_by |        | facility_id PK  |---| facility_id FK       |
+---------------+        | deal_id FK      |   | institution_id       |
                         | tranche_type    |   | commitment_amt       |
+---------------+        | limit_amt       |   | effective_from/to    |
| ALLOCATION    |        | margin_bps      |   +----------------------+
+---------------+        +-----------------+
| order_id FK   |
| alloc_qty     |
| adjusted_by   |
+---------------+

Modeling principles:

Workflow Engine Design

The deal lifecycle, wall crossing, credit approval, and signature tracking are all workflows. Whether you build your own or use an engine (Camunda, Temporal, and so on), the IB domain demands these characteristics.

# Enforcing deal stage transitions with an explicit state machine
from enum import Enum

class Stage(Enum):
    PITCH = "PITCH"
    CONFLICT_CHECK = "CONFLICT_CHECK"
    MANDATED = "MANDATED"
    DUE_DILIGENCE = "DUE_DILIGENCE"
    MARKETING = "MARKETING"
    PRICING = "PRICING"
    CLOSED = "CLOSED"
    DEAD = "DEAD"

TRANSITIONS = {
    Stage.PITCH:          {Stage.CONFLICT_CHECK, Stage.DEAD},
    Stage.CONFLICT_CHECK: {Stage.MANDATED, Stage.DEAD},
    Stage.MANDATED:       {Stage.DUE_DILIGENCE, Stage.DEAD},
    Stage.DUE_DILIGENCE:  {Stage.MARKETING, Stage.DEAD},
    Stage.MARKETING:      {Stage.PRICING, Stage.DEAD},
    Stage.PRICING:        {Stage.CLOSED, Stage.DEAD},
}

REQUIRED_APPROVALS = {
    (Stage.PITCH, Stage.CONFLICT_CHECK): ["team_head"],
    (Stage.CONFLICT_CHECK, Stage.MANDATED): ["compliance", "business_head"],
    (Stage.MARKETING, Stage.PRICING): ["syndicate_head", "compliance"],
}

def transition(deal, target: Stage, approvals: set, actor: str):
    if target not in TRANSITIONS[deal.stage]:
        raise ValueError(f"illegal transition {deal.stage} -> {target}")
    needed = set(REQUIRED_APPROVALS.get((deal.stage, target), []))
    if not needed.issubset(approvals):
        raise PermissionError(f"missing approvals: {needed - approvals}")
    audit_log(deal.deal_id, deal.stage, target, actor, approvals)
    deal.stage = target

Additional needs:

Pitfalls and Anti-Patterns

Build Checklist

Closing Thoughts

The essence of IB systems is not transaction processing but controlled collaboration. The reason these systems exist is to precisely control information access, approvals, and records around a small number of high-value deals. The functional requirements (pipeline, bookbuilding, loan administration) are relatively plain; it is the non-functional requirements — immutable history, point-in-time queries, deny-by-default entitlements, automatic revocation — that decide success. If you are building a new system, design the data model and entitlement model before the screens.

Once more: this article is a technical resource, not investment or legal advice.

References

Comments

No comments yet.

Sign in to leave a comment