StreamLink.NET
How to use Container Filtering and Sorting

The Caplin.StreamLink.Subscription.ExtendedContainer.IExtendedContainerSubscription interface allows client applications to subscribe to containers that are filtered and sorted in the Caplin Refiner module of Caplin Transformer, rather than in the client application. Filter and sort criteria would typically be constructed in response to actions by the end user of the application, such as when the end user wants to view instruments that have a coupon rate greater than, or less than, a particular value.

The document Caplin Xaqua: How To Use Containers describes how to configure Caplin Liberator and Caplin Transformer to support container filtering and sorting.

Filtering

You can filter records based on the value of a single field. For example, the simple filter expression bid > 5 selects just those records where the field called bid has a value greater than 5.

You can define compound ("logical") filters that combine simple filters using logical operators. For example, (bid > 5) AND (ask < 6). This filter selects records where the field called bid has a value greater than 5 and the ask field has a value less than 6.

All the simple filters in a compound filter must be combined using the same logical operation; for example, the following filter expressions are possible:

(bid > 5) AND (ask < 6) AND (coupon >= 3)

(bid > 5) AND (ask < 6) AND (coupon >= 3)

Whereas the following filter expression cannot be defined by one compound filter:

( (bid > 5) AND (ask < 6) ) OR (coupon >= 3)

To construct this expression, two compound filters are required. The first compound filter uses the AND logical operator to combine (bid > 5) and (ask < 6). The filter expression is:

(bid > 5) AND (ask < 6)

The second compound filter uses the OR logical operator to combine the first compound filter and (coupon >= 3). The filter expression is now:

( (bid > 5) AND (ask < 6) ) OR (coupon >= 3)

Sorting

The records in a container can also be sorted based on the value of a single field.

Grouping

The records in a container can be grouped according to the value of the sort field. Grouping adds extra records to the container that act as headers for blocks of records that have the same field value. For example, if records are sorted and grouped by the Description field, the group header identifies the value of this field for each group of records. An application could use the group header when it displays the sorted records in a grid.

Implementation

To subscribe to a container that can be filtered and sorted, use the Caplin.StreamLink.Subscription.ExtendedContainer.IExtendedContainerSubscription interface, which extends the standard Caplin.StreamLink.Subscription.Container.IContainerSubscription interface.

An instance of IExtendedContainerSubscription is created using one of the Caplin.StreamLink.Subscription.ExtendedContainer.IExtendedContainerSubscription factory methods.

To define filter and sort criteria, create extended parameters using the Caplin.StreamLink.IParametersFactory, and then attach these parameters to the Caplin.StreamLink.Subscription.ExtendedContainer.IExtendedContainerSubscription. If extended parameters are not attached, the subscription will be equivalent to a standard Caplin.StreamLink.Subscription.Container.IContainerSubscription(that is, the container will not be filtered or sorted).

To create a simple filter (such as bid > 5 ) use the Caplin.StreamLink.IParametersFactory.CreateFieldFilterExpression method.

To create a custom filter that specifies a custom data type for the field to be filtered (such as Description:tenor > 5Y ) use the Caplin.StreamLink.IParametersFactory.CreateCustomFieldFilterExpression method. Custom data types are defined in the Caplin Refiner module.

To create a compound logical filter (such as (bid > 5) AND (ask < 6)) use the Caplin.StreamLink.IParametersFactory.CreateLogicalFilterExpression method.

To create a sort rule use the Caplin.StreamLink.IParametersFactory.CreateFieldSortRule method.

To create a custom sort rule where you specify a custom data type for the field to be sorted (such as "sort the Description field by Tenor") use the Caplin.StreamLink.IParametersFactory.CreateCustomSortRule method. Custom data types are defined in the Caplin Refiner module.

Examples

In the code examples that follow, the application code that creates the Caplin.StreamLink.IStreamLink and Caplin.StreamLink.Subscription.Container.IContainerSubscriptionListener is omitted for simplicity. The Caplin.StreamLink.Subscription.Container.IContainerSubscription interface has code examples that show you how to do this.

The following example shows you how to apply a simple filter to a container subscription:

CopyC#
using Caplin.StreamLink;
using Caplin.StreamLink.Subscription.Container;
using Caplin.StreamLink.Subscription.Container.ExtendedParameters;
using Caplin.StreamLink.Subscription.Container.ExtendedParameters.Filtering;
using Caplin.StreamLink.Subscription.ExtendedContainer;

namespace ContainerFilteringExamples
{
    class FieldFilterExample
    {


        public IExtendedContainerSubscription CreateFieldFilterSubscription(IStreamLink streamLink, IContainerSubscriptionListener listener, string subject)
        {
            IExtendedContainerSubscription subscription = streamLink.StreamLinkProvider.CreateExtendedContainerSubscription(listener, subject);

            // Create an expression that returns records with a Bid>10.
            IFilterExpression filterExpression = streamLink.StreamLinkProvider.ParametersFactory.CreateFieldFilterExpression("Bid", FieldFilterExpressionOperator.GreaterThan, "10");

            // Set the filter on the subscription.
            subscription.SetExtendedParameters(filterExpression, null);

            //The calling code makes the Liberator subscription.

            return subscription;
        }

    }
}

A container can also be sorted. In this example we sort in ascending numeric order on the Bid field and also group on the Bid field:

CopyC#
using Caplin.StreamLink;
using Caplin.StreamLink.Subscription.Container;
using Caplin.StreamLink.Subscription.Container.ExtendedParameters;
using Caplin.StreamLink.Subscription.Container.ExtendedParameters.Filtering;
using Caplin.StreamLink.Subscription.ExtendedContainer;
using Caplin.StreamLink.Subscription.Container.ExtendedParameters.Sorting;

namespace ContainerFilteringExamples
{
    class FieldFilterAndSortExample
    {


        public IExtendedContainerSubscription CreateFieldFilterSubscription(IStreamLink streamLink, IContainerSubscriptionListener listener, string subject)
        {
            IExtendedContainerSubscription subscription = streamLink.StreamLinkProvider.CreateExtendedContainerSubscription(listener, subject);

            // Create an expression that returns records with a Bid>10
            IFilterExpression filterExpression = streamLink.StreamLinkProvider.ParametersFactory.CreateFieldFilterExpression("Bid", FieldFilterExpressionOperator.GreaterThan, "10");

            // Now, create a sort rule.
            IFieldSortRule sort = streamLink.StreamLinkProvider.ParametersFactory.CreateFieldSortRule("Bid", FieldType.Number, SortOrder.Ascending); 

            //Group by "Bid" field.
            sort.GroupField = "Bid";

            // Set the filter on the subscription.
            subscription.SetExtendedParameters(filterExpression, sort);

            //The calling code makes the Liberator subscription.

            return subscription;
        }

    }
}

Custom filtering and sorting can also be specified in the container subscription. In this example we filter on the Description field using a custom data type of tenor. We sort in descending order on the Rate field using a custom data type of integer, and we also group on the Rate field:

CopyC#
using Caplin.StreamLink;
using Caplin.StreamLink.Subscription.Container;
using Caplin.StreamLink.Subscription.Container.ExtendedParameters;
using Caplin.StreamLink.Subscription.Container.ExtendedParameters.Filtering;
using Caplin.StreamLink.Subscription.ExtendedContainer;
using Caplin.StreamLink.Subscription.Container.ExtendedParameters.Sorting;

namespace ContainerFilteringExamples
{
    class CustomFieldFilterAndSortExample
    {


        public IExtendedContainerSubscription CreateCustomFieldFilterAndSortSubscription(IStreamLink streamLink, IContainerSubscriptionListener listener, string subject)
        {
            IExtendedContainerSubscription subscription = streamLink.StreamLinkProvider.CreateExtendedContainerSubscription(listener, subject);

            // Create an expression that returns records with a Description:tenor > 5Y.
            ICustomFieldFilterExpression filterExpression = streamLink.StreamLinkProvider.ParametersFactory.CreateCustomFieldFilterExpression("Description", "tenor", FieldFilterExpressionOperator.GreaterThan, "5Y");

            // Now, create a custom sort rule on the Rate field with a custom data type "integer"
            ICustomSortRule sort = streamLink.StreamLinkProvider.ParametersFactory.CreateCustomSortRule("Rate", "integer", SortOrder.Descending); 

            //Group by "Rate" field.
            sort.GroupField = "Rate";

            // Set the filter on the subscription.
            subscription.SetExtendedParameters(filterExpression, sort);

            //The calling code makes the Liberator subscription.

            return subscription;
        }

    }
}

Compound logical expressions can also be specified in the container subscription. In the following example we filter on bonds that mature before 1st January 2012 with a coupon greater than 5%, or any other bond that has a BidYield greater than 6.0. The filter is constructed using a simple filter and two compound filters:

CopyC#
using Caplin.StreamLink.Subscription.Container.ExtendedParameters.Filtering;
using Caplin.StreamLink.Subscription.Container.ExtendedParameters;
using Caplin.StreamLink.Subscription.ExtendedContainer;
using Caplin.StreamLink;
using Caplin.StreamLink.Subscription.Container;

namespace ContainerFilteringExamples
{
    class LogicalFiltering
    {
        //This simple filter returns bonds that have a bid yield greater than 6.
        // The filter expression is: "BidYield > 6.0"
        private IFilterExpression SimpleFilterExpression(IParametersFactory parameterFactory)
        {
            return (parameterFactory.CreateFieldFilterExpression("BidYield", FieldFilterExpressionOperator.GreaterThan, "6"));
        }

        // This compound filter returns bonds that mature before 1st January 2012 with a coupon greater than 5%.
        //The filter expression is:
        //(MaturityDate < 20120101) AND (CpnRate > 5.0)
        private IFilterExpression CompositeFilterExpression(IParametersFactory parameterFactory)
        {
            ILogicalFilterExpression logicalExpression = parameterFactory.CreateLogicalFilterExpression(LogicalFilterExpressionOperator.AND);
            logicalExpression.AddExpression(parameterFactory.CreateFieldFilterExpression("CpnRate", FieldFilterExpressionOperator.GreaterThan, "5"));
            logicalExpression.AddExpression(parameterFactory.CreateFieldFilterExpression("MaturityDate", FieldFilterExpressionOperator.LessThan, "20100101"));
            return logicalExpression;
        }

        //The final compound filter returns bonds that mature before 1st January 2012
        // with a coupon greater than 5%, or any other bond that has a "BidYield" greater than 6.0.
        //The filter expression is:
        //[(MaturityDate < 20120101) AND (CpnRate > 5.0)] OR (BidYield > 6.0)
        private IFilterExpression CompoundFilterExpression(IParametersFactory parameterFactory)
        {
            ILogicalFilterExpression logicalFilterExpression = parameterFactory.CreateLogicalFilterExpression(LogicalFilterExpressionOperator.OR);
            logicalFilterExpression.AddExpression(CompositeFilterExpression(parameterFactory));
            logicalFilterExpression.AddExpression(SimpleFilterExpression(parameterFactory));
            return logicalFilterExpression;
        }

        public IExtendedContainerSubscription CreateLogicalFilterSubscription(IStreamLink streamLink, IContainerSubscriptionListener listener, string subject)
        {
            //Create the subscription.
            IExtendedContainerSubscription subscription = streamLink.StreamLinkProvider.CreateExtendedContainerSubscription(listener, subject);

            //Create the compound filter for this subscription.
            IFilterExpression filterExpression = CompoundFilterExpression(streamLink.StreamLinkProvider.ParametersFactory);

            // Set the filter on the subscription
            subscription.SetExtendedParameters(filterExpression, null);

            //The calling code makes the Liberator subscription.

            return subscription;
        }


    }
}

Caplin Systems Ltd.