Implementing Post-trade Allocation
This page describes how to implement FX Sales' Post-trade Allocation feature in your trading adapter.
Requirements
You require:
-
Front end: FX Sales 2.33 or greater, configured to use the User Config to supply user entitlements instead of permissioning.
-
Back end: an integration adapter built against the FX Integration API 3.69 or later, with a registered implementation of the
AllocateTradeListener
interface.
Overview
Implement the AllocateTradeListener interface
In this section you will implement the AllocateTradeListener
interface.
AllocateTradeListener
handles client-sent events in the Allocate trade model, the state diagram for which is reproduced below:
Once an Allocate trade enters the Queued state, the trade model is identical to the RFS trade model. If your system already supports the RFS trade model and implements the |
Follow the steps below:
-
Create an implementation of the
AllocateTradeListener
interface: -
In the constructor for your implementation, store a reference to the
AllocateTrade
constructor parameter:public class MyAllocateTradeListener implements AllocateTradeListener { private AllocateTrade allocateTrade = null; public MyAllocateTradeListener(AllocateTrade allocateTrade) { this.allocateTrade = allocateTrade; } ... }
-
Implement the following
AllocateTradeListener
methods:
Implement onDetailsRequest
When the user launches an allocation, a DetailsRequest message is received from the client and the onDetailsRequest(DetailsRequestTradeEvent)
listener is triggered.
In the onDetailsRequest(DetailsRequestTradeEvent)
method of your implementation, handle the client’s request for trade details:
-
Using the
TradeID
field of theDetailsRequestTradeEvent
as a reference, request the trade’s details from your trading system. -
Check the trade is identified by the trading system as allocatable, and perform any further validation required by your implementation. If the trade is invalid, then send a Reject message to the client:
this.allocateTrade.sendRejectTradeEvent();
-
If the trade is valid, then create and send a DetailsUpdate message to the client:
-
Create an instance of AllocationSpotSalesDetailsUpdate or AllocationForwardSalesDetailsUpdate using the class’s associated builder, accessed via the
newBuilder()
method. For documentation on the builders, see AllocationSpotSalesDetailsUpdate.Builder and AllocationForwardSalesDetailsUpdate.Builder.// Build the DetailsUpdate message Message tradeDetails = AllocationSpotSalesDetailsUpdate.newBuilder() .setSpotSalesTradeConfirmation( ... ) .setDisplayFields( ... ) // ... example truncated
The DisplayFields value on the DetailsUpdate message determines which fields are displayed under the Original Deal Details heading. You may use the utility method
addDefaultSalesAllocationDetailsUpdateFields
, which adds the Caplin-default display fields to aDisplayFields
instance. Using this method, you may add custom fields before or after the default fields. Alternatively, you can compose your display fields configuration field by field, combining your custom fields with Caplin-default fields, for whichDefaultDisplayFields
provides static builders methods.The Caplin-default display fields for the Sales Allocate DetailsUpdate message are: Amount, Contra Amount, Currency Pair, Settlement Currency (if non-deliverable), Settlement, Fixing Date (if non-deliverable), Fixing Source (if non-deliverable), Account and Rate. -
Send the
AllocationSpotSalesDetailsUpdate
orAllocationForwardSalesDetailsUpdate
message to the client:// Send the DetailsUpdate message to the client this.allocateTrade.sendDetailsUpdateEvent(tradeDetails);
-
Implement onClientClose
In the onClientClose(ClientCloseEvent)
method of your implementation, handle the client’s closure of the allocation:
-
Perform any clean up and logging required by your implementation
-
Send a ClientCloseAck message to the client:
this.allocateTrade.sendClientCloseAckTradeEvent();
Implement onSubmit
When a user submits the allocation they want to perform, a Submit message is sent to your adapter and the onSubmit(SubmitTradeEvent)
listener method is called.
In the onSubmit(SubmitTradeEvent)
method of your implementation, handle the submitted allocation:
-
Retrieve the legs from the
SubmitTradeEvent
instance and validate them. If any of the allocation legs are invalid, then send a Reject message to the client:this.allocateTrade.sendRejectTradeEvent();
-
If the settlement date of each leg is identical to the settlement date of the original trade, then follow the steps below:
-
Send an AllocateAck message to the client, which transitions the trade from the Submitted state to the Allocated state:
this.allocateTrade.sendAllocateAckTradeEvent();
-
Re-allocate the trade using your trading system’s API.
-
Update blotter records for the original trade:
Field Value Status
Allocated
CanAllocate
false
CanRoll
false
IsAllocated
true
-
-
If the settlement date of any leg is different to the settlement date of the original trade, then follow the steps below.
-
Send a SubmitAck message to the client, which transitions the trade from the Submitted state to the Queued state:
this.allocateTrade.sendSubmitAckTradeEvent();
-
Currently, manual pricing via dealer intervention is not supported for allocations. Do not send the allocation to the active deals blotter. Instead, immediately send a PickUp message to the client, which transitions the trade from the Queued state to the PickedUp state:
this.allocateTrade.sendPickUpTradeEvent();
-
Send the first of a series of PriceUpdate messages, which transitions the trade from the PickedUp state to the Executable state:
// Build the PriceUpdate message PriceUpdateTradeEvent priceUpdate = AllocationQuote.newBuilder() .setCommonTradeDetailsFields( ... ) // ... example truncated this.allocateTrade.sendPriceUpdateEvent(priceUpdate);
-
Implement onExecute
When the user attempts to finalise a reprice allocation, an Execute message is received from the client and the onExecute(ExecuteTradeEvent)
listener method will be triggered.
In the onExecute(ExecuteTradeEvent)
method of your implementation, perform the following steps:
-
Send an ExecuteAck message to the client, which transitions the trade from the Executable state to the ExecuteSent state:
this.allocateTrade.sendExecuteAckTradeEvent();
-
Validate the ExecuteTradeEvent legs. If the leg data is invalid, then send a Reject message to the client:
this.allocateTrade.sendRejectTradeEvent();
-
If the leg date is valid, perform the following steps:
-
Re-allocate the trade using your trading system’s API.
New trades created from repriced legs should use the rate and margin details of the Allocate trade, however legs that were not repriced should still use the details of the original trade.
-
Send a TradeConfirmation message to the client:
// Build the TradeConfirmed message AllocationSalesConfirmation msg = AllocationSalesConfirmation.newBuilder() .setCommonFields( ... ) .setDisplayfields( ... ) // ... example truncated this.allocateTrade.sendTradeConfirmationEvent(msg);
The DisplayFields value on the DetailsUpdate message drives which fields are displayed above the trade confirmation table. You may utilise the utility method
addDefaultSalesAllocationConfirmationFields
, which adds the Caplin-default display fields to aDisplayFields
instance. Using this method, you may add custom fields before or after the default fields. Alternatively, you can compose your display fields configuration field by field, combining your custom fields with Caplin-default fields, for whichDefaultDisplayFields
provides static builders methods.The Caplin-default display fields for the Sales Allocate TradeConfirmation message are: Client, Currency Pair, Settlement Currency (if non-deliverable), Fixing Source (if non-deliverable), Date, Time, Trader Spot Rate, Spot Margin, Client Spot Rate, Total Deals, Estimated Profit. -
Update blotter records for the original trade:
Field Value Status
Allocated
CanAllocate
false
CanRoll
false
IsAllocated
true
-
Implement onTradeClosed
In the onTradeClosed
method in your implementation, handle any clean up and logging required when the trade channel is closed.
Register your implementation of AllocateTradeListener
Implement and register an instance of AllocateTradeListenerFactory
with the FXTradeAdapter instance in your adapter.
The code example below creates and registers an anonymous implementation of the AllocateTradeListenerFactory
interface:
fxTradeAdapter.registerAllocateTradeListenerFactory(
new AllocateTradeListenerFactory() {
@Override
public AllocateTradeListener createTradeListener(AllocateTrade trade)
throws TradeException {
return new MyAllocateTradeListener(trade);
}
}
)
The code above can also be expressed using a Java method reference to the MyAllocateTradeListener
constructor, which shares the same method signature as the method createTradeListener
in AllocateTradeListenerFactory
:
fxTradeAdapter.registerAllocateTradeListenerFactory(MyAllocateTradeListener::new);
Add PTA fields to trade confirmation messages
Wherever your back end code creates a trade confirmation message, set values for the CanAllocate
, CanRoll
and IsAllocated
fields in the CommonTradeConfirmationFields
field set.
The CommonTradeConfirmationFields
field set is used in TradeConfirmation messages in the following trade models:
-
ESP trade model
-
RFS trade model
-
Amend trade model
-
SalesIntervention trade model
The CommonTradeConfirmationFields
field set is used in the following blotter records:
- CanAllocate
-
When you set this field to
true
, it indicates to front-end applications that the back-end trading system supports allocation of this trade. - CanRoll
-
When you set this field to
true
, it indicates to front-end applications that the back-end trading systems supports the rolling of settlement dates during allocations of this trade. - IsAllocated
-
When you set this field to
true
, it indicates to front-end applications that the trade has been allocated and can no longer be allocated or rolled (regardless of the value ofCanAllocate
).
Front-end applications should refer to the values of both CanAllocate
and IsAllocated
to determine if a trade is allocatable.
CanAllocate | CanRoll | IsAllocated | Trade is allocatable? | Trade is rollable? |
---|---|---|---|---|
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
Configure user entitlements
Post-trade Allocation is enabled via the Configuration Service.
Add the following feature to the feature configuration in your client configuration:
new FXFeatures().postAllocation(new FXFeaturesPostAllocation().enabled(true));
If CAPLIN.PTA.ENTITY_SEARCH.ENABLED
is enabled, i.e. if the Client or Entity column is shown on your frontend, add the following feature to the feature configuration in your user configuration:
new FXFeatures().postAllocation(new FXFeaturesPostAllocation().toboSelection(USER_CONFIG));
For toboSelection
, choose either USER_CONFIG
to provide clients via user config, or CLIENT_SEARCH
to provide clients via the client search API.
For more information on the configuration service see, see User Config.
Configure Post-trade Allocation in FX Sales
The following FX Sales configuration items apply to Post-trade Allocation:
- CAPLIN.PTA.ENTITY_SEARCH.ENABLED
-
Set to
true
to display the client column in the allocation table on Post-trade Allocation tickets. The client column allows the trader to allocate to a different client than that of the original trade. For more information, see CAPLIN.PTA.ENTITY_SEARCH.ENABLED. - CAPLIN.MOTF.TICKET.ACCOUNT.ALLOW_NULL_SELECTION
-
Set to
true
to allow traders to allocate to null trading accounts. Also allows traders to trade against null trading accounts in MOTF tickets. For more information, see CAPLIN.MOTF.TICKET.ACCOUNT.ALLOW_NULL_SELECTION - CAPLIN.MOTF.TICKET.ACCOUNT.AUTO_SELECT_FIRST
-
Set to
true
to automatically select the first valid trading account after changing the value in a Client cell in the allocation table on Post-trade Allocation tickets (see CAPLIN.PTA.ENTITY_SEARCH.ENABLED). Also automatically selects the first valid trading account in MOTF tickets. For more information, see CAPLIN.MOTF.TICKET.ACCOUNT.AUTO_SELECT_FIRST
See also: