Defining portfolio rebalancing algorithms

Note: As a prerequisite to this article, it is recommended that you are familiar with performing valuations in LUSID.

LUSID allows you to create your own custom rebalancing algorithms to rebalance portfolios and easily create new orders using the results. You define these custom rebalancing algorithms using Luminesce custom views. Once you have created a custom view, you can select it as your rebalancing algorithm when interacting with the Rebalance dashboard in the LUSID web app:

When using the Rebalance dashboard, users must select a portfolio to rebalance and a recipe and rebalancing algorithm to use (if selecting a Rebalance type of Algorithm). The rebalancing algorithm is a custom view which must take in the following input parameters:

  • Portfolio scope and code

  • Valuation recipe scope and code

  • A scope for the resulting order instructions.

The custom view should then do the following:

  1. Perform a valuation to retrieve the portfolio's current holdings and exposures.

  2. Aggregate columns and pivot the valuation using Tools.Pivot to access one row of data per instrument. Read more about using Tools.Pivot.

  3. Use its own custom algorithm to generate order instructions, with each order instruction containing the instrument identifier for the order and one of quantity, weight or (coming soon) value.

  4. Save the order instructions into the scope specified in the input parameters.

Example: Creating a rebalancing algorithm that sells out of all equity holdings less than 1%

Let's imagine you want to see which orders might be required to sell all equity holdings which make up less than 1% of the exposure of a portfolio. You can use Sys.Admin.SetupView to define the following rebalancing algorithm that can be applied to any relevant portfolio, specifying in your query:

  • A name for the custom view.

  • The required input parameters for a rebalancing algorithm, as detailed above.

  • The valuation metrics required to perform a valuation using Lusid.Portfolio.Valuation. In this example:

    • The algorithm uses 'Valuation/ExposureInPortfolioCcy/Amount','Proportion' to calculate portfolio exposure as a percentage. Note the algorithm has access to any field returned from GetValuation (and any other data accessible via Luminesce).

    • Tools.Pivot is then used to aggregate relevant columns and pivot the valuation to access one row of data per instrument. Read more about using Tools.Pivot.

  • The holdings to generate order instructions for from the valuation output. In this example:

    • To identify any holdings of less than 1% of the total portfolio exposure, you can filter on the Proportion(Valuation/ExposureInPortfolioCcy/Amount) metric to select all non-currency holdings which make up less than 1%.

    • You can also specify at this point that the Weight of these holdings should be adjusted to 0%.

    These order instructions must then be written into LUSID using Lusid.OrderInstruction.Writer.

@@providerName = select 'RebalanceAlgo.RemoveSmallPositions';

-- Create the View

@x = use Sys.Admin.SetupView with @@providerName
--provider={@@providerName}
--description="An example algorithm for Rebalancing, sells any position less than 100bps"
--parameters
EntityType,Text,Portfolio,false
EntityScope,Text,FBNUniversity,false
EntityCode,Text,Module-4-1,false
RecipeScope,Text,FBNUniversity,false
RecipeCode,Text,Module-4-1Recipe,false
OrderInstructionScope,Text,Finbourne-Examples,false
----

@@EntityType = select #PARAMETERVALUE(EntityType);
@@EntityScope = select #PARAMETERVALUE(EntityScope);
@@EntityCode = select #PARAMETERVALUE(EntityCode);
@@RecipeScope = select #PARAMETERVALUE(RecipeScope);
@@RecipeCode = select #PARAMETERVALUE(RecipeCode);
@@OrderInstructionScope = select #PARAMETERVALUE(OrderInstructionScope);

@@Recipe = select @@RecipeScope || '/' || @@RecipeCode;

@metrics = values
  ('Valuation/ExposureInPortfolioCcy/Amount','Proportion');
@toReturn = select column1 as MeasureName, column2 as Operation from @metrics;

@valuation = select 
    PortfolioScope,
    PortfolioCode,
    LusidInstrumentId,
    MeasureName,
    MeasureDecimalValue
  from Lusid.Portfolio.Valuation
  where PortfolioCode = @@EntityCode
    and PortfolioScope = @@EntityScope
    and Recipe = @@Recipe
    and MeasuresToReturn = @toReturn
union
  select
    @@EntityScope as PortfolioScope,
    @@EntityCode as PortfolioCode,
    'PLACEHOLDER' as LusidInstrumentId,
    'Proportion(Valuation/ExposureInPortfolioCcy/Amount)' as MeasureName,
    0 as MeasureDecimalValue;

@pivoted = use Tools.Pivot with @valuation
--key=MeasureName
--aggregateColumns=MeasureDecimalValue
enduse;

@orders = select
  LusidInstrumentId,
  LusidInstrumentId as OrderInstructionCode,
  @@OrderInstructionScope as OrderInstructionScope,
  PortfolioCode,
  PortfolioScope,
  0 as Weight
from @pivoted
where LusidInstrumentId != 'PLACEHOLDER' 
  and LusidInstrumentId not like '%CCY%'
  and [Proportion(Valuation/ExposureInPortfolioCcy/Amount)] < 0.01;
  
select 
  PortfolioCode,
  PortfolioScope,
  OrderInstructionCode,
  WriteError,
  WriteErrorDetail,
  WriteAction
from Lusid.OrderInstruction.Writer
where ToWrite = @orders;

enduse;

@create_view = select * from @x;

--- Set the requirement metadata on the view

@metadata = values
  (@@providerName, 'RebalanceAlgo', 'True');
@toWrite = select
  column1 as ProviderName,
  column2 as MetadataKey,
  column3 as MetadataValue
from @metadata;

select * from Sys.Registration.Metadata.Writer
  where ToWrite = @toWrite

Once you have created a rebalancing algorithm in the form of a custom view, you can navigate to Dashboard > Rebalance via the LUSID web app and try out your algorithm. Select a Rebalance type of Algorithm followed by your custom view under Algo to use the algorithm against a selected portfolio. For example, running the rebalancing algorithm on the following portfolio shows that 50 Microsoft shares should be sold to reduce its weight from 0.67% to 0%:

Once the algorithm has executed, you can convert the target orders, or order instructions, into actual orders using the Generate orders button. The Generate orders screen allows you to pick and choose which order instructions you'd like to convert into orders, and make changes to the orders before you confirm such as adjusting the quantity.