Document Purpose: Explain the complexity of COREP/FINREP regulatory reporting, the Data Point Model (DPM) approach, and GLOMIDCO's innovative middleware-based solution using distributed mapping and intelligent merging
Last Updated: January 2026
Target Audience: Regulatory reporting architects, banking IT professionals, XBRL implementers
The Challenge:
COREP and FINREP are European banking regulatory reporting frameworks that produce massive XBRL instances - often 60+ tables with thousands of data points, using complex dimensional structures via Table Linkbase.
Traditional Approach:
Most solutions use a Data Point Model (DPM) database - a monolithic structure that must be populated before generating the final XBRL instance.
Problems with DPM:
GLOMIDCO Solution:
Leverage middleware platforms (MuleSoft, Tibco BW, webMethods) with specialized XBRL plugins/connectors to:
Result:
COREP (Common Reporting)
FINREP (Financial Reporting)
Relationship:
Both are part of the Supervisory Reporting framework under CRR/CRD IV.
┌─────────────────────────────────────────────┐
│ European Banking Supervision │
├─────────────────────────────────────────────┤
│ │
│ EBA (European Banking Authority) │
│ └─ Develops technical standards │
│ └─ Publishes taxonomies (XBRL) │
│ └─ Updates requirements annually │
│ │
│ National Regulators │
│ └─ Implement EBA standards │
│ └─ Collect reports from banks │
│ └─ Forward to EBA and ECB │
│ │
│ Banks (Reporting Entities) │
│ └─ Must submit COREP/FINREP │
│ └─ Must use EBA XBRL taxonomy │
│ └─ Strict deadlines (T+30 to T+55 days) │
│ │
└─────────────────────────────────────────────┘
Typical COREP/FINREP Submission (2024):
Total Templates: 60-100+
Required Templates: 40-70 (depends on institution type)
Examples:
COREP:
├─ C 01.00 - Own Funds
├─ C 02.00 - Own Funds Requirements
├─ C 03.00 - Credit Risk (SA)
├─ C 04.00 - Credit Risk (IRB)
├─ C 08.00 - Large Exposures
├─ C 09.00 - Geographical Breakdown
├─ C 14.00 - Market Risk
├─ C 16.00 - Operational Risk
├─ C 67.00 - Leverage Ratio
├─ ... (30+ more templates)
FINREP:
├─ F 01.01 - Balance Sheet - Assets
├─ F 01.02 - Balance Sheet - Liabilities
├─ F 01.03 - Balance Sheet - Equity
├─ F 02.00 - Income Statement
├─ F 04.00 - Breakdown of Loans
├─ F 08.00 - Geographical Breakdown
├─ F 18.00 - Asset Encumbrance
├─ ... (30+ more templates)
Data Volume:
Update Frequency:
COREP/FINREP extensively use XBRL Table Linkbase specification:
<!-- Simplified example: C 01.00 Own Funds table structure -->
<table:table>
<table:tableBreakdown>
<!-- Axis 1: Line items (rows) -->
<table:breakdown axis="eba_dim:CAPAxis">
<table:ruleNode>
<table:concept>
eba:OwnFundsTier1
</table:concept>
</table:ruleNode>
<table:ruleNode>
<table:concept>
eba:OwnFundsTier2
</table:concept>
</table:ruleNode>
<!-- ... hundreds more rows -->
</table:breakdown>
<!-- Axis 2: Columns -->
<table:breakdown axis="eba_dim:MCYAxis">
<table:ruleNode>
<table:dimensionMember>
eba:ReportingDate
</table:dimensionMember>
</table:ruleNode>
<table:ruleNode>
<table:dimensionMember>
eba:PriorReportingDate
</table:dimensionMember>
</table:ruleNode>
</table:breakdown>
<!-- Axis 3: Additional dimensions (if applicable) -->
<table:breakdown axis="eba_dim:BANAxis">
<!-- Bank entity breakdown -->
</table:breakdown>
</table:tableBreakdown>
</table:table>
Challenges:
Multi-dimensional cells
Open vs Closed axes
Complex hierarchies
Conditional structures
Single cell in C 01.00 (Own Funds):
Concept: eba:OwnFundsTier1Capital
Dimensions:
├─ Period: 2024-12-31
├─ Entity: Bank XYZ (LEI: 1234567890ABCDEFGHIJ)
├─ Scenario: Actual (not pro-forma)
├─ Reporting Currency: EUR
├─ Consolidation Basis: Consolidated
├─ Accounting Portfolio: IFRS9
└─ Exposure Class: All (not broken down)
Value: 1,250,000,000 EUR
XBRL Representation:
<xbrli:context id="ctx_1">
<xbrli:entity>
<xbrli:identifier scheme="http://standards.iso.org/iso/17442">
1234567890ABCDEFGHIJ
</xbrli:identifier>
<xbrli:segment>
<!-- Consolidation basis -->
<xbrldi:explicitMember dimension="eba_dim:BASAxis">
eba:Consolidated
</xbrldi:explicitMember>
<!-- Accounting portfolio -->
<xbrldi:explicitMember dimension="eba_dim:APPAxis">
eba:IFRS9
</xbrldi:explicitMember>
<!-- Exposure class -->
<xbrldi:explicitMember dimension="eba_dim:ECLAxis">
eba:AllExposures
</xbrldi:explicitMember>
<!-- Reporting currency -->
<xbrldi:explicitMember dimension="eba_dim:MCYAxis">
iso4217:EUR
</xbrldi:explicitMember>
</xbrli:segment>
</xbrli:entity>
<xbrli:period>
<xbrli:instant>2024-12-31</xbrli:instant>
</xbrli:period>
<xbrli:scenario>
<xbrldi:explicitMember dimension="eba_dim:REPAxis">
eba:Actual
</xbrldi:explicitMember>
</xbrli:scenario>
</xbrli:context>
<eba:OwnFundsTier1Capital contextRef="ctx_1" unitRef="EUR" decimals="0">
1250000000
</eba:OwnFundsTier1Capital>
Multiply this by 50,000-200,000 data points!
EBA provides extensive validation rules:
1. Business Rules (Formula Linkbase)
Example: v0001_m
C 01.00, r010, c010 =
C 01.00, r020, c010 +
C 01.00, r030, c010
(Total Own Funds = Tier 1 + Tier 2)
2. Calculation Rules
3. Existence Rules
4. Consistency Rules
Typical validation rule count: 5,000-10,000+ rules
Banks must aggregate data from multiple systems:
┌─────────────────────────────────────────────┐
│ Bank's Source Systems │
├─────────────────────────────────────────────┤
│ │
│ Core Banking System │
│ └─ Loan portfolios │
│ └─ Deposit accounts │
│ └─ Customer data │
│ │
│ Risk Management System │
│ └─ Credit risk calculations │
│ └─ Market risk positions │
│ └─ Operational risk │
│ │
│ General Ledger │
│ └─ Financial accounts │
│ └─ Trial balance │
│ └─ Regulatory adjustments │
│ │
│ Treasury System │
│ └─ Liquidity positions │
│ └─ Funding structures │
│ └─ Capital management │
│ │
│ Data Warehouse / Data Lake │
│ └─ Historical data │
│ └─ Aggregations │
│ └─ Reconciliations │
│ │
└─────────────────────────────────────────────┘
│
▼
COREP/FINREP Reporting Solution
Challenges:
Data Point Model (DPM) is EBA's conceptual model defining the structure of supervisory reporting.
DPM Components:
DPM Database
├─ Metrics (concepts)
│ └─ Own Funds Tier 1 Capital
│ └─ Total Assets
│ └─ Net Interest Income
│
├─ Dimensions
│ └─ Reporting Period
│ └─ Bank Entity
│ └─ Exposure Class
│ └─ Geographic Area
│
├─ Members (dimension values)
│ └─ EU Countries
│ └─ Non-EU Countries
│ └─ Retail exposures
│ └─ Corporate exposures
│
├─ Templates (tables)
│ └─ C 01.00 Own Funds
│ └─ F 01.01 Balance Sheet
│
└─ Data Points (cells)
└─ Template + Row + Column + Filters
└─ Links to Metric + Dimensions
┌─────────────────────────────────────────────┐
│ PHASE 1: Data Collection │
├─────────────────────────────────────────────┤
│ Extract data from source systems │
│ Transform to common format │
│ Load into staging area │
└─────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ PHASE 2: DPM Population │
├─────────────────────────────────────────────┤
│ DPM Database (Relational) │
│ ┌───────────────────────────────────────┐ │
│ │ Table: DATA_POINTS │ │
│ │ ──────────────────────────────────── │ │
│ │ TEMPLATE_ID │ │
│ │ ROW_CODE │ │
│ │ COLUMN_CODE │ │
│ │ DIMENSION_1_VALUE │ │
│ │ DIMENSION_2_VALUE │ │
│ │ ... │ │
│ │ METRIC_VALUE │ │
│ │ ──────────────────────────────────── │ │
│ │ C_01_00 | r010 | c010 | EUR | ... | │ │
│ │ C_01_00 | r020 | c010 | EUR | ... | │ │
│ │ C_01_00 | r030 | c010 | EUR | ... | │ │
│ │ ... (50,000-200,000 rows) │ │
│ └───────────────────────────────────────┘ │
│ │
│ Complex SQL or stored procedures │
│ populate DPM from staging │
└─────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ PHASE 3: XBRL Generation │
├─────────────────────────────────────────────┤
│ Read entire DPM database │
│ Generate contexts for all dimensions │
│ Generate facts for all data points │
│ Apply taxonomy structure │
│ Produce single massive XBRL instance │
└─────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ PHASE 4: Validation │
├─────────────────────────────────────────────┤
│ Run EBA validation rules │
│ Check all 5,000+ business rules │
│ If errors found, go back to Phase 2 │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────┐
│ Single Large DPM Database │
│ (All 60+ templates) │
│ │
│ - One huge ETL process │
│ - All-or-nothing execution │
│ - Single point of failure │
│ - Difficult to troubleshoot │
└─────────────────────────────────────┘
Issue: If template 47 has a problem, you must debug the entire DPM population process.
-- Example: Populating C 01.00 Own Funds template
INSERT INTO DPM_DATA_POINTS (
template_id, row_code, column_code,
dim1, dim2, dim3, dim4, dim5, value
)
SELECT
'C_01_00',
CASE
WHEN account_type = 'CET1' THEN 'r020'
WHEN account_type = 'AT1' THEN 'r030'
WHEN account_type = 'T2' THEN 'r040'
...
END,
'c010',
entity_id,
'EUR',
'Consolidated',
reporting_date,
'Actual',
SUM(balance)
FROM
STAGE_CAPITAL_ACCOUNTS ca
JOIN STAGE_ENTITIES e ON ca.entity = e.entity_code
JOIN STAGE_ACCOUNTING_RULES ar ON ca.account = ar.gl_account
WHERE
reporting_period = '2024-12-31'
AND consolidation_status = 'CONS'
AND (complex conditions...)
GROUP BY
account_type, entity_id, reporting_date
UNION ALL
-- Additional logic for regulatory adjustments
SELECT ...
FROM STAGE_REGULATORY_ADJUSTMENTS
...
UNION ALL
-- Additional logic for deductions
SELECT ...
FROM STAGE_DEDUCTIONS
...
-- (Hundreds more lines of SQL)
Issues:
If ANY template has an error:
└─ Entire DPM population fails
└─ Or entire XBRL generation fails
└─ Must fix and restart from beginning
└─ No partial deliverables
To test one template:
└─ Must populate entire DPM
└─ Must run full XBRL generation
└─ Must validate entire submission
└─ Cannot isolate individual templates
When EBA adds new template or changes structure:
└─ Must modify complex SQL
└─ Must update DPM schema
└─ Must update XBRL generation
└─ High risk of regression
└─ Long testing cycle
DPM logic is specific to COREP/FINREP:
└─ Cannot reuse for other reporting
└─ Cannot reuse mappings
└─ Tight coupling to DPM structure
As data volume grows:
└─ DPM database becomes huge
└─ SQL performance degrades
└─ Generation takes hours
└─ Validation takes hours
┌─────────────────────────────────────────────┐
│ Bank's Source Systems │
│ (Core Banking, Risk, GL, Treasury, etc.) │
└─────────────────────────────────────────────┘
│
│ Standard APIs/Files
▼
┌─────────────────────────────────────────────┐
│ Middleware Platform │
│ (MuleSoft / Tibco BW / webMethods) │
├─────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Flow: C01.00 │ │ Flow: C02.00 │ │
│ │ (Own Funds) │ │ (Own Funds │ │
│ │ │ │ Requirem.) │ ... │
│ └──────────────┘ └──────────────┘ │
│ │ │ │
│ │ ┌──────────────┐ │
│ └────┤ XBRL Plugin ├─────┐ │
│ │ /Connector │ │ │
│ └──────────────┘ │ │
│ │ │ │
│ ┌───────────┴──────────────┘ │
│ │ │
│ ▼ │
│ Partial XBRL │
│ Documents │
│ ├─ C01_partial.xbrl │
│ ├─ C02_partial.xbrl │
│ ├─ C03_partial.xbrl │
│ └─ ... (60+ partial documents) │
│ │
└─────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ GLOMIDCO Intelligent Merger │
├─────────────────────────────────────────────┤
│ • Merge partial XBRL documents │
│ • Resolve context conflicts │
│ • Deduplicate shared contexts/units │
│ • Validate cross-template rules │
│ • Check completeness │
│ • Generate final instance │
└─────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ Complete COREP/FINREP Instance │
│ (Single validated XBRL file) │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ MuleSoft Anypoint Platform │
├─────────────────────────────────────────────┤
│ │
│ Mule Flow: COREP C01.00 Own Funds │
│ ┌───────────────────────────────────────┐ │
│ │ │ │
│ │ 1. HTTP Request │ │
│ │ └─ Fetch capital data from API │ │
│ │ │ │
│ │ 2. Transform Message (DataWeave) │ │
│ │ └─ Map to XBRL structure │ │
│ │ │ │
│ │ 3. GLOMIDCO XBRL Connector │ │
│ │ ┌─────────────────────────────┐ │ │
│ │ │ Operation: Create Table │ │ │
│ │ │ Template: C 01.00 │ │ │
│ │ │ Taxonomy: EBA 3.4 │ │ │
│ │ │ Data: ${payload} │ │ │
│ │ └─────────────────────────────┘ │ │
│ │ Returns: Partial XBRL │ │
│ │ │ │
│ │ 4. File Write │ │
│ │ └─ Save C01_partial.xbrl │ │
│ │ │ │
│ └───────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────┘
DataWeave Mapping Example:
%dw 2.0
output application/java
---
{
entityLEI: payload.bank.lei,
reportingDate: payload.reporting.date,
currency: "EUR",
consolidation: "Consolidated",
rows: payload.capitalComponents map {
rowCode: $.accountType match {
case "CET1" -> "r020"
case "AT1" -> "r030"
case "T2" -> "r040"
else -> "r010"
},
columnCode: "c010",
value: $.amount,
dimensions: {
accountingPortfolio: "IFRS9",
exposureClass: "AllExposures"
}
}
}
┌─────────────────────────────────────────────┐
│ Tibco BusinessWorks 5.x Process │
├─────────────────────────────────────────────┤
│ │
│ Process: FINREP_F01_01_BalanceSheet │
│ ┌───────────────────────────────────────┐ │
│ │ │ │
│ │ [Start] │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ [JDBC Query] │ │
│ │ SELECT * FROM GL_ACCOUNTS │ │
│ │ WHERE reporting_date = ? │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ [Mapper] │ │
│ │ Map DB rows to XBRL structure │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ [GLOMIDCO XBRL Plugin] │ │
│ │ ┌─────────────────────────────────┐ │ │
│ │ │ Activity: GenerateXBRLTable │ │ │
│ │ │ Input: MappedData │ │ │
│ │ │ Taxonomy: EBA FINREP 3.4 │ │ │
│ │ │ Template: F 01.01 │ │ │
│ │ │ Output: PartialXBRL │ │ │
│ │ └─────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ [File Writer] │ │
│ │ Write to F01_01_partial.xbrl │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ [End] │ │
│ │ │ │
│ └───────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ webMethods Integration Server │
├─────────────────────────────────────────────┤
│ │
│ Flow Service: generateCOREP_C03 │
│ ┌───────────────────────────────────────┐ │
│ │ │ │
│ │ INVOKE: queryCreditRiskData │ │
│ │ └─ Get credit risk positions │ │
│ │ │ │
│ │ INVOKE: transformToXBRLStructure │ │
│ │ └─ Apply business logic │ │
│ │ └─ Map to EBA taxonomy │ │
│ │ │ │
│ │ INVOKE: com.glomidco.xbrl:createTable│ │
│ │ Input: │ │
│ │ templateID = "C 03.00" │ │
│ │ taxonomyVersion = "3.4" │ │
│ │ tableData = mappedData │ │
│ │ Output: │ │
│ │ partialXBRL = XBRL document │ │
│ │ │ │
│ │ INVOKE: writeFile │ │
│ │ └─ Save C03_partial.xbrl │ │
│ │ │ │
│ └───────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────┘
Key Concept: Each template is an independent mapping/flow.
Template C 01.00 (Own Funds):
┌─────────────────────────────────────────┐
│ Data Source: Capital Management System │
│ Mapping Logic: Own Funds Rules │
│ Output: C01_partial.xbrl │
│ Owner: Capital Management Team │
│ Test: Independent test cases │
└─────────────────────────────────────────┘
Template C 03.00 (Credit Risk - SA):
┌─────────────────────────────────────────┐
│ Data Source: Risk System │
│ Mapping Logic: Credit Risk Calc │
│ Output: C03_partial.xbrl │
│ Owner: Credit Risk Team │
│ Test: Independent test cases │
└─────────────────────────────────────────┘
Template F 01.01 (Balance Sheet):
┌─────────────────────────────────────────┐
│ Data Source: General Ledger │
│ Mapping Logic: GL to FINREP mapping │
│ Output: F01_01_partial.xbrl │
│ Owner: Finance Team │
│ Test: Independent test cases │
└─────────────────────────────────────────┘
... (60+ independent mappings)
Benefits:
Team Independence
Testability
Maintainability
Reusability
GLOMIDCO Merger Component:
public class XBRLIntelligentMerger {
public XBRLInstance merge(List<File> partialXBRLs)
throws MergeException {
System.out.println("=== XBRL Intelligent Merger ===");
System.out.println("Partial documents: " + partialXBRLs.size());
// Phase 1: Load all partial documents
List<PartialInstance> partials = loadPartials(partialXBRLs);
// Phase 2: Extract and merge contexts
ContextMerger contextMerger = new ContextMerger();
Set<Context> mergedContexts =
contextMerger.mergeContexts(partials);
System.out.println("Unique contexts: " + mergedContexts.size());
// Phase 3: Extract and merge units
UnitMerger unitMerger = new UnitMerger();
Set<Unit> mergedUnits = unitMerger.mergeUnits(partials);
System.out.println("Unique units: " + mergedUnits.size());
// Phase 4: Collect all facts
FactCollector factCollector = new FactCollector();
List<Fact> allFacts = factCollector.collectFacts(partials);
System.out.println("Total facts: " + allFacts.size());
// Phase 5: Check for conflicts
ConflictDetector detector = new ConflictDetector();
List<Conflict> conflicts = detector.detectConflicts(allFacts);
if (!conflicts.isEmpty()) {
System.err.println("CONFLICTS DETECTED:");
for (Conflict conflict : conflicts) {
System.err.println(" " + conflict.describe());
}
throw new MergeException("Conflicts found: " +
conflicts.size());
}
// Phase 6: Validate cross-template rules
CrossTemplateValidator validator =
new CrossTemplateValidator();
ValidationResult validation =
validator.validateCrossTemplateRules(allFacts);
if (!validation.isValid()) {
System.err.println("VALIDATION ERRORS:");
for (ValidationError error : validation.getErrors()) {
System.err.println(" " + error.getMessage());
}
throw new MergeException("Validation failed");
}
// Phase 7: Build final instance
XBRLInstanceBuilder builder = new XBRLInstanceBuilder();
builder.addContexts(mergedContexts);
builder.addUnits(mergedUnits);
builder.addFacts(allFacts);
XBRLInstance finalInstance = builder.build();
System.out.println("=== Merge Complete ===");
System.out.println("Final document size: " +
finalInstance.getSizeInMB() + " MB");
return finalInstance;
}
}
Merger Responsibilities:
1. Context Deduplication
Partial 1 contains:
<context id="ctx_1">
<entity><identifier>LEI123</identifier></entity>
<period><instant>2024-12-31</instant></period>
</context>
Partial 2 contains:
<context id="ctx_2">
<entity><identifier>LEI123</identifier></entity>
<period><instant>2024-12-31</instant></period>
</context>
Merger recognizes these are identical:
└─ Keep one context
└─ Update fact references
└─ Result: Single context with canonical ID
2. Conflict Detection
public class ConflictDetector {
public List<Conflict> detectConflicts(List<Fact> facts) {
List<Conflict> conflicts = new ArrayList<>();
// Group facts by concept + context
Map<FactKey, List<Fact>> factGroups =
facts.stream()
.collect(Collectors.groupingBy(
f -> new FactKey(f.getConcept(), f.getContext())));
// Check for duplicate values
for (Map.Entry<FactKey, List<Fact>> entry :
factGroups.entrySet()) {
if (entry.getValue().size() > 1) {
// Multiple values for same concept+context
Set<String> distinctValues =
entry.getValue().stream()
.map(Fact::getValue)
.collect(Collectors.toSet());
if (distinctValues.size() > 1) {
// Conflict! Different values
conflicts.add(new Conflict(
entry.getKey(),
entry.getValue()));
}
}
}
return conflicts;
}
}
Example conflict:
Template C 01.00 says:
eba:OwnFundsTier1Capital = 1,250,000,000
Template C 02.00 says:
eba:OwnFundsTier1Capital = 1,245,000,000
CONFLICT! Same concept, same context, different values.
Merger flags this and requires resolution.
3. Cross-Template Validation
public class CrossTemplateValidator {
public ValidationResult validateCrossTemplateRules(
List<Fact> allFacts) {
ValidationResult result = new ValidationResult();
// Example: C 01.00 r010 must equal C 02.00 r010
Fact c01_r010 = findFact(allFacts, "C_01_00", "r010");
Fact c02_r010 = findFact(allFacts, "C_02_00", "r010");
if (c01_r010 != null && c02_r010 != null) {
if (!c01_r010.getValue().equals(c02_r010.getValue())) {
result.addError(
"Cross-template inconsistency: " +
"C 01.00 r010 (" + c01_r010.getValue() + ") " +
"!= C 02.00 r010 (" + c02_r010.getValue() + ")");
}
}
// Check balance sheet balancing
validateBalanceSheet(allFacts, result);
// Check other cross-template rules
validateCapitalRequirements(allFacts, result);
return result;
}
}
4. Completeness Check
// Check all required templates present
Set<String> requiredTemplates =
getRequiredTemplates(institution.getCategory());
Set<String> providedTemplates =
extractTemplates(partials);
Set<String> missing =
Sets.difference(requiredTemplates, providedTemplates);
if (!missing.isEmpty()) {
throw new MergeException(
"Missing required templates: " + missing);
}
public class ParallelTemplateGenerator {
private ExecutorService executor;
public void generateAllTemplates(ReportingPeriod period) {
executor = Executors.newFixedThreadPool(8);
List<Future<File>> futures = new ArrayList<>();
// Submit all template generation tasks in parallel
for (String templateId : getRequiredTemplates()) {
futures.add(executor.submit(() ->
generateTemplate(templateId, period)));
}
// Collect results
List<File> partialXBRLs = new ArrayList<>();
for (Future<File> future : futures) {
try {
partialXBRLs.add(future.get());
} catch (Exception e) {
System.err.println("Template generation failed: " +
e.getMessage());
}
}
// Merge all partials
XBRLIntelligentMerger merger = new XBRLIntelligentMerger();
XBRLInstance finalInstance = merger.merge(partialXBRLs);
// Save final instance
finalInstance.saveTo(new File("COREP_FINREP_2024Q4.xbrl"));
}
private File generateTemplate(String templateId,
ReportingPeriod period) {
// Call middleware flow/process
// Returns partial XBRL file
return middlewareAPI.generateTemplate(templateId, period);
}
}
Benefit: 60 templates generated in parallel → Much faster than sequential.
| Aspect | Traditional DPM | GLOMIDCO Middleware |
|---|---|---|
| Architecture | Monolithic | Distributed |
| Maintainability | Complex SQL, hard to maintain | Visual flows, easy to understand |
| Testability | All-or-nothing | Template-by-template |
| Team Structure | Centralized team | Distributed teams |
| Failure Impact | Complete failure | Isolated to one template |
| Development Speed | Sequential, slow | Parallel, fast |
| Debugging | Difficult | Easy (isolated flows) |
| Reusability | Low | High |
| Performance | Sequential processing | Parallel processing |
| Flexibility | Rigid | Flexible |
| Learning Curve | Steep (SQL, DPM) | Moderate (middleware platform) |
| Tool Integration | Custom code | Platform connectors |
Traditional DPM:
Change to C 01.00 template:
└─ Modify monolithic SQL stored procedure
└─ Risk breaking other templates
└─ Must test entire DPM
└─ High regression risk
GLOMIDCO:
Change to C 01.00 template:
└─ Modify C01.00 flow only
└─ Other templates unaffected
└─ Test only C01.00 flow
└─ Zero regression risk for other templates
Traditional DPM:
-- Complex SQL - hard to understand
CASE
WHEN acc.type = 'CET1' AND adj.category = 'DEDUCT'
AND adj.timing = 'POST_2014'
THEN 'r025'
WHEN acc.type = 'CET1' AND adj.category = 'DEDUCT'
AND adj.timing = 'PRE_2014'
THEN 'r026'
...
END
GLOMIDCO (MuleSoft DataWeave):
// Visual, readable
rowCode: if (accountType == "CET1")
if (adjustmentCategory == "DEDUCT")
if (adjustmentTiming == "POST_2014") "r025"
else "r026"
else "r020"
else ...
Or in Tibco BW: Visual mapper with drag-and-drop.
Traditional DPM:
Cannot deliver until ALL templates complete:
└─ Must wait for slowest template
└─ Cannot submit partial report
└─ All-or-nothing delivery
GLOMIDCO:
Can deliver as templates complete:
├─ C 01.00 ready → Include in merge
├─ C 02.00 ready → Include in merge
├─ C 03.00 still pending → Exclude from merge
└─ Can submit partial report if acceptable
Traditional DPM:
Central team owns all mappings:
└─ Bottleneck for changes
└─ Hard to distribute work
└─ Knowledge concentration risk
GLOMIDCO:
Distributed ownership:
├─ Capital team owns C 01.00, C 02.00
├─ Credit risk team owns C 03.00-C 08.00
├─ Market risk team owns C 14.00-C 17.00
├─ Finance team owns F 01.00-F 04.00
└─ Parallel development, clear ownership
Traditional DPM:
Error in one template:
└─ May cause entire DPM population to fail
└─ Hard to identify root cause
└─ Must debug entire process
GLOMIDCO:
Error in C 03.00:
└─ Only C03.00 flow fails
└─ Other 59 templates succeed
└─ Error clearly identified
└─ Debug only C03.00 flow
└─ Can merge other 59 templates
Leverage existing middleware capabilities:
Enterprise Integration
Orchestration
Scalability
Security
Operational Management
Traditional DPM:
New EBA taxonomy version released:
└─ Analyze changes (2 weeks)
└─ Modify SQL stored procedures (4 weeks)
└─ Test entire DPM (3 weeks)
└─ Deploy (1 week)
Total: 10 weeks
GLOMIDCO:
New EBA taxonomy version released:
└─ Analyze changes (2 weeks)
└─ Update affected flows only (2 weeks)
└─ Test affected templates only (1 week)
└─ Deploy (1 week)
Total: 6 weeks (40% faster)
Scenario: Bank needs to add new template C 99.00 (hypothetical new requirement)
Traditional DPM Approach:
Week 1-2: Analysis
└─ Understand new template structure
└─ Identify source data
└─ Design DPM changes
Week 3-4: Development
└─ Modify DPM schema
└─ Write complex SQL
└─ Update XBRL generator
Week 5-6: Testing
└─ Test new template
└─ Regression test all existing templates
└─ Fix any breaks
Week 7: Deployment
└─ Deploy to production
└─ Risk: Might break existing templates
Total: 7 weeks, high risk
GLOMIDCO Approach:
Week 1: Analysis
└─ Understand new template structure
└─ Identify source data
Week 2: Development
└─ Create new flow C99.00
└─ Map source data to XBRL
└─ Use GLOMIDCO plugin
Week 3: Testing
└─ Test C99.00 flow independently
└─ Test merge with existing templates
└─ NO regression testing needed (isolated)
Week 4: Deployment
└─ Deploy new flow
└─ Zero risk to existing templates
Total: 4 weeks, low risk
Result: 43% faster, much lower risk
<!-- C01_partial.xbrl -->
<?xml version="1.0" encoding="UTF-8"?>
<xbrli:xbrl
xmlns:xbrli="http://www.xbrl.org/2003/instance"
xmlns:eba="http://www.eba.europa.eu/xbrl/crr/dict/met">
<!-- Only contexts needed for this template -->
<xbrli:context id="c1">
<xbrli:entity>
<xbrli:identifier scheme="http://standards.iso.org/iso/17442">
1234567890ABCDEFGHIJ
</xbrli:identifier>
</xbrli:entity>
<xbrli:period>
<xbrli:instant>2024-12-31</xbrli:instant>
</xbrli:period>
</xbrli:context>
<!-- Only units needed for this template -->
<xbrli:unit id="EUR">
<xbrli:measure>iso4217:EUR</xbrli:measure>
</xbrli:unit>
<!-- Only facts for C 01.00 template -->
<eba:OwnFunds contextRef="c1" unitRef="EUR" decimals="0">
1500000000
</eba:OwnFunds>
<eba:OwnFundsTier1 contextRef="c1" unitRef="EUR" decimals="0">
1250000000
</eba:OwnFundsTier1>
<eba:OwnFundsTier2 contextRef="c1" unitRef="EUR" decimals="0">
250000000
</eba:OwnFundsTier2>
<!-- ... more facts for C 01.00 ... -->
</xbrli:xbrl>
<!-- COREP_FINREP_2024Q4.xbrl - Final merged instance -->
<?xml version="1.0" encoding="UTF-8"?>
<xbrli:xbrl>
<!-- Merged contexts (deduplicated) -->
<xbrli:context id="ctx_001">
<!-- Shared context used by multiple templates -->
</xbrli:context>
<!-- ... 100s of contexts ... -->
<!-- Merged units (deduplicated) -->
<xbrli:unit id="EUR">
<xbrli:measure>iso4217:EUR</xbrli:measure>
</xbrli:unit>
<!-- Facts from all 60+ templates -->
<!-- From C 01.00 -->
<eba:OwnFunds contextRef="ctx_001" unitRef="EUR">
1500000000
</eba:OwnFunds>
<!-- From C 02.00 -->
<eba:OwnFundsRequirement contextRef="ctx_001" unitRef="EUR">
120000000
</eba:OwnFundsRequirement>
<!-- From F 01.01 -->
<eba:Assets contextRef="ctx_001" unitRef="EUR">
25000000000
</eba:Assets>
<!-- ... 50,000-200,000 total facts ... -->
</xbrli:xbrl>
// GLOMIDCO XBRL Plugin API (simplified)
public interface XBRLTableGenerator {
/**
* Generate partial XBRL for a single template
*/
PartialXBRL generateTable(
String templateId,
String taxonomyVersion,
TableData data,
ContextInfo contextInfo
) throws XBRLException;
/**
* Validate partial XBRL
*/
ValidationResult validate(
PartialXBRL partial
) throws XBRLException;
}
// Usage in MuleSoft connector
public class GlomidcoXBRLConnector {
private XBRLTableGenerator generator;
@Processor
public String createTable(
@Payload TableData tableData,
@Optional(defaultValue = "C_01_00") String templateId,
@Optional(defaultValue = "3.4") String taxonomyVersion) {
try {
ContextInfo context = extractContextInfo(tableData);
PartialXBRL partial = generator.generateTable(
templateId,
taxonomyVersion,
tableData,
context
);
ValidationResult validation = generator.validate(partial);
if (!validation.isValid()) {
throw new XBRLException(
"Validation failed: " + validation.getErrors());
}
return partial.toXML();
} catch (Exception e) {
throw new RuntimeException(
"Failed to generate XBRL table: " + e.getMessage(), e);
}
}
}
Phase 1: Pilot (2-3 templates)
Step 1: Select 2-3 simple templates
Step 2: Implement in middleware
Step 3: Test independently
Step 4: Test merger
Step 5: Validate approach
Phase 2: Core Templates (20-30 templates)
Step 1: Implement critical templates
Step 2: Parallel development by teams
Step 3: Regular merge testing
Step 4: Establish patterns
Phase 3: Full Implementation (all templates)
Step 1: Complete all templates
Step 2: End-to-end testing
Step 3: Performance optimization
Step 4: Production deployment
Template Ownership:
Register:
├─ Template ID
├─ Owner team
├─ Source systems
├─ Update frequency
├─ Critical dependencies
└─ Contacts
Version Control:
Each template flow in separate repository:
├─ Independent versioning
├─ Independent CI/CD
├─ Clear change history
└─ Rollback capability
Testing Standards:
Each template must have:
├─ Unit tests
├─ Integration tests
├─ Sample data
├─ Expected output
└─ Validation rules
Template-Level Monitoring:
Track for each template:
├─ Execution time
├─ Success/failure rate
├─ Data volume
├─ Error patterns
└─ Dependencies
Merge-Level Monitoring:
Track:
├─ Merge duration
├─ Context count
├─ Fact count
├─ Conflict count
├─ Validation errors
❌ Don't:
✅ Do:
COREP/FINREP Challenges:
Traditional DPM Limitations:
GLOMIDCO Advantages:
Why GLOMIDCO Approach Works:
Leverages Middleware Strengths
Distributes Complexity
Intelligent Merging
Production-Ready
Bottom Line:
For complex regulatory reporting like COREP/FINREP, a distributed, middleware-based approach with intelligent merging is superior to monolithic DPM architectures.
GLOMIDCO's plugins for MuleSoft, Tibco BW, and webMethods enable banks to:
Result: Regulatory compliance achieved with lower cost, lower risk, and better maintainability.
This document explains COREP/FINREP regulatory reporting complexity and how GLOMIDCO's middleware-based approach with distributed mapping and intelligent merging provides a superior solution to traditional DPM architectures.