Implementing Historic Search
This page provides a guide to the changes you need to make to your integration adapters to implement FX Sales' Historic Search feature.
Requirements
To provide a backend implementation of the Historic Search, you require the following:
-
Front end: Caplin FX Sales 2.13 or greater
-
Back end: A trading integration adapter based on the FX Integration API 3.49 or greater.
Implementation checklist
To enable the use of Historic Search in your instance of Caplin FX Sales, perform each of the tasks below:
-
Create an implementation of a search blotter listener
-
Create an implementation of a configuration provider
-
Grant user permissions
-
Enable Historic Search
For a working example of an adapter with a Historic Search implementation, see the Novo Trading Adapter example in the FX Integration API Kit (v3.50 or greater).
Implementing a search blotter provider
To implement a search blotter provider, follow the steps below:
-
Create an implementation of the SearchBlotterListener interface:
-
In your implementation’s
searchChannelOpened
method, perform the following tasks:-
Refering to the
SearchExpression
parameter, build a query to a source of historical data (for example, a database). For more information see Search expression syntax and Parsing a search expression. -
For each trade returned by your query, create a blotter item using the
BlotterItemFactory
instance passed to your implementation in theinitialise
method. Publish each blotter item with theSearchBlotterChannel.sendBlotterItem
method.
-
-
Register your implementation of
SearchBlotterListener
with an instance of FXTradeBlotterAdapter:FXTradeBlotterAdapter blotterAdapter = new FXTradeBlotterAdapter(dataSource); blotterAdapter.registerSalesExecutionSearchBlotterListener( new MySearchBlotterListener());
Search expression syntax
The Historic Search subject takes the following format:
/PRIVATE/FX/SALES/BLOTTER/SEARCH/EXECUTION/searchFilter=search_expression
The search_expression is a string with the following format:
Operator | Description |
---|---|
& |
Logical AND |
| |
Logical OR |
Comparator | Description |
---|---|
== |
Equals |
!= |
Not Equals |
>= |
Greater Than or Equal To |
<= |
Less Than or Equal To |
> |
Greater Than |
< |
Less Than |
Example search subjects:
-
/PRIVATE/FX/SALES/BLOTTER/SEARCH/EXECUTION/searchFilter=Status==Completed
-
/PRIVATE/FX/SALES/BLOTTER/SEARCH/EXECUTION/searchFilter=Status==Completed&(Amount>1000&Amount<=2000)
Parsing a search expression
The FX Integration API parses the search expression and passes it to the SearchBlotterListener.searchChannelOpened
method as a parse tree of SearchExpression
objects.
Each node in the tree is one of three types:
-
SearchExpression.Type.OPERATOR
: a boolean operator (AND, OR) -
SearchExpression.Type.COMPARATOR
: a comparator (==, !=, <, >, <=, >=) -
SearchExpression.Type.TEXT
: a string operand (a field name or a field value)
For example, the parse tree for the search expression Field1=ABCDE&Field2>=1000
would be as follows:
You can use the SearchExpression
parse tree to build a query to a source of historical data. The example below shows a recursive method that builds a WHERE clause for a SQL query. To keep the example simple, the method makes the following assumptions:
-
Trading history is stored in one database table
-
Database column names are identical to FX Sales field names
-
All columns are string types (TEXT, VARCHAR, CHAR, …)
private String buildWhereClause(SearchExpression se, String tableName)
{
StringBuilder sb = new StringBuilder();
switch (se.getType()) {
case OPERATOR:
switch (se.getOperator()) {
case AND:
sb.append("(");
sb.append(buildWhereClause(se.getLeft(), tableName));
sb.append(" AND ");
sb.append(buildWhereClause(se.getRight(), tableName));
sb.append(")");
break;
case OR:
sb.append("(");
sb.append(buildWhereClause(se.getLeft(), tableName));
sb.append(" OR ");
sb.append(buildWhereClause(se.getRight(), tableName));
sb.append(")");
break;
}
break;
case COMPARATOR:
String fieldName = se.getLeft().getText();
String fieldValue = se.getRight().getText();
sb.append(tableName).append(".").append(fieldName);
switch (se.getComparator()) {
case EQ:
sb.append("==");
break;
case NE:
sb.append("!=");
break;
case GTE:
sb.append(">=");
break;
case LTE:
sb.append("<=");
break;
case GT:
sb.append(">");
break;
case LT:
sb.append("<");
break;
}
sb.append("'").append(fieldValue).append("'");
break;
case TEXT:
break;
}
return sb.toString();
}
Implementing a search configuration provider
The Historic Search user interface includes a query builder panel above the search results blotter:
The query builder is rendered automatically based on search field meta-data provided by the FX Integration API’s Configuration Service.
To provide search field meta-data to FX Sales, see User Config in the FX Integration API documentation.
Granting permissions
To allow a user to request Historic Search subjects, grant the user (or a group the user belongs to) the following permissions in the global namespace:
Field | Description |
---|---|
Action |
VIEW |
Product |
^/PRIVATE/%u/FX/SALES/BLOTTER/SEARCH/EXECUTION/.* |
Namespace |
|
Authorisation |
ALLOW |
Field | Description |
---|---|
Action |
VIEW |
Product |
^/FILTER/PRIVATE/%u/FX/SALES/BLOTTER/SEARCH/EXECUTION/.* |
Namespace |
|
Authorisation |
ALLOW |
For instructions on granting users permission to access the FX Integration API’s Configuration Service, see User Config.
Caplin FX Sales uses Caplin’s Permissioning Service to authenticate and authorise users. For more information on the Caplin Permissioning Service and the terms used in the tables above, see Caplin Platform Architecture > Permissioning.
Enabling Historic Search
By default, the Historic Search feature is disabled. To enable this feature in FX Sales, set the the configuration option HISTORIC_SEARCH.ENABLED to the boolean value true
.
See also: