---
title: "Transactions and exchange rates"
slug: "transactions-and-exchange-rates"
tags: ["exchangeRate", "portfolio currency", "SettledToPortfolioRate", "settlement currency", "totalConsideration", "TradeToPortfolioRate", "transaction currency"]
updated: 2026-06-08T07:53:33Z
published: 2026-06-08T07:53:33Z
canonical: "support.lusid.com/transactions-and-exchange-rates"
---

> ## Documentation Index
> Fetch the complete documentation index at: https://support.lusid.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Transactions and exchange rates

When you [book a transaction](/v1/docs/how-do-i-create-or-update-a-transaction#using-the-lusid-rest-api), the *mandatory* fields in the request assume that the transaction, settlement and portfolio currencies are all the same.

For example, to buy 10 units of BP @ £20, paying and settling in GBP in a GBP-denominated portfolio, you only need set the `totalConsideration.currency` field to GBP and the `totalConsideration.amount` field to £200. This is the *settlement* currency.

LUSID automatically sets the `transactionCurrency` field to GBP, the `exchangeRate` field to 1, the `TradeToPortfolioRate` system property to 1, and the `SettledToPortfolioRate` calculated field to 1 (more on these in the next section).

```json
{
  "transactionRequest-1": {
    "transactionId": "Txn-0000001",
    "type": "Buy",
    "instrumentIdentifiers": {"Instrument/default/Figi": "BBG000C6K6G9"},
    "transactionDate": "2024-06-15T00:00:00.0000000+00:00",
    "settlementDate": "2024-06-18T00:00:00.0000000+00:00",
    "units": 10,
    "transactionPrice": {"price": 20, "type": "Price"},
    "totalConsideration": {"amount": 200, "currency": "GBP"},
  }
}
```

## Handling different transaction, settlement and portfolio currencies

### Hard-coding an exchange rate between transaction and settlement currencies

If a transaction has different transaction and settlement currencies, you can specify the `exchangeRate` field to hard-code an exchange rate when you upsert that transaction. Note if you subsequently want to amend this rate you must re-upsert the transaction.

Consider the following example, to buy 100 units of MSFT @ $30, paying in USD but settling in EUR:

- The `transactionCurrency` field is the *transaction* currency, USD.
- The `totalConsideration.currency` field is the *settlement* currency, EUR.
- The `totalConsideration.amount` field is the trade amount in the *settlement* currency, €2,700.
- The `exchangeRate` field is the USD/EUR spot rate on the transaction date, 0.9. This enables LUSID to calculate the trade amount in the *transaction* currency: €2,700 / 0.9 = $3,000.

```json
{
  "transactionRequest-2": {
    "transactionId": "Txn-0000002",
    "type": "Buy",
    "instrumentIdentifiers": {"Instrument/default/Figi": "BBG000BPH459"},
    "transactionDate": "2024-06-15T00:00:00.0000000+00:00",
    "settlementDate": "2024-06-18T00:00:00.0000000+00:00",
    "units": 100,
    "transactionPrice": {"price": 30, "type": "Price"},
    "transactionCurrency": "USD",
    "totalConsideration": {"amount": 2700, "currency": "EUR"},
    "exchangeRate": 0.9
  }
}
```

### Hard-coding an exchange rate between transaction and portfolio currencies

If a transaction has different transaction and portfolio currencies, you can specify the `TradeToPortfolioRate` [system property](/v1/docs/adding-system-properties-to-transactions-and-to-transaction-types) to hard-code an exchange rate when you upsert that transaction. This is optional but enables LUSID to maintain the cost basis of the portfolio. Note if you subsequently want to amend this rate you must re-upsert the transaction.

Consider the following example, to buy 100 units of MSFT @ $30, paying and settling in USD in a GBP-denominated portfolio:

- The `transactionCurrency` field is the *transaction* currency, USD.
- The `totalConsideration.currency` field is the *settlement* currency, also USD.
- The `totalConsideration.amount` field is the trade amount in the *settlement* currency, $3,000.
- The `TradeToPortfolioRate` system property is the USD/GBP spot rate on the transaction date, 0.8. This enables LUSID to calculate the trade amount in the *portfolio* currency: $3,000 * 0.8 = £2,400.

```json
{
  "transactionRequest-3": {
    "transactionId": "Txn-0000003",
    "type": "Buy",
    "instrumentIdentifiers": {"Instrument/default/Figi": "BBG000BPH459"},
    "transactionDate": "2024-06-15T00:00:00.0000000+00:00",
    "settlementDate": "2024-06-18T00:00:00.0000000+00:00",
    "units": 100,
    "transactionPrice": {"price": 30, "type": "Price"},
    "transactionCurrency": "USD",
    "totalConsideration": {"amount": 3000, "currency": "USD"},
    "properties": {
      "Transaction/default/TradeToPortfolioRate": {
        "key": "Transaction/default/TradeToPortfolioRate",
        "value": {
          "metricValue": {"value": 0.8, "unit": ""}
        }
      }
    }
  }
}
```

> **Note**: LUSID automatically sets the `SettledToPortfolioRate` calculated field to `TradeToPortfolioRate` / `exchangeRate`. In this example, this is 0.8 / 1 = 0.8, but will be different if the transaction and settlement currencies are different, and means you don't need a triangulating spot rate between the settlement and portfolio currencies. This field can be used in the `rate` field of a [side](/v1/docs/what-is-a-side).

### Looking up exchange rates dynamically using a recipe

You can use a combination of a [transaction type](/v1/docs/what-is-a-transaction-type) and a [recipe](/v1/docs/what-is-a-recipe) to look up exchange rates dynamically:

- From transaction currency to settlement currency, and/or
- From transaction currency to portfolio currency.

This might be more convenient than hard-coding exchange rates when you upsert transactions, and means you can amend exchange rates if required without having to re-upsert those transactions.

Consider the following example, to buy 100 units of MSFT @ $30, paying in USD but settling in EUR in a GBP-denominated portfolio on 01 June 2024, settling three days later on 04 June 2024:

- The `transactionCurrency` field is the *transaction* currency, USD.
- The `totalConsideration.currency` field is the *settlement* currency, EUR.
- The `totalConsideration.amount` field is the trade amount in the *settlement* currency, €2,700.
- The `exchangeRate` field is omitted, so LUSID requires an exchange rate from transaction to settlement currency.
- The `TradeToPortfolioRate` system property is omitted, so LUSID requires an exchange rate from transaction to portfolio currency.

```json
{
  "transactionRequest-4": {
    "transactionId": "Txn-0000004",
    "type": "Buy",
    "instrumentIdentifiers": {"Instrument/default/Figi": "BBG000BPH459"},
    "transactionDate": "2024-06-01T00:00:00.0000000+00:00",
    "settlementDate": "2024-06-04T00:00:00.0000000+00:00",
    "units": 100,
    "transactionPrice": {"price": 30, "type": "Price"},
    "transactionCurrency": "USD",
    "totalConsideration": {"amount": 2700, "currency": "EUR"},
  }
}
```

If you were to call the [GetHoldings](https://www.lusid.com/docs/api#operation/GetHoldings) API at this point, the `cost.amount` (in USD) and `costPortfolioCcy.amount` (in GBP) fields would both be set to the total consideration of the transaction (in EUR):

![](https://cdn.document360.io/d575ad81-c0ed-4980-bbd1-d59ac5c3de82/Images/Documentation/b498d3f2-46d3-470e-ac4a-76042c6e4834.png)

To look up exchange rates dynamically for this transaction:

1. Call the [SetTransactionType](https://www.lusid.com/docs/api#operation/SetTransactionType) API to extend the `Buy` transaction type to which this transaction belongs to include both the `Txn:TradeToPortfolioRate` and `Txn:ExchangeRate` [calculation types](/v1/docs/what-is-a-transaction-type-calculation):

```json
{
  ...
  "calculations": [
    {
      "type": "Txn:TradeToPortfolioRate",
    }
    {
      "type": "Txn:ExchangeRate",
    }
  ]
}
```
2. Call the [UpsertConfigurationRecipe](https://www.lusid.com/docs/api#operation/UpsertConfigurationRecipe) API to either create a new recipe or configure an existing one to look up exchange rates in the LUSID Quote Store. In this example, two [market data rules](/v1/docs/recipes-locating-market-data) are required: the first to locate USD/EUR rates from transaction to settlement currency, and the second to locate USD/GBP rates from transaction to portfolio currency:

```json
{
  "configurationRecipe": {
    "scope": "MyRecipes",
    "code": "MyFxRateLookupRecipe",
    "market": {
      "marketRules": [
        {
          "key": "Fx.USD.EUR",
          "supplier": "Lusid",
          "dataScope": "MyFxRates",
          "quoteType": "Rate",
          "field": "mid",
          "quoteInterval": "1D.0D"
        },
        {
          "key": "Fx.USD.GBP",
          "supplier": "Lusid",
          "dataScope": "MyFxRates",
          "quoteType": "Rate",
          "field": "mid",
          "quoteInterval": "1D.0D"
        }
      ]
    }
  }
}
```
3. Call the [PatchPortfolioDetails](https://www.lusid.com/docs/api#operation/PatchPortfolioDetails) API to register the scope and code of this recipe with the portfolio containing the transaction, for example:

```json
[
  {
    "value": {
      "scope": "MyRecipes",
      "code": "MyFxRateLookupRecipe"
    },
    "path": "/instrumentEventConfiguration/recipeId",
    "op": "add"
  }
]
```
4. Call the [UpsertQuotes](https://www.lusid.com/docs/api#operation/UpsertQuotes) API to [load appropriate exchange rates](/v1/docs/how-do-i-upload-a-market-price-or-fx-spot-rate-to-the-quote-store) for the transaction date (not settlement date) into the Quote Store, ensuring the scope (in the URL) matches the `dataScope` field in the recipe, for example:

```json
curl -X POST 'https://<your-domain>.lusid.com/api/api/quotes/MyFxRates'
  -H 'Authorization: Bearer <your-API-access-token>'
  -H 'Content-Type: application/json-patch+json'
  -d '{
  "Quote-0001": {
    "quoteId": {
      "quoteSeriesId": {
        "provider": "Lusid",
        "instrumentIdType": "CurrencyPair",
        "instrumentId": "USD/EUR",
        "quoteType": "Rate",
        "field": "mid"
      },
      "effectiveAt": "2024-06-01T00:00:00Z"
    },
    "metricValue": {
      "value": 0.93, "unit": "USD/EUR"
    }
  },
  "Quote-0002": {
     "quoteId": {
      "quoteSeriesId": {
        "provider": "Lusid",
        "instrumentIdType": "CurrencyPair",
        "instrumentId": "USD/GBP",
        "quoteType": "Rate",
        "field": "mid"
      },
      "effectiveAt": "2024-06-01T00:00:00Z"
    },
    "metricValue": {
      "value": 0.75, "unit": "USD/GBP"
    }
  }
}'
```

Now if you call the [GetHoldings](https://www.lusid.com/docs/api#operation/GetHoldings) API, LUSID looks up the exchange rates and re-calculates the `cost.amount` (€2,700 / 0.93 = $2903.23) and `costPortfolioCcy.amount` ($2903.23 * 0.75 = £2177.42) fields:

![](https://cdn.document360.io/d575ad81-c0ed-4980-bbd1-d59ac5c3de82/Images/Documentation/image(66).png)

You can call the [BuildTransactions](https://www.lusid.com/docs/api#operation/BuildTransactions) API to audit the exchange rates used:

![](https://cdn.document360.io/d575ad81-c0ed-4980-bbd1-d59ac5c3de82/Images/Documentation/image(67).png)

For more on the impact of transaction currencies on LUSID’s calculation of local and portfolio holding cost, see [this article](/v1/docs/how-is-cost-calculated-in-lusid).

## Booking FX transactions

If you are exchanging two currencies LUSID can automatically calculate the exchange rate between them. This means you do not need to hard-code the `exchangeRate` field, nor load and look up exchange rates in the Quote Store.

### Booking a FX spot transaction

Consider the following example, to sell GBP and buy USD at a spot rate of 1.2:

- The `instrumentIdentifiers` field maps the transaction to the sell currency instrument, GBP. Note all major currency instruments are pre-mastered in LUSID.
- The `transactionCurrency` field is the currency to sell, GBP.
- The `units` field is the amount to sell, £100,000.
- The `totalConsideration.currency` field is the currency to buy, USD.
- The `totalConsideration.amount` field is the trade amount in the buy currency, $120,000.
- The `exchangeRate` field is deliberately omitted. LUSID automatically calculates the exchange rate as `totalConsideration.amount / units`, so in this case `120000 / 100000 = 1.2`.

```json
{
  "transactionRequest-3": {
    "transactionId": "Txn-0000003",
    "type": "FxSell",
    "instrumentIdentifiers": {"Instrument/default/Currency": "GBP"},
    "transactionDate": "2023-05-15T00:00:00.0000000+00:00",
    "settlementDate": "2023-05-18T00:00:00.0000000+00:00",
    "transactionCurrency": "GBP",
    "units": 100000,
    "transactionPrice": {"price": 1, "type": "Price"},
    "totalConsideration": {"amount": 120000, "currency": "USD"}
 }
}
```

### Modelling a FxForward as a transaction

> **Note**: The recommended way to model a foreign exchange or currency forward contract ("FxForward") is to master an instrument in the LUSID Security Master and then book a unitised transaction in a portfolio. This is a small amount of extra setup, but LUSID's full suite of analytical capability is available. [See how to do this](/v1/docs/modelling-fxforwards-in-lusid).

Alternatively, you can forgo mastering an instrument and book a forward-settled cash transaction directly in a portfolio with different buy and sell currencies, using the `FwdFxBuy` and `FwdFxSell` [built-in transaction types](/v1/docs/what-built-in-transaction-types-and-sides-are-provided-with-lusid) provided with LUSID.

Consider the following example, of a transaction to sell GBP and buy USD in a EUR-denominated portfolio in 6 months' time at a strike rate of 1.2:

- The transaction `type` field is set to `FwdFxSell` but this could equally be `FwdFxBuy` with the amounts and rates reversed.
- The `instrumentIdentifiers` field maps the transaction to the sell currency instrument, GBP. Note all major currency instruments are pre-mastered in LUSID.
- The `transactionDate` field marks the start of the contract.
- The `settlementDate` field is the maturity date.
- The `transactionCurrency` field is the currency to sell, GBP.
- The `units` field is the amount to sell, £100,000.
- The `totalConsideration.currency` field is the currency to buy, USD.
- The `totalConsideration.amount` field is the trade amount in the buy currency: $120,000.
- The `exchangeRate` field is deliberately omitted. LUSID automatically calculates the exchange rate as `totalConsideration.amount / units`, so in this case `120000 / 100000 = 1.2`.
- The `TradeToPortfolioRate` [system property](/v1/docs/adding-system-properties-to-transactions-and-to-transaction-types) records the GBP/EUR spot rate, 1.1. This enables LUSID to calculate the trade amount in the portfolio currency, thereby maintaining the cost basis of the portfolio: £100,000 * 1.1 = €110,000.

```json
curl -X POST 'https://<your-domain>.lusid.com/api/api/transactionportfolios/Funds/Managed/transactions/$batchUpsert?successMode=Partial' 
  -H 'Content-Type: application/json-patch+json'
  -H 'Authorization: Bearer <your-API-access-token>'
  -d '{
  "transactionRequest-4": {
    "transactionId": "Txn-0000004",
    "type": "FwdFxSell",
    "instrumentIdentifiers": {"Instrument/default/Currency": "GBP"},
    "transactionDate": "2023-06-07T00:00:00.0000000+00:00",
    "settlementDate": "2023-12-11T00:00:00.0000000+00:00",
    "transactionCurrency": "GBP",
    "units": 100000,
    "transactionPrice": {"price": 1, "type": "Price"},
    "totalConsideration": {"amount": 120000, "currency": "USD"},
    "properties": {
      "Transaction/default/TradeToPortfolioRate": {
        "key": "Transaction/default/TradeToPortfolioRate",
        "value": {
          "metricValue": {
            "value": 1.1, "unit": ""
          }
        }
      }
    }
  }
}'
```

LUSID generates two temporary holdings for each FxForward booked as a transaction while the contract is live, one per currency. Note the [holding type](/v1/docs/what-are-the-holding-types) is `Forward FX` on the inception date, 7 June 2023, and that no units are settled:

![](https://cdn.document360.io/d575ad81-c0ed-4980-bbd1-d59ac5c3de82/Images/Documentation/2202bb89-54dd-4dc6-bbf4-24ef15ecd9a4.png)

When the contract matures, LUSID automatically updates the main cash holdings in the two currencies and removes the temporary holdings. Note the holding type is `Cash Balance` on the maturity date, 11 December 2023, and that all units are now settled:![](https://cdn.document360.io/d575ad81-c0ed-4980-bbd1-d59ac5c3de82/Images/Documentation/64f8693b-7a0d-49d4-a61d-f369079188bc.png)
