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. Contact us for 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 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
},
"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 onstartDate, 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 can automatically handle refunding the seller. More information.
The
haircutis set to0.091but you could specify either amarginor apurchasePriceif 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.05representing 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 configures the repurchase date. Note the
currencymust be the same asrepoCcy, andpaymentFrequency:Should be
1Tfor aTermRepoSet to the same as
openRepoRollingPeriodfor anOpenRepo
notionalshould be1.paymentCurrencymust be the same asrepoCcy.
In summary:
You must specify
collateralValueand one ofhaircut,marginorpurchasePriceto determine the purchase price. Note if you do not specify an explicitpurchasePricethen LUSID calculates it as follows:purchasePrice = collateralValue * (1 - haircut). In our example, this yields1000000.purchasePrice = collateralValue / margin
You must specify either
couponRate(within therepoRateSchedulesarray) orrepurchasePriceto determine the repurchase price. Note if you do not specify an explicitrepurchasePricethen 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 yields1012054.79.
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:
{
"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
},
"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": 1000000,
"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 no 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.
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
}
]
}'The StockMovement uses a custom Side1EnterRepo to set the cost of the transaction to zero in order to yield the correct accounting treatment:
curl -X PUT 'https://<your-domain>.lusid.com/api/api/transactionconfiguration/sides/Side1EnterRepo?scope=default'
-H 'Content-Type: application/json-patch+json'
-H 'Authorization: Bearer <your-API-access-token>'
-d '{
"security": "Txn:LusidInstrumentId",
"currency": "Txn:TradeCurrency",
"rate": "Txn:TradeToPortfolioRate",
"units": "Txn:Units",
"amount": "0"
}'Note this is the same as Side1 except the amount field is set to 0 instead of Txn:TradeAmount.
Confirming positions
We can generate a holdings report on the transaction date of 1 January 2025 to see that we have:
One unit of the repo holding at no cost
Three units of a holding in the bond collateral instrument (the transaction to generate this 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 (note the cost has been automatically set to
purchasePriceby an instrument event)Four units of the bond holding (LUSID has automatically transferred one unit from the seller)
A cash holding of -£1000000 (LUSID has automatically transferred
purchasePriceto the seller):

Auditing LUSID’s automatically-generated transactions
We can examine the output transactions generated by instrument events to understand how LUSID has automatically transfered collateral and cash between buyer and seller on 2 January 2025:

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 recommend keeping this default.
For example, to value the portfolio shown above on 15 February 2025:
Load market prices into the LUSID Quote Store:
A dummy price of
1for theFlexibleRepo. TheSimpleStaticmodel has a dependency on this data, but it can be unitised and valid for the lifetime of the contract.A price for the bond collateral instrument valid for the valuation date:
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": "Buyer-TermFlexRepo", "quoteType": "Price", "field": "mid" }, "effectiveAt": "2025-01-01T00:00:00Z" }, "metricValue": { "value": 1, "unit": "GBP" } }, "Quote-0002": { "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 model for the bond collateral instrument. Note the ‘look back’
quoteIntervalfor the dummyFlexibleRepoprice is equivalent to the length of the contract: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": "3M.0D" } ] }, "pricing": { "modelRules": [ { "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 on the instrument event framework, start here.
The following events are available for a FlexibleRepo:
Instrument event type | Repo type | Event emission criteria | If emitted, effect of LUSID default transaction template | Transaction type recommendations |
|---|---|---|---|---|
| Any | This event is automatically emitted by LUSID:
| One transaction for a cash amount is automatically generated on each date. | |
| Any | This event is automatically emitted by LUSID:
| One transaction for a number of collateral units at zero cost is automatically generated on each date. | |
|
| This event is automatically emitted by LUSID at the end of each payment window to transfer accrued interest from seller to buyer. | One transaction for a cash amount is automatically generated on each payment date. | |
| Any | 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 | |
| Any | 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. |