RFS Trade Messages
This documentation is for FX Professional 2.18 and earlier. From version 2.19 (2 Jun 2019), FX Professional requires back end adapters to implement the FX Integration API 3. For documentation on FX Integration API 3 messages, see FX Integration API. |
The following trade model and set of messages describe the fields and values required to successfully execute an RFS Trade using FX Professional.
For each of the messages below, [c] denotes that the message is sent by the client, [s] denotes that the message is sent by the server, and [c/s] both client or server.
- Architecture
- Trade Model State Diagram
- Submit Message [c]
- SubmitAck [s]
- PickUp Message [s]
- PriceUpdate Message [s]
- Execute Message [c]
- ExecuteAck Message [s]
- TradeConfirmation Message [s]
- Expire Message [c]
- Withdraw Message [c]
- Reject Message [s]
- Error Message [s]
- Hold Message [s]
- ClientClose Message [s]
- ClientCloseAck Message [s]
Architecture
For the front-end client, the trademodel library handles the processing of these messages. Streamlink is used to send messages to the back end. For RFS trades, two messages must be sent by the client:
-
the first message, Submit, requests a quote (RFQ) or stream (RFS). If successful, a trade channel is created and the back end begins to process the request.
-
the second message, Execute, executes a trade at a specific price.
For the back-end adapters, the FXIntegrationAPI consumes the client messages. The requests for RFS are handled by an Adapter that instantiates the FXTradeAdapter object and registers an RFSTradeListener (see the FX Integration API documentation for more information on Adapters). The RFS is handled by the FX Integration API using the RFSTrade object. The object contains the Responders and Events required to send price updates, as well as transition to the next stage of the trade model.
Trade Model State Diagram
Blue arrows denote a message sent by the client, and green arrows denote messages sent by the server.
States that allow the server to send messages can also send the Error and Reject message. These two transitions are therefore not shown on the diagram above.
Submit Message [c]
This is the message that the client sends in order to open an RFS ticket and receive quotes.
Field Name | Value | Example | ||
---|---|---|---|---|
MsgType |
The transition that the client wants to make in the state model. |
Submit |
||
CurrencyPair |
The currency pair for the trade. This is sent in preference to BaseCurrency and TermCurrency because CurrencyPair is what we permission on. It would be a security hole for the back end to read the BaseCurrency and the TermCurrency fields, because a malicious client could send a valid currency pair in the CurrencyPair field in order to pass the permission check, but send two different currencies in the BaseCurrency and TermCurrency fields in order to execute a trade on a non-permissioned currency pair. |
GBPUSD |
||
DealtCurrency |
The dealt currency for the trade (what the amount is expressed in). Must be either the base or term currency. |
USD |
||
AssetClass |
The asset class for the trade; used by permissioning and licensing. |
FX |
||
TradingAssetClass |
The trading asset class for the trade; used by permissioning and licensing. |
FX |
||
TradingProtocol |
The trade protocol. The Trading DataSource library needs this so that it knows which state model to use for the trade. Also used for permissioning. |
RFS |
||
TradingType |
This could be SPOT, FWD or SWAP, unlike for ESP where the value can only be SPOT or FWD. |
SPOT |
||
Account |
The settlement account to use. |
- |
||
BuySell |
The value of this field denotes the pricing side. The pricing side denotes whether or not pricing is one-way, where the just the bid price ask price is sent. Or if the pricing is two-way, where both prices are sent. Some users may not be permissioned for two-way, others may request a specific side. The following list shows which values of BuySell are mapped to which pricing side:
If the value of BuySell is empty, or no BuySell field is sent by the client, then the pricing side defaults to TWO_WAY.
|
TWO_WAY, BUY, or SELL |
Field Name | Value | Example |
---|---|---|
L1_Amount |
The amount to trade in the dealt currency. |
1000000 |
L1_Tenor |
The tenor at which to settle. Use this field for standard tenors. For broken dates, use the L1_SettlementDate field. |
12M |
L1_SettlementDate |
The settlement date of the trade, in ISO format. Use this field for broken dates. For standard tenors, use the L1_Tenor field. |
20121212 |
SubmitAck [s]
This is the message the server (a trading adapter) will send in order to acknowledge that the request to initiate an RFS has been received by the back-end adapters. These fields should be identical to the ESP SubmitAck message apart from the following differences:
Field Name | Value | Example |
---|---|---|
SubmissionDate |
This should be not sent because the user hasn’t submitted a trade yet |
N/A |
SubmissionTime |
This should be not sent for the same reason as above |
N/A |
PickUp Message [s]
This is the message the server (a trading adapter) will send in order to notify the client that the RFS request is being processed by the back-end trading system.
Field Name | Value | Example |
---|---|---|
RequestID |
The client generated id that is unique for this user and trade. The client-side trading library generates this. |
112314243333 |
MsgType |
The transition that the server wants to make in the state model |
PickUp |
PriceUpdate Message [s]
This is the message the server (a trading adapter) will send to the client when it receives a price update from the back-end trading system. The initial price update should contain the overall timeout, which is the duration for which prices will be streamed. Subsequent quotes in the stream should not set the overall timeout, otherwise they will reset the overall timeout for the stream to a new value.
The trade fields and trade-leg fields in the RFS PriceUpdate extend the standard Streaming price update message.
Field Name | Value | Example |
---|---|---|
RequestID |
The client generated ID that is unique for this user and trade. The client-side trading library generates this. |
112314243333 |
MsgType |
The transition that the server wants to make in the state model |
PriceUpdate |
OverallTimeOut |
This is not present on standard price updates. It is the number of seconds remaining before this stream (not this individual quote) is timed out. |
60 |
BidAskQuoteID |
For RFS swaps, this is the unique OMS generated ID that the client should trade on if he wants to execute the bid price on the near leg and the ask price on the far leg, i.e the client is executing a SELL/BUY swap. For non-swap quotes, this field is not sent. |
|
AskBidQuoteID |
For RFS swaps, this is the unique OMS generated ID that the client should trade on if he wants to execute the ask price on the near leg and the bid price on the far leg, i.e the client is executing a BUY/SELL swap. For non-swap quotes, this field is not sent. |
|
BidPips |
For RFS swaps, this contains the swap points, specified in pips. It generally equals the value of L2_FwdBidPips - L1_FwdBidPips, although the rules are different for short swaps. This is what we would display on the buy and sell buttons. For non-swap quotes, this field is not sent. |
4.5 |
AskPips |
See BidPips. |
4.5 |
For swap quotes this contains the swap points, specified as a raw number. It generally equals the value of L2_FwdBidPoints - L1_FwdBidPoints, although the rules are different for short swaps. The client will typically never display this to the end user. For non-swap quotes, this field is not sent. |
0.00045 |
|
AskPoints |
See BidPoints |
0.000045 |
Field Name | Description | Example | ||
---|---|---|---|---|
BidQuoteID |
A unique ID that identifies the bid side of this quote. This is typically provided by the OMS (Order Management System) and needs to be sent back to the OMS when you want to trade on the bid side, i.e client sells. |
EUR_USD_TIER1_B_15.12563.342.12 |
||
AskQuoteID |
A unique ID that identifies the ask side of this quote. This is typically provided by the OMS (Order Management System) and needs to be sent back to the OMS when you want to trade on the ask side, i.e client buys. |
EUR_USD_TIER1_A_15.12563.342.12 |
||
SpotBidRate |
For SPOT quotes this value will be identical to the L1_AllInBidRate. For forward quotes this will contain the SPOT rate that the forward all-in rate was derived from, and the value in this field should always equal L1_AllInBidRate - L1_FwdBidPoints. |
0.1566 |
||
SpotAskRate |
See SpotBidRate |
0.1116 |
||
SwapBidPoints |
This field represents the difference between L1_FwdBidPoints and L2_FwdBidPointsSwap, see below in Trade Leg Fields. Points and Margins are also sent in a Swap Price Update Message. |
|||
SwapAskPoints |
See SwapBidPoints |
|||
CurrencyPair |
The currency pair that the quote relates to, in the form "<Base Currency><Term Currency>".
|
USDGBP |
||
BaseCurrency |
The first part of the currency pair, e.g for USDGBP this would be USD. |
USD |
||
TermCurrency |
The second part of the currency pair, e.g for USDGBP this would be GBP. |
GBP |
||
DealtCurrency |
The currency that the amount is specified in, which can either be the base currency or the term currency. The client is allowed to specify the dealt currency when they make the market data request or RFS request. The dealt currency does not affect the rate, but it might affect your volume band. For example if the client wants rates for USDGBP and you specify an amount of 1,000,000 and dealt currency GBP, then you would be trading more currency than if you specify an amount of 1,000,000 and a dealt currency of USD. It also affects your GFA, for the same reason - you’re allowed to trade a higher quantity of lower value currencies. |
USD |
||
DigitsBeforePips |
Precision-related field that tells the client how to display rates. This is the number of digits between the decimal point and the pips (i.e the "big digits" that the client wants to look at). For most currency pairs the value of this field will be 2, for example for a USDGBP rate of 1.23456 the pips are 45 so there are two digits between the decimal point and the pips. For USDJPY the rate could be 103.256 and the pips are the 25, so in this case the value of DigitsBeforePips should be 0. |
2 |
||
NumberOfPips |
Precision-related field that tells the client how to display rates. This is the number of pips the client wants to look at. Normally this value is 2. |
2 |
||
NumberOfFractionalPips |
Precision-related field that tells the client how to display rates. This is the number of digits after the pips. For example, for a USDGBP rate of 1.23456 the pips are the 45 and there is one digit (the 6) after the pips, so the value of the NumberOfFractionalPips field should be 1. There are typically more fractional pips on forward rates than spot rates.
|
0 |
||
SpotRateDPS |
The number of decimal places to display after the decimal point. Available as of FX Integration API 2.6.0. |
4 |
||
GFA |
The maximum amount the client is allowed to trade. |
10000000 |
||
Indicative |
Optional. If this field is included and has the value "true" then the quote is indicative only and not tradeable. If the field is absent or has the value "false" then the quote is tradeable. |
true |
||
SwapGFA |
Optional. For forward quotes, this value indicates the maximum tradeable amount for even SPOT/FWD swaps involving this tenor. For example, if you send a quote for the "1M" tenor with GFA=1000000 and SwapGFA=50000000 it indicates that the user can trade up to 1 million on a 1M forward outright, but up to 50 million on an even SPOT/1M swap. The GFA/liquidity for even swaps is usually much higher than that for SPOT or forward GFA; where it’s typically ten times higher. This is because an even swap has less risk for the bank than an outright trade - if you buy an amount (even a very large amount) and sell it back in a month’s time then the potential loss for the bank is fairly small, barring unusual price fluctuations. |
50000000 |
Field Name | Value | Example |
---|---|---|
L1_Amount |
Unlike streaming prices, which are based on volume bands, RFS quotes are based on the exact amount the user specified, so we could send this field if we want to. However the client already knows it, so it’s probably unnecessary. |
50000 |
Field Name | Description | Example | ||
---|---|---|---|---|
L1_AllInBidRate |
For SPOT quotes this will be the bid rate. For forward quotes this will be the bid all-in rate (SPOT + L1_FwdBidPoints). This is the primary rate that should be displayed. |
0.111455 |
||
L1_AllInAskRate |
For SPOT quotes this will be the ask rate. For forward quotes this will be the ask all-in rate (SPOT + L1_FwdAskPoints). This is the primary rate that should be displayed. |
0.156808 |
||
L1_FwdBidPips |
For forward quotes this field contains the bid points, specified in pips. The pip rules differ by currency pair and should be handled by the back end. For SPOT quotes, this field is not sent. |
-1.45 |
||
L1_FwdAskPips |
For forward quotes this field contains the ask points, specified in pips. The pip rules differ by currency pair and should be handled by the back end. For SPOT quotes, this field is not sent. |
2.08 |
||
L1_Tenor |
The tenor for the near leg. This will either be a tenor code such as "SPOT", "1M", "1Y", or if the value date is not a tenor, this field will contain the string "BROKEN". |
SPOT |
||
L1_FwdBidPoints |
Optional. For forward quotes this field contains the raw amount to add to the SPOT rate in order to produce the forward all-in rate, i.e this field contains the forward points specified as a normal decimal number rather than in pips. For forward quotes the value of L1_SpotBidRate + L1_FwdBidPoints should always equal L1_AllInBidRate. For SPOT quotes this field is not sent. |
0.000145 |
||
L1_FwdAskPoints |
Optional. For forward quotes this field contains the raw amount to add to the SPOT rate in order to produce the forward all-in rate, i.e this field contains the forward points specified as a normal decimal number rather than in pips. For forward quotes the value of L1_SpotAskRate + L1_FwdAskPoints should always equal L1_AllInBidRate. For SPOT quotes this field is not sent. |
0.000208 |
||
L1_NumberOfFractionalPoints |
Optional. Number of decimal places the displayed value of the forward points may have, usually 2 but may be other values. Can vary per tenor, so they need to be specified at the leg level as a swap could have different values per leg. If not sent the front end will need derive this data from the L1_FwdBidPips if it needs it.
|
2 |
||
L1_AllInRateDPS |
Optional. Number of digits to display after the decimal point. Available as of FX Integration API 2.6.0. |
6 |
||
L1_MidRate |
Optional. This field represents the midrate; which is usually shown for regulatory purposes and not traded on. The midrate should be the rate that represents the median average between the bid all-in rate and the ask all-in rate, before the bank applies it’s spread. The midrate is not calculated in the adapter, but should be received from the back-end trading system. |
0.134132 |
Execute Message [c]
This is the message the client will send in order to execute a trade on a quote received on the stream. The fields on this message are similar to, but subtly different from the ESP Submit message.
Field Name | Value | Example | ||
---|---|---|---|---|
RequestID |
The client generated ID that is unique for this user and trade. The client-side trading library generates this. |
112314243333 |
||
MsgType |
The transition that the client wants to make in the state model |
Execute |
||
Account |
(Optional) The settlement account to use - if defined, it should be the same as on the ESP Submit message |
- |
||
BidPips |
For swap trades, this field is included in the PriceUpdate message, and should be sent back unchanged in the Execute message. For non-swap trades, this field should not be sent. |
4.5 |
||
AskPips |
For swap trades, this field is included in the PriceUpdate message, and should be sent back unchanged in the Execute message. For non-swap trades, this field should not be sent. |
4.5 |
||
QuoteID |
The unique ID of the quote the client wants to trade on. This is generated by the OMS. Unlike ESP, where you have a quote ID for the forward points and a quote ID for the related SPOT quote, there is only one quote ID for an RFS quote, even if it’s a forward or swap. |
EQ:1366899484.1:230 |
||
This field is updated regularly by PriceUpdate messages. It should be included in the Execute message unchanged.
|
1.2345 |
|||
SpotAskRate |
This field is updated regularly by PriceUpdate messages. It should be included in the Execute message unchanged.
|
1.2345 |
||
CurrencyPair |
The currency pair for the trade. This is sent in preference to BaseCurrency and TermCurrency because CurrencyPair is what we permission on. It would be a security hole for the back end to read the BaseCurrency and the TermCurrency fields, because a malicious client could send a valid currency pair in the CurrencyPair field in order to pass the permission check, but send two different currencies in the BaseCurrency and TermCurrency fields in order to execute a trade on a non-permissioned currency pair.
|
GBPUSD |
||
AssetClass |
The asset class for the trade; used by permissioning and licensing.
|
FX |
||
TradingAssetClass |
The trading asset class for the trade; used by permissioning and licensing.
|
FX |
||
TradingProtocol |
The trade protocol. The Trading DataSource library needs this so that it knows which state model to use for the trade. Also used for permissioning.
|
RFS |
||
TradingType |
This could be SPOT, FWD or SWAP, unlike for ESP where the value can only be SPOT or FWD.
|
SPOT |
Trade Leg Fields
Field Name | Value | Example | ||
---|---|---|---|---|
L1_Amount |
The amount to trade in the dealt currency |
1000000 |
||
L1_BuySell |
The trade direction of the base currency, from the perspective of the user. Valid values: "BUY", "SELL". |
BUY |
||
L1_Price |
The all-in rate that the client wants to trade on. The value of this field must equal the value of either the L1_AllInBidRate or L1_AllInAskRate field in the PriceUpdate message. The front end typically populates this field by reading the currently rendered price on the buy or sell button at the time the user clicks. |
1.2345 |
||
L1_FwdPips |
For forward trades this is the forward pips that the client wants to trade on. The value of this field must equal the value of either the BidPips or AskPips field in the PriceUpdate message. The front end typically populates this field by reading the currently rendered forward points on the buy or sell button at the time the user clicks. For SPOT trades this field should be not sent. |
4.5 |
||
L1_FwdPoints |
For forward trades this is the forward points that the client wants to trade on. The value of this field must equal the value of either the BidPoints or AskPoints field in the PriceUpdate message. For SPOT trades this field should be not sent. If the trade is a forward but the back end did not send the BidPoints and AskPoints fields (because they are optional) then this field should be not sent. |
0.00045 |
||
L1_AllInBidRate |
This field is included in the PriceUpdate message, and should be sent back unchanged in the Execute message.
|
1.2345 |
||
L1_AllInAskRate |
This field is included in the PriceUpdate message, and should be sent back unchanged in the Execute message.
|
1.2345 |
||
L1_FwdBidPips |
This field is included in the PriceUpdate message if it is a streaming Forward rate, and should be sent back unchanged in the Execute message. If this field is not present in the PriceUpdate message (which will be the case for an RFS SPOT trade), then it should not be included in the Execute message. |
4.5 |
||
L1_FwdAskPips |
This field is included in the PriceUpdate message if it is a streaming Forward rate, and should be sent back unchanged in the Execute message. If this field is not present in the PriceUpdate message (which will be the case for an RFS SPOT trade), then it should not be included in the Execute message. |
4.5 |
If the trade is a swap, then we want L2_ fields for each of the L1_ fields above, representing the second leg of the swap.
ExecuteAck Message [s]
This is the message sent by the server (a trading adapter) to acknowledge that the client’s request to execute an RFS quote has been received by the back-end adapters.
Field Name | Value | Example |
---|---|---|
RequestID |
The client generated id that is unique for this user and trade. The client-side trading library generates this. |
112314243333 |
MsgType |
The transition that the server wants to make in the state model |
ExecuteAck |
SubmissionDate |
The date on the server that the trade was submitted to the OMS (ISO format) |
20130425 |
SubmissionTime |
The time on the server that the trade was submitted to the OMS (HH:MM:SS) |
20130425 |
TradeConfirmation Message [s]
This is the message sent by the server (a trading adapter) to confirm to the client that the RFS trade has been successfully executed in the back-end trading system. The message contains the details of the trade that the client wants to see in order to verify the correctness of the trade.
Not all fields are sent. Others may be added as needed. Could be used as the Execution/History message as well.
Field Name | Value | Example |
---|---|---|
RequestID |
The client generated ID that is unique for this user and trade. The client-side trading library generates this. |
112314243333 |
MsgType |
The transition that the server wants to make in the state model |
TradeConfirmation |
TradeID |
The ID for the trade as generated by the OMS |
EQ:1366900842.9:245 |
OrderId |
If trade was based on an Order, generated by the OMS |
4.1.12345678 |
FillID |
A unique identifier for the execution. This is generated by the OMS, and is different to the Trade ID. For example, in the OMS there might be a trade with ID 1 and an execution for that trade with ID 2. |
1366844776:228_1 |
CurrencyPair |
The currency pair being traded. |
EURUSD |
DealtCurrency |
The currency the L1_Amount is in. |
EUR |
SpotRate |
The SPOT rate that the client traded on. This should be either the L1_AllInBidRate or L1_AllInAskRate, depending on whether the client wanted to do a buy or a sell. |
1.2345 |
ExecutionDateTime |
The timestamp in UTC that the trade was executed. The front end should convert this to the users’s local time. |
20121212150000 |
TradeDate |
The date the trade was booked on. May be rolled to the next work day. |
20121212 |
Account |
The Client Account that the deal was booked into. |
Account 1 |
SubmittedBy |
Username of person booking the deal. |
|
SubmittedFor |
Username the deal was booked on behalf of by Sales Traders. The same as SubmittedBy for regular users. |
|
SwapPips |
If a Swap the pips on the whole deal. In scaled format, i.e. sent as 4.50 but would be used as say 0.000450. |
4.50 |
TradingType |
Trade Type |
SPOT |
AssetType |
The type of the Asset |
FX |
SwapType |
The Type of Swap, if it is one |
SPOTFWD |
DigitsBeforePips |
Number of digits before the pips |
2 |
NumberOf Pips |
Number of pips, nearly always 2 |
2 |
NumberOfFractionalPips |
Whether Spot Rate has sub-pips or not |
0 or 1 |
Field Name | Value | Example |
---|---|---|
L1_AllInRate |
The rate that the client traded on. This should be either the L1_AllInBidRate or L1_AllInAskRate sent on the ESP Submit message, depending on whether the client wanted to do a buy or a sell. |
1.23456 |
L1_BuySell |
The trade direction of the base currency, from the perspective of the user. Valid values: "BUY", "SELL". |
BUY |
L1_Amount |
The amount that the client traded specified in the dealt currency. |
500.00 |
L1_ContraAmount |
The amount that the client traded specified in the non-dealt currency. |
617.28 |
L1_FwdPips |
The forward points used in the rate. In scaled format, i.e. sent as 4.50 but would be used as say 0.000450. |
4.50 |
L1_FwdPipsPrecission |
Number of decimals places for Forward Pips. |
2 |
L1_Tenor |
The tenor of the leg. |
6M |
L1_SettlementDate |
The actual date for the tenor. |
20130614 |
L1_RegulatoryID |
Unique transaction Id for the deal. (Optional) |
Long string, 35+ |
If the trade is a swap, then we want L2_ fields for each of the L1_ fields above, representing the second leg of the swap.
Expire Message [c]
At various states (see the trade model above) the server may send an Expire message. A state will be made to transitioned to the Expired state in certain instances, for example if the stream was kept open for the total amount of time without a quote being traded on it.
Field Name | Value | Example |
---|---|---|
RequestID |
The client generated id that is unique for this user and trade. The client-side trading library generates this. |
112314243333 |
MsgType |
The transition that the client wants to make in the state model |
Expire |
Withdraw Message [c]
At various states (see the trade model above) the server may send a Withdraw message. The state will be made to transition to the either the PickedUp state or the Error state depending on what state the transition is made from. The withdraw message is sent to notify the client that the back-end trading system has withdrawn the current quote stream, and that we are awaiting a new set of price updates.
Field Name | Value | Example |
---|---|---|
RequestID |
The client generated ID that is unique for this user and trade. The client-side trading library generates this. |
112314243333 |
MsgType |
The transition that the client wants to make in the state model |
Withdraw |
Reject Message [s]
Error Message [s]
Hold Message [s]
ClientClose Message [s]
ClientCloseAck Message [s]
See also: