Views:

Related resources:

Explanation

Tutorials

Reference

Providing you have suitable access control permissions, you can:

For much more information on recipes, including all the mandatory and optional fields and allowed values, start with this article.

Creating a recipe by hand

Using the LUSID REST API

  1. Obtain an API access token.
  2. Call the UpsertConfigurationRecipe API, specifying at a minimum:
    • A scope and code that together uniquely identify the recipe.
    • At least one market data rule in the marketRules array of the market section that enables LUSID to retrieve market data suitable to value the instruments held.

By default, a recipe uses a built-in pricing model for each type of instrument (such as SimpleStatic for instruments of type Equity); you can specify vendor model rules to choose more sophisticated pricing models if you wish. A recipe also has many options that default to sensible values; you can choose to override these.

For example, to create a simple recipe that might be suitable to value a portfolio of equities using market prices that are:

  • Supplied by EDI
  • Loaded into the LUSID Quote Store using FIGI identifiers
  • Encapsulated in a MyQuoteScope:
curl -X POST "https://<your-domain>.lusid.com/api/api/recipes" 
  -H "Content-Type: application/json-patch+json" 
  -H "Authorization: Bearer <your-API-access-token>" 
  -d '{
 "configurationRecipe": {
   "scope": "Recipes",
   "code": "SimpleEquityPricer",
   "market": {
     "marketRules": [
       {
         "key": "Quote.Figi.*",
         "supplier": "Edi",
         "dataScope": "MyQuoteScope",
         "quoteType": "Price",
         "field": "mid",
         "quoteInterval": "2D.0D"
       }
     ]
   },
   "description": "Simple recipe to value equities using price * units"
 }
}'

Using the LUSID web app

This functionality is coming soon. At the moment, you can list your recipes by signing into the LUSID web app and navigating to the Data Management > Recipes dashboard.

To examine a recipe in JSON form, select it and click the View or Edit button. Note a Create recipe button exists but currently there is no wizard to help you do so.

Asking LUSID to generate a recipe for you

You can specify a portfolio to value and characteristics of appropriate market prices in the LUSID Quote Store and ask LUSID to generate a recipe that calculates the value of each position by multiplying the price of the underlying instrument by the number of units held.

Note: Alternatively, you can supply a simple recipe and ask LUSID to create a more sophisticated recipe for you.

To do this:

  1. Obtain an API access token.
  2. Call the GenerateConfigurationRecipe API, specifying:
    • The scope and code of a transaction portfolio to value.
    • One or more quote scopes encapsulating prices for the underlying instruments loaded into the LUSID Quote Store.

For example, to value a portfolio with a scope of Growth and code of UKEquities using prices encapsulated in a quote scope of MyQuoteScope:

curl -X POST "https://<your-domain>.lusid.com/api/api/aggregation/Growth/UKEquities/$generateconfigurationrecipe" 
  -H "Content-Type: application/json-patch+json" 
  -H "Authorization: Bearer <your-API-access-token>"
  -d '{
  "recipeCreationMarketDataScopes": [
    "MyQuoteScope"
  ],
  "effectiveAt": "2022-11-01"
}'

LUSID might generate a recipe like the one below (note all recipe options are set to sensible default values):

{
  "scope": "Growth",
  "code": "LUSID_generated_recipe",
  "market": {
    "marketRules": [
      {
        "key": "Quote.Figi.*",
        "supplier": "Lusid",
        "dataScope": "MyQuoteScope",
        "quoteType": "Price",
        "field": "mid",
        "priceSource": "",
        "sourceSystem": "Lusid"
      },
      {
        "key": "Fx.*.*",
        "supplier": "Lusid",
        "dataScope": "default",
        "quoteType": "Price",
        "field": "mid",
        "priceSource": "",
        "sourceSystem": "Lusid"
      }
    ],
    "suppliers": {},
    "options": {
      "defaultSupplier": "Lusid",
      "defaultInstrumentCodeType": "LusidInstrumentId",
      "defaultScope": "default",
      "attemptToInferMissingFx": false,
      "calendarScope": "CoppClarkHolidayCalendars",
      "conventionScope": "Conventions"
    },
    "specificRules": []
  },
  "pricing": {
    "modelRules": [],
    "modelChoice": {},
    "options": {
      "modelSelection": {
        "library": "Lusid",
        "model": "SimpleStatic"
      },
      "useInstrumentTypeToDeterminePricer": false,
      "allowAnyInstrumentsWithSecUidToPriceOffLookup": false,
      "allowPartiallySuccessfulEvaluation": false,
      "produceSeparateResultForLinearOtcLegs": false,
      "enableUseOfCachedUnitResults": false,
      "windowValuationOnInstrumentStartEnd": false,
      "removeContingentCashflowsInPaymentDiary": false,
      "useChildSubHoldingKeysForPortfolioExpansion": false,
      "validateDomesticAndQuoteCurrenciesAreConsistent": false
    },
    "resultDataRules": []
  },
  "aggregation": {
    "options": {
      "useAnsiLikeSyntax": false,
      "allowPartialEntitlementSuccess": false,
      "applyIso4217Rounding": false
    }
  },
  "inheritedRecipes": [],
  "description": "- recipe has been supplemented with additional market data rules",
  "holding": {
    "taxLotLevelHoldings": true
  }
}

Using the default recipe provided with LUSID

A simple default recipe is automatically available in every portfolio scope. You can use this recipe to:

  • Value a portfolio containing equities where the underlying instruments are priced in the same currency as the portfolio base currency.
  • Retrieve market prices loaded into the LUSID Quote Store in a particular way, and calculate value by multiplying price by the number of units held.

For example, to value a GBP-denominated portfolio with a scope of Growth and code of UKEquities:

  1. Call the UpsertQuotes API to load prices for the underlying instruments in the portfolio into the LUSID Quote Store with the following characteristics:
    quoteSeriesId object data fieldValue (case-sensitive)
    providerLusid
    instrumentIdTypeLusidInstrumentId
    instrumentIdThis must be the LUID of the underlying instrument, for example LUID_00003D9N 
    quoteTypePrice
    fieldmid
    Note: The quote scope encapsulating this set of prices must be the same as the scope of the portfolio to value.

    For example, to load a price of 100 for LUID_00003D9N (representing BP shares) effective 7 March 2022 into a Growth quote scope (highlighted in red in the URL; this is created if it does not exist, and must be the same as the portfolio scope):

    curl -X POST "https://<your-domain>.lusid.com/api/api/quotes/Growth"
      -H "Authorization: Bearer <your-API-access-token>"
      -H "Content-Type: application/json-patch+json"
      -d '{
        "Quote-0001": {
          "quoteId": {
            "quoteSeriesId": {
              "provider": "Lusid",
              "instrumentIdType": "LusidInstrumentId",
              "instrumentId": "LUID_00003D9N",
              "quoteType": "Price",
              "field": "mid"
            },
            "effectiveAt": "2022-03-07T00:00:00Z"
          },
          "metricValue": {
            "value": 100,
            "unit": "GBP"
          }
        }
      }'
    
  2. Call the GetValuation API and specify the default recipe:
    • The scope of the recipeId object must match the scope of the portfolioEntityIds object (in this case, both must be Growth, highlighted in red).
    • The code of the recipeId object must be default (highligted in yellow).
    curl -X POST "https://<your-domain>.lusid.com/api/api/aggregation/$valuation" 
      -H "Content-Type: application/json-patch+json" 
      -H "Authorization: Bearer <your-API-access-token>" 
      -d '{
      "recipeId": {
        "scope": "Growth",
        "code": "default"
      },
      "metrics": [
        { "key": "Instrument/default/Name", "op": "Value" },
        { "key": "Valuation/PV", op": "Value" }
      ],
      "portfolioEntityIds": [
        {
          "scope": "Growth",
          "code": "UKEquities",
        }
      ],
      "valuationSchedule": {
        "effectiveAt": "2022-03-07T00:00:00.0000000+00:00",
      }
    }'