You can model a repurchase agreement (“repo”) as a buyer or as a seller using the FlexibleRepo instrument type. See all supported instruments.
Note: This article explains how to master an instrument and then load a transaction using the LUSID API. It is possible to simply load a transaction in the LUSID web app and have LUSID master the instrument for you. More information.
Mastering an instrument
There are numerous tools you can use to master a FlexibleRepo in the LUSID Security Master.
Some fields are common to all types of instrument, such as an intuitive name, the requirement to specify a set of identifiers, and the facility to store extra information as properties.
Fields in the economic definition object are specific to FlexibleRepo. For more information on these fields, select FlexibleRepo from the definition dropdown in the UpsertInstruments API reference, or alternatively examine the FlexibleRepo schema:

Mastering a collateral instrument
If the repo has collateral that is a supported instrument, master it separately and then provide a reference to a MasteredInstrument. See how to master a bond.
Mastering a FlexibleRepo instrument
The following call to the UpsertInstruments API masters a term repo as a buyer with a MasteredInstrument reference to a vanilla fixed-rate bond as collateral:
curl -X POST 'https://mydomain.lusid.com/api/api/instruments?scope=MyCustomInstrScope'
-H 'Content-Type: application/json-patch+json'
-H 'Authorization: Bearer myAPIAccessToken'
-d '{"upsert-request-1": {
"name": "Buyer-TermFlexRepo",
"identifiers": {"ClientInternal": {"value": "Buyer-TermFlexRepo"}},
"definition": {
"instrumentType": "FlexibleRepo",
"startDate": "2025-01-02T00:00:00.0000000+00:00",
"maturityDate": "2025-03-31T00:00:00.0000000+00:00",
"buyerOrSeller": "Buyer",
"repoCcy": "GBP",
"repoType": "TermRepo",
"accrualBasis": "Act365",
"collateral": {
"collateralInstruments": [{
"units": 1,
"instrument": {
"instrumentType": "MasteredInstrument",
"identifiers": {"Instrument/default/ClientInternal": "BondCollateral"}
}
}
],
"collateralValue": 1100000,
"buyerReceivesCashflows": false,
"buyerReceivesCorporateActionPayments": false
},
"isCollateralTransferActivated": True,
"haircut": 0.091,
"margin": null,
"purchasePrice": null,
"repoRateSchedules": [{
"scheduleType": "FixedSchedule",
"couponRate": 0.05,
"startDate": "2025-01-02T00:00:00.0000000+00:00",
"maturityDate": "2025-03-31T00:00:00.0000000+00:00",
"flowConventions": {
"currency": "GBP",
"paymentFrequency": "1T",
"dayCountConvention": "Act365",
"rollConvention": "None",
"paymentCalendars": [],
"resetCalendars": []
},
"notional": 1,
"paymentCurrency": "GBP"
}
],
"repurchasePrice": null,
"openRepoRollingPeriod": "1D"
}
}
}'Note the following:
This
FlexibleRepoinstrument is mastered in a custom instrument scope (specified in the URL).Its
identifiersobject is set to reference aClientInternalunique identifier.buyerOrSelleris set toBuyerto receive collateral and send cash, but it could beSellerto send collateral and receive cash.repoTypeisTermRepobecausematurityDateis known. If it is not, specifyOpenRepoand set:maturityDateto a significantly distant date, for example9999-12-31.openRepoRollingPeriodto a tenor representing an interest payment window, for example1Dor1Wor1M.
accrualBasisisAct365to count the number of accrual days using a particular convention.The Collateral object:
Specifies an
instrumentTypeofMasteredInstrumentand a unique identifier (in this caseClientInternal) to resolve to the collateral instrument.Specifies the
collateralValue.Retains the default values of
falseforbuyerReceivesCashFlowsandbuyerReceivesCorporateActionPayments, so the seller keeps payments while the contract is in effect. Note the buyer actually receives the cashflows but LUSID uses instrument events to automatically refund the seller. More information.
isCollateralTransferActivatedis set toTrue(the default isFalse) to trigger LUSID to emitFlexibleRepoCollateralTransferEventonstartDateto transfer collateral units to the buyer, and again onmaturityDateto transfer units back to the seller. More information.The
haircutis set to0.091but you could specify either amarginorpurchasePriceif these are known instead.The
repoRateSchedulesarray has a single FixedSchedule object to specify an absolute repo rate, though you can specify a single FloatSchedule to link the repo rate to an index if you wish:The
couponRate(that is, repo rate) is expressed as a fraction, so0.05represents 5%. Note you can omit therepoRateSchedulesarray entirely and specify an explicitrepurchasePriceif this is known instead.The
startDateandmaturityDatemust be the same as theFlexibleRepoitself.The FlowConventions object determines the repurchase date. Note the
currencymust be the same asrepoCcy. ThepaymentFrequency:Should be
1Tfor aTermRepoSet to the same as
openRepoRollingPeriodfor anOpenRepo.
notionalshould be1.paymentCurrencymust be the same asrepoCcy.
Determining the purchase price
In summary, you must specify collateralValue and one of haircut, margin or purchasePrice to determine the purchase price. Note if you do not specify an explicit purchasePrice then LUSID calculates it as follows:
purchasePrice = collateralValue * (1 - haircut). In our example, this yields1000000.purchasePrice = collateralValue / margin
Determining the repurchase price
In summary, you must specify either couponRate (within the repoRateSchedules array) or repurchasePrice to determine the repurchase price. Note if you do not specify an explicit repurchasePrice then LUSID calculates it as follows:
repurchasePrice = (1 + couponRate * <day-count-fraction>) * purchasePrice
…where <day-count-fraction> depends on the number of days in the contract and the day count convention. In our example, this yields 1012054.79.
Examining the response
Providing the request is successful, the response:
Confirms the globally-unique LUID of the
FlexibleRepoinstrument (in this caseLUID_00003G9T).Confirms the LUID of the collateral
MasteredInstrumentproviding LUSID is able to resolve it correctly (in this caseLUID_00003G9S). If not, the unknown instrument is returned.Generates extra fields that are stored as part of the instrument definition and can be filtered on.
Supplies default values for fields not explicitly specified in the request.
For example:
{
"values": {
"upsert-request-1": {
"scope": "MyCustomInstrScope",
"lusidInstrumentId": "LUID_00003G9T",
"name": "Buyer-TermFlexRepo",
"identifiers": {
"ClientInternal": "Buyer-TermFlexRepo",
"LusidInstrumentId": "LUID_00003G9T"
},
"properties": [],
"instrumentDefinition": {
"startDate": "2025-01-02T00:00:00.0000000+00:00",
"maturityDate": "2025-03-31T00:00:00.0000000+00:00",
"buyerOrSeller": "Buyer",
"repoCcy": "GBP",
"repoType": "TermRepo",
"accrualBasis": "Actual365",
"collateral": {
"buyerReceivesCashflows": false,
"buyerReceivesCorporateActionPayments": false,
"collateralInstruments": [
{
"units": 1,
"instrument": {
"identifiers": {
"Instrument/default/ClientInternal": "BondCollateral"
},
"masteredDomCcy": "GBP",
"masteredInstrumentType": "Bond",
"masteredLusidInstrumentId": "LUID_00003G9S",
"masteredName": "BondCollateral",
"masteredScope": "MyCustomInstrScope",
"masteredAssetClass": "Credit",
"instrumentType": "MasteredInstrument"
}
}
],
"collateralValue": 1100000
},
"isCollateralTransferActivated": True,
"haircut": 0.091,
"repoRateSchedules": [
{
"startDate": "2025-01-02T00:00:00.0000000+00:00",
"maturityDate": "2025-03-31T00:00:00.0000000+00:00",
"flowConventions": {
"currency": "GBP",
"paymentFrequency": "1T",
"dayCountConvention": "Actual365",
"rollConvention": "None",
"paymentCalendars": [],
"resetCalendars": [],
"settleDays": 0,
"resetDays": 0,
"leapDaysIncluded": true,
"accrualDateAdjustment": "Adjusted",
"businessDayConvention": "None",
"accrualDayCountConvention": "Actual365"
},
"couponRate": 0.05,
"notional": 1,
"paymentCurrency": "GBP",
"stubType": "None",
"scheduleType": "FixedSchedule"
}
],
"tradingConventions": {
"priceScaleFactor": 1,
"minimumOrderSize": 0,
"minimumOrderIncrement": 0
},
"instrumentType": "FlexibleRepo"
},
"state": "Active",
"assetClass": "InterestRates",
"domCcy": "GBP",
"relationships": [],
"dataModelMembership": {
"membership": []
}
}
},
...
}Booking a transaction to establish a position
Once a FlexibleRepo instrument is mastered, you can call the BatchUpsertTransactions API to record the acquisition of a number of contracts in a particular portfolio, for example:
curl -X POST 'https://mydomain.lusid.com/api/api/transactionportfolios/MyPortfolioScope/MyPortfolioCode/transactions/$batchUpsert?successMode=Partial&preserveProperties=true'
-H 'Content-Type: application/json-patch+json'
-H 'Authorization: Bearer myAPIAccessToken'
-d '{
"transactionRequest-1": {
"transactionId": "my_repo_purchase_001",
"type": "EnterRepo",
"instrumentIdentifiers": {"Instrument/default/ClientInternal": "Buyer-TermFlexRepo"},
"transactionDate": "2025-01-01T00:00:00.0000000+00:00",
"settlementDate": "2025-01-01T00:00:00.0000000+00:00",
"units": 1,
"transactionPrice": {
"price": 0,
"type": "Price"
},
"totalConsideration": {
"amount": -1000000,
"currency": "GBP"
}
}
}'Note the following:
The
typefield invokes a customEnterRepotransaction type to acquire a single unit of the repo at a particular cost (see below).The
transactionDateandsettlementDatemust be before the start date of the repo in the instrument definition. This is so LUSID can automatically handle the transfer of collateral and cash between buyer and seller. More information.The
totalConsideration.amount(cost) is set to thepurchasePriceof theFlexibleRepo. See the section above for how to work this out if not explicitly known:If
buyerOrSellerisBuyerin the instrument definition, the amount must be signed negative, for example-1000000If
buyerOrSellerisSeller, the amount must be signed positive, for example1000000.
Note: This example assumes the transaction, settlement and portfolio currencies are all the same. If not, you can specify exchange rates.
We might create a custom EnterRepo transaction type as follows:
curl -X PUT 'https://<your-domain>.lusid.com/api/api/transactionconfiguration/types/default/EnterRepo?scope=default'
-H 'Content-Type: application/json-patch+json'
-H 'Authorization: Bearer <your-API-access-token>'
-d '{
"aliases": [
{
"type": "EnterRepo",
"description": "Transaction type for starting a repurchase agreement",
"transactionClass": "Basic",
"transactionRoles": "AllRoles",
"isDefault": false
}
],
"movements": [
{
"name": "Increase units of security",
"movementTypes": "StockMovement",
"side": "Side1EnterRepo",
"direction": 1
},
{
"name": "Transfer cash",
"movementTypes": "CashReceivable",
"side": "Side2",
"direction": 1
},
{
"name": "Report cost",
"movementTypes": "StockMovement",
"side": "Side1EnterRepoCost",
"direction": -1
}
]
}'Note both StockMovement movements have custom sides:
|
|
|---|---|
| |
This is the same as | This is similar to |
Confirming positions
As a buyer, we can generate a holdings report on the transaction/settlement date of 1 January 2025 to see that we have:
One unit of the repo holding.
A negative cash balance of -£1,000,000 representing the transfer of
purchasePriceto the seller by theEnterRepotransaction type.Three units of a holding in the bond collateral instrument (the transaction to generate this holding isn’t shown in this article but you can see an example here).

If we fast-forward to the start date of the instrument on 2 January 2025 we see that we have:
One unit of the repo holding.
A negative cash balance of -£1,000,000.
Four units of a holding in the bond collateral instrument (the transfer of collateral from the seller has been handled by the
FlexibleRepoCollateralEventinstrument event).

Auditing LUSID’s automatically-generated transactions
We can examine the output transactions to understand how LUSID has automatically transfered collateral and cash between buyer and seller between 1 and 2 January 2025 (click to enlarge):

Valuing your position
To value a position in a FlexibleRepo (and also any collateral instrument) held in a portfolio, work through our valuation checklist.
Note: The default pricing model for a
FlexibleRepoisSimpleStatic. We strongly recommend changing this to the dedicatedFlexibleRepoSimplePricer. See how to do this.
For example, to value the portfolio shown above on 15 February 2025:
Load a market price for the collateral instrument valid for the valuation date into the LUSID Quote Store (there is no need to load market data for the
FlexibleRepo):curl -X POST 'https://mydomain.lusid.com/api/api/quotes/MyRepoPortfolioQuotes' -H 'Authorization: Bearer myAPIAccessToken' -H 'Content-Type: application/json-patch+json' -d '{ "Quote-0001": { "quoteId": { "quoteSeriesId": { "provider": "Lusid", "instrumentIdType": "ClientInternal", "instrumentId": "BondCollateral", "quoteType": "Price", "field": "mid" }, "effectiveAt": "2025-02-15T00:00:00Z" }, "metricValue": { "value": 101, "unit": "GBP" }, "scaleFactor": 100 } }'Create a recipe to locate this market data and change the default pricing models:
curl -X POST 'https://mydomain.lusid.com/api/api/recipes' -H 'Content-Type: application/json-patch+json' -H 'Authorization: Bearer myAPIAccessToken' -d '{ "configurationRecipe": { "scope": "MyRecipes", "code": "MyRepoValuationRecipe", "market": { "marketRules": [ { "key": "Quote.ClientInternal.*", "dataScope": "MyRepoPortfolioQuotes", "supplier": "Lusid", "quoteType": "Price", "field": "mid", "quoteInterval": "1D.0D" } ] }, "pricing": { "modelRules": [ { "instrumentType": "FlexibleRepo", "modelName": "FlexibleRepoSimplePricer" }, { "instrumentType": "Bond", "modelName": "BondLookupPricer" } ] } } }'Generate a valuation report with appropriate metrics, for example:

Assessing risk
For more on how LUSID calculates exposure, see this article.
LUSID supports both analytic and bump and valuation mechanisms for assessing risk; contact Technical Support for more information.
Handling the lifecycle of the instrument
A FlexibleRepo instrument is tightly integrated into LUSID’s instrument event framework. To enable this for your domain, you must:
Register a recipe with every portfolio holding a
FlexibleRepo.Create transaction types to determine the economic impact of the transactions automatically generated by
FlexibleRepoevents.
For much more information, learn how to handle instrument events for repurchase agreements.
Instrument event | Repo type | Event emission criteria | If emitted, effect of LUSID default transaction template |
|---|---|---|---|
| Both | This event is automatically emitted by LUSID on the maturity date ( | One transaction for a cash amount is automatically generated. |
| Both | This event is automatically emitted by LUSID on the maturity date ( | One transaction for a cash amount is automatically generated. |
| This event is automatically emitted by LUSID at the end of each payment window to transfer incremental accrued interest from seller to buyer. | One transaction for a cash amount is automatically generated on each payment date. | |
| Both | If activated, this event is automatically emitted by LUSID:
| One transaction for a number of collateral units at zero cost is automatically generated on each date. |
| Both | This event is not automatically emitted by LUSID. You can manually load it to partially close a repo. | N/A |
|
| This event is not automatically emitted by LUSID. You should manually load it to close an open repo. | N/A |
| Both | This event is automatically emitted by LUSID on the maturity date ( | One transaction for all units at zero cost is automatically generated to reduce the holding to zero. |
Appendix: Using the LUSID web app to simplify repurchase agreements
A dashboard is available in the LUSID web app that you can use to both book a trade and simultaneously master a FlexibleRepo instrument, which may be a simpler user experience. To enable this:
Contact Technical Support for the required license.
In the transaction type you use to enter into a repurchase agreement, add the
TransactionConfiguration/default/UIClasssystem property and set the value toPMS - Repo.Navigate to Portfolio Management > Transactions
Click the Create transaction button and open the Repo tab.