Trades
Description
Trade is one of the crucial operations of the Send Platform. Trades allow the users to move their funds from one currency to another.
Trades are a conversion between 2 different currencies within the same Trading Account. At the time of creating a Trade, funds must be instructed to be transferred to a Wallet within the same Trading Account or paid to a Recipient and their Payment Address.
Before booking a Trade the user can request a Ratesheet. Requesting the Ratesheet will lock in a rate for the client for a short period of time. That will guarantee that the Trade will be performed with exactly that locked rate*. If Ratesheet is not included in Trade request, then Send will apply the best market rate available at the time of booking.
*Rates may vary due to the commercial agreement you have with Send. Rates quoted by the Ratesheet will include any relevant markup for the deal except for the cases where there are specific discounts given for trades over time OR you have previously agreed with Send that the margin will not be included.
The following example contains a Payment Object which will be handled after the Trade is complete.
How to request a Ratesheet
To fetch a Ratesheet you need to send a POST /rate-sheets
request including the accessToken
you’ve received
during the Authentication process in the headers.
Within the request you can optionally specify the tradingAccountId
to apply the rates to a particular Trading Account. If not supplied the Ratesheet and its Rate will be applied for the whole Enterprise Parent Account.
Ratesheets expire in a standard 2.5 minutes (160 seconds) time period.
Variable Ratesheet Expiry Windows
If you have a requirement for a different ratesheet expiry window please let us know. We're looking to extend this functionality in the future.
Besides this the request must include at least one Currency Pair. A Currency Pair consists of buyCurrency
and sellCurrency
. The request can include unlimited number of valid Currency Pairs.
Request example for POST /rate-sheets
{
"tradingAccountId": "a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6",
"currencyPairs": [
{
"buyCurrency": "NZD",
"sellCurrency": "AUD"
}
]
}
In response to your request you will receive either a SUCCESS 201
response or one of the error responses (400, 401, 500). See Status Codes & Error Messages.
In case of successful response you will receive back all the information you’ve sent with a rate
specified for each Currency Pair and expiresAt
(Ratesheet expiry) date and time.
Ratesheet expiration time is explicit. If the user tries to book a Trade referring to the expired Ratesheet the Trade will be rejected.
Rates are always represented as
sellCurrency
→buyCurrency
.For example, for a AUD → USD trade a 0.7 rate will indicate that for every 1 AUD you will get 0.7 USD.
Response example for POST /rate-sheets
{
"item": {
"rateSheetId": "string",
"tradingAccountId": "string",
"currencyPairs": [
{
"buyCurrency": "AUD",
"sellCurrency": "AUD",
"rate": 0
}
],
"expiresAt": "2024-08-12T05:53:05.709Z"
}
}
Each Ratesheet can be used across multiple Trades.
The quoted rate
for a currency will be updated based on its liquidity in Send network. The rate
of the higher liquid currencies will update every few minutes whilst lower liquid currencies will only update once in 1-2 hours.
Ratesheets can be fetched 24/7 but that rates fetched outside of market hours will have an additional spread
applied to cover market movement during the market close window.
How to book a Trade
To book and further perform a Trade you need to send a POST /trades
request including the accessToken
you’ve received during the Authentication process in the headers.
Within the request you need to specify the following:
-
buyCurrency
andsellCurrency
;- The list of available currencies to use will be defined as part of your enterprise agreement.
-
Either
buyAmount
ORsellAmount
.- Send will automatically use rates to calculate the amount that was not provided. When booking a Trade the amount should be in the lowest denominator of the currency.
F.e. for AUD $1.00 would be 100 and in JPY ¥100 = 100. - The maximum amount that can be booked for a Trade without first prefunding the Wallet with the required cash will be negotiated as part of your contract with Send.
- Send will automatically use rates to calculate the amount that was not provided. When booking a Trade the amount should be in the lowest denominator of the currency.
-
FromWalletId
- The balance of the
fromWallet
will be reduced to cover thesellAmount
. ThefromWallet
currency must match thesellCurrency
.
- The balance of the
-
Either
toWalletId
ORPayment
Object- The ability to include
Payment
Object in Trade can help in cases where the user needs to make a Trade into a currency not supported by Wallets. It is also possible to includePayment
Object in Trade even if currencies are supported by the Wallets. - If a
Payment
Object is provided with the Trade then a Payment Transaction will be automatically created. After the settlement of the Trade the funds will be sent to the Recipient. For detailed description of the Payments see Payments Endpoint. - If a
toWalletId
is supplied instead, then this Wallet should be created, active and must be within the same Trading Account as thefromWalletId
. (If you would like to trade into a currency to be given to anothertradingAccountId
then you will need to create a Trade and then a Transfer separately. - The same applies to
Payment
Object - bothrecipientId
andpaymentAddressId
should be created and Active before booking a Trade. toWallet
/paymentAddress
currency must match thebuyCurrency
.
- The ability to include
-
RatesheetId (optionally)
- The Ratesheet can only be included if it is not expired yet. If no
ratesheetId
provided then real time rates will be applied for the Trade.
- The Ratesheet can only be included if it is not expired yet. If no
Request Example for POST /trades without the Payment Object
{
"buyCurrency": "NZD",
"sellCurrency": "AUD",
"buyAmount": 20000,
"ratesheetId": "1a2b3c4d-5e6f-7g8h-9i0j-1k2l3m4n5o6",
"fromWalletId": "a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6",
"toWalletId": "a1b2c3d4-5e6f-7g8h-9i0j-klmnop123456",
"externalReference": "string"
}
Request Example for POST /trades with the Payment Object
{
"buyCurrency": "NZD",
"sellCurrency": "AUD",
"sellAmount": 19000,
"ratesheetId": "1a2b3c4d-5e6f-7g8h-9i0j-1k2l3m4n5o6",
"fromWalletId": "a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6",
"externalReference": "string",
"payment": {
"paymentReason": "buying_a_vehicle",
"reference": "string",
"recipientId": "a1b2c3d4-5e6f-7g8h-9i0j-klmnop123456",
"paymentAddressId": "a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6"
}
}
In response to your request you will receive either a SUCCESS 201
response or one or the error responses (400, 401, 500). See Status Codes & Error Messages.
Within the successful response you will receive all the data you’ve provided with the following data included:
tradeTransactionId
which can be used to refer to the trade transaction- both
buyAmount
andsellAmount
as either one of them was provided in the request and the other will be calculated based on the Rate ratesheetId
will only be returned if it was provided in the request.- Factual
rate
will be provided even if there was no Ratesheet provided in the request status
How do Trade Transactions workcreatedAt
,updatedAt
dates and time.Payment
object details
Details includepaymentTransactionId
which can be used to subsequently fetch details about
(or listen to Webhooks about) the Payment. Detailed description of the Payments Endpoint can be found here.
To receive updates on the Trade Transaction and Payment Transaction status
changes please refer to Webhooks.
Response example for POST /trades without the Payment Object
{
"item": {
"tradeTransactionId": "string",
"buyCurrency": "NZD",
"sellCurrency": "AUD",
"buyAmount": 20000,
"sellAmount": 19000,
"rateSheetId": "string",
"rate": 0,
"status": "submitted",
"fromWalletId": "string",
"toWalletId": "string",
"tenor": "T0",
"settlementDate": "2024-08-12T05:53:05.709Z",
"createdAt": "2024-08-12T05:53:05.709Z",
"updatedAt": "2024-08-12T05:53:05.709Z",
"externalReference": "string"
}
}
Response example for POST /trades with the Payment Object can be found below
{
"item": {
"tradeTransactionId": "string",
"buyCurrency": "NZD",
"sellCurrency": "AUD",
"buyAmount": 20000,
"sellAmount": 19000,
"rateSheetId": "string",
"rate": 0,
"status": "submitted",
"fromWalletId": "string",
"toWalletId": "string",
"tenor": "T0",
"settlementDate": "2024-08-12T05:53:05.709Z",
"createdAt": "2024-08-12T05:53:05.709Z",
"updatedAt": "2024-08-12T05:53:05.709Z",
"externalReference": "string",
"payment": {
"paymentTransactionId": "string",
"paymentReason": "string",
"reference": "string",
"paymentType": "payout",
"payoutType": "swift",
"currency": "AUD",
"amount": 0,
"fromWalletId": "string",
"recipientId": "string",
"paymentAddressId": "string",
"rejectReason": "string",
"status": "submitted",
"createdAt": "2024-08-12T05:53:05.709Z",
"updatedAt": "2024-08-12T05:53:05.709Z",
"paymentDate": "2024-08-12",
"externalReference": "string"
}
}
}
How do Trade Transactions work
Firstly before creating a Trade Transaction a Trade undergoes a round of checks to make sure everything is set correctly and no data is missing. These checks include:
- needed data is provided;
- currencies match the Wallets;
- currencies are available for trading;
- trade is within the parameters set for your commercial agreement with Send*;
- the balance is sufficient** to make a Trade;
- ratesheet is not expired and ratesheetId is correct (if provided)
Provided all checks pass, the status
of the Transaction will be set to Submitted and the Wallet’s balances will be updated (you will see the fromWallet
has the trade value added to it's committed balance).
If there is a Payment
object within the Trade request any necessary payments will also be initiated here and the paymentTransactionId
passed back in the API for future reference.
After that, the Trade will then be internally confirmed with Send and the status
of the Transaction will be changed to Processing. In most cases that should happen immediately.
The next step for the Transaction is to undergo the transaction monitoring (if any action is required, Send will reach out via established channels to rectify any issues/gather necessary documentation).
At this point, if compliance fails the Trade it will go into a Rejected status
and Wallet debt will be erased along with the Payment
if one was initiated by the Trade. Otherwise, once the trades settlement date has arrived, the Trade will go into the Awaiting Funds status
. Note: This is true for the reverse as well, if a payment linked to a trade fails compliance checks, the trade will also be marked as Rejected.
Once enough funds are in the fromWallet
(which may already have enough) the Trade will go into the Settled
status
and either the toWallet
will have its balance updated with the buyCurrency
or the linked Payment
will be released to the Recipient via the established payment rails.
Regarding the time frames please note the following:
- In the response Send will provide settlement date and time which will indicate when the Trade will settle (this is when enough funds are available on the wallet to close the trade position and the agreed settlement date is reached).
- If the
fromWallet
does not have sufficient funds by the settlement date, Send will reach out to determine the reason for this, and may choose to cancel the trade if the trade remains unfunded.
- If the
T0
Trades booked on weekends, or after market hours will fully settle at 9:30AM AEST on the next business day. Full details can be found at Trade Settlement and Cutoff Times.
* When you sign your contract with Send to use our services we will work with you to define a set of acceptable parameters for your activity. This will include things like Min/Max trade limits, enabled currencies, funding flows etc.
**You can have an agreement with Send for a post-funding model where trades can be booked before funds being on a wallet. In that case the Transaction will stay in “Awaiting Funds” status after the Compliance Check until the Wallet has enough funds for the Trade.
Trade Status Flow
Fetching Trade Information
Fetching the previously created Ratesheet
To request the information about the previously created Ratesheet you can send a signed GET /rate-sheets/{rateSheetId}
request.
In response to your request you will receive either a SUCCESS 200
response or one or the error responses (400, 401, 500) See Status Codes & Error Messages.
Given a valid ratesheetId
in the URL, a SUCCESS response will return the previously created Ratesheet.
Even if the Ratesheet has expired by the moment of GET request it will be still returned in the response.
Only Trade POST requests will fail if they include an expired Ratesheet.
Fetching the previously created Trade Transaction
To request the information about the previously created Trade Transaction you can send a signed GET /trades/{tradeTransactionId}
request.
In response to your request you will receive either a SUCCESS 200
response or one or the error responses (400, 401, 500) See Status Codes & Error Messages.
Given a valid tradeTransactionId
in the URL, a SUCCESS response will return the previously created Trade Transaction.
Fetching all the trades for the a given Trading Account
To request the information about all the Trades made for the Trading Account you can send a signed GET /accounts/{tradingaccountId}/trades
request.
In response to your request you will receive either a SUCCESS 200
response or one or the error responses (400, 401, 500) See Status Codes & Error Messages.
Given a valid tradingAccountId
in the URL, a SUCCESS response will return all the Trades made for the Trading Account.
Note that standard pagination rules are applied for the response.
Not Seeing What You're Looking For?
We are always looking to improve our API documentation to ensure Sends systems are easy to understand and quick to build against. If you're struggling to find the answer to a question we either haven't made it easy enough to find the relevant docs or we haven't had a chance to write something up for it yet.
Either way we want to hear from you!
Head over to our Discussion Board and leave us a note. We keep a close eye on this and want to ensure we make these docs as useful as they can be so will jump on any posts quickly.
Updated about 1 month ago