Skip to Content

재무 모델 — xlsx 를 DB 의 일급 entity 로

한 줄 정의

ic skill 의 ic/finance/{3fs_*,scenario_deltas,exit_matrix,irr_analysis} 산출물을 6-table typed model 로 승격. xlsx 가 source 가 아니라 DB 가 source, xlsx 는 ingest 입력 + export 출력. DSL formula + topo evaluator 가 cell 재계산 deterministic. fund_investment 가 cash flow + IRR carrier — 한 deal 의 여러 fund × 여러 round 별 IRR 독립 산출.

본 페이지는 index 의 L1 (relational compute substrate) 이다. 이 relational 값을 지배하는 판단 (가정·calibration·comp·base_rate) 은 그 위 L2 — artifact-first judgment layer (D-index-45) 가 typed fact 로 보존하며, citation index_field (ref {deal,field}) 로 여기 relational field 에 링크된다. “왜 이 driver/exit_multiple/probability 가 이 값인가” 추적 = get_judgment_provenance. 3-layer 전체 = /services/index § 3-layer 모델.

왜 필요한가

ic skill 의 현재 흐름:

회사 IR pack ↓ vision_ingest dataroom/*.{pdf,pptx,xlsx} ↓ /ic 19-agent orchestration (3-5시간) ic/finance/3fs_base/v7.xlsx ← scenario 4종 × 3FS 모델 (8 sheet) ic/finance/scenario_deltas/v7.yaml ← 4 scenario × ~15 driver ic/finance/exit_matrix/v7.yaml ← scenario × timing × path leaf 트리 ic/finance/irr_analysis/v7.xlsx ← 확률가중 IRR 산출 ic/memo/v8.md ← IRR 23.4% 라는 한 줄 cite ↓ PDF render + Teams reply 산출물 휘발 — 다음 deal 도 grep 으로 재추출

5 격차:

격차현재 (xlsx + yaml + markdown)결과
Cross-deal driver benchmarkportfolio 의 churn / gross_margin / IRR 시계열 grep 으로 못 풀음”axec/axev 포폴 평균 gross margin?” 답 토큰 폭증
Citation chainIC memo “IRR 23.4%” 가 xlsx 어느 cell, 어느 driver 에서 왔는지 trace 불가LP audit 시 “한 숫자라도 잡히면” IRR 신뢰 무너짐 (ic skill citation_trace.py 본질)
Time-travelQ2 IC 시점의 IRR vs 현재 IRR diff 안 됨의사결정 archaeology 불가
펀드별 IRR 분리1호 + 2호 동시 투자 시 각각 IRR 산출 수작업Iippo / Sentry 같은 multi-fund deal 의 정합성 안 잡힘
Sanity check 휘발ic skill 의 4 check 가 매번 재실행. 누적 audit 없음모순 반복 (Superman v4 “11,250백만원 (1,200억 × 18.75%)” 4-number 모순 같은 사고)

→ DB 가 source 면 위 5 격차 모두 SQL aggregate / FK / trigger 로 자연 해결.

6-table SoT

financial_model (deal 별 1+, version) ├─ financial_driver (driver tree DAG — code, kind, formula DSL, dependencies[]) │ ↑ topological sort 로 평가 순서 결정 ├─ financial_scenario (Upside/Base/Mgmt/Downside, probability, driver_changes) │ ↑ ic skill 의 PR-J 4-scenario 정합 ├─ financial_driver_value (model × driver × scenario × period_index → value) │ ↑ scenario 가 baseline 위에 override 만 — driver_changes 의 DB 형태 ├─ financial_output (model × scenario × output_code × period?) │ ↑ irr / moic / npv / exit_val / runway / revenue_year_5 ... │ ↑ inputs_hash 가 driver_value snapshot sha256 — reproducibility lock └─ exit_matrix_leaf (scenario × timing × path) ↑ ic skill exit_matrix yaml 의 3-level tree 의 DB 형태 ↑ probability × proceeds_krw + dead_leaf/concentration flag (check_exit_matrix.py 결과 캐시)

Schema (SQL skeleton)

-- per-entity schema (axe_ia_001 / axe_ia_002 / ...) CREATE TABLE financial_model ( id uuid PRIMARY KEY, deal_id uuid NOT NULL REFERENCES shared.deal(id), version int NOT NULL, name text NOT NULL, -- e.g., "Iippo IC v8 base model" time_axis_kind text NOT NULL CHECK (time_axis_kind IN ('year','quarter','month')), start_period date NOT NULL, -- e.g., 2025-01-01 (Y0) horizon_periods int NOT NULL, -- e.g., 7 (Y0~Y7) currency text NOT NULL DEFAULT 'KRW', unit_scale numeric NOT NULL DEFAULT 1, -- 1 / 1000 / 1000000 (천원/백만원) base_revenue_period0 numeric, -- e.g., 120,000,000 (Iippo Y0 매출) created_by text NOT NULL, created_at timestamptz NOT NULL DEFAULT now(), locked_at timestamptz, -- 후 immutable source_xlsx_sha256 text, source_xlsx_citation jsonb, -- {kind:"onedrive", drive_item_id, version, sheet} source_yaml_citations jsonb DEFAULT '[]'::jsonb, -- scenario_deltas/exit_matrix yaml refs UNIQUE (deal_id, version) ); CREATE TABLE financial_driver ( id uuid PRIMARY KEY, model_id uuid NOT NULL REFERENCES financial_model(id) ON DELETE CASCADE, code text NOT NULL, -- e.g., "revenue_growth_y1" kind text NOT NULL CHECK (kind IN ('input','derived','output')), formula text, -- DSL — null if input dependencies text[] NOT NULL DEFAULT '{}', -- 다른 driver code list units text NOT NULL, -- '%', 'KRW', 'count', 'months', 'multiple' category text NOT NULL, -- 'revenue', 'cost', 'opex', 'capex', 'financing', 'wc' description text, display_order int, UNIQUE (model_id, code) ); CREATE TABLE financial_scenario ( id uuid PRIMARY KEY, model_id uuid NOT NULL REFERENCES financial_model(id) ON DELETE CASCADE, code text NOT NULL, -- 'base', 'upside', 'mgmt', 'downside', 'custom_*' name text NOT NULL, -- 'AXE Base' kind text NOT NULL CHECK (kind IN ('base','upside','mgmt','downside','custom')), probability numeric(5,4) NOT NULL, -- 0.0000 ~ 1.0000 (per-scenario, 합 = 1) description text, driver_changes jsonb NOT NULL DEFAULT '{}'::jsonb, -- narrative {story, rationale[], key_assumption_overrides} parent_scenario_id uuid REFERENCES financial_scenario(id), -- fork chain locked_at timestamptz, UNIQUE (model_id, code) ); CREATE TABLE financial_driver_value ( model_id uuid NOT NULL, driver_code text NOT NULL, scenario_id uuid NOT NULL REFERENCES financial_scenario(id) ON DELETE CASCADE, period_index int NOT NULL, -- 0 ~ horizon_periods value numeric, is_override bool NOT NULL DEFAULT false, -- true = scenario override on baseline PRIMARY KEY (model_id, driver_code, scenario_id, period_index), FOREIGN KEY (model_id, driver_code) REFERENCES financial_driver(model_id, code) ); CREATE TABLE financial_output ( id uuid PRIMARY KEY, model_id uuid NOT NULL REFERENCES financial_model(id) ON DELETE CASCADE, scenario_id uuid NOT NULL REFERENCES financial_scenario(id) ON DELETE CASCADE, output_code text NOT NULL, -- 'irr', 'moic', 'npv', 'exit_valuation', 'axe_proceeds_total' period_index int, -- null = terminal output, int = time series value numeric, computed_at timestamptz NOT NULL DEFAULT now(), inputs_hash text NOT NULL, -- sha256(driver_value snapshot) — reproducibility UNIQUE (model_id, scenario_id, output_code, period_index) ); CREATE TABLE exit_matrix_leaf ( id uuid PRIMARY KEY, scenario_id uuid NOT NULL REFERENCES financial_scenario(id) ON DELETE CASCADE, timing text NOT NULL, -- '3y', '5y', '7y', 'never' path text NOT NULL, -- 'ma', 'ipo', 'secondary', 'writedown', 'ma_strategic', 'partial' probability numeric(5,4) NOT NULL, -- 0.0000~1.0000 (per timing, 합 = 1) description text, proceeds_krw numeric, -- 회사 전체 exit proceeds (EqV or EV) axe_proceeds_krw numeric, -- AXE 회수 (proceeds × ownership_pct_fd × dilution) recovery_rate numeric(5,4), -- writedown 시 5-15% 잔존 (D-PR 22 wd-assumption) dead_leaf bool NOT NULL DEFAULT false, -- check_exit_matrix.py 결과 concentration bool NOT NULL DEFAULT false, -- 단일 leaf P > 10% (concentration warning) UNIQUE (scenario_id, timing, path) );

상세 RLS · trigger · index 는 Phase 0 migration SQL 참조.

fund_investment

본 서비스의 두 번째 핵심 abstraction (D-index-5).

deal 은 회사 단위 thesis. fund_investment 는 cash flow + IRR carrier.

왜 3차원 N:M?

실 데이터:

  • Iippo: 1 deal × 2 fund (1호 99,998,912 + 2호 100,000,000, 같은 round Pre-A)
  • Sentry: 1 deal × 1 fund × multi-round option (1호 5억 + 후속 5억 pro-rata option future)
  • Canopy: 1 deal × 1 fund × 다른 시점 multi-round (1호 BW 5억 initial + 1호 신주 follow 1억 v5)

세 deal 모두 N:M 의 다른 축. 단일 (deal, fund) FK pair 로는 부족.

Schema

CREATE TABLE shared.fund_investment ( id uuid PRIMARY KEY, deal_id uuid NOT NULL REFERENCES shared.deal(id), fund_entity_id text NOT NULL REFERENCES shared.entity(id), -- e.g., 'axe_ia_001' round_label text NOT NULL, -- '초기', 'follow-on v5', 'pro-rata option' instrument text NOT NULL, -- 'RCPS', 'BW', 'SAFE', '신주', '보통주' committed_krw numeric NOT NULL, -- 약정 금액 invested_krw numeric, -- 실 납입 (paid 후 set) share_count numeric, -- 주식 수 price_per_share numeric, -- 주당 가격 entry_date date, -- 결의/계약일 paid_date date, -- 납입일 (status=paid 후 set) pre_money_krw numeric, -- 진입 시점 post_money_krw numeric, ownership_pct_post numeric(7,6), -- 0.000000 ~ 1.000000 ownership_pct_fd numeric(7,6), -- F/D 희석 후 status text NOT NULL CHECK (status IN ('committed','paid','locked_in','written_off','partial_exited','exited')), conditions jsonb DEFAULT '[]'::jsonb, -- PCC trigger 같은 조건 conditions_met_at timestamptz, -- 조건부 → 무조건 전환 시점 evidence_citations jsonb DEFAULT '[]'::jsonb, -- 계약서 OneDrive ref 등 created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now(), UNIQUE (deal_id, fund_entity_id, round_label) ); CREATE INDEX fund_investment_deal_idx ON shared.fund_investment (deal_id); CREATE INDEX fund_investment_fund_idx ON shared.fund_investment (fund_entity_id); CREATE INDEX fund_investment_status_idx ON shared.fund_investment (status) WHERE status IN ('committed','paid','locked_in');

Per-fund IRR 계산

-- financial_output 의 axe_proceeds_total 산출 → fund_investment.ratio 로 split -- Iippo 케이스: -- financial_output (scenario=base, output_code=axe_proceeds_total) = 9.4억 (Y5 회수) -- fund_investment Iippo×axe_ia_001 ratio = 99,998,912 / 199,998,912 = 0.500003 -- fund_investment Iippo×axe_ia_002 ratio = 100,000,000 / 199,998,912 = 0.499997 -- ↓ -- 1호 회수 = 9.4억 × 0.500003 ≈ 4.70억 -- 1호 IRR = irr(cash_flow = [-99,998,912 @ 2026-05-15, +4.70억 @ 2030-06-30]) -- 2호 회수 = 9.4억 × 0.499997 ≈ 4.70억 -- 2호 IRR = irr(cash_flow = [-100,000,000 @ 2026-09-?? (PCC 6 후), +4.70억 @ 2030-06-30]) -- -- 같은 회사 같은 회수 비율이지만 paid_date 가 다르면 IRR 다름 (2호 납입 지연 → IRR 약간 ↓)

view fund_investment_irr:

CREATE VIEW shared.fund_investment_irr AS SELECT fi.id AS fund_investment_id, fi.deal_id, fi.fund_entity_id, fi.round_label, fi.committed_krw, fi.invested_krw, fi.paid_date, fs.scenario_id, fs.code AS scenario_code, fs.probability AS scenario_probability, fo.value AS total_axe_proceeds_krw, -- fund_investment 비례 split fi.committed_krw / SUM(fi.committed_krw) OVER (PARTITION BY fi.deal_id) AS ratio, fo.value * (fi.committed_krw / SUM(fi.committed_krw) OVER (PARTITION BY fi.deal_id)) AS fund_share_proceeds_krw, -- IRR 계산은 Rust 측 compute_outputs 가 채워서 별 row 로 저장 (output_code='irr_per_fund') FROM shared.fund_investment fi JOIN financial_scenario fs ON fs.model_id IN ( SELECT id FROM financial_model WHERE deal_id = fi.deal_id ORDER BY version DESC LIMIT 1 ) JOIN financial_output fo ON fo.scenario_id = fs.id AND fo.output_code = 'axe_proceeds_total';

이 view 위에 확률가중 IRR 합산도 SQL aggregate 한 줄.

DSL Formula

왜 한정 DSL?

xlsx formula 를 그대로 못 옮김 — cell ref (B14) 를 driver ref (revenue_y2) 로 매핑 필요. 또한 Excel 의 ~500 함수 중 IC memo cite 하는 건 10개 미만. 한정 DSL 이 (a) parser 단순, (b) audit 가능, (c) 보안 (eval 안 함).

문법 (10 operators)

expr = term (('+' | '-') term)* term = factor (('*' | '/') factor)* factor = number | driver_ref | func_call | '(' expr ')' driver_ref = identifier '[' period ']' | identifier period = 'y0' | 'y1' | ... | 'y<n>' | 'current' func_call = func_name '(' args ')' func_name = 'min' | 'max' | 'if' | 'sum' | 'avg' | 'lag' | 'growth' | 'cum'

예제:

# 매출 = 직전 매출 × (1 + 성장률) revenue[y1] = revenue[y0] * (1 + revenue_growth_y1) revenue[y2] = revenue[y1] * (1 + revenue_growth_y2) # ... revenue[y_n] = lag(revenue, 1) * (1 + lag(revenue_growth, 0)) # 매출원가 = 매출 × (1 - 매출총이익률) cogs = revenue * (1 - gross_margin_terminal) # 영업이익 = 매출 - 매출원가 - 판관비 ebit = revenue - cogs - opex_sm - opex_rnd - opex_ga opex_sm = revenue * opex_sm_per_revenue opex_rnd = revenue * opex_rnd_per_revenue opex_ga = revenue * opex_ga_per_revenue # 운전자본 ar = revenue * ar_days / 365 inventory = cogs * inventory_days / 365 ap = cogs * ap_days / 365 # 세후 영업이익 + CAPEX nopat = ebit * (1 - tax_rate) capex = revenue * capex_per_revenue # 자유현금흐름 + 잔여가치 + IRR fcf = nopat + depreciation - capex - delta_wc terminal_value = ebit[exit_year] * exit_multiple exit_valuation = if(path == 'ipo', terminal_value, terminal_value * 0.85) # M&A discount axe_proceeds = exit_valuation * ownership_pct_fd

Topological evaluator

Rust petgraph::algo::toposort:

  1. DAG 구성: (driver_code) -[depends_on]-> (driver_code) edge
  2. cycle detect — toposort 가 cycle 감지 시 fail-fast (운영자에게 명시적 오류)
  3. period 별 evaluation:
    • p=0: input driver value 읽기 (driver_value 테이블)
    • p=1..horizon: derived driver 를 toposort 순서로 평가
    • lag(driver, n) 는 p-n 의 cached value 조회
  4. scenario 별 4 단계 반복 (base / upside / mgmt / downside)
  5. 결과 → financial_output row insert (output_code = irr / moic / npv / exit_valuation / etc)
  6. inputs_hash = sha256(serialized driver_value snapshot) — 같은 input 으로 다시 돌리면 같은 hash + 같은 output

Reproducibility lock

compute_outputs(model_id=X, scenario_id=Y) 호출 ↓ driver_value snapshot 읽기 → sha256 ↓ financial_output 의 (model, scenario, output_code) 마다 inputs_hash 비교 ↓ 같으면 skip (이미 계산됨), 다르면 재산출 + inputs_hash update

→ ic skill 의 tests/fixtures/{DEAL}.json (lockfile baseline) 패턴 완성. PR 머지 전 fixture diff 자동 검출.

xlsx round-trip

ingest (xlsx → DB)

ingest_financial_model_xlsx(deal_id, xlsx_blob, hint?) MCP tool. LLM 보조 driver tree extract:

1. xlsx 의 sheet 목록 + cell range 파싱 (Rust `calamine`) 2. LLM prompt (Anthropic Sonnet, 1 call ~ 60s): "Sheet 'Base' 의 row 'Revenue', 'COGS', 'Gross Profit', ... 의 cell B14:H14 가 무엇의 어떤 시계열을 표현하는지 추정. Schema = financial_driver row 예시 [...]." 3. LLM 응답 → 제안 financial_driver rows + dependencies 4. ctx review queue 에 propose (사용자 confirm/edit/reject) 5. confirmed → financial_driver + financial_driver_value 적재 6. exit_matrix yaml 은 직접 파싱 (LLM 불필요) — schema 정형 7. scenario_deltas yaml 도 직접 (driver value override 만) 8. xlsx 의 IRR cell 과 DB compute_outputs 결과 비교 → ±1pp diff 시 warn

vision-heavy 시점만 API direct (D-bp-artifact-7 layer 1 정합). 일상 propose 는 Claude Code OAuth (Max plan).

export (DB → xlsx)

export_xlsx(model_id, scenarios[]). driver tree → xlsx sheet 재생성:

1. 시나리오마다 한 sheet (Base / Upside / Mgmt / Downside) 2. row = driver (display_order 순), column = period (y0..y_n) 3. cell value = financial_driver_value.value (input) 또는 evaluator 산출 (derived) 4. derived cell 은 xlsx formula 도 출력 ('=B14*(1+B$3)') — 사용자가 xlsx 안에서 trace 가능 5. exit_matrix → 별 sheet (scenario × timing × path 표) 6. financial_output (IRR / MOIC / NPV) → Output sheet

ic skill 의 기존 ic/finance/3fs_base/v8.xlsx 와 cell-by-cell 비교 가능 — Phase 0 acceptance test.

Sanity check 흡수

ic skill 의 4 check 가 index 의 DB CHECK + trigger + validate_financial_model tool 로 이전:

ic skill checkindex 측 대응
xlsx_integrity.py (5 assertion: BS/CF formula coverage, IS Y-o-Y, Retained Earnings flow, Driver range sanity, cross-scenario shape)trigger validate_driver_tree — DAG cycle / orphan driver / dependency 누락 검출. cross-scenario shape = scenario × driver_code coverage matrix 검사
check_arithmetic.py (paragraph self-claim 산수 검증)memo artifact propose 시 numeric claim 추출 → financial_output cell 비교. validate_memo_arithmetic(memo_artifact_id, model_id) tool
check_exit_matrix.py (dead leaf / concentration / downside semantic / WD recovery 0%)trigger exit_matrix_sanity — INSERT/UPDATE 시 자동 검사. dead_leaf / concentration flag 자동 set
citation_trace.py (memo 의 단위 동반 숫자 trace)artifact citation 의 kind: "index.financial_output" 가 강제. trace 안 되는 숫자 = orphan citation warning

ic skill 의 4 Python script 가 index Phase 1 후 deprecate — DB-side enforcement 가 더 결정론적.

3 deal worked example (실 데이터 기반)

Iippo (킵코퍼레이션, iipuda)

기초 데이터: /Users/axe/Library/CloudStorage/OneDrive-AXE/AXE - Ventures/1_Project/Prj_Iippo/ic/finance/* (memo v8, scenario_deltas v7, exit_matrix v7).

target_company + deal:

target_company: legal_name: "주식회사 킵코퍼레이션" brand_name: "iipuda" biz_no: "TBD (dataroom 06.정관_등본)" sector: "Medical Tourism Platform" founding_date: "TBD" deal: deal_code: "Iippo" target_company: Iippo primary_entity_id: "axe_ia_001" # 1호가 리드 (블라인드 펀드) stage: "Closed" # 2026-05-06 IC v8 통과 owner_email: "[email protected]"

fund_investment — Iippo 의 1:N split (D-index-5 의 핵심 검증 케이스):

fund_investments: - fund_entity_id: "axe_ia_001" round_label: "Pre-A RCPS 1호 v9.0" instrument: "RCPS" committed_krw: 99998912 # 16,832주 × 5,941원 share_count: 16832 price_per_share: 5941 entry_date: "2026-04-30" # v9.0 sign-off APPROVED paid_date: "2026-05-15" pre_money_krw: 6000000000 # 60억 post_money_krw: 6200000000 # 62억 ownership_pct_post: 0.016130 # 1호 단독 1.613% (1호 + 2호 = 3.226%) ownership_pct_fd: 0.010325 # F/D 1.0325% (희석 0.64x 후) status: "paid" conditions: [] # 무조건 GO evidence_citations: - kind: onedrive path: "dataroom/07.리드투자_서류준비/RCPS_v9.0/" - fund_entity_id: "axe_ia_002" round_label: "Pre-A RCPS 2호 v6 (Conditional)" instrument: "RCPS" committed_krw: 100000000 # 잠정 1.5-2.0억 미확정 (강태훈 IC #2) share_count: null # 협상 진행 중 price_per_share: 5941 # 같은 round 같은 단가 entry_date: null # 협상 미완 paid_date: null # 6 PCC 후 pre_money_krw: 6000000000 post_money_krw: 6200000000 ownership_pct_post: 0.016129 # 1.613% ownership_pct_fd: 0.010325 status: "committed" conditions: # 6 PCC trigger - "PCC #3 — KPI 정합성 + AXEV 소개 병원 status" - "PCC #4 — 앤틀러 RCPS amend + Michael Lin SAFE amend" - "PCC #5 — 이사회 관찰권 + Pro-rata 명시" - "PCC #6 — Q4 anti-dilution 법무 검토" - "운영 신호 — 샤오홍슈 캠페인 + Q1-Q2 2026 경영성과" - "품질 KPI — iipuda Guide 인증 dashboard 가동" evidence_citations: - kind: onedrive path: "ic/memo/v8.md#1.1.5"

financial_model (v7 base 기준):

financial_model: deal_code: "Iippo" version: 7 name: "Iippo IC v7 base model" time_axis_kind: "year" start_period: "2025-01-01" # Y0 = 2025 가결산 horizon_periods: 7 # Y0 ~ Y7 (2025~2032) currency: "KRW" unit_scale: 1 base_revenue_period0: 120000000 # 1.20억 = 2025 가결산 source_xlsx_citation: kind: onedrive path: "Prj_Iippo/ic/finance/3fs_base/v7.xlsx"

financial_scenario (4종):

financial_scenarios: - code: base name: "AXE Base" kind: base probability: 0.50 description: "AXE 보수화 — 회사 IR 8개월 200병원 시뮬레이션을 시장 ramp 평균 (월 +5병원) 으로 할인" driver_changes: story: "병원 ramp 월 +5, Y3 매출 34.6억, 2030 EBITDA 38억 × EV/EBITDA 12x = 456억 EV" key_assumption_overrides: hospital_ramp: "월 +5병원 (vs Mgmt 월 +25)" china_share: "60% 유지, 다변화 Y3 부터" exit_multiple: "EV/EBITDA 12x" - code: mgmt name: "Mgmt Case" kind: mgmt probability: 0.10 description: "회사 IR 가정 그대로 lift" driver_changes: story: "Y1 200병원/14.75억, Y5 275억, 회사 주장 2030 EV 2조" - code: upside name: "Upside" kind: upside probability: 0.30 # base 보다 약간 낮음 driver_changes: story: "닥터스클럽 leverage 폭발 + 일본/대만 가속 + M&A premium 18x" - code: downside name: "Downside" kind: downside probability: 0.10 driver_changes: story: "Y3 매출 stall + 중국 의존 충격"

financial_driver (15 driver — scenario_deltas yaml 정합):

financial_drivers: - code: revenue_growth_y1 kind: input units: multiple category: revenue description: "Y1 매출 성장 multiplier (revenue[y1] / revenue[y0])" - code: revenue_growth_y2 kind: input units: multiple category: revenue - code: revenue_growth_y3 kind: input # ... y4, y5, y6, y7 - code: gross_margin_terminal kind: input units: percent category: cost - code: opex_sm_per_revenue kind: input units: percent category: opex - code: opex_rnd_per_revenue kind: input - code: opex_ga_per_revenue kind: input - code: ar_days kind: input units: count category: wc - code: inventory_days kind: input - code: ap_days kind: input - code: capex_per_revenue kind: input units: percent category: capex - code: depreciation_years kind: input units: count - code: tax_rate kind: input units: percent # Derived - code: revenue kind: derived formula: "lag(revenue, 1) * (1 + revenue_growth_y[period])" dependencies: ["revenue", "revenue_growth_y1", ..., "revenue_growth_y7"] units: KRW category: revenue - code: ebit kind: derived formula: "revenue * gross_margin_terminal - revenue * (opex_sm_per_revenue + opex_rnd_per_revenue + opex_ga_per_revenue)" dependencies: ["revenue", "gross_margin_terminal", "opex_sm_per_revenue", "opex_rnd_per_revenue", "opex_ga_per_revenue"] units: KRW category: revenue # ... 추가 derived (fcf / nopat / exit_valuation / axe_proceeds)

financial_driver_value (base scenario 일부):

financial_driver_values: # base scenario - { scenario: base, driver: revenue_growth_y1, period: 1, value: 6.5 } # Y1 = 7.8억 (Y0 × 6.5) - { scenario: base, driver: revenue_growth_y2, period: 2, value: 2.4 } # Y2 = 18.7억 - { scenario: base, driver: revenue_growth_y3, period: 3, value: 1.85 } # Y3 = 34.6억 - { scenario: base, driver: revenue_growth_y4, period: 4, value: 1.55 } - { scenario: base, driver: revenue_growth_y5, period: 5, value: 1.40 } # Y5 = 75억 - { scenario: base, driver: revenue_growth_y6, period: 6, value: 1.30 } - { scenario: base, driver: revenue_growth_y7, period: 7, value: 1.25 } - { scenario: base, driver: gross_margin_terminal, period: 5, value: 0.85 } - { scenario: base, driver: opex_sm_per_revenue, period: 5, value: 0.35 } - { scenario: base, driver: opex_rnd_per_revenue, period: 5, value: 0.12 } - { scenario: base, driver: opex_ga_per_revenue, period: 5, value: 0.20 } - { scenario: base, driver: ar_days, period: 5, value: 30 } - { scenario: base, driver: inventory_days, period: 5, value: 0 } - { scenario: base, driver: ap_days, period: 5, value: 30 } - { scenario: base, driver: capex_per_revenue, period: 5, value: 0.02 } - { scenario: base, driver: depreciation_years, period: 5, value: 5 } - { scenario: base, driver: tax_rate, period: 5, value: 0.22 } # ... upside / mgmt / downside override (scenario_deltas yaml 의 다른 값)

exit_matrix_leaf (Iippo base 5y 일부):

exit_matrix_leaves: # base × 5y × ma - { scenario: base, timing: '5y', path: ma, probability: 0.55, axe_proceeds_krw: 1235000000 } # base × 5y × ipo - { scenario: base, timing: '5y', path: ipo, probability: 0.20, axe_proceeds_krw: 1000000000 } # base × 5y × secondary - { scenario: base, timing: '5y', path: secondary, probability: 0.20, axe_proceeds_krw: 600000000 } # base × 5y × writedown - { scenario: base, timing: '5y', path: writedown, probability: 0.05, recovery_rate: 0.10 } # ... 3y / 7y / mgmt / upside / downside 동형

financial_output (compute_outputs 산출):

financial_outputs: - { scenario: base, output_code: axe_proceeds_total, value: 940000000 } # Y5 base 회수 9.4억 - { scenario: base, output_code: irr, value: 0.470 } # 47.0% - { scenario: base, output_code: moic, value: 4.70 } # 회수/투자 ≈ 4.7x # 확률가중 (4 scenario × probability) - { scenario: weighted, output_code: irr_success_only, value: 0.539 } # 성공 IRR 53.9% (memo §1.1) - { scenario: weighted, output_code: irr_loss_included, value: 0.370 } # 손실 포함 IRR 37.0% - { scenario: weighted, output_code: moic_loss_included, value: 14.9 } # MoM 14.9x

Per-fund IRR (fund_investment 별):

# financial_output 의 axe_proceeds_total = 9.4억 (base) # 1호 ratio = 99,998,912 / 199,998,912 = 0.500003 # 2호 ratio = 100,000,000 / 199,998,912 = 0.499997 fund_investment_irrs: - { fund: axe_ia_001, scenario: base, paid_date: "2026-05-15", proceeds_at: "2030-06-30", cash_flow: [-99998912, +470004700], irr: 0.4732, moic: 4.70 } - { fund: axe_ia_002, scenario: base, paid_date: "2026-08-15", # PCC 6 후 3 개월 가정 proceeds_at: "2030-06-30", cash_flow: [-100000000, +469995300], irr: 0.4801, moic: 4.70 } # 같은 회수, paid 3 개월 지연 → IRR 약간 ↑ (보유 기간 짧음)

Sentry (센티넬딥액티브)

기초 데이터: /Users/axe/Library/CloudStorage/OneDrive-AXE/AXE - Ventures/1_Project/Prj_Sentry/ic/{memo/v4.md, finance/*}.

target_company: legal_name: "주식회사 센티넬딥액티브" biz_no: "708-86-02988" sector: "AI Asset Management" founding_date: "2023" deal: deal_code: "Sentry" primary_entity_id: "axe_ia_001" stage: "Closed" # 2026-05-14 v4 만장 찬성 fund_investments: - fund_entity_id: "axe_ia_001" round_label: "Pre-A Bridge RCPS" instrument: "RCPS" committed_krw: 500068750 # 4,495주 × 111,250원 share_count: 4495 price_per_share: 111250 entry_date: "2026-05-06" # 현대차 5-6 날인 paid_date: "2026-05-08" pre_money_krw: 9290000000 # 92.9억 post_money_krw: 9790000000 # 97.9억 ownership_pct_post: 0.0473 # 4.73% ownership_pct_fd: 0.0446 # 4.46% F/D status: "paid" - fund_entity_id: "axe_ia_001" round_label: "Series A Pro-rata Option" instrument: "TBD" # 후속 라운드 시 결정 committed_krw: 500000000 # 추가 5억 option status: "committed" # 옵션 — 6 개월 KPI 충족 시 행사 conditions: - "Series A 라운드 진입 확정" - "후속 6개월 KPI 충족" # financial_model (Sentry v3 기준 — 본 docs 의 worked example 은 abbreviate) financial_model: version: 3 source_xlsx_citation: path: "Prj_Sentry/ic/finance/3fs_base/v3.xlsx" scenarios: - { code: upside, probability: 0.19, axe_proceeds: 23600000000 } # 236억 (5y M&A_strategic or IPO) - { code: base, probability: 0.49 } - { code: mgmt, probability: 0.05 } - { code: downside, probability: 0.27 } outputs: irr_success_only: 0.599 # 59.9% (memo §1.1) irr_loss_included: 0.414 # 41.4% moic_success_only: 16.8 moic_loss_included: 13.2

Sentry 는 1 deal × 1 fund × 2 round (initial + future option) — fund_investment 2 row.

Canopy (사이클로이드, bardream)

기초 데이터: Prj_Canopy/ic/{memo/v5_final.md, finance/*}.

target_company: legal_name: "주식회사 사이클로이드" brand_name: "bardream" sector: "Electric Mobility Subscription" deal: deal_code: "Canopy" primary_entity_id: "axe_ia_001" stage: "Closed" # v5 final 2026-05-15 fund_investments: - fund_entity_id: "axe_ia_001" round_label: "Initial BW (Pre-A)" instrument: "BW" # Bond with Warrants committed_krw: 500000000 # 5억 entry_date: "TBD" paid_date: "TBD" pre_money_krw: 6500000000 # v4 기준 (v5 협상 anchor 80억 F/D 81.28억) status: "paid" - fund_entity_id: "axe_ia_001" round_label: "v5 신주 follow-on" instrument: "신주" committed_krw: 100000000 # 1억 follow (Soohun framing) entry_date: "2026-05-15" # v5 final paid_date: "TBD" pre_money_krw: 8000000000 # O/S Pre 80억 (Post 100억, F/D Pre 81.28억) post_money_krw: 10000000000 status: "committed" conditions: - "AXEC 자금 별도 plug (§10 CP-5)" - "컨소시엄 분담 시도 (부산창경 등)" # financial_model (Canopy v1) financial_model: version: 1 source_xlsx_citation: path: "Prj_Canopy/ic/finance/3fs_base/v1.xlsx" scenarios: - { code: upside, probability: 0.25 } - { code: base, probability: 0.45 } - { code: downside, probability: 0.30 } exit_assumptions: fleet_year_5: 5500 # V3 base 5,500대 market_share: 0.30 # 30% (서울시 PM 25만대 expansion) ebitda_year_5_krw: 6641000000 # 66.41억 (57.5 + 광고 element 8.91) exit_multiple_ev_ebitda: 12 exit_ev_krw: 79700000000 # 797억 exit_net_debt_krw: 30000000000 # 300억 exit_eqv_fd_krw: 49800000000 # 498.28억 outputs: # D-index-16 (2026-05-28): per-leaf methodology 통일. V5_final 정합 데이터로 # per-leaf 가 27% 매칭 검증 완료 (Canopy 26.39%, baseline 27%, Δ=0.01). # 아래 anchor 산출은 deprecated — V1 → V5_final 정합 후 자동 일치. irr_loss_included_per_leaf: 0.27 # ⭐ IC PASS (per-leaf, D-index-16) hurdle_irr: 0.15 irr_excess: 0.119 # +11.9pp 여유

Canopy 는 1 deal × 1 fund × 2 round (다른 시점 + 다른 instrument BW → 신주).

3 deal cross-check 표

항목IippoSentryCanopy
Multi-fund2 fund (1호+2호) ⭐1 fund1 fund
Multi-round1 round2 round (initial + future option)2 round (initial + follow-on)
Instrument 변화RCPS onlyRCPS → TBD (옵션)BW → 신주 ⭐
Total committed199,998,912원500,068,750원 (+ 5억 option)500,000,000원 (+ 1억 follow)
Scenarios4 (base/mgmt/upside/downside)43 (upside/base/downside)
Probability base0.500.490.45
Success IRR (per-leaf)53.9%59.9%44.1% (V5 정합 후)
IC pass IRR (loss-included, per-leaf)37%41%27%
Hold years4.17y5.4y4.67y
Exit multipleEV/EBITDA 12xPER 15x (upside) / 8x (base)EV/EBITDA 12x
Key memov8 (2026-05-06)v4 (2026-05-14)v5_final (2026-05-15)

세 deal 이 fund_investment 의 3 차원 N:M 을 모두 cover — Phase 0 acceptance fixture (D-index-10).

MCP tools (financial 관련)

⚠ design-era 이름 — 아래 표는 D-index-4/5 설계 시 가안한 tool 명세다. served tool 의 현행 SoT 는 /services/index § MCP 도구 카탈로그 (27개). 매핑: ingest_financial_model_xlsximport_xlsx/propose_artifacts_from_ingest, compare_drivers_across_dealscross_deal_benchmark, export_xlsxexport_lp_model/export_lp_bundle, get_financial_modelget_deal. IRR 은 weighting 인자 없이 IRR(E[CF]) 가 유일 canonical (D-index-25/32success_only/loss_included weighting 폐기). compute_full_model (DSL evaluator) + compute_3fs (IS/BS/CF) 가 추가됨.

ToolScope기능
ingest_financial_model_xlsx(deal_id, xlsx_blob, hint?)writeLLM 보조 driver tree extract → propose financial_model + drivers + values
propose_financial_model(deal_id, drivers, scenarios, values, exit_matrix)writeDB 직접 (xlsx 없이)
update_driver(model_id, code, formula?, dependencies?, units?)writeunlocked 만
update_driver_value(model_id, driver_code, scenario_id, period_index, value)writeunlocked 만
create_scenario(model_id, code, name, kind, probability, driver_changes, overrides{})writeparent_scenario fork chain
compute_outputs(model_id, scenario_id?)writetopo evaluator 실행 → output row 적재. inputs_hash 비교
get_financial_model(model_id, include_drivers?, include_values?)readmodel + components
list_scenarios(model_id)readscenario 4종 + probability
query_driver_series(deal_id, driver_code, periods[], scenarios[])readcross-deal driver benchmark — 본 서비스 핵심 query
`query_irr(deal_id, fund_investment_id?, weighting=‘success_only''loss_included’)`read
compare_drivers_across_deals(driver_code, deal_ids[], scenarios[])readcross-portfolio benchmark
lock_financial_model(model_id)approveimmutable 전환 + locked_at set
export_xlsx(model_id, scenario_ids[])readround-trip 재생성
validate_financial_model(model_id)readic skill 의 4 check 통합 결과

Phase 0 Acceptance Bar

D-index-10 의 검증 fixture:

Test조건
A13 deal seed yaml → index DB ingest 성공 (target_company + deal + fund_investment + financial_model + financial_driver + financial_scenario + financial_driver_value + exit_matrix_leaf 모두 적재)
A2compute_outputs(iippo_model_id, base_scenario_id) 결과의 axe_proceeds_total 가 ic skill 의 irr_analysis/v7.xlsx cell J42 와 ±1% 일치
A3query_irr(iippo_deal_id, fund_investment_id=axe_ia_001, weighting='success_only') = 53.9% ±0.5pp
A4query_irr(iippo_deal_id, fund_investment_id=axe_ia_002, weighting='success_only') 가 1호 IRR 과 다름 (paid_date 지연 반영)
A5compare_drivers_across_deals('gross_margin_terminal', [iippo, sentry, canopy], ['base']) 가 3 row 반환
A6export_xlsx(iippo_model_id, [base_scenario_id]) 결과 xlsx 가 원본 3fs_base/v7.xlsx 와 ±0 driver cell diff
A7validate_financial_model(iippo_model_id) 4 check 모두 PASS (또는 ic skill 의 기존 warning 과 100% 일치)
A8Blueprint artifact 의 IC memo citation = { kind: "index.financial_output", model_id, scenario_id: "base", output_code: "irr" } resolve 시 0.470 반환

8 test 통과 시 Phase 0 완료.

관련 페이지

Last updated on