Navigating Relationships

Navigational requests were briefly mentioned in the introduction to snapshots and streaming here.

In this tutorial we'll describe how to make these requests. Their syntax differs only very slightly from a simple non-navigational request so should be easy to use, yet powerful.

So, let's start by doing another getEqual request for MSFT. but instead of retrieving MSFT. itself, we'll get the company record for Microsoft. We don't need to know the symbol for the company record, we just need to know the appropriate relationshipId to use; in this case, it is RelationshipId.company. This is an example of a 1:1 relationship, since there's only one company record for a given listing record:

const requestHandle = client.streaming.getEqual({
    key: "MSFT.",
    relationships: {
        [activCgApi.RelationshipId.company]: {
            fieldIds: [activCgApi.FieldId.FID_NAME]
        }
    }
});

Instead of a single fieldIds property, there is now a relationships indexed property. This defines the navigation relationship(s) we want to follow from the requested key(s). The keys of the property are the relationshipId, and the values are a IRelationship which is where the fieldIds property can now be found.

Naturally, we can request multiple relationships in a single request by using multiple relationship ids. If we also want to get non-navigational fields, i.e. in the record(s) corresponding to the provided key(s), we can use the special relationship id RelationshipId.none:

const requestHandle = client.streaming.getEqual({
    key: "MSFT.",
    relationships: {
        [activCgApi.RelationshipId.none]: {
            fieldIds: [activCgApi.FieldId.FID_BID, activCgApi.FieldId.FID_ASK]
        },
        [activCgApi.RelationshipId.company]: {
            fieldIds: [activCgApi.FieldId.FID_NAME]
        }
    }
});

Note that when specifying multiple relationships in a request, the fieldIds can be different for each relationship. You can therefore request fields that are relevant for the relationship. Here we'll get FID_BID and FID_ASK for MSFT. and FID_NAME for MSFT.COM.

1:n relationships

Some relationships may return multiple records. An example is RelationshipId.option, which as its name implies, retrieves all options for a given symbol:

const requestHandle = client.streaming.getEqual({
    key: "MSFT.",
    relationships: {
        [activCgApi.RelationshipId.none]: {
            fieldIds: [activCgApi.FieldId.FID_BID, activCgApi.FieldId.FID_ASK]
        },
        [activCgApi.RelationshipId.option]: {
            fieldIds: [activCgApi.FieldId.FID_BID, activCgApi.FieldId.FID_ASK]
        }
    }
});

Here we'll get FID_BID and FID_ASK for MSFT. and all its options in a single request.

Pattern filtering

In order to reduce the result set for a 1:n relationship, it's possible to specify some additional per-relationship filtering using the navigationFilterPattern property. The previous example would retrieve all options for MSFT., meaning both regional exchanges and NBBO. Here's an example using a filter to limit the results to NBBO only:

const requestHandle = client.streaming.getEqual({
    key: "MSFT.",
    relationships: {
        [activCgApi.RelationshipId.none]: {
            fieldIds: [activCgApi.FieldId.FID_BID, activCgApi.FieldId.FID_ASK]
        },
        [activCgApi.RelationshipId.option]: {
            fieldIds: [activCgApi.FieldId.FID_BID, activCgApi.FieldId.FID_ASK],
            navigationFilterPattern: "*.O"
        }
    }
});

Note that for this use case, there is actually a relationship id that will do this for you: RelationshipId.nbboOption. This is preferable to navigationFilterPattern, since as well as reducing server-side processing it helps to abstract away the symbology of NBBO options.

Supported request types

All the request types described in further request types support the navigation model using this syntax.

Please be aware that a getPattern request in combination with 1:n navigational requests can result in massive result sets!

Making a subscription request

Subscription is handled exactly the same as for a simple non-navigational request, by specifying a subscription property in the request's parameters object.

By default, when requesting subscription, you will be subscribed to updates for all relationships specified in the request. However, it is possible to disable subscription on a per-relationship basis. Here's an example:

// Initiate a getEqual request to the ContentGateway.
const requestHandle = client.streaming.getEqual({
    key: "MSFT.",
    relationships: {
        [activCgApi.RelationshipId.none]: {
            fieldIds: [activCgApi.FieldId.FID_BID, activCgApi.FieldId.FID_ASK]
            // "subscribe" defaults to true if not specified.
        },
        [activCgApi.RelationshipId.company]: {
            fieldIds: [activCgApi.FieldId.FID_NAME],
            subscribe: false
        }
    },
    subscription: {
        updateHandler: (update) => displayFields(update)
    }
});

Here we'll receive updates for the MSFT. record, but not for the company record.

Complete example

The Option chain example is implemented using navigation requests. See the source code here.

Also in this Section