open-annex-iv
v1.0.0
Published
Open-source AIFMD Annex IV XML serialization library. Converts plain report objects to ESMA-compliant XML.
Maintainers
Readme
open-annex-iv
Open-source AIFMD Annex IV XML serialization library.
Zero dependencies. Pure functions. TypeScript-first. XSD-validated against ESMA AIFMD_DATAIF_V1.2.xsd (Rev 6).
Why this exists
Every AIFM in Europe must file Annex IV reports to regulators (BaFin, CSSF, AMF, CNMV, etc.) under Article 24 of the AIFMD. The XML format follows ESMA's technical standards, but there are zero open-source tools to generate it. Fund managers either pay €15–50K/yr for enterprise software or build fragile in-house pipelines.
This library changes that.
Features
- XML Serialization — Convert a plain
AnnexIVReportobject to ESMA-compliant Annex IV XML - Aggregate Reports — Generate AIFM-level XML covering multiple funds
- ESMA Code Mappings — Fund types, asset classes, depositary types → ESMA codes
- EEA Helpers — Country name/code validation, domicile-to-member-state mapping
- Reporting Obligation Detection — Article 24(1)/24(2)/24(4) classification
- XSD Validated — Output passes ESMA AIFMD_DATAIF_V1.2.xsd Rev 6 schema validation
- 179 tests passing
Installation
npm install open-annex-ivQuick Start
import { serializeAnnexIVToXml, type AnnexIVReport } from 'open-annex-iv';
const report: AnnexIVReport = {
aif_identification: {
reporting_period: { start: '2025-01-01', end: '2025-03-31' },
aif_name: 'Muster Immobilien Spezial-AIF',
aif_national_code: 'DE000001',
aif_type: 'Spezial_AIF',
domicile: 'Germany',
inception_date: '2020-01-15',
aifm_name: 'Muster KVG GmbH',
aifm_lei: '529900EXAMPLE000LEI00',
reporting_obligation: 'Article 24(2)',
base_currency: 'EUR',
},
investor_concentration: {
total_investors: 12,
by_type: [{ investor_type: 'professional', count: 8, percentage_of_nav: 72.5 }],
by_domicile: [{ domicile: 'Germany', count: 10, percentage_of_nav: 85.0 }],
beneficial_owners_concentration: { top_5_investors_pct: 45.2 },
},
principal_exposures: {
total_aum_units: 10000,
total_allocated_units: 8500,
total_aum_eur: 150_000_000,
total_nav_eur: 127_500_000,
utilization_pct: 85.0,
asset_breakdown: [{
asset_name: 'Berlin Office Portfolio',
asset_type: 'real_estate',
units: 5000,
value_eur: 75_000_000,
percentage_of_total: 58.8,
}],
},
depositary: {
name: 'CACEIS Bank',
lei: '96950023O5B6JXLY0S86',
jurisdiction: 'Germany',
type: 'credit_institution',
},
sub_asset_type: 'OTHR_OTHR',
leverage: {
commitment_method: 1.2,
gross_method: 1.4,
commitment_limit: 2.0,
gross_limit: 3.0,
leverage_compliant: true,
},
risk_profile: {
liquidity: {
investor_redemption_frequency: 'Quarterly',
portfolio_liquidity_profile: [],
liquidity_management_tools: [],
},
operational: { total_open_risk_flags: 0, high_severity_flags: 0 },
},
geographic_focus: [{ region: 'Germany', percentage: 85.0 }],
counterparty_risk: { top_5_counterparties: [], total_counterparty_count: 0 },
compliance_status: {
kyc_coverage_pct: 100,
eligible_investor_pct: 100,
recent_violations: 0,
last_compliance_check: '2025-03-31T00:00:00Z',
},
generated_at: '2025-03-31T12:00:00Z',
report_version: '1.0',
disclaimer: 'For regulatory reporting purposes only.',
};
const xml = serializeAnnexIVToXml(report);
// → Valid ESMA Annex IV XML ready for NCA submissionAPI Reference
Serializers
| Function | Description |
|---|---|
| serializeAnnexIVToXml(report) | Single fund → ESMA Annex IV XML string |
| serializeAggregateAnnexIVToXml(reports) | Multiple funds → AIFM-level aggregate XML |
Helpers
| Function | Description |
|---|---|
| isEEADomicile(domicile) | Check if country name or ISO code is in the EEA |
| mapDomicileToMemberState(domicile) | Country name → ISO 3166-1 alpha-2 code |
| toISOCountryCode(region) | Region/country → ISO code (supports aggregate regions) |
| mapToPredominantAIFType(legalForm, name?) | Legal form → ESMA PredominantAIFType code |
| mapAssetType(assetType) | Asset type → ESMA SubAssetType code |
| mapDepositaryType(type) | Depositary type → ESMA code |
| mapReportingObligationToFrequencyCode(obligation) | Reporting obligation → frequency code |
| escapeXml(str) | XML-safe string escaping |
| tag(name, value, attrs?) | XML element builder |
Types
import type {
AnnexIVReport,
LiquidityManagementTool,
LiquidityBucket,
GeographicExposure,
CounterpartyExposure,
} from 'open-annex-iv';XSD Validation
The XML output is validated against the official ESMA schemas included in schema/:
AIFMD_DATAIF_V1.2.xsd— AIF-level reportingAIFMD_DATMAN_V1.2.xsd— AIFM-level reportingAIFMD_REPORTING_DataTypes_V1.2.xsd— Shared data types
All 179 tests pass, including full XSD validation against these schemas.
ESMA Alignment
The XML output follows the ESMA AIFMD Reporting Technical Standards structure:
AIFReportingInfo → AIFMRecordInfo → AIFRecordInfo → sectionsCovers: AIF Identification, Investor Concentration, Principal Exposures, Leverage, Liquidity Risk, Counterparty Risk, Geographic Focus, Depositary Information.
Contributing
Contributions welcome. Please open an issue first to discuss what you'd like to change.
git clone https://github.com/julianlaycock/open-annex-iv.git
cd open-annex-iv
npm install
npm testLicense
Built by Caelith Technologies — compliance infrastructure for EU fund managers.
