Main Content

This example shows how to determine buy-sell imbalance using transaction cost analysis from the Kissell Research Group. Imbalance is the difference between buy-initiated and sell-initiated volume given actual market conditions on the day and over the specified trading period. A positive imbalance indicates buying pressure in the stock and a negative imbalance indicates selling pressure. The cost index helps investors to understand how the trading cost environment affects the order flow in the market. The index can be a performance-based index, such as the S&P 500, that shows market movement and value or a volatility index that shows market uncertainty.

The imbalance share quantity is the value of *x* such
that

$$0=\left|MICost\right|\cdot 10000-MI\left(x\right),$$

where

$$MI\left(x\right)=\left[{b}_{1}\cdot {\left(\frac{x}{Volume}\right)}^{{a}_{4}}+\left(1-{b}_{1}\right)\right]\cdot \left[{a}_{1}\cdot {\left(\frac{x}{ADV}\right)}^{{a}_{2}}\cdot {\sigma}^{{a}_{3}}\cdot Pric{e}^{{a}_{5}}\right].$$

*MI* is the market-impact cost for a stock
transaction. The estimated trading costs represent the incremental
price movement of the stock in relation to the underlying index price
movement. *Volume* is the actual daily volume of
a stock in the basket. *ADV* is the average daily
volume of a stock in the basket. *Price* is the price
of a stock in the basket. The other variables in the equations are:

$$\sigma $$ — Price volatility.

$${a}_{1}$$ — Price sensitivity to order flow.

$${a}_{2}$$ — Order size shape.

$${a}_{3}$$ — Volatility shape.

$${a}_{4}$$ — Percentage of volume rate shape.

$${a}_{5}$$ — Price shape.

$$1-{b}_{1}$$ — Percentage of permanent market impact. Permanent impact is the unavoidable impact cost that occurs because of the information content of the trade.

$${b}_{1}$$ — Percentage of temporary market impact. Temporary impact is dependent upon the trading strategy. Temporary impact occurs because of the liquidity demands of the investor.

$$MICost=TotalCost-Beta\cdot IndexCost,$$ where:

*TotalCost*— Change in the volume-weighted average price compared to the open price for the stocks.*Beta*— Beta.*IndexCost*— Change in the volume-weighted average price compared to the open price for the index. Index cost adjusts the price for market movement using an underlying index and beta.

In this example, you can run this code using current or historical data. Current data includes prices starting from the open time through the current time. Historical data uses the prices over the entire day. Historical costs use market-impact parameters for the specified region and date. Therefore, historical costs change from record to record.

For a current cost index, you load the example table `TradeDataCurrent`

from
the file `KRGExampleData.mat`

. For a historical cost
index, you load the example table `TradeDataHistorical`

from
the file `KRGExampleData.mat`

. This example calculates
a current cost index.

To access the example code, enter `edit KRGCostIndexExample.m`

at
the command line.

After running this code, you can submit an order for execution
using Bloomberg^{®}, for example.

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

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('ftp.kissellresearch.com','username','pwd'); mget(f,'MI_Encrypted_Parameters.csv'); close(f) miData = readtable('MI_Encrypted_Parameters.csv','delimiter', ... ',','ReadRowNames',false,'ReadVariableNames',true);

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 `TradeDataCurrent`

,
which is included with the Trading Toolbox™. Calculate the number
of stocks in the portfolio.

load KRGExampleData.mat TradeDataCurrent TradeData = TradeDataCurrent; numStocks = height(TradeData);

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

Define the maximum number of function iterations for optimization.
Set `'MaxIterations'`

to a large value so that the
optimization can iterate many times to solve a system of nonlinear
equations.

options = optimoptions('fsolve','MaxIterations',4000);

Determine the total cost and beta cost. Calculate the side of
the initial market-impact cost estimate. Determine the initial volume `x0`

.

```
totalCost = TradeData.VWAP ./ TradeData.Open - 1;
indexCost = TradeData.Beta .* ...
(TradeData.IndexVWAP ./ TradeData.IndexOpen - 1);
miCost = totalCost - indexCost;
sideIndicator = sign(miCost);
x0 = 0.5 * TradeData.Volume;
```

Create a table that stores all output data. First, add these variables:

`Symbol`

— Stock symbol`Date`

— Transaction date`Side`

— Side`TotalVolume`

— Transaction volume`TotalCost`

— Total transaction cost`IndexCost`

— Index cost

costIndexTable = table; costIndexTable.Symbol = TradeData.Symbol; costIndexTable.Date = TradeData.Date; costIndexTable.Side = sideIndicator; costIndexTable.TotalVolume = TradeData.Volume; costIndexTable.TotalCost = totalCost; costIndexTable.IndexCost = indexCost;

Use a `for`

-loop to calculate the cost
index for each stock in the portfolio. Each stock might have different
market-impact codes and dates. Use the `costIndexExampleEq`

function
that contains the nonlinear equation to solve. To access the code
for the `costIndexExampleEq`

function, enter ```
edit
KRGCostIndexExample.m
```

.

Add these variables to the output table:

`Imbalance`

— Imbalance`ImbalancePctADV`

— Imbalance as percentage of average daily volume`ImbalancePctDayVolume`

— Imbalance as percentage of the daily volume`BuyVolume`

— Buy volume`SellVolume`

— Sell volume`MI`

— Market-impact cost`ExcessCost`

— Excess cost

for i = 1:numStocks % Set the MiCode and MiDate of the object for each stock k.MiCode = TradeData.MICode(i); k.MiDate = TradeData.Date(i); % Solve for Shares for each stock that results in the target market % impact cost. % In this example, x is the number of shares (imbalance) that causes % the MI impact cost, the number of shares that result in a market % impact cost of MI. Here use abs(MI) since market-impact % cost is always positive. If the market-impact cost is 0.0050 then % fsolve tries to find the number of shares x so that the market % impact formula returns 0.0050. % Note that fsolve is using the cost in basis points. x = fsolve(@(x) costIndexExampleEq(x,miCost(i),TradeData(i,:),k), ... x0(i),options); % The imbalance must be between 0 and the actual traded volume. x = max(min(x,TradeData.Volume(i)),0); % Recalculate the percentage of volume and shares based on x. TradeData.POV(i) = x/TradeData.Volume(i); TradeData.Shares(i) = x; % Calculate the new cost as a decimal value. mi = marketImpact(k,TradeData(i,:))/10000; % imbalance is the share amount specified as buy or sell by the % sideIndicator. imbalance = sideIndicator(i) * x; % Calculate the buy and sell volumes. % Knowing that: % % Volume = buyVolume + sellVolume; % Imbalance = buyVolume - sellVolume; % % Solve for buyVolume and sellVolume buyVolume = (TradeData.Volume(i) + imbalance) / 2; sellVolume = (TradeData.Volume(i) - imbalance) / 2; % Fill output table costIndexTable.Imbalance(i,1) = imbalance; costIndexTable.ImbalancePctADV(i,1) = imbalance/TradeData.ADV(i); costIndexTable.ImbalancePctDayVolume(i,1) = imbalance/TradeData.Volume(i); costIndexTable.BuyVolume(i,1) = buyVolume; costIndexTable.SellVolume(i,1) = sellVolume; costIndexTable.MI(i,1) = mi * sideIndicator(i); costIndexTable.ExcessCost(i,1) = totalCost(i) - mi - indexCost(i); end

Display the imbalance amount for the first stock in the output data.

costIndexTable.Imbalance(1)

ans = -8.7894e+04

The negative imbalance amount indicates selling pressure. Decide whether to buy, hold, or sell shares of this stock in the portfolio.

For details about the preceding calculations, contact the Kissell Research Group.

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

[2] Malamut, Roberto. “Multi-Period Optimization Techniques for Trade Scheduling.” Presentation at the QWAFAFEW New York Conference, April 2002.

[3] Kissell, Robert, and Morton Glantz. *Optimal
Trading Strategies*. New York, NY: AMACOM, Inc., 2003.

`krg`

| `marketImpact`

| `fsolve`

(Optimization Toolbox) | `optimoptions`

(Optimization Toolbox)