Documentation

Create Basket Summary and Efficient Trading Frontier

In this example, you can see a basket summary analysis table and a principal bid summary. The basket summary provides trading cost estimates for the basket across different categories, such as side, market capitalization, and market sector. The principal bid summary contains the efficient trading frontier that provides the different estimated trading costs for different time periods. The efficient trading frontier shows how cost and risk change by trading more aggressively or passively. With passive trading, market impact decreases as timing risk increases. With aggressive trading, market impact increases as timing risk decreases.

The code in this example depends on the output data from the example Optimize Trade Schedule Trading Strategy for Basket. Run the code in that example first and then run the code in this example.

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

After executing the code in this example, you can submit an order for execution using Bloomberg®, for example.

Determine the covariance matrix. Covariance indicates how the prices of stocks in the basket relate to each other.

% Covariance matrix is annualized covariance matrix in decimals.
% Convert to (\$/Shares)^2 units for the trade period, this matrix is for a
% two-sided portfolio, buys and sells or long and short.
diagPrice * CovarianceTradeOpt * diagPrice;

% Covariance Matrix in \$/Share^2 by Day
CD = diagPrice * CovarianceTradeOpt * diagPrice;    % compute Covariance Matrix in (\$/share)^2
CD = CD / k.TradeDaysInYear;                        % scale to 1-day
.* CD;

Add the estimated trading costs from the trade schedule optimization to the basket data.

% Market impact in basis points

% Timing risk in basis points

% Percentage of volume, price appreciation and liquidity factor

Calculate trading costs in basis points, cents per share, and dollars.

% Build optimal cost table
OptimalCostTable = table(cell(3,1),zeros(3,1),zeros(3,1),zeros(3,1), ...
zeros(3,1),'VariableNames',{'CostUnits','MI','PA','TotalCost','TR'});
OptimalCostTable.CostUnits(1) = {'Basis Points'};
OptimalCostTable.CostUnits(2) = {'Cents per Share'};
OptimalCostTable.CostUnits(3) = {'Dollars'};

% Market impact,
OptimalCostTable.MI(1) = TotMI;
OptimalCostTable.MI(2) = TotMI / 100 * mean(TradeDataTradeOpt.Price);
OptimalCostTable.MI(3) = TotMI / 100 * (TradeDataTradeOpt.Shares' * ...

% Price appreciation
OptimalCostTable.PA(1) = TotPA;
OptimalCostTable.PA(2) = TotPA / 100 * mean(TradeDataTradeOpt.Price);
OptimalCostTable.PA(3) = TotPA / 100 * (TradeDataTradeOpt.Shares' * ...

% Total cost
OptimalCostTable.TotalCost(1) = TotMI + TotPA;
OptimalCostTable.TotalCost(2) = (TotMI + TotPA) / 100 * mean(TradeDataTradeOpt.Price);
OptimalCostTable.TotalCost(3) = (TotMI + TotPA) / 100 * ...

% Timing risk
OptimalCostTable.TR(1) = TotTR;
OptimalCostTable.TR(2) = TotTR / 100 * mean(TradeDataTradeOpt.Price);
OptimalCostTable.TR(3) = TotTR / 100 * ...

Display the optimal costs for the basket. Format the display output to show cents and dollars. Optimal costs are market impact, price appreciation, total cost, and timing risk.

format bank
OptimalCostTable
OptimalCostTable =

3×5 table array

CostUnits             MI          PA      TotalCost           TR
_________________    ____________    ____    ____________    ____________

'Basis Points'              38.30    0.00           38.30           26.57
'Cents per Share'           14.88    0.00           14.88           10.32
'Dollars'            171134479.73    0.00    171134479.73    118710304.48

Determine Risk Components in Basket

Calculate risk statistics. The marginal contribution to risk captures the risk of changing one of the components in the basket, such as the number of shares. The risk contribution is the risk for each trade in the basket.

% Portfolio Risk in Dollars
PortfolioRisk = sqrt(TradeDataTradeOpt.Shares' * CD * ...

% MCR and RC calculations
PortfolioRiskMCR = zeros(numberStocks,1);
PortfolioRiskRC =zeros(numberStocks,1);
for i = 1:numberStocks
SharesRC(i) = 0;
PortfolioRiskMCR(i) = sqrt(SharesMCR' * CD * SharesMCR);
PortfolioRiskRC(i) = sqrt(SharesRC' * CD * SharesRC);
end
TradeDataTradeOpt.MCR = PortfolioRisk ./ PortfolioRiskMCR - 1;
TradeDataTradeOpt.RC = PortfolioRisk ./ PortfolioRiskRC - 1;

Display the side, symbol, and number of shares for the safest trade in the basket using the risk contribution.

for i = 1:25
idx = i;
end
end
ans =

1×3 cell array

'B'    'ABC'    

The buy order of 100,000 shares of stock ABC contributes the most overall portfolio risk.

Create Basket Report Summary

Create a table for the basket report summary.

% Get sector identifiers
numSectors = size(uniqueSectors,1);
numGroups = 14 + size(uniqueSectors,1);  % Using 14 categories plus number of sectors

% Preallocate BasketReport table

Calculate the basket report summary.

Divide the trades in the basket into these categories:

• Total — All trades in basket

• Cover — Buy trades that cover a short position

• Sell — Sell trades

• Short — Short trades

• <=1% — Trades that have percentage of average daily volume less than or equal to 1%

• 1%-3% — Trades that have percentage of average daily volume between 1% and 3%

• 3%-5% — Trades that have percentage of average daily volume between 3% and 5%

• 5%-10% — Trades that have percentage of average daily volume between 5% and 10%

• 10%-20% — Trades that have percentage of average daily volume between 10% and 20%

• >20% — Trades that have percentage of average daily volume greater than 20%

• LC — Large-capitalization stock trades

• MC — Mid-capitalization stock trades

• SC — Small-capitalization stock trades

• Consumer Discretionary — Trades in the consumer discretionary industry

• Consumer Staples — Trades in the consumer staples industry

• Energy — Trades in the energy industry

• Financials — Trades in the financial industry

• Health Care — Trades in the health care industry

• Industrials — Trades in the industrial industry

• Information Technology — Trades in the information technology industry

• Materials — Trades in the materials industry

• Telecommunication Services — Trades in the telecommunication services industry

• Utilities — Trades in the utilities industry

For stocks in each category, calculate these values:

• Weight — Total trade value weight

• MI — Weighted average market-impact cost

• TR — Timing risk

• POV — Weighted average percentage of volume rate

• TradeTime — Weighted average trade time to complete the order

• PctADV — Weighted average order size (measured as percentage of average daily volume)

• Price — Weighted average share price

• Volatility — Weighted average volatility

• Risk — Portfolio risk

• RC — Risk contribution to the overall portfolio risk (shows the amount of risk that an order contributes to the basket)

• MCR — Marginal contribution to risk (shows the amount of risk that 10% of shares in the order contribute to the basket)

• Beta — Weighted average beta

• LF — Weighted average liquidity factor

• TotalValue — Total trade value

• BuyValue — Total trade value of the buy transactions

• SellValue — Total trade value of the sell transactions

• NetValue — Difference between total trade value of the buy and sell transactions

• Shares — Number of shares

• BuyShares — Number of shares to buy

• SellShares — Number of shares to sell

% Fill table, indRecord is index of matching TradeData rows
j = 0;
for i = 1:24

switch i

% Total
case 1

indRecord = true(numberStocks,1);

% Side
case 2

case 3

case 4

case 5

% Liquidity Category
case 6

% Percentage of average daily volume is less than 1 %

case 7

% Percentage of average daily volume is between 1 and 3 %

case 8

% Percentage of average daily volume is between 3 and 5 %

case 9

% Percentage of average daily volume is between 5 and 10 %

case 10

% Percentage of average daily volume is between 10 and 20 %

case 11

% Percentage of average daily volume is greater than 20 %

% Market cap
case 12

% Large cap

case 13

% Mid cap
indRecord = (TradeDataTradeOpt.MktCap > 1000000000 & ...

case 14

% Small cap

% Sectors
% Description of basket category
case {15, 16, 17, 18, 19, 20, 21, 22, 23, 24}
j = j + 1;
if j <= numSectors
end

end

% Get subset of TradeData

if ~isempty(TD)

% Covariance Matrix in \$/Shares^2
CC2 = CC(indRecord,indRecord);    %Trading Period Covariance Matrix in \$/Shares^2
C2 = C1(indRecord,indRecord);     %Annualized Covariance Matrix in \$/Shares^2
RR = R(indRecord,:);              %Residuals for Stocks in group

% Basket Summary Calculations
Weight2 = TD.Value / sum(TD.Value);

% Side
I_Buy = (TD.SideIndicator == 1);
I_Sell = (TD.SideIndicator == -1);

% Fill basket report table
BasketReport.Number(i) = size(TD,1);                     % Number of records that match criteria
BasketReport.Weight(i) = sum(TD.Value)/PortfolioValue;   % Weight of assets in criteria
BasketReport.MI(i) = Weight2' * TD.MI;                   % Market impact of assets
BasketReport.TR(i) = sqrt(trace(RR'*CC2*RR)) / sum(TD.Value) * 10000;   % Timing risk of assets
BasketReport.POV(i) = Weight2' * TD.POV;                 % POV of assets
BasketReport.Price(i) = Weight2' * TD.Price;             % Total price of assets
BasketReport.Volatility(i) = Weight2' * TD.Volatility;   % Volatility
BasketReport.Risk(i) = sqrt(TD.Shares' * C2 * TD.Shares) / ...
sum(TD.Value);   % Risk value

% RC and MCR
Shares2(indRecord) = 0;
Shares3(indRecord) = Shares3(indRecord) * 0.90;

if sum(Shares2) > 0
BasketReport.RC(i) = PortfolioRisk / sqrt(Shares2' * CD * Shares2) - 1;
else
end
BasketReport.MCR(i) = PortfolioRisk / sqrt(Shares3' * CD * Shares3) - 1;

% Beta value, liquidity factor and total value
BasketReport.Beta(i) = sum(Weight2 .* TD.SideIndicator .* TD.Beta);
BasketReport.LF(i) = Weight2' * TD.LF;

% Calculate buy share values
if sum(I_Buy) > 0
else
end

% Calculate sell share values
if sum(I_Sell) > 0
else
end

% Calculate net value of criteria and number of shares

end
end

% Remove rows with no stocks
indRecord = (BasketReport.Number > 0);

Display market capitalization by volatility as a pie chart.

title('Market Capitalization by Volatility') Create Principal Bid Summary

Determine the efficient trading frontier by time. Use different trade time scenarios. Estimate trading costs for price appreciation, market impact, and timing risk for each scenario.

ScenarioTime = [0.10;0.25;0.50;0.75;1.0;1.50;2.0;2.5;3.0;3.5;4.0;4.5;5.0];
numScenarios = size(ScenarioTime,1);
ETFCosts = zeros(numScenarios,5);

if sum(strcmp(TableVariableNames,'DeltaP')) > 0
elseif sum(strcmp(TableVariableNames,'Alpha_bp')) > 0
else
DeltaP = zeros(NumberStocks,1);
end

% Convert DeltaP from basis points per day to cents/share per period
DeltaP = DeltaP / 1000 .* TradeDataTradeOpt.Price / totalNumberPeriods;

for i = 1:numScenarios

% Price Appreciations in Dollars
TotPA = sum(PA) / (TradeDataTradeOpt.Shares' * ...
PA = PA ./ (TradeDataTradeOpt.Shares .* ...

% Market Impact in Dollars
TotMI = sum(MI) / (TradeDataTradeOpt.Shares' * ...
MI = MI ./ (TradeDataTradeOpt.Shares .* ...

% Timing Risk in Dollars
TotTR = sqrt(1/3 * TradeDataTradeOpt.Shares' * ...

% Total Cost Dollars
TotTC = (TotMI + TotPA);

% ETF Cost Table
ETFCosts(i,2) = TotMI;
ETFCosts(i,3) = TotPA;
ETFCosts(i,4) = TotTC;
ETFCosts(i,5) = TotTR;

end

% Save as Table
ETFCosts = table(ETFCosts(:,1),ETFCosts(:,2),ETFCosts(:,3),ETFCosts(:,4), ...
ETFCosts(:,5),'VariableNames',{'Days','MI_bp','PA_bp','TotalCost_bp', ...
'TR_bp'});

Determine the trade time with the lowest total cost.

mintotcost = min(ETFCosts.TotalCost_bp);
for i = 1:numScenarios
if(ETFCosts.TotalCost_bp(i) == mintotcost)
scenario = ETFCosts.Days(i);
end
end
scenario
scenario =

5

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

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

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

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