Skip to content

필사 모드: IB 시스템 아키텍처 — 딜 파이프라인부터 신디케이션까지

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

들어가며

은행 IT를 이야기할 때 대부분의 자료는 리테일 뱅킹(수신/여신/계정계)에 집중되어 있습니다. 그런데 투자은행(IB) 부문의 시스템은 전혀 다른 모양을 하고 있습니다. 계좌 수백만 개를 다루는 대신 딜(deal) 수십 건을 다루고, 초당 수천 건의 거래 대신 수개월짜리 워크플로를 다룹니다. 트랜잭션 볼륨은 작지만 딜 하나의 금액이 수천억 원에서 수조 원에 이르고, 미공개중요정보(MNPI)가 흐르는 곳이기 때문에 통제 실패의 비용이 어마어마합니다.

이 글은 IB 부문 시스템을 처음 설계하거나 유지보수하게 된 엔지니어를 위해, 업무 도메인 맵부터 딜 라이프사이클, 컨플릭트 체크, 차이니즈 월(정보교류차단)의 시스템적 구현, 북빌딩, 신디케이트론 관리, 문서 관리, 규제 보고까지를 하나의 그림으로 정리합니다. 한국 자본시장(자본시장법, 금융투자업규정) 맥락도 함께 다룹니다.

참고로 이 글은 시스템 설계 관점의 기술 자료이며, 투자 자문이나 법률 자문이 아닙니다. 규제 관련 내용은 반드시 소속 기관의 준법감시 부서와 확인하시기 바랍니다.

IB 업무 도메인 맵

IB 부문은 크게 다섯 개 도메인으로 나눌 수 있습니다.

+---------------------------------------------------------------+

| Investment Banking Division |

| |

| +-----------+ +-----------+ +-----------+ |

| | ECM | | DCM | | M&A | |

| | (주식자본 | | (부채자본 | | (인수합병 | |

| | 시장) | | 시장) | | 자문) | |

| | IPO/유상 | | 회사채/ | | 매수/매도 | |

| | 증자/CB | | ABS/MTN | | 자문, 공정 | |

| +-----------+ +-----------+ +-----------+ |

| |

| +------------------+ +---------------------------+ |

| | Acquisition | | Loan Syndication | |

| | Finance (인수금융)| | (신디케이트론 주선/참여) | |

| | LBO/브리지론 | | 주선(Arranger)/대리(Agent) | |

| +------------------+ +---------------------------+ |

| |

| 공통 인프라: 딜 파이프라인 / 컨플릭트 체크 / 차이니즈 월 |

| 문서 관리 / 내부자 리스트 / 규제 보고 / CRM |

+---------------------------------------------------------------+

각 도메인의 시스템 요구사항을 비교하면 다음과 같습니다.

| 도메인 | 핵심 산출물 | 핵심 시스템 기능 | 라이프사이클 길이 |

| --- | --- | --- | --- |

| ECM | IPO, 유상증자, 전환사채 | 북빌딩, 수요예측, 배정 | 3~12개월 |

| DCM | 회사채, ABS, MTN 프로그램 | 발행 일정 관리, 프라이싱, 수요예측 | 1~6개월 |

| M&A | 매수/매도 자문, 밸류에이션 | 딜룸(VDR), 문서 관리, 컨플릭트 체크 | 6~18개월 |

| 인수금융 | LBO 대출, 브리지론 | 한도/익스포저 관리, 신용 승인 워크플로 | 3~9개월 |

| 신디케이션 | 신디케이트론 주선 | 참여기관 관리, 수수료 배분, 에이전트 업무 | 대출 만기까지 수년 |

리테일과 가장 다른 점은 **모든 도메인이 딜 단위로 움직인다**는 것입니다. 시스템의 1급 객체(first-class object)는 계좌가 아니라 딜이고, 딜에는 팀, 문서, 승인, 정보 접근 권한이 모두 매달립니다.

딜 라이프사이클과 딜 파이프라인 관리

딜은 보통 다음 단계를 거칩니다.

[Origination] [Execution] [Closing] [Post-Close]

| | | |

아이디어/피칭 --> 위임(Mandate) --> 실사(DD) --> 마케팅/북빌딩 --> 프라이싱

| | | | |

v v v v v

컨플릭트 체크 엔게이지먼트 레터 딜룸 오픈 내부자 리스트 배정/결제

(사전 스크리닝) (계약 체결) (VDR/문서) (확대 관리) 수수료 정산

|

v

사후 관리/리그테이블

딜 파이프라인 관리 시스템(Deal Pipeline Management)의 핵심 요구사항은 다음과 같습니다.

- **단계(stage) 기반 상태 관리**: 각 딜은 정확히 하나의 단계에 있고, 단계 전이는 승인 이벤트에 의해서만 발생합니다.

- **확률 가중 파이프라인**: 단계별 성사 확률을 곱해 예상 수수료 수익을 집계합니다. 경영진 대시보드의 핵심 지표입니다.

- **팀 멤버십과 정보 접근의 결합**: 딜 팀에 추가되는 순간 차이니즈 월 통제 대상이 되고, 내부자 리스트 후보가 됩니다.

- **감사 추적(audit trail)**: 누가 언제 어떤 딜 정보를 조회/수정했는지 전부 남아야 합니다. 규제 검사 시 첫 번째로 요구되는 자료입니다.

단계 전이를 코드로 강제하는 것이 중요합니다. 스프레드시트로 파이프라인을 관리하면 컨플릭트 체크를 우회한 딜이 반드시 생깁니다.

컨플릭트 체크 — 딜을 받기 전에 막아야 한다

컨플릭트 체크(conflict check)는 새 딜을 수임하기 전에 기존 딜·고객 관계와 이해상충이 없는지 확인하는 절차입니다. 예를 들어 A사 매각 자문을 수임하려는데 이미 B사의 A사 인수 자문을 맡고 있다면 양쪽을 동시에 수임할 수 없습니다.

시스템 관점에서 컨플릭트 체크는 **딜 생성 워크플로의 게이트**입니다.

-- 컨플릭트 체크의 핵심 질의: 동일/관련 대상 기업에 대해

-- 활성 상태의 딜이 존재하는지 탐지

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 (

-- 신규 딜 대상 기업과 같은 기업집단까지 확장

SELECT company_group_id FROM company

WHERE company_id = :new_deal_target_id

);

실무에서 주의할 점:

- **기업집단(계열사) 단위로 확장**해야 합니다. 대상 회사만 보면 같은 그룹 계열사 딜과의 충돌을 놓칩니다.

- 검색은 **법인 식별자 기준**이어야 합니다. 회사명 문자열 매칭은 오타와 약칭 때문에 신뢰할 수 없습니다. LEI(법인식별기호)나 사업자등록번호를 마스터 데이터로 관리하세요.

- 결과는 자동 승인이 아니라 **준법감시 담당자의 판단 큐**로 들어갑니다. 시스템은 후보를 탐지하고, 사람이 판단하고, 판단 근거가 기록됩니다.

차이니즈 월(정보교류차단)의 시스템적 구현

차이니즈 월은 IB 부문(private side, MNPI 보유)과 리서치/세일즈앤트레이딩 부문(public side) 사이의 정보 흐름을 차단하는 통제입니다. 한국에서는 자본시장법상 정보교류차단(이해상충 방지) 규제로 구현이 의무화되어 있습니다. 시스템적으로는 세 개 레이어로 구현합니다.

레이어 1 — 권한(접근 통제)

딜 정보는 기본적으로 deny-all이고, 딜 팀 멤버십에 의해서만 열립니다.

딜 단위 접근 정책 예시 (정책 엔진 입력)

policy:

resource: deal/PRJ-FALCON

default: deny

rules:

- effect: allow

subjects:

- group: deal-team/PRJ-FALCON # 딜 팀 멤버

- group: compliance-surveillance # 준법감시(상시 열람권)

actions: [read, write]

- effect: allow

subjects:

- group: ib-management # 부문 경영진

actions: [read-summary] # 요약 정보만, 문서 접근 불가

- effect: deny

subjects:

- group: research # 리서치 부문은 명시적 차단

- group: sales-trading

actions: [read, write, read-summary]

override: true # allow보다 우선

핵심 설계 원칙:

- **프로젝트 코드네임**을 사용합니다. 딜 목록 화면에서도 권한 없는 사용자에게는 실제 회사명이 아닌 코드네임만 보이거나, 딜 존재 자체가 보이지 않아야 합니다.

- **월 크로싱(wall crossing)** 절차를 시스템화합니다. public side 직원이 딜에 일시 참여해야 하면, 준법감시 승인 → 내부자 리스트 등재 → 기간 한정 권한 부여 → 만료 시 자동 회수가 한 워크플로로 묶여야 합니다.

- 권한 부여/회수는 모두 이벤트로 남기고, 권한 보유자 목록의 **시점 조회(point-in-time query)**가 가능해야 합니다. "3월 15일에 이 딜 정보에 접근 가능했던 사람"을 즉시 뽑을 수 있어야 규제 검사에 대응할 수 있습니다.

레이어 2 — 워터마킹

딜 문서는 유출 시 출처를 추적할 수 있어야 합니다. 다운로드/열람 시점에 사용자별 워터마크를 동적으로 입힙니다.

문서 열람 시 동적 워터마크 적용 (개념 예시)

from pypdf import PdfReader, PdfWriter

from reportlab.pdfgen import canvas

from io import BytesIO

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)

대각선 반복 워터마크

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()

가시적 워터마크 외에 메타데이터/스테가노그래피 기반 비가시 워터마크를 병행하는 기관도 있습니다. 중요한 것은 워터마크 적용 이벤트 자체가 접근 로그와 연결되어야 한다는 점입니다.

레이어 3 — 로깅과 감시

- 딜 문서의 열람/다운로드/인쇄/공유는 전부 구조화 로그로 남깁니다(누가, 언제, 무엇을, 어디서).

- 준법감시 부서가 사용하는 **이상 접근 탐지** 배치: 딜 팀이 아닌 사용자의 접근 시도, 단시간 대량 다운로드, 퇴사 예정자의 접근 패턴 변화 등을 룰로 탐지합니다.

- 로그는 위변조 방지를 위해 append-only 저장소(WORM 스토리지 또는 해시 체인)에 보관합니다. 전자금융감독규정상 기록 보존 의무 기간을 확인해 보존 정책을 설정합니다.

MNPI 관리와 내부자 리스트

내부자 리스트(insider list)는 특정 딜의 미공개중요정보에 접근한 사람의 명부입니다. EU MAR(시장남용규제)는 발행사와 자문사에 내부자 리스트 작성을 명시적으로 의무화하고 있고, 한국에서도 미공개중요정보 이용행위 규제(자본시장법 제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, -- 등재 사유 (딜 팀, 월 크로싱, 외부 자문 등)

obtained_at TIMESTAMP NOT NULL, -- MNPI 접근 시작 시각

notified_at TIMESTAMP, -- 본인 통지 시각 (의무 고지)

removed_at TIMESTAMP, -- 리스트 제외 시각

removed_reason VARCHAR(200),

created_by VARCHAR(50) NOT NULL,

created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP

);

-- 내부자 리스트는 정정 이력까지 보존해야 하므로 UPDATE 금지,

-- 변경은 신규 row + 이전 row 무효화로 처리 (bitemporal 패턴)

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);

운영 포인트:

- 내부자 리스트는 **딜 팀 멤버십과 자동 동기화**하되, 외부인(법무법인, 회계법인, 인쇄소까지)은 수동 등재 경로를 제공합니다.

- 등재 시 본인에게 의무 고지(MNPI 보유 사실, 거래 제한, 법적 책임)를 발송하고 수신 확인을 기록합니다.

- 개인 거래 사전승인 시스템(PA dealing)과 연동해, 내부자 리스트에 있는 직원이 해당 종목 거래를 신청하면 자동 차단합니다.

북빌딩 시스템 — 수요예측과 배정

ECM/DCM 딜의 하이라이트는 북빌딩(bookbuilding)입니다. 기관투자자로부터 수요(가격, 수량)를 접수해 수요 곡선을 만들고, 발행가를 결정한 뒤 물량을 배정합니다. 한국 IPO에서는 기관 수요예측이 금융투자협회 규정에 따라 운영됩니다.

북빌딩 시스템의 핵심 모델은 주문(order)과 배정(allocation)입니다.

단순화한 배정 엔진 개념 예시

실제 배정은 정성 평가(앵커 투자자, 장기 보유 성향)가 결합된

심사 절차이며, 아래는 비례 배정 골격만 보여준다.

from dataclasses import dataclass

@dataclass

class Order:

investor_id: str

quantity: int # 신청 수량

limit_price: int # 희망 가격 (원), 시장가는 None 대신 최고가 처리

investor_grade: str # 내부 등급: 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):

"""가격대별 누적 수요 곡선: 해당 가격 이상을 써낸 주문의 합"""

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

잔여 물량은 라운딩 보정 규칙으로 재배분 (생략)

return allocations, remaining

시스템 설계에서 중요한 것들:

- **주문 수정 이력**: 북빌딩 기간 중 투자자는 주문을 수정/취소합니다. 모든 버전이 보존되어야 하며, 마감 시각 이후 주문은 시스템이 거부해야 합니다.

- **수요 곡선의 실시간 집계**: 신디케이트 데스크는 북 커버리지(수요/공급 배율)를 실시간으로 봅니다. 이벤트 소싱으로 주문 스트림을 쌓고 구체화 뷰로 집계하는 구조가 적합합니다.

- **배정 결과의 설명가능성**: 배정은 분쟁과 규제 이슈가 많은 영역입니다. 배정 로직의 입력(등급, 가중치)과 수동 조정 내역이 전부 기록되어야 하고, 수동 조정에는 사유 입력이 강제되어야 합니다.

- **이해상충 통제**: 자기운용 펀드나 계열사에 대한 배정은 별도 승인 경로를 태우거나 차단합니다.

신디케이트론 관리 — 수년짜리 운영 시스템

신디케이트론은 여러 금융기관이 하나의 차주에게 공동으로 대출하는 구조입니다. 주선기관(arranger)이 딜을 조직하고, 에이전트 뱅크(agent bank)가 대출 기간 내내 이자 계산, 원리금 배분, 차주와 참여기관 간 통지를 담당합니다. LMA(유럽)/LSTA(미국) 표준 계약이 사실상의 업계 표준입니다.

시스템이 관리해야 하는 핵심 데이터:

| 영역 | 내용 |

| --- | --- |

| 퍼실리티 구조 | Term Loan A/B, RCF 등 트랜치 구조와 한도 |

| 참여기관 지분 | 기관별 커밋먼트 금액, 양도(assignment) 이력 |

| 인출/상환 | 인출 요청, 이자 기간, 상환 스케줄 |

| 이자/수수료 | 기준금리+마진, 약정수수료, 주선수수료, 에이전트수수료 |

| 배분 | 이자/원금/수수료의 참여기관별 안분 계산과 지급 |

수수료 배분 계산 예시:

이자 기간 종료 시 참여기관별 배분 계산 (개념 예시)

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

마지막 기관이 라운딩 잔차를 흡수 — 합계가 반드시 일치해야 함

last_inst = items[-1][0]

result[last_inst] = total_interest - allocated

assert sum(result.values()) == total_interest

return result

운영상 가장 까다로운 부분:

- **지분 양도(secondary trading)**: 참여기관이 지분을 다른 기관에 양도하면, 그 시점 이후의 이자/원금 배분 기준이 바뀝니다. 양도 효력 발생일 기준의 시점별 지분 원장이 필요합니다.

- **라운딩 정책**: 배분 합계는 1원 단위까지 원금과 일치해야 합니다. 잔차 흡수 규칙을 명시적으로 정의하고 테스트하세요.

- **에이전트 업무의 통지 의무**: 금리 확정, 인출 통지, 디폴트 이벤트 등은 기한 내 통지 의무가 있습니다. 워크플로 엔진의 타이머/에스컬레이션 기능이 필수입니다.

인수금융 한도와 익스포저 관리

인수금융(LBO 파이낸싱, 브리지론)은 은행 자기자본이 직접 노출되는 영역이라 한도 관리가 핵심입니다.

- **차주/기업집단 단위 한도**: 동일인/동일차주 신용공여 한도 규제(은행법, 자본시장법상 금투업자 규제)에 따라 기업집단 단위로 익스포저를 합산합니다.

- **언더라이팅 한도 vs 보유 한도**: 인수(underwriting) 시점의 일시적 대량 익스포저와 셀다운(sell-down) 후 최종 보유분을 구분해 각각 한도를 둡니다. 셀다운이 계획대로 안 되면(hung deal) 보유 한도를 초과하는 상황이 생기므로, 시스템은 셀다운 계획 대비 실적을 추적해야 합니다.

- **파이프라인 익스포저**: 아직 실행되지 않은 커밋먼트(승인됐지만 미인출)도 잠재 익스포저로 집계합니다.

익스포저 집계 개념:

총 익스포저(기업집단 G)

= Σ 실행 잔액(집단 내 모든 차주)

+ Σ 미인출 약정 × 신용환산율(CCF)

+ Σ 언더라이팅 포지션(셀다운 미완료분)

한도 체크는 신규 딜 승인 시점 + 일배치 양쪽에서 수행

딜 문서 관리 — 버전과 서명

M&A와 신디케이션은 문서가 산출물의 거의 전부입니다. 요구사항:

- **버전 관리**: 계약서 드래프트는 수십 번 오갑니다. 버전 트리(누가 어느 버전에서 분기했는지), 비교(redline) 생성, 최종본(execution version) 지정이 필요합니다.

- **VDR(가상 데이터룸)**: 실사 단계에서 매도자 측이 자료를 올리고 매수 후보들이 열람합니다. 후보별 접근 범위 차등, 열람 로그, Q&A 워크플로가 표준 기능입니다.

- **전자서명 통합**: 서명 패키지 구성(서명자, 서명 위치, 순서) → 발송 → 서명 완료 추적 → 최종본 보관소 격납까지 워크플로로 묶습니다. 서명 완료 이벤트가 딜 단계 전이(예: 계약 체결)를 트리거하도록 연결하면 파이프라인 데이터 품질이 좋아집니다.

- **보존과 리걸 홀드**: 딜 분쟁 발생 시 관련 문서 일체에 삭제 금지(legal hold)를 걸 수 있어야 합니다.

규제 보고와 한국 자본시장 맥락

한국에서 IB 업무는 자본시장과 금융투자업에 관한 법률(자본시장법)과 금융투자업규정의 적용을 받습니다. 시스템 관점에서 자주 만나는 보고/공시 의무는 다음과 같습니다(정확한 요건은 시점·기관 유형에 따라 다르므로 준법 부서 확인 필수).

- **증권신고서/투자설명서**: ECM/DCM 발행 시 금융위원회 전자공시(DART) 제출. 발행 시스템의 딜 데이터가 신고서 작성의 원천 데이터가 됩니다.

- **수요예측 관련 자료 보존**: IPO 수요예측의 주문·배정 내역은 협회 규정에 따른 보존 의무가 있습니다.

- **대주주/계열사 거래 보고, 이해상충 기록 유지**: 정보교류차단 장치 운영 기록, 월 크로싱 승인 기록 등이 검사 대상입니다.

- **금융감독원 검사 대응**: 접근 로그, 내부자 리스트, 컨플릭트 체크 기록의 시점 조회가 빠르게 가능해야 합니다.

설계 시사점은 명확합니다. 규제 보고를 별도 시스템의 일로 미루지 말고, **딜 시스템의 데이터 모델 자체가 보고 가능한 형태(불변 이력, 시점 조회)**로 만들어져야 합니다.

CRM과의 통합

IB의 CRM은 영업 CRM과 결이 다릅니다. 커버리지 뱅커가 고객사 경영진과의 미팅, 피칭 이력, 딜 기회를 관리합니다. 통합 포인트:

- 컨플릭트 체크는 CRM의 관계 데이터(누가 어느 회사를 커버하는지, 과거 딜 이력)를 입력으로 사용합니다.

- 딜이 위임 단계로 넘어가면 CRM의 기회(opportunity)가 딜 파이프라인의 딜로 승격되고, 양쪽 ID가 상호 참조됩니다.

- 단, **차이니즈 월은 CRM에도 적용**됩니다. 딜 상세 정보가 CRM을 통해 public side에 노출되면 통제 전체가 무너집니다. CRM에는 딜 존재와 코드네임 수준만 동기화하는 것이 안전합니다.

데이터 모델 예시

핵심 엔터티의 관계를 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/ | +--------+-----+ +-----+------+ +-+----------+

| ACQUIRER/ | | DEAL_DOCUMENT| | DEAL_TEAM | | INSIDER_ |

| ISSUER...) | +--------------+ +------------+ | LIST_ENTRY |

+---------------+ | doc_id PK | | deal_id FK | +------------+

| deal_id FK | | person_id | | deal_id FK |

+---------------+ | version | | role | | person_id |

| ORDER (북빌딩) | | status | | granted_at | | obtained_at|

+---------------+ | sha256 | | revoked_at | | removed_at |

| order_id PK | +--------------+ +------------+ +------------+

| deal_id FK |

| investor_id | +-----------------+ +----------------------+

| qty / price | | FACILITY (론) | | PARTICIPATION (지분) |

| superseded_by | +-----------------+ +----------------------+

+---------------+ | facility_id PK |---| facility_id FK |

| deal_id FK | | institution_id |

+---------------+ | tranche_type | | commitment_amt |

| ALLOCATION | | limit_amt | | effective_from/to |

+---------------+ | margin_bps | +----------------------+

| order_id FK | +-----------------+

| alloc_qty |

| adjusted_by |

+---------------+

모델링 원칙:

- **이력은 불변**: 주문, 배정, 팀 멤버십, 내부자 리스트는 UPDATE 대신 신규 행 + 유효기간(effective_from/to) 패턴을 씁니다.

- **문서는 해시로 무결성 보장**: 최종본의 SHA-256을 기록해 사후 변조를 탐지합니다.

- **모든 금액은 통화와 함께**: 크로스보더 딜이 흔하므로 amount + currency 쌍을 기본으로 합니다.

워크플로 엔진 설계

딜 라이프사이클, 월 크로싱, 신용 승인, 서명 추적은 전부 워크플로입니다. 직접 만들든 엔진(Camunda, Temporal 등)을 쓰든, IB 도메인에서 요구되는 특성은 다음과 같습니다.

딜 단계 전이를 명시적 상태기계로 강제하는 예시

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

추가로 필요한 것:

- **타이머와 에스컬레이션**: 통지 기한, 승인 SLA 초과 시 상위자 알림.

- **보상 처리**: 딜이 DEAD가 되면 내부자 리스트 정리, 권한 회수, VDR 폐쇄가 연쇄적으로 실행되어야 합니다. 이 후처리가 수동이면 반드시 누락됩니다.

- **워크플로 이력 자체가 감사 자료**: 누가 승인했고 어떤 근거 문서가 첨부됐는지가 전이 이벤트에 붙어야 합니다.

함정과 안티패턴

- **스프레드시트 파이프라인**: 가장 흔하고 가장 위험합니다. 컨플릭트 체크와 권한 통제가 우회됩니다. 이행기에는 스프레드시트 임포트 기능을 제공해서라도 시스템으로 끌어오세요.

- **회사명 문자열 매칭 기반 컨플릭트 체크**: 법인 식별자 마스터 없이 시작하면 결과를 신뢰할 수 없습니다.

- **권한 회수 누락**: 딜 종료/팀 이탈 시 권한이 남아 있는 계정은 검사 단골 지적 사항입니다. 만료 기반(grant with expiry) 설계로 기본값을 안전하게 만드세요.

- **배정 로직의 블랙박스화**: 설명 불가능한 배정은 규제 리스크입니다. 입력과 수동 조정을 전부 기록하세요.

- **신디케이트론 라운딩 잔차 방치**: 1원 차이가 수년간 누적되어 대사 브레이크를 만듭니다.

- **딜 시스템과 CRM의 양방향 무차별 동기화**: 차이니즈 월에 구멍을 냅니다. 동기화 범위를 명시적으로 정의하세요.

- **로그를 남기지만 조회할 수 없는 구조**: 시점 조회가 안 되는 감사 로그는 검사 대응에서 무용지물입니다.

구축 체크리스트

- [ ] 법인 마스터(그룹/계열 관계 포함)와 LEI 기반 식별 체계가 있는가

- [ ] 딜 생성 전 컨플릭트 체크가 워크플로 게이트로 강제되는가

- [ ] 딜 정보 기본 정책이 deny-all이고 팀 멤버십 기반으로만 열리는가

- [ ] 코드네임이 권한 없는 화면에서 실명을 대체하는가

- [ ] 월 크로싱이 승인-등재-기간한정권한-자동회수의 단일 워크플로인가

- [ ] 내부자 리스트가 불변 이력 + 시점 조회를 지원하는가

- [ ] 문서 열람/다운로드에 사용자별 워터마크와 접근 로그가 남는가

- [ ] 북빌딩 주문의 전체 수정 이력이 보존되고 마감 후 주문이 차단되는가

- [ ] 배정 로직의 입력·가중치·수동조정이 전부 기록되는가

- [ ] 신디케이트론 지분의 시점별 원장과 라운딩 잔차 규칙이 있는가

- [ ] 익스포저가 기업집단 단위로 합산되고 미인출 약정이 포함되는가

- [ ] 딜 종료 시 권한 회수·VDR 폐쇄·리스트 정리가 자동 연쇄되는가

- [ ] 감사 로그가 append-only로 보존되고 보존 기간 정책이 규정과 맞는가

마치며

IB 시스템의 본질은 거래 처리가 아니라 **통제된 협업**입니다. 소수의 고액 딜을 둘러싸고 정보 접근, 승인, 기록이 정확하게 통제되는 것이 시스템의 존재 이유입니다. 기능 요구사항(파이프라인, 북빌딩, 론 관리)은 비교적 평이하지만, 비기능 요구사항 — 불변 이력, 시점 조회, 권한의 기본 차단, 자동 회수 — 이 설계의 성패를 가릅니다. 새로 시스템을 만든다면 화면보다 데이터 모델과 권한 모델부터 설계하시기를 권합니다.

다시 한번, 본 글은 기술 자료이며 투자·법률 자문이 아닙니다.

참고 자료

- 자본시장과 금융투자업에 관한 법률 (국가법령정보센터): https://www.law.go.kr

- 금융감독원: https://www.fss.or.kr

- 금융투자협회 (수요예측 관련 규정): https://www.kofia.or.kr

- 한국거래소 상장 규정: https://www.krx.co.kr

- 전자공시시스템 DART: https://dart.fss.or.kr

- ICMA (International Capital Market Association): https://www.icmagroup.org

- LSTA (Loan Syndications and Trading Association): https://www.lsta.org

- LMA (Loan Market Association): https://www.lma.eu.com

- ESMA — Market Abuse Regulation 자료: https://www.esma.europa.eu

- BIS (국제결제은행): https://www.bis.org

- IOSCO (국제증권감독기구): https://www.iosco.org

- GLEIF (LEI 재단): https://www.gleif.org

현재 단락 (1/347)

은행 IT를 이야기할 때 대부분의 자료는 리테일 뱅킹(수신/여신/계정계)에 집중되어 있습니다. 그런데 투자은행(IB) 부문의 시스템은 전혀 다른 모양을 하고 있습니다. 계좌 수백만...

작성 글자: 0원문 글자: 14,252작성 단락: 0/347