Fidessa
Overview
The purpose of a mapper is to provide complete context for all interop.io-enabled applications. In many deployments, the Fidessa Adapter needs to sync not just with Bloomberg, but also with applications such as Salesforce, Microsoft Teams, or internal analytics tools. Each of these may require a different symbology (Bloomberg ticker, RIC, FIM, etc.)
The adapter supports two mapping mechanisms — the Service Mapper (an external interop method) and the Internal Mapper (local regex rules). Both are optional. When all mapping is disabled, the adapter still publishes context to channels, but with minimal symbology.
⚠️ Neither mapping mechanism is implemented by the Fidessa Adapter itself. The Service Mapper requires you to register and implement the named interop method in your own environment. The Internal Mapper requires you to provide the regex rules in the adapter configuration. Without either, the adapter publishes only raw FIM data to channels.
Default Context Shape
When both the Service Mapper and Internal Mapper are disabled, the adapter writes the following context to the io.Connect Channel:
{
instrument: {
id: {
fim: "VOD.L"
}
},
client: "VC001",
order: {
fidessaReference: "ord-id-0000123"
},
instrumentList: [],
clientList: [],
orderList: []
}Key points:
- Instruments are always wrapped in an object — the adapter converts the raw FIM string into
{ fim: "..." }before any mapping step. The channel always receives{ id: { fim: "..." } }, never a bare string. - Clients are written as plain strings (the Fidessa viewCode) when no mapping service is available.
- Orders use the path configured in
"orderIdPath"(default:order.fidessaReference) and are never processed by any mapper. - Instrument and client paths are configurable per channel via the Tracking Groups properties
"instrumentIdPath","clientIdPath", and"orderIdPath". The"fimPath"and"fidClientPath"properties are configured globally in the adapter configuration.
Context Shape by Mapping Scenario
| Scenario | instrument value |
client value |
|---|---|---|
| Service Mapper active | { id: { fim: "VOD.L", bloomberg: "VOD LN Equity", ric: "VOD.L" } } |
{ id: "VC001", salesforceId: "..." } (enriched object) |
| Internal Mapper active | { id: { fim: "VOD.L", bloomberg: "VOD LN Equity" } } (regex-derived) |
"VC001" (plain string — internal mapper does not process clients) |
| No mapper configured | { id: { fim: "VOD.L" } } (FIM only) |
"VC001" (plain string) |
With the Service Mapper active and a full enrichment response, the context looks like:
{
instrument: {
id: {
fim: "VOD.L",
bloomberg: "VOD LN Equity",
ric: "VOD.L"
}
},
client: {
id: "VC001",
salesforceId: "SF123"
},
order: {
fidessaReference: "ord-id-0000123"
},
instrumentList: [...],
clientList: [...],
orderList: [...]
}ℹ️ Apps reading from channels should handle both string and object forms for the
clientfield, depending on whether a mapping service is deployed.
Context Updates
A Channel is updated every time the user selects an instrument, order or counterparty in a Fidessa app or in an interop-enabled app.
Fidessa → Channel
When an update from a Fidessa app arrives, the adapter processes each context type as follows:
Instruments — the raw FIM code is converted into a multi-symbology object. The conversion depends on which mapping mechanism is configured:
With the Service Mapper or Internal Mapper active, the FIM code is enriched with additional symbologies:
{
instrument: {
id: {
fim: "VOD.L",
bloomberg: "VOD LN Equity",
ric: "VOD.L"
}
}
}With no mapping service and no internal mapper, the adapter still wraps the FIM code in an object:
{
instrument: {
id: {
fim: "VOD.L"
}
}
}ℹ️ The
instrument.idvalue is always an object — never a bare string.
Clients — the raw viewCode string from Fidessa is sent to the Service Mapper for enrichment. If the Service Mapper is active, the result is an enriched object (e.g., { id: "VC001", salesforceId: "SF123" }). If no Service Mapper is available, the bare viewCode string is written to the channel as-is (e.g., "VC001"). The Internal Mapper is never used for clients.
⚠️ The Service Mapper must return the client identifier as a plain string in the
idfield (e.g.,{ id: "VC001" }) — not as a nested object with dot-separated keys (e.g.,{ id: { "com.fidessa.viewCode": "VC001" } }). The adapter cannot resolve complex dot-separated property names when reading back from the Channel in the Channel → Fidessa direction.
Orders — no mapping is performed. The order reference string from Fidessa is wrapped in a fixed structure and written directly to the channel:
{
order: {
fidessaReference: "ord-id-0000123"
}
}Channel → Fidessa
When an interop-enabled app updates the Channel context, the Fidessa Adapter first tries to retrieve the FIM code directly from the configured "fimPath" (default: "id.fim" — see Configuration). If a FIM value is found at that path, it is sent to Fidessa immediately — no mapper is called.
If no value is available at "fimPath", the adapter extracts the object at the channel's "instrumentIdPath" (default: "id" — see Tracking Groups) and sends it to the active mapper (Service Mapper or Internal Mapper) for reverse lookup. If no mapper is available, or if the reverse lookup does not produce a FIM code, the update is ignored and Fidessa is not notified.
For clients, the adapter reads the Fidessa viewCode from "fidClientPath" (default: "id:com.fidessa.viewCode", split by "fidClientPathSep"). Since the adapter cannot resolve complex dot-separated property names, the Service Mapper should write the viewCode as a plain string in client.id rather than as a nested object. If the viewCode is not found at the configured path, the adapter sends the client object to the Service Mapper for reverse lookup. The Internal Mapper is never used for clients.
For orders, the adapter reads the order reference from the channel's "orderIdPath" (default: order.fidessaReference — see Tracking Groups) — no mapper is involved.
Service Mapper
The Service Mapper is a contract for an interop method that you implement and register in your environment. The Fidessa Adapter does not ship a mapping service — it only acts as a caller. When a context update flows between Fidessa and the io.Connect channels, the adapter invokes the configured method name on the interop bus (window.io.interop.invoke). If no method is registered under that name, the adapter silently skips the call and publishes the original data unchanged.
The primary use case is multi-symbology enrichment: Fidessa natively works with FIM codes, but other interop-enabled apps (Bloomberg, Salesforce, Microsoft Teams, internal analytics tools, etc.) may require RIC, Bloomberg ticker, or proprietary identifiers. An external mapping service that holds a live reference database can resolve those identifiers on demand and return a fully populated instrument or client object. The adapter passes the raw Fidessa data to that service and publishes the enriched result to the channel.
The method name is controlled by the serviceMethod config property.
Configuration
| Property | Type | Default |
|---|---|---|
serviceMethod |
string |
"Glue42.ContextMapper.Enhance" |
ℹ️ The default method name
"Glue42.ContextMapper.Enhance"is a convention, not a built-in service. No implementation is shipped with the adapter — you must implement and register this method yourself.
Set it in the app-definition customProperties (recommended) or in custom-configs.json:
{
"adapterConfig": {
"serviceMethod": "Glue42.ContextMapper.Enhance"
}
}customProperties example (inside the adapter app definition):
{
"customProperties": {
"serviceMethod": "Glue42.ContextMapper.Enhance"
}
}To disable remapping, set serviceMethod to an empty string ("") — the adapter will publish the raw Fidessa data directly to the channel.
⚠️ If the Internal Mapper is configured (
"useInternalMapper"is a non-empty array), the Service Mapper is bypassed entirely for instrument context. Client context always goes through the Service Mapper.
Method Invocation
The service method is invoked in both directions of the data flow.
Fidessa → io.Connect channel
When a message arrives from Fidessa, the adapter calls the service method to enrich the raw FIM symbols into multi-symbology instrument objects before publishing them to the channel:
- Instruments — called for all instruments received from Fidessa that need to be enriched with additional symbology (RIC, Bloomberg, etc.).
- Clients — called for all clients received from Fidessa.
io.Connect Channel → Fidessa
When channel data needs to be sent back to Fidessa, the adapter calls the service method to resolve a FIM code from the channel context:
- Instruments — called when no FIM code is found in the channel data.
Each instrument in the
instrumentListthat lacks a FIM code is also individually remapped. - Clients — called when no recognized client ID is found in the channel data.
Each client in the
clientListthat lacks an ID is also individually remapped.
If the named method is not currently registered on the interop bus, the call is skipped and the original data is used as-is.
Data types
InstrumentInChannel
An FDC3-style instrument object. At least one symbology field inside id must be present:
{
id: {
ric?: string; // Reuters Instrument Code
bloomberg?: string; // Bloomberg ticker
fim?: string; // Fidessa Instrument Mnemonic
rCode?: string; // R-code
// additional symbology fields are allowed
};
// additional top-level fields are allowed
}ClientInChannel
{
id: string; // primary client identifier
salesforceId?: string; // optional Salesforce ID
// additional fields are allowed
}Interop Contract
Method registration check
Before invoking, the adapter checks whether the method is available on the bus:
window.io.interop.methods({ name: config.serviceMethod })If the returned array is empty, the invocation is skipped.
Invocation — instruments
const result = await window.io.interop.invoke(config.serviceMethod, { instruments });Argument:
{
instruments: Array<InstrumentInChannel | string>
}Expected response (result.returned):
{
instruments: Array<{
result: InstrumentInChannel | string;
error: Error | null;
}>
}The response array must be the same length and order as the input array. Items where error is
non-null are considered failed and are dropped from the result. If every item has an error (total failure), the entire original input is returned unchanged.
Invocation — clients
const result = await window.io.interop.invoke(config.serviceMethod, { clients });Argument:
{
clients: Array<ClientInChannel | string>
}Expected response (result.returned):
{
clients: Array<{
result: ClientInChannel | string;
error: Error | null;
}>
}Same partial-failure semantics as the instruments case.
Error Handling
| Scenario | Adapter behavior |
|---|---|
| Method not registered | Skip call; publish original data |
| Invocation rejects (network / timeout) | Publish original data |
| All results contain errors | Publish original data |
| Some results contain errors | Failed items are dropped; only successfully mapped items are returned |
Internal Mapper
The Internal Mapper offers a lightweight alternative for instrument symbology conversion using regex rules, without requiring an external mapping service or database.
⚠️ Priority: When
"useInternalMapper"contains one or more entries, the Internal Mapper is used instead of the Service Mapper for instruments. The Service Mapper is bypassed entirely for instrument context — it is not used as a fallback. Client context is always handled by the Service Mapper regardless of this setting.
Configuration
Enabling & Disabling the Internal Mapper
- To enable: set
"useInternalMapper"to an array of mapping rule objects (see below). - To disable: set
"useInternalMapper"to an empty array[].
If you already have a working Service Mapper ("serviceMethod") deployed for instrument enrichment, leave "useInternalMapper" as [] so that the Service Mapper is used instead.
Bidirectional Mapping
The Internal Mapper works in both directions:
- Fidessa → io.Connect channel: Rules where
"sourceSymbology"is"fim"are applied. The FIM code from Fidessa is converted to the target symbology (e.g., Bloomberg) and both values are written to the channel. - io.Connect channel → Fidessa: Rules where
"sourceSymbology"is not"fim"are applied. The channel symbology (e.g., Bloomberg ticker) is converted back to a FIM code.
ℹ️ In the Channel → Fidessa direction, the Internal Mapper is only invoked as a fallback when the channel context does not already contain a FIM code at the configured
"fimPath". If"fimPath"resolves successfully, the FIM is used directly and no mapper is called.
If no regex rule matches the input value, the instrument is returned unchanged — the Service Mapper is not used as a fallback.
Only the first matching rule is applied per instrument. Once a regex match succeeds, the remaining rules are skipped.
Example Configuration Settings
[{
"sourceSymbology": "fim",
"targetSymbology": "bloomberg",
"lookupRegex": "([A-Z0-9]+)[:.]C",
"outputFormat": "$1 CN Equity"
},{
"sourceSymbology": "fim",
"targetSymbology": "bloomberg",
"lookupRegex": "([A-Z0-9]+)[:.]CNN",
"outputFormat": "$1 CN Equity"
},{
"sourceSymbology": "bloomberg",
"targetSymbology": "fim",
"lookupRegex": "(.*) DT .*",
"outputFormat": "$1.C"
},{
"sourceSymbology": "bloomberg",
"targetSymbology": "fim",
"lookupRegex": "(.*) CN .*",
"outputFormat": "$1.CCN"
},{
"sourceSymbology": "fim",
"targetSymbology": "bloomberg",
"lookupRegex": "([A-Z0-9]+)[:.]([A-Z0-9]+)N",
"outputFormat": "$1 $2N Equity"
}]
| Property | Type | Description |
|---|---|---|
"sourceSymbology" |
string |
The property name on the instrument id object to read from (e.g., "fim", "bloomberg"). |
"targetSymbology" |
string |
The property name on the instrument id object where the converted value will be written. |
"lookupRegex" |
string |
A regular expression to test against the source value. If it matches, this rule is applied. Capture groups can be referenced in "outputFormat". |
"outputFormat" |
string |
The output template. Use $1, $2, etc. to reference capture groups from "lookupRegex". |
When a message comes from Fidessa we end up to a context value similar to {"instrument": {id:{"fim": "IN:CNN"}}}. If we configure the adapter to use Internal Mapper it will be handled by the second mapping configuration in the array above. The value from the "fim" will be taken and will be tested versus the "lookupRegex" value. Then it will save a new value inside the "bloomberg" property. The value will be calculated by applying the value "IN", from the regex first group to the template "$1 CN Equity". That will result to the next value in the channel context:
{
"instrument": {
"id":{
"bloomberg": "IN CN Equity",
"fim": "IN:CNN"
}
}
}