Canonical CSV
Upload Protocol
Governing field definitions, scaling conventions, identity validation, and submission requirements for Engine B institutional diagnostic processing.
Overview
Engine B is a deterministic, Six-Pillar bankability diagnostic engine. It accepts issuer financial data in a strictly defined canonical CSV format and produces a VIU Bankability Score™ for each submitted period. The engine enforces all input rules programmatically — files that do not conform are rejected before any diagnostic processing begins.
This protocol defines the exact structure, field semantics, scaling conventions, and validation rules required for a successful upload. It is the authoritative reference for all client data preparation teams, financial analysts, and third-party integrators submitting issuer data for Engine B evaluation.
File Format Requirements
- Format: Comma-separated values (.csv) — UTF-8 encoded, no BOM
- Header row: Required on line 1 — exact column names in exact order (see Section 03)
- One row per issuer per fiscal year — multiple periods for the same issuer are submitted as multiple rows
- No blank rows, no subtotals, no summary rows — data rows only after the header
- No currency symbols, commas within numbers, or percentage signs — numeric fields are plain integers or decimals
- No quoted strings unless the field value contains a comma
- Line endings: LF or CRLF both accepted
- Maximum file size: 10MB per submission
Field Definitions
The canonical header is exactly 17 columns in the order below. REQUIRED fields must be populated. CONDITIONAL fields depend on issuer type. ZERO-OK fields accept 0 for unlisted or unavailable data.
ticker,name,sector,revenue,ebitda,net_income,total_assets,equity,debt,cash,capex,cfo,price,shares,beta,sector_pe,fiscal_year
| Column | Type | Definition & Engine Rule |
|---|---|---|
| ticker REQUIRED | string | Issuer identifier. 2–6 uppercase characters. Used as the primary key across multi-period submissions. Must be consistent across all rows for the same issuer. |
| name REQUIRED | string | Full issuer name as it should appear on the diagnostic output. Appears verbatim on the Engine B report header. |
| sector REQUIRED | string | Issuer sector classification. Used for peer benchmarking and sector_pe cross-referencing. Must be consistent across all periods for the same issuer. Examples: Agro-Industrial · Electrical Equipment · Financial Services · Technology · Healthcare · Energy |
| revenue REQUIRED | integer | Total revenue for the fiscal year. Full absolute value in the issuer's reporting currency. Must be a positive integer. If source data is in thousands (USD '000), multiply by 1,000 before submission. |
| ebitda REQUIRED | integer | Earnings Before Interest, Tax, Depreciation and Amortisation. May be negative for loss periods. Full absolute value. EBITDA = Gross Profit − Operating Expenses (before D&A). Do not use EBIT. |
| net_income REQUIRED | integer | Net profit after all items including tax and interest. May be negative. Full absolute value. |
| total_assets REQUIRED | integer | Total assets from the balance sheet. Must equal Total Liabilities + Total Equity. Engine B validates this identity on every row. |
| equity REQUIRED | integer | Total shareholders' equity (Share Capital + Retained Earnings + Reserves). Used to compute Debt/Equity and the balance sheet identity. |
| debt REQUIRED | integer |
TOTAL LIABILITIES — not financial debt. Engine B defines debt as total_assets − equity. This includes all current liabilities, long-term debt, deferred liabilities, and any other non-equity obligations.
Identity enforced: debt = total_assets − equity. Any deviation causes immediate rejection.
⚠ Common error: submitting only LT Debt + ST Borrowings. This will fail the identity check.
|
| cash REQUIRED | integer | Cash and cash equivalents from the balance sheet. Used in Altman-Z and liquidity ratio calculations. Must be a non-negative integer. |
| capex REQUIRED | integer | Capital expenditure for the period. Submitted as a positive integer (the engine applies the sign). From the investing activities section of the cash flow statement. Use 0 if no capex was incurred. Do not submit as negative. |
| cfo REQUIRED | integer | Net Cash from Operating Activities — the bottom line of Section A of the cash flow statement. May be negative. This is the direct operating cash flow, not EBITDA. Do not substitute EBITDA for CFO. They are distinct inputs mapped to distinct pillars. |
| price ZERO-OK | decimal | Share price at fiscal year end in the issuer's reporting currency. Required for P/E, P/B, and P/S ratio calculations under Pillar II. Submit 0 for private (unlisted) issuers. Valuation ratios will return 0.00; EV/EBITDA remains active. |
| shares CONDITIONAL | integer | Shares outstanding at fiscal year end. Required for market-cap-dependent valuation ratios under Pillar II.
For listed issuers: submit actual shares outstanding as a positive integer.
For private/unlisted issuers: submit 1 (not 0). The engine requires a non-zero placeholder to avoid division-by-zero in market capitalisation calculations. All share-price-dependent ratios (P/E, P/B, P/S) will return 0.00. EV/EBITDA remains active.
⚠ Submitting 0 for shares on a private issuer may cause calculation errors in Pillar II sub-ratios. Use 1 as the canonical private issuer placeholder.
|
| beta ZERO-OK | decimal | Equity beta relative to the issuer's primary market index. Used in Pillar V — Risk & Resilience calculations.
For listed issuers: source from the issuer's primary exchange. Typical ranges: 0.60–0.85 (defensive), 0.85–1.20 (cyclical), 1.20+ (high-volatility).
For private/unlisted issuers or where beta is unavailable due to jurisdictional data constraints: submit 0. The engine applies a neutral beta treatment and processes Pillar V from balance sheet and cash flow inputs only. This will reduce the Pillar V score but will not cause a rejection.
Jurisdictional note: in markets where equity beta data is not publicly published or where the issuer has no listed comparable, submitting 0 is the correct and accepted approach.
|
| sector_pe ZERO-OK | decimal | Sector-level price-to-earnings multiple used as the valuation benchmark in Pillar II normalisation. Source from current market data for the issuer's sector where available.
Where available: use a peer-derived or published sector P/E. Common ranges: Consumer/Agro 10–15 · Industrial 12–18 · Technology 20–35 · Financial Services 8–14.
Where unavailable due to jurisdictional constraints, private issuer status, or absence of listed comparable peers: submit 0. The engine applies a floor treatment for Pillar II normalisation. When sector_pe = 0, Pillar II will score at the engine floor of 25.0 — preserving the diagnostic output without rejection.
Jurisdictional note: in Sub-Saharan Africa, Central Asia, and other markets where sector P/E multiples are not publicly available for Agro-Industrial or equivalent sectors, submitting 0 is the canonical accepted approach.
|
| fiscal_year REQUIRED | integer | Four-digit fiscal year of the data period (e.g. 2023, 2024, 2025). Audited actuals and forward forecasts use the same format — the engine does not distinguish between A and F designations in the CSV. Each issuer-year combination must be unique. Duplicate rows for the same ticker and fiscal_year will cause a rejection. |
The Balance Sheet Identity Rule
Engine B enforces a hard balance sheet identity on every row before any diagnostic processing begins. This is the single most common cause of rejection.
debt = total_assets − equity Equivalently: total_assets = debt + equity Any row where this identity does not hold to the integer is rejected immediately. No partial processing occurs.
What this means in practice: the debt column must contain Total Liabilities — the full liability side of the balance sheet — not financial debt alone.
(48,000 + 22,000) × 1,000
104,600,000 ≠ 70,000,000 + 16,100,000
total_assets − equity
104,600,000 = 88,500,000 + 16,100,000
Scaling Convention
Engine B expects all monetary fields in full absolute currency units — not thousands, not millions. Financial statements that report in USD '000 or USD millions must be scaled up before submission.
Source reports in USD '000 → multiply all monetary fields × 1,000 Source reports in USD 'M → multiply all monetary fields × 1,000,000 Source reports in full USD → submit as-is Example — KAGA Group Revenue FY2025: Source (USD '000): 104,890 Submitted to Engine B: 104,890,000
- Scaling applies to all 9 monetary fields:
revenue · ebitda · net_income · total_assets · equity · debt · cash · capex · cfo - Non-monetary fields (
beta · sector_pe · price) are submitted as decimals with no scaling - Mixed scaling within a single file — some rows in USD '000 and others in full USD — will produce incorrect diagnostic outputs that Engine B cannot detect. The submitter is responsible for consistency
- Currency must be consistent across all rows in a single file. Multi-currency submissions require prior conversion to a single reporting currency
Private and Unlisted Issuers
Engine B fully supports private, unlisted, and state-owned issuers. Market-dependent fields are handled via a defined protocol that preserves Pillar II (Valuation) scoring through EV/EBITDA while zeroing out price-based ratios.
| Field | Canonical Private Value | Engine Behaviour |
|---|---|---|
| price | 0 | P/E, P/B, P/S ratios return 0.00. EV/EBITDA computed from balance sheet proxy. Does not cause rejection. |
| shares | 1 | Submit 1, not 0. The engine requires a non-zero placeholder to prevent division-by-zero in market capitalisation calculations. All share-price-dependent ratios return 0.00. EV/EBITDA remains active from balance sheet inputs. |
| beta | 0 | Submit 0 where beta is unavailable or where listed comparable data does not exist for the jurisdiction. Engine applies neutral beta treatment. Pillar V scored from balance sheet and cash flow inputs only. No rejection. |
| sector_pe | 0 | Submit 0 where sector P/E is unavailable for the jurisdiction or sector. Engine applies floor treatment. Pillar II scores at the engine floor of 25.0. No rejection. |
Multi-Period Submissions
Engine B is designed for multi-period analysis. Submitting multiple fiscal years for the same issuer in a single file is the recommended approach — it enables the engine to compute growth rates, trend signals, and period-over-period pillar progression.
- Each period is a separate row with the same
tickerand a distinctfiscal_year - Rows may include audited actuals (e.g. FY2023A, FY2024A) and forward forecasts (FY2025F, FY2026F) — the engine processes both identically
- Minimum 1 period required. Maximum periods per issuer per submission: 20
- Multiple issuers may be included in a single file — rows are grouped by
ticker - The engine generates one diagnostic output per issuer per period — a 6-period submission for one issuer produces 6 diagnostic reports
Rejection Reference
Engine B returns a rejection code and affected row number when a file fails validation. Common rejection causes, error signals, and corrections:
Worked Example — KAGA Group
The following is the accepted canonical CSV for KAGA Group (Agro-Industrial), covering FY2023 through FY2028F. Six individual CSV files were submitted — one per period — each cumulative from FY2023. All files passed Engine B validation and produced six diagnostic outputs. The complete trajectory demonstrates credit enhancement from Critical to Strong across a six-year horizon.
This is a private, unlisted Agro-Industrial holding entity operating in a jurisdiction where equity beta data and sector P/E comparables are not publicly available. The canonical private issuer values — shares=1, beta=0, sector_pe=0 — are applied throughout and accepted by the engine without modification.
ticker,name,sector,revenue,ebitda,net_income,total_assets,equity,debt,cash,capex,cfo,price,shares,beta,sector_pe,fiscal_year KGF,KAGA Group,Agro-Industrial,67700000,13000000,3300000,83000000,13000000,70000000,4200000,9800000,8000000,0,1,0,0,2023 KGF,KAGA Group,Agro-Industrial,86100000,17000000,7400000,93700000,13700000,80000000,6800000,10400000,11600000,0,1,0,0,2024 KGF,KAGA Group,Agro-Industrial,104890000,22290000,11410000,104600000,16100000,88500000,8500000,11200000,14830000,0,1,0,0,2025 KGF,KAGA Group,Agro-Industrial,114900000,24500000,12860000,111900000,18800000,93100000,9900000,11700000,18420000,0,1,0,0,2026 KGF,KAGA Group,Agro-Industrial,125900000,26800000,14300000,120000000,22200000,97800000,11400000,12300000,19800000,0,1,0,0,2027 KGF,KAGA Group,Agro-Industrial,138900000,29700000,16300000,129200000,26600000,102600000,13200000,13000000,27500000,0,1,0,0,2028
Gold values = debt field (Total Liabilities). Each satisfies: total_assets − equity = debt exactly. Source data was in full currency units. Green values = canonical private issuer placeholders: shares=1 (non-zero engine placeholder), beta=0 (jurisdictional constraint), sector_pe=0 (no listed peer universe). KAGA Group is a private Agro-Industrial holding entity — no exchange listing, no public beta, no sector P/E reference available in jurisdiction.
KAGA Group — Credit Enhancement Trajectory
The KAGA Group submission demonstrates the Engine B multi-period diagnostic as a credit enhancement instrument. Six CSVs were submitted sequentially — each adding one additional fiscal year — producing six independent diagnostic outputs that document the issuer's complete bankability trajectory.
| Period | Score | Zone | Key Pillar Movement | CSV Submitted |
|---|---|---|---|---|
| FY2023 | 21.43 | CRITICAL | Risk & Resilience 0.0 · Balance Sheet 8.4 · Cash Flow 19.1 | ve2023testF1.csv |
| FY2024 | 32.01 | EXPOSED | Risk & Resilience 10.4 · Balance Sheet 12.1 · Cash Flow 24.2 | ve2024testF1.csv |
| FY2025 | 40.43 | EXPOSED | Risk & Resilience 22.7 · Balance Sheet 13.5 · Cash Flow 46.2 | ve2025testF1.csv |
| FY2026 | 45.85 | EXPOSED | Risk & Resilience 26.3 · Balance Sheet 14.8 · Cash Flow 81.1 | ve2026testF1.csv |
| FY2027 | 47.16 | EXPOSED | Risk & Resilience 29.7 · Balance Sheet 15.8 · Cash Flow 83.2 | ve2027testF1.csv |
| FY2028 | 50.84 | STRONG | Risk & Resilience 34.0 · Balance Sheet 17.0 · Cash Flow 94.7 | ve2028testF.csv |
FY2023 21.43 CRITICAL ████░░░░░░░░░░░░░░░░░░░░░░░░░░ FY2024 32.01 EXPOSED ████████░░░░░░░░░░░░░░░░░░░░░░ FY2025 40.43 EXPOSED ██████████░░░░░░░░░░░░░░░░░░░░ FY2026 45.85 EXPOSED ████████████░░░░░░░░░░░░░░░░░░ FY2027 47.16 EXPOSED ████████████░░░░░░░░░░░░░░░░░░ FY2028 50.84 STRONG █████████████░░░░░░░░░░░░░░░░░ Trajectory driver: Cash Flow Quality (19.1 → 94.7) and Risk & Resilience (0.0 → 34.0) — five-year compounding. Pillar II fixed at engine floor 25.0 — jurisdiction constraint.
Pre-Submission Checklist
Verify all items below before submitting a CSV to Engine B. A file that passes this checklist will not be rejected on structural grounds.
- ✓Header row is present on line 1 and matches the canonical sequence exactly — 17 columns, exact names, exact order
- ✓All monetary fields are in full absolute currency units — no USD '000 or USD millions submitted without scaling
- ✓debt = total_assets − equity on every row — verified to the integer
- ✓debt represents Total Liabilities — not LT Debt, not financial debt, not net debt
- ✓cfo is Net Cash from Operating Activities — not EBITDA, not operating profit
- ✓capex is a positive integer — sign applied by the engine
- ✓For private issuers: price = 0 and shares = 1 (not 0 — use 1 as the engine placeholder); beta = 0 where jurisdictional data is unavailable; sector_pe = 0 where no listed peer universe exists. All three combinations are accepted by Engine B.
- ✓No duplicate ticker + fiscal_year combinations
- ✓No currency symbols, percentage signs, or comma-formatted numbers in numeric fields
- ✓Sector classification is consistent across all periods for the same issuer
- ✓All monetary fields share the same reporting currency — no mixed-currency rows
- ✓File is saved as .csv with UTF-8 encoding — no BOM, no Excel .xlsx format