Main Content

Liquidate Dollar Value from Portfolio

This example shows how to liquidate a dollar value from a portfolio while minimizing market-impact costs using transaction cost analysis from the Kissell Research Group. This example always results in a portfolio that shrinks in size. The market-impact cost minimization is expressed as


where MI is the market-impact cost for the traded shares and x denotes the final weights for each stock.

This example requires an Optimization Toolbox™ license. For background information, see Optimization Theory Overview (Optimization Toolbox).

The optimization finds a local minimum for the market-impact cost of liquidating a dollar value from a portfolio. For ways to search for the global minimum, see Local vs. Global Optima (Optimization Toolbox).

To access the example code, enter edit KRGLiquidityOptimizationExample.m at the command line.

Retrieve Market-Impact Parameters and Load Data

Retrieve the market-impact data from the Kissell Research Group FTP site. Connect to the FTP site using the ftp function with a user name and password. Navigate to the MI_Parameters folder and retrieve the market-impact data in the MI_Encrypted_Parameters.csv file. miData contains the encrypted market-impact date, code, and parameters.

f = ftp('','username','pwd');

miData = readtable('MI_Encrypted_Parameters.csv','delimiter', ...

Create a Kissell Research Group transaction cost analysis object k. Specify initial settings for the date, market-impact code, and number of trading days.

k = krg(miData,datetime('today'),1,250);

Load the example data TradeDataPortOpt and the covariance data CovarianceData from the file KRGExampleData.mat, which is included with the Datafeed Toolbox™. Limit the data set to the first 10 rows.

load KRGExampleData.mat TradeDataPortOpt CovarianceData

n = 10;
TradeDataPortOpt = TradeDataPortOpt(1:n,:);
CovarianceData = CovarianceData(1:n,1:n);
C = table2array(CovarianceData);

For a description of the example data, see Kissell Research Group Data Sets.

Define Optimization Parameters

Set the portfolio liquidation value to $100,000,000. Set the portfolio risk boundaries between 90% and 110%. Set the maximum total market-impact cost to 50 basis points. Determine the number of stocks in the portfolio. Retrieve the upper bound constraint for the maximum market-impact cost for liquidating shares in each stock.

PortLiquidationValue = 100000000; 
PortRiskBounds = [0.9 1.10];
maxTotalMI = 0.005;
numPortStocks = length(TradeDataPortOpt.Symbol);
maxMI = TradeDataPortOpt.UB_MaxMI;

Determine the target portfolio value PortfolioTargetValue by subtracting the portfolio liquidation value from the total portfolio value.

PortfolioValue = sum(TradeDataPortOpt.Value);
absPortValue = abs(TradeDataPortOpt.Value);
PortfolioAbsValue = sum(absPortValue);
PortfolioTargetValue = PortfolioValue-PortLiquidationValue;

Determine the current portfolio weight w based on the value of each stock in the portfolio.

w = sign(TradeDataPortOpt.Shares).*absPortValue/PortfolioAbsValue;

Specify constraints Aeq and beq to indicate that the weights must sum to one. Initialize the linear inequality constraints A and b.

Aeq = ones(1,numPortStocks);
beq = 1;

A = [];
b = [];

Retrieve the lower and upper bounds for the final portfolio weight in TradeDataPortOpt.

LB = TradeDataPortOpt.LB_Wt;
UB = TradeDataPortOpt.UB_Wt;

Determine the lower and upper bounds for the number of shares in the final portfolio using other optional constraints in the example data set.

lbShares = max([TradeDataPortOpt.LB_MinShares, ...
    TradeDataPortOpt.LB_MinValue./TradeDataPortOpt.Price, ...

ubShares = min([TradeDataPortOpt.UB_MaxShares, ...
    TradeDataPortOpt.UB_MaxValue./TradeDataPortOpt.Price, ...

Specify the initial portfolio weights.

x0 = TradeDataPortOpt.Value./sum(TradeDataPortOpt.Value);
x = x0;

Define optimization options. Set the optimization algorithm to sequential quadratic programming. Set the termination tolerance on the function value and on x. Set the tolerance on the constraint violation. Set the termination tolerance on the PCG iteration. Set the maximum number of function evaluations 'MaxFunEvals' and iterations 'MaxIter'. The options 'MaxFunEvals' and 'MaxIter' are set to large values so that the optimization can iterate many times to find a local minimum. Set the minimum change in variables for finite differencing.

options = optimoptions('fmincon','Algorithm','sqp', ...
    'TolFun',10E-8,'TolX',10E-16,'TolCon',10E-8,'TolPCG',10E-8, ...

Minimize Market-Impact Costs for Portfolio Liquidation

Define the function handle objectivefun for the sample objective function krgLiquidityFunction. To access the code for this function, enter edit krgLiquidityFunction.m. Define the function handle constraintsfun for the sample function krgLiquidityConstraint that sets additional constraints. To access the code for this function, enter edit krgLiquidityConstraint.m.

objectivefun = @(x) krgLiquidityFunction(x,TradeDataPortOpt, ...

constraintsfun = @(x) krgLiquidityConstraint(x,w,C,TradeDataPortOpt, ...

Minimize the market-impact costs for the portfolio liquidation. fmincon finds the optimal value for the portfolio weight for each stock based on the lower and upper bound values. It does this by finding a local minimum for the market-impact cost.

[x,~,exitflag] = fmincon(objectivefun,x0,A,b,Aeq,beq,LB,UB, ...

To check whether fmincon found a local minimum, display the reason why the function stopped.

exitflag =


fmincon returns 1 when it finds a local minimum. For details, see exitflag (Optimization Toolbox).

Determine the optimized weight value x1 of each stock in the portfolio in decimal format.

x1 = x.*PortfolioTargetValue/PortfolioValue;

Determine the optimized portfolio target value TargetValue and number of shares SharesToTrade for each stock in the portfolio.

TargetShares = x*PortfolioTargetValue./TradeDataPortOpt.Price;
SharesToTrade = TradeDataPortOpt.Shares-TargetShares;
TargetValue = x*PortfolioTargetValue;
TradeDataPortOpt.Shares = abs(SharesToTrade);

Determine the optimized percentage of volume strategy.

TradeDataPortOpt.TradeTime = TradeDataPortOpt.TradeTime ...
    .* TradeDataPortOpt.ADV;
TradeDataPortOpt.POV = krg.tradetime2pov(TradeDataPortOpt.TradeTime, ...

Estimate the market-impact costs MI for the number of shares to liquidate.

MI = marketImpact(k,TradeDataPortOpt)/10000;

To view the market-impact cost in decimal format, specify the display format. Display the market-impact cost for the first three stocks in the portfolio.


ans =

   1.0e-03 *


To view the target number of shares with two decimal places, specify the display format. Display the target number of shares for the first three stocks in the portfolio.

format bank

ans =


The negative values denote selling shares from the portfolio.

Display the traded value for the first three stocks in the portfolio.

ans =


To simulate trading the target number of shares on a historical date range, you can now conduct a stress test on the optimized portfolio. For details about conducting a stress test, see Conduct Stress Test on Portfolio.


[1] Kissell, Robert. “Creating Dynamic Pre-Trade Models: Beyond the Black Box.” Journal of Trading. Vol. 6, Number 4, Fall 2011, pp. 8–15.

[2] Kissell, Robert. “TCA in the Investment Process: An Overview.” Journal of Index Investing. Vol. 2, Number 1, Summer 2011, pp. 60–64.

[3] Kissell, Robert. The Science of Algorithmic Trading and Portfolio Management. Cambridge, MA: Elsevier/Academic Press, 2013.

[4] Chung, Grace and Robert Kissell. “An Application of Transaction Costs in the Portfolio Optimization Process.” Journal of Trading. Vol. 11, Number 2, Spring 2016, pp. 11–20.

See Also

| | (Optimization Toolbox) | (Optimization Toolbox)

Related Topics