Overview
The UK Financial Conduct Authority (FCA) requires regulated firms to submit regular prudential returns. The FSA005 Market Risk return captures detailed information on a firm's market risk exposures across interest rate risk, equity risk, commodity risk, foreign currency risk, and collective investment undertaking risk.
Using North52 Business Rules Engine, organizations can automate XML data validation directly within Dynamics 365 or Dataverse - ensuring totals reconcile correctly, PRR calculations are accurate, and reporting thresholds are met before submission to the regulator.
This article demonstrates how to validate FSA005 Market Risk XML data using a Microsoft Copilot Studio agent that calls a North52 formula via an unbound Dataverse action. The validation rules check various calculations including General Interest Rate Risk PRR totals, Specific Interest Rate Risk aggregations, and Internal Models-based charges.
Rules for Validation
The validation rules for the FSA005 return are defined in the FCA's data definition specification. A sample of the rules implemented in this example is shown below:
| Rule # | Description |
|---|---|
| 3G ERR0030 | GeneralInterestRateRisk-PRR-Total = + GeneralInterestRateRisk-PRR-USD + GeneralInterestRateRisk-PRR-GBP + GeneralInterestRateRisk-PRR-EUR + GeneralInterestRateRisk-PRR-CHF + GeneralInterestRateRisk-PRR-YEN + GeneralInterestRateRisk-PRR-Other |
| 18G ERR0010 | InterestRate-TotalPRR-Total = GeneralInterestRate-PRR-Total + SpecificInterestRate-PRR-Total + the higher of (LongSecuritisationPRR-Total + LongReSecuritisationPRR-Total) or (ShortSecuritisationPRR-Total + ShortReSecuritisationPRR-Total) + Sum of (OrdinaryCDSPRR-Total, SecuritisationCDSPRR-Total, BasicPRR-Total, OptionPRR-Total, CAD1PRR-Total, OtherPRR-Total) + the higher of (LongCorrelationTradingPRR-Total,ShortCorrelationTradingPRR-Total) |
| 70G | Conditional: mandatory if InterestRate-ShortCorrelationTradingPRR-Total (71G) is present |
| Add-ons | Description is conditional mandatory if the add-on row is present Value is conditional mandatory if the add-on row is present Repeat this for as many add-on rows are present in the XML document |
Solution Architecture
The solution consists of two main components:
- North52 Formula - A server-side Action formula that parses the XML, extracts values using XPath, performs validation calculations, and returns either a success message or detailed error messages.
- Microsoft Copilot Studio Agent - A Data Validation Agent that allows users to upload FSA005 XML files for validation through a conversational interface. The agent calls an unbound Dataverse action which triggers the North52 formula.
North52 Formula Configuration
Create Formula
- Open the North52 App
- Navigate to Business Process Activities > Formulas
- Create a new Formula, setting the following values in the Formula Guide:
- Source Entity set to N52 Command
- Set Formula Type to Action
- Select the Decision Table editor
- Change the Name of the formula to UK Financial Conduct Authority - Market Risk Reporting XML Validation
- Click Save
Sheet - Main Data Validation
This sheet contains the primary validation logic for the FSA005 rules. Each row evaluates a specific validation condition. If a condition fails (returns FALSE), the corresponding error message is added to the combined validation messages using the CombineMessages Global Action {CombineMessages[[ {ValidationMessage-XXX} ]] }.
The validation conditions compare calculated totals against reported totals, check that sums add correctly across rows and columns, and verify that derived values match their component calculations.
Columns:
- Column A-H (Conditions) - Each column tests a specific validation rule condition
- Column I (Calc-Inline Result) - Returns TRUE if all conditions pass, FALSE if any fail
- Column J (Combined Validation Messages) - Appends the appropriate error message when a condition fails

Sheet - Dynamic Row Validation
This sheet handles validation of repeating row structures, specifically the Internal Models Add-ons section which can contain a variable number of entries (rows 1 to n in section 63 of FSA005).
The ForEachRecord function iterates through the Add-ons elements in the XML, and for each record checks whether required data fields contain values using ContainsData(CurrentRecord('Description')) and ContainsData(CurrentRecord('Value')). The RecordIndex() function is used to idenitify which row failed in the validation messages output (+1 as the index is zero based).

Sheet - Output
This sheet determines the final output returned to the Unbound Action.
The Result row sets the output to [north52_command.ValidationResult].
If any validation failed (the Result variable is FALSE), the ValidationResult is set to the {Combined Validation Messages} containing all error details.
If all validations passed, the ValidationResult is set to “✅ Validation Passed!”

Sheet - Global Calculations
This sheet extracts all required values from the XML document using XPath queries. The first calculation loads the XML document, then subsequent calculations extract specific cell values from the FSA005 return.
The SetVar('responsecontent', [north52_command.XML]) function loads the XML content passed from the Unbound Action. Then GetVarXPathValue() functions extract values for each data point using the FSA005 XML schema namespace.
Example calculations include:
- XMLDoc-Load - Loads the XML document from the action input
- InterestRate-GeneralInterestRate-Long-Total - Extracts row 1 total (Valuations of longs)
- InterestRate-GeneralInterestRate-Short-Total - Extracts row 2 total (Valuation of shorts)
- InterestRate-GeneralInterestRate-PRR-[Currency] - Extracts PRR values by currency (USD, GBP, EUR, CHF, YEN, Other, Total)
- InterestRate-SpecificInterestRate-Risk[X]-Total - Extracts specific interest rate risk by risk bucket
- InternalModelsCharges-AddOnsEC - loads the Add-on rows into an entity collection so that we can loop over them: GetVarXPathEC('//fsa:AddOnRow', 'fsa|urn:fsa-gov-uk:MER:FSA005:10')
- InternalModelsCharges-AddOnsSumValue - Uses the XPath sum function to sum add-rows values: GetVarXPathValue('sum(//fsa:AddOnRow/fsa:Value)', 'fsa|urn:fsa-gov-uk:MER:FSA005:10')

Sheet - Global Actions
This sheet defines the action used to combine validation messages. The CombineMessages action appends each failed validation message with a line break separator, building up a complete list of all validation failures.

Custom Action
The Custom Action is set up like this:

Copilot Studio Agent
The Data Validation Agent is configured in Microsoft Copilot Studio with an XML Validation tool Unbound Connector action. Users can upload their FSA005 XML file and request validation. The agent passes the XML content to the Dataverse action and returns the validation result.
Inputs:
- Environment (String) - The Dynamics 365 environment URL
- Action Name (String) - n52demo_XMLValidation
- item.XML (String) - The FSA005 XML content to validate
Outputs:
- Validation Result (String) - Either "✅ Validation Passed!" or a list of validation error messages

Testing
To test the validation:
- Open the Data Validation Agent in Copilot Studio Test mode
- Upload a valid FSA005 XML file and request validation
- The agent will display "✅ Validation Passed!" if all rules pass
- Upload an invalid FSA005 XML file with calculation errors
- The agent will display all validation failures with specific error messages indicating which rules failed and why
Example validation failure messages:
- ❗ Sum of General Interest Rate Risk PRR values does not match total (3G)
- ❗ Total is incorrect (18G) :
Total should equal 3G+10G
+ the higher of (66G+68G) or (67G+69G)
+ SUM(12G:17G)
+ the higher of 70G or 71G
