StreamLink Container Filter Subscriptions
StreamLink Container Filtering subscriptions enable filtering and sorting of the elements within a container. The filtering and sorting are done with Caplin Xaqua's Transformer component, rather than in the client application.
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 based on a logical combination of simple filters. 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 is not supported:
(bid > 5) AND (ask < 6) OR (coupon >= 3)
Sorting
The records can also be sorted within the container based on the value of a single field.
Implementation
The filtering and sorting capabilities are implemented through the Caplin.StreamLink.Subscription.ExtendedContainer.IExtendedContainerSubscription interface, which extends the standard StreamLink Caplin.StreamLink.Subscription.Container.IContainerSubscription interface.
You create an instance of Caplin.StreamLink.Subscription.ExtendedContainer.IExtendedContainerSubscription directly rather than by using a factory. You can then create an extended parameters object (one of the supplied implementations of Caplin.StreamLink.Subscription.Container.ExtendedParameters.IExtendedParameters) that specifies the filtering and sorting criteria for the elements in the container. There is a factory available for creating extended parameters objects (Caplin.StreamLink.Subscription.Container.ExtendedParameters.ExtendedParametersFactory). Finally, you attach the IExtendedParameters to the IExtendedContainerSubscription, and use the IExtendedContainerSubscription within your application in the same way as a standard IContainerSubscription.
Extended parameters can be changed (for example when a user clicks on a column heading) and the changes will be applied automatically for you.
An IExtendedContainerSubscription that does not have an IExtendedParameters attached to it behaves in the same way as a standard StreamLink IContainerSubscription. So, for ease of development, you may prefer to always use IExtendedContainerSubscriptions in your application, rather than a mix of IExtendedContainerSubscriptions and IContainerSubscriptions.
An Caplin.StreamLink.Subscription.ExtendedContainer.IExtendedContainerSubscription extends the standard StreamLink Caplin.StreamLink.Subscription.Container.IContainerSubscription adding additional semantics for filtering and sorting.
An instance of Caplin.StreamLink.Subscription.ExtendedContainer.IExtendedContainerSubscription instance can be created directly using the new directive. If no extended parameters are set upon it will behave in the same way as a Caplin.StreamLink.Subscription.Container.IContainerSubscription, for ease of development it may be preferable to use this subscription type instead of the type supplied by StreamLink.
Extended parameters are constructed using the Caplin.StreamLink.Subscription.Container.ExtendedParameters.ExtendedParametersFactory and may contain a single field filter or composite logical filters encompassing multiple conditions. Sorting on a single field is also supported.
Extended parameters can be changed (for example when a user clicks on a column heading) and the changes will be applied automatically for you.
Examples
The following example demonstrates how to subscribe to a filtered container:
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 sub = new ExtendedContainerSubscription(streamLink.StreamLinkProvider, listener, subject); // Create an expression that returns records with a Bid>10 IFilterExpression expr = ExtendedParametersFactory.CreateFieldFilterExpression("Bid", FieldFilterExpressionOperator.GreaterThan, "10"); // Set the filter on the subscription sub.SetExtendedParameters(expr, null, FilteredUpdateType.Live); // .Subscribe can then be called return sub; } } }
Sorting can also be applied, in this example we sort in ascending numeric order on the Bid field:
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 sub = new ExtendedContainerSubscription(streamLink.StreamLinkProvider, listener, subject); // Create an expression that returns records with a Bid>10 IFilterExpression expr = ExtendedParametersFactory.CreateFieldFilterExpression("Bid", FieldFilterExpressionOperator.GreaterThan, "10"); // Now, create a sort rule ISortRule sort = ExtendedParametersFactory.CreateFieldSortRule("Bid", FieldType.Number, SortOrder.Ascending); // Set the filter on the subscription sub.SetExtendedParameters(expr, sort, FilteredUpdateType.Live); // .Subscribe can then be called return sub; } } }
Complex logical expressions can also be applied, in the following example we filter on bonds which mature before 1st January 2012 and have a coupon greater than 5%, or any other bond that has a BidYield greater than 6.0:
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 { // The following expression filters results based on a single field, // returning all bonds with a bid yield greater than 6 - // // filterExpression: BidYield > 6.0 private IFilterExpression SimpleFilterExpression() { return (ExtendedParametersFactory.CreateFieldFilterExpression("BidYield", FieldFilterExpressionOperator.GreaterThan, "6")); } // Composite filter expression can be based on multiple rules, the following // returns all bonds which mature before 1st January 2012 and have a coupon greater than 5% - // // filterExpression: (MaturityDate < 20120101) AND (CpnRate > 5.0) private IFilterExpression CompositeFilterExpression() { ILogicalFilterExpression resultant = ExtendedParametersFactory.CreateLogicalFilterExpression(LogicalFilterExpressionOperator.AND); resultant.AddExpression(ExtendedParametersFactory.CreateFieldFilterExpression("CpnRate", FieldFilterExpressionOperator.GreaterThan, "5")); resultant.AddExpression(ExtendedParametersFactory.CreateFieldFilterExpression("MaturityDate", FieldFilterExpressionOperator.LessThan, "20100101")); return resultant; } // Another composite filter expression return all bonds that mature before 1st January 2012 // and have a coupon greater than 5%, or any other bond which has a BidYield greater than 6.0. // // filterExpression: [(MaturityDate < 20120101) AND (CpnRate > 5.0)] OR (BidYield > 6.0) private IFilterExpression ComplexFilterExpression() { ILogicalFilterExpression resultant = ExtendedParametersFactory.CreateLogicalFilterExpression(LogicalFilterExpressionOperator.OR); resultant.AddExpression(CompositeFilterExpression()); resultant.AddExpression(SimpleFilterExpression()); return resultant; } public IExtendedContainerSubscription CreateLogicalFilterSubscription(IStreamLink streamLink, IContainerSubscriptionListener listener, string subject) { IExtendedContainerSubscription sub = new ExtendedContainerSubscription(streamLink.StreamLinkProvider, listener, subject); IFilterExpression expr = ComplexFilterExpression(); // Set the filter on the subscription sub.SetExtendedParameters(expr, null, FilteredUpdateType.Live); // .Subscribe can then be called return sub; } } }