Skip to main content

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 client field, 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.id value 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 id field (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 instrumentList that 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 clientList that 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"
        }
    }
}