--- title: "Defining portfolio rebalancing algorithms" slug: "defining-portfolio-rebalancing-algorithms" tags: ["rebalance", "valuation", "oms"] updated: 2026-08-18T15:58:54Z published: 2026-08-18T15:58:54Z canonical: "support.lusid.com/defining-portfolio-rebalancing-algorithms" --- > ## 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. # Defining portfolio rebalancing algorithms > **Note:** As a prerequisite to this article, we recommend you’re familiar with [performing valuations in LUSID](/v1/docs/valuations). 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](/v1/docs/creating-custom-views-sysadminsetupview). 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](https://www.lusid.com/app/home): ![](https://cdn.document360.io/d575ad81-c0ed-4980-bbd1-d59ac5c3de82/Images/Documentation/image-V3ASY7GY.png?sv=2026-02-06&spr=https&st=2026-11-09T06%3A00%3A16Z&se=2026-11-09T07%3A00%3A16Z&sr=c&sp=r&sig=YFy2yGskhHKMP4mnxt2vJo%2F0Ru4fXLgzDs17L%2FG18ZU%3D) > [!NOTE] > Note > > LUSID collapses the toolbar options into menus if your dashboard is below a particular width. To choose your algorithm, simply click the **Orders** menu: > > ![](https://cdn.document360.io/d575ad81-c0ed-4980-bbd1-d59ac5c3de82/Images/Documentation/image-SBAYWLX3.png?sv=2026-02-06&spr=https&st=2026-11-09T06%3A00%3A16Z&se=2026-11-09T07%3A00%3A16Z&sr=c&sp=r&sig=YFy2yGskhHKMP4mnxt2vJo%2F0Ru4fXLgzDs17L%2FG18ZU%3D) When using the Rebalance dashboard, you must select a portfolio to rebalance and a recipe and, optionally, a rebalancing algorithm to use (if selecting a **Rebalance type** of **Manual**). The rebalancing algorithm is a [Luminesce custom view](/v1/docs/creating-custom-views-sysadminsetupview) that must take in the following input parameters: - Portfolio scope and code - Valuation recipe scope and code - A scope for the resulting [order instructions](/v1/docs/what-is-rebalancing-in-lusid) 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.](/v1/docs/toolspivot) 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 using [Lusid.OrderInstruction.Writer](/v1/docs/lusidorderinstructionwriter). > [!NOTE] > Note > > To run an algorithm against a portfolio group, the group must have a defined portfolio mapping so the Rebalance dashboard treats it as a single portfolio. [Read more about portfolio mappings.](/v1/docs/what-are-portfolio-mappings) > > When you run an algorithm against a portfolio group, the algorithm currently runs once for the group as a whole, rather than once per portfolio within the group. ## Example: Creating a rebalancing algorithm that sells out of all holdings below 0.5% exposure Let's imagine you want to see which orders might be required to sell all holdings which make up less than 0.5% of the exposure of a portfolio. You can use [Sys.Admin.SetupView](/v1/docs/creating-custom-views-sysadminsetupview) 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](/v1/docs/valuing-a-multi-asset-multi-region-portfolio#deciding-which-metrics-to-report) required to perform a valuation using [Lusid.Portfolio.Valuation](/v1/docs/lusidportfoliovaluation). 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](http://lusid.com/docs/api/lusid/endpoints/aggregation/GetValuation/) (and any other data accessible via Luminesce). - The algorithm runs two separate valuation queries depending on `EntityType`: The results are then combined sp the algorithm works regardless of the supplied entity type. - One filters on `PortfolioCode` and `PortfolioScope` - The other filters on `TopGroupCode` and `TopGroupScope` - `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.](/v1/docs/toolspivot) - The holdings to generate order instructions for from the valuation output. In this example: These order instructions must then be written into LUSID using [Lusid.OrderInstruction.Writer](/v1/docs/lusidorderinstructionwriter). - To identify any holdings below 0.5% of the total portfolio exposure, you can filter on the `Proportion(Valuation/ExposureInPortfolioCcy/Amount)` metric to select all non-currency holdings below that threshold. - You can also specify at this point that the `Weight` of these holdings should be adjusted to 0%. ```sql @@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,OrderInstructions,true ---- @@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; -- Portfolio branch: only returns rows when EntityType = 'Portfolio' @portfolio_valuation = select    PortfolioScope,    PortfolioCode,    LusidInstrumentId,    MeasureName,    MeasureDecimalValue  from Lusid.Portfolio.Valuation  where PortfolioCode = @@EntityCode    and PortfolioScope = @@EntityScope    and Recipe = @@Recipe    and MeasuresToReturn = @toReturn    and @@EntityType = 'Portfolio'; -- PortfolioGroup branch: only returns rows when EntityType = 'PortfolioGroup' @group_valuation = select    PortfolioScope,    PortfolioCode,    LusidInstrumentId,    MeasureName,    MeasureDecimalValue  from Lusid.Portfolio.Valuation  where TopGroupCode = @@EntityCode    and TopGroupScope = @@EntityScope    and Recipe = @@Recipe    and MeasuresToReturn = @toReturn    and @@EntityType = 'PortfolioGroup'; @valuation=  select * from @portfolio_valuation  union all  select * from @group_valuation  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,  PortfolioScope || '.' || PortfolioCode || '.' || 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.005;   select  PortfolioCode,  PortfolioScope,  OrderInstructionScope as ResultingOrderInstructionScope,  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 **Portfolio Management > Rebalance** via the [LUSID web app](https://www.lusid.com/app/home) and try out your algorithm. Select a **Rebalance type** of **Manual** and your custom view under **Algorithm** to run the algorithm against a selected portfolio. For example, running the rebalancing algorithm on the following portfolio shows that all bond holdings should be sold to reduce their weight to 0%: ![](https://cdn.document360.io/d575ad81-c0ed-4980-bbd1-d59ac5c3de82/Images/Documentation/image-PZRAYM6N.png?sv=2026-02-06&spr=https&st=2026-11-09T06%3A00%3A16Z&se=2026-11-09T07%3A00%3A16Z&sr=c&sp=r&sig=YFy2yGskhHKMP4mnxt2vJo%2F0Ru4fXLgzDs17L%2FG18ZU%3D) 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.