Optimize Trade Schedule Trading Strategy for Basket
This example shows how to optimize the strategy for a basket by minimizing trading costs using transaction cost analysis from the Kissell Research Group. Using this optimization, you determine the optimal order slicing strategy for the basket based on the trade-off between trading cost, risk, and the specified level of risk aversion. The optimization minimizes trading costs associated with the trade schedule trading strategy and a specified risk aversion parameter Lambda. The trading cost minimization is expressed as
where trading costs are market impact MI, price appreciation PA, and timing risk TR.
To access the example code, enter edit
KRGTradeOptimizationExample.m
at the command line. In this example,
you can run this code using a trade schedule trading strategy or a percentage of
volume trading strategy. This example shows the trade schedule trading strategy. An
exponential function determines the optimal trade schedule.
After executing the code in this example, 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 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('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 TradeDataTradeOpt
and the covariance
data CovarianceTradeOpt
from the file
KRGExampleData.mat
, which is included with the
Datafeed Toolbox™.
load KRGExampleData TradeDataTradeOpt CovarianceTradeOpt
For a description of the example data, see Kissell Research Group Data Sets.
Define Optimization Parameters
Specify initial values for risk, trading periods, portfolio value, and covariance matrix. Convert to a buy-only problem. Set the initial trade schedule.
% Convert table to array CovarianceTradeOpt = table2array(CovarianceTradeOpt); % Use total trading time of 1 day with 13 trading periods totalDays = 1; periodsPerDay = 13; % Set risk aversion level Lambda = 0.5; % Set minimum and maximum percentage of volume minPOV = 0.00; maxPOV = 0.60; % total number of trading periods totalNumberPeriods = totalDays * periodsPerDay; % Portfolio Value PortfolioValue = TradeDataTradeOpt.Price'*TradeDataTradeOpt.Shares; % Number of stocks numberStocks = height(TradeDataTradeOpt); % 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. CC = diag(TradeDataTradeOpt.Price) * CovarianceTradeOpt * ... diag(TradeDataTradeOpt.Price); % Scale to one trading period CC = CC / periodsPerDay / k.TradeDaysInYear; % Convert to buy-only problem (e.g., one-sided problem) CC = TradeDataTradeOpt.SideIndicator * TradeDataTradeOpt.SideIndicator' .* CC; % Convert Alpha_bp from basis points per day to cents/share per period TradeDataTradeOpt.Alpha_bp = TradeDataTradeOpt.Alpha_bp / 1000 .* ... TradeDataTradeOpt.Price / totalNumberPeriods; % Set the initial trade schedule or POV values theta0 = rand(numberStocks,1);
Define optimization options using the optimset
function.
For details about these options, see Optimization Options Reference (Optimization Toolbox).
optionsold = optimset; options = optimset(optionsold,'LargeScale','on','GradObj','off', ... 'DerivativeCheck','off','FinDiffType','central','FinDiffRelStep',1E-12, ... 'TolFun',10E-5,'TolX',10E-12,'TolCon',10E-12,'TolPCG',10E-12, ... 'MaxFunEvals',20000,'MaxIter',20000,'DiffMinChange',10E-04);
Define lower and upper bounds of shares traded per interval for optimization.
LB = zeros(numberStocks,1); UB = 100 * ones(numberStocks,1);
Minimize Trading Costs for Trade Strategy
Minimize the trading costs for the trade schedule strategy.
fmincon
finds the optimal value for the trade schedule
trade strategy based on the lower and upper bound values. It does this by
finding a local minimum for the trading cost. Use the objective function
optimizeTradingSchedule
. To access the code for this
function, enter edit KRGTradeOptimizationExample.m
.
[theta,fval,exitflag,output] = fmincon(@optimizeTradingSchedule,theta0,[], ... [],[],[],LB,UB,[],options,totalNumberPeriods,numberStocks,periodsPerDay, ... TradeDataTradeOpt,CC,Lambda,k);
To check whether fmincon
found a local minimum, display
the reason why the function stopped.
exitflag
exitflag = 1.00
fmincon
returns 1
when it finds a
local minimum. For details, see exitflag
(Optimization Toolbox).
Calculate shares to trade, residual shares, price appreciation, and timing risk. Then, calculate the average percentage of volume rate and trade time.
numPeriods = 1:totalNumberPeriods; K_Matrix = repmat(numPeriods,numberStocks,1); Theta_Matrix = repmat(theta,1,totalNumberPeriods); Volume_Matrix = repmat(TradeDataTradeOpt.ADV/periodsPerDay,1, ... totalNumberPeriods); TradeDataTradeOpt.VolumeProfile = Volume_Matrix; Shares_Matrix = repmat(TradeDataTradeOpt.Shares,1,totalNumberPeriods); % X = Shares to trade in period i Xpct = (exp(-K_Matrix .* Theta_Matrix) .* (exp(Theta_Matrix)-1)) ./ ... (1 - exp(-totalNumberPeriods * Theta_Matrix)); X = repmat(TradeDataTradeOpt.Shares,1,totalNumberPeriods) .* Xpct; TradeDataTradeOpt.TradeSchedule = X; % R = Residual Shares at beginning of period i Rpct = (exp(-(K_Matrix-1).*Theta_Matrix) - exp(-totalNumberPeriods.*Theta_Matrix)) ./ ... (1-exp(-totalNumberPeriods.*Theta_Matrix)); R = repmat(TradeDataTradeOpt.Shares,1,totalNumberPeriods) .* Rpct; % Price Appreciations in Dollars PA = sum(R,2) .* TradeDataTradeOpt.Alpha_bp; % Market Impact in Dollars MI = marketImpact(k,TradeDataTradeOpt) .* TradeDataTradeOpt.Shares .* ... TradeDataTradeOpt.Price ./10000; % Timing Risk in Dollars TR = sqrt(sum(R.^2,2) .* diag(CC)); TR_bp = TR ./ (TradeDataTradeOpt.Shares .* TradeDataTradeOpt.Price) * 10000; % Avg POV Rate kTR = ((TR_bp/10000*1./TradeDataTradeOpt.Volatility).^2).*(k.TradeDaysInYear*3 ./ ... (TradeDataTradeOpt.Shares./TradeDataTradeOpt.ADV)); POV = 1./(1+kTR); POV = max(POV,TradeDataTradeOpt.Shares./(TradeDataTradeOpt.Shares+totalDays .* ... TradeDataTradeOpt.ADV)); % TradeTime TradeDataTradeOpt.TradeTime = TradeDataTradeOpt.Shares./TradeDataTradeOpt.ADV .* ... (1-POV)./POV;
Estimate total trading costs using the optimized trade strategy.
TotMI = sum(MI) / (TradeDataTradeOpt.Shares' * TradeDataTradeOpt.Price) ... .* 10000; % bp TotPA = sum(PA) / (TradeDataTradeOpt.Shares' * TradeDataTradeOpt.Price) ... .* 10000; % bp TotTR = sqrt(trace(R'*CC*R)) ./ (TradeDataTradeOpt.Shares' * ... TradeDataTradeOpt.Price) * 10000;
Display total market-impact cost, price appreciation, and timing risk.
totalcosts = [TotMI TotPA TotTR]
totalcosts = 38.2902 0 26.5900
For details about the preceding calculations, contact the Kissell Research Group.
References
[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.
See Also
krg
| marketImpact
| optimset
(Optimization Toolbox) | fmincon
(Optimization Toolbox) | priceAppreciation
| timingRisk