function main_ETF()
close all;clear all
% Read the ETF, stock and date information
% ETF.mat contains the etf data in structured format
% StockInfo.mat contains the stock data in structured format
tic
fprintf('============================================================\n')
fprintf('PARAMETERS OPTIMIZATION\n')
fprintf('------------------------------------------------------------\n')
fprintf('Performing optimization...skipped! (This will take one day)\n')
fprintf('------------------------------------------------------------\n')
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Optimization %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if 0
load('ETF.mat');
load('Stocks.mat');
% Select date in YYYYMMDD
StartDate = 20060104;
EndDate = 20081231;
% Number of Stocks and ETF used
NoOfStock = length(Stocks);
NoOfETF = length(ETF);
% Sort the desired data for selected date from ETF and stock.
for ii = 1:NoOfETF
ETFused(ii).name = ETF(ii).name;
ETFused(ii).Return = ETF(ii).Return(find(ETF(ii).Date==StartDate):find(ETF(ii).Date==EndDate));
ETFused(ii).Date = ETF(ii).Date(find(ETF(ii).Date==StartDate):find(ETF(ii).Date==EndDate));
end
for ii = 1:NoOfStock
Stocksused(ii).name = Stocks(ii).name;
Stocksused(ii).Return = Stocks(ii).Return(find(Stocks(ii).Date==StartDate):find(Stocks(ii).Date==EndDate));
Stocksused(ii).Date = Stocks(ii).Date(find(Stocks(ii).Date==StartDate):find(Stocks(ii).Date==EndDate));
end
% Find the optimal stock for the trading strategy with the optimise score
% levels.
TradingParameters = [];
profit = [];
ProfitAll = [];
Signal = [];
Wealth = [];
for ii = 1:NoOfStock
[profit,SSO,SSC,SBO,SBC,Sigtmp,wealthtmp,stocktmp,indretur] = optimizeOmegaETF(ETFused,Stocksused,ii);
TradingParameters = [TradingParameters;[SSO,SSC,SBO,SBC]];
ProfitAll = [ProfitAll;profit]; % This is the omega for Optimise omega code.
Wealth = [Wealth;wealthtmp];
Signal = [Signal;Sigtmp];
save('ETFresultsOptimizeOmega.mat','TradingParameters','ProfitAll','Wealth','Signal');
end
[maxProfit maxStockind] = max(ProfitAll);
fprintf('==============================================\n')
fprintf('The optimal stock chosen is %s with a profit of $%.2f\n',StocksUsed(maxStockind).name,maxProfit);
fprintf('==============================================\n')
end
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Outsample Test %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if 1
clear all
load('ETF.mat');
load('Stocks.mat');
% This is the results from optimization
load('ETFresultsOptimizeOmega.mat')
% Select date in YYYYMMDD
StartDate = 20090102;
EndDate = 20101231;
% Number of Stocks and ETF used
NoOfStock = length(Stocks);
NoOfETF = length(ETF);
ETFused = [];
Stocksused = [];
ProfitAll(33) = 0;
fprintf('============================================================\n')
fprintf('BACKTESTING\n')
fprintf('------------------------------------------------------------\n')
fprintf('Performing Outsample test...')
% Sort the desired data for selected date from ETF and stock.
for ii = 1:NoOfETF
ETFused(ii).name = ETF(ii).name;
ETFused(ii).Return = ETF(ii).Return(find(ETF(ii).Date==StartDate):find(ETF(ii).Date==EndDate));
ETFused(ii).Date = ETF(ii).Date(find(ETF(ii).Date==StartDate):find(ETF(ii).Date==EndDate));
end
for ii = 1:NoOfStock
Stocksused(ii).name = Stocks(ii).name;
Stocksused(ii).Return = Stocks(ii).Return(find(Stocks(ii).Date==StartDate):find(Stocks(ii).Date==EndDate));
Stocksused(ii).Date = Stocks(ii).Date(find(Stocks(ii).Date==StartDate):find(Stocks(ii).Date==EndDate));
end
[maxOmega maxStockind] = max(ProfitAll);
OptTradingPara = TradingParameters(maxStockind,:);
OptWealth = Wealth(maxStockind,:);
[TradeSignalBackTest,WealthBackTest,OmegaBackTest] = outSampleTest(ETFused,Stocksused,maxStockind,OptTradingPara);
figure(1115);plot(WealthBackTest,'linewidth',2)
title(sprintf('Outsample Test: P&L of %s over a 3 years period (2008-2010) with omega of %.2f for ETF','ATI',1.15),'fontsize',12)
ylabel('Capital $','fontsize',12)
xlabel('Time (Days)','fontsize',12)
set(gca,'linewidth',2)
set(gca,'fontsize',10)
grid on
fprintf('Completed!~\n')
fprintf('------------------------------------------------------------\n')
end
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% BootStrapping %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if 1
clear all;
load('ETF.mat');
load('Stocks.mat');
% This is the results from optimization
load('ETFresultsOptimizeOmega.mat')
% Number of Monte Carlo
MonteCarloRuns = 50;
% Select date in YYYYMMDD
StartDate = 20060104;
EndDate = 20101231;
% Number of Stocks and ETF used
NoOfStock = length(Stocks);
NoOfETF = length(ETF);
ETFused = [];
Stocksused = [];
% Number of Bootstrapping samples
SampleNo = 500;
ProfitAll(33) = 0;
% Optimal parameter to use
[maxOmega maxStockind] = max(ProfitAll);
OptTradingPara = TradingParameters(maxStockind,:);
OptWealth = Wealth(maxStockind,:);
TradeSignalBS = [];
WealthBS = [];
OmegaBS = [];
fprintf('Performing Bootstrapping - 50 Monte Carlos runs...')
for ii = 1:MonteCarloRuns
fprintf('%d...',ii);
% Bootstrapping to select SampleNo randomly from population
[ETFused,Stocksused]=SampleBootstrap(ETF,Stocks,SampleNo,NoOfStock,NoOfETF);
[TradeSignalBackTest,WealthBackTest,OmegaBackTest] = outSampleTest(ETFused,Stocksused,maxStockind,OptTradingPara);
TradeSignalBS = [TradeSignalBS;TradeSignalBackTest];
WealthBS = [WealthBS;WealthBackTest];
OmegaBS = [OmegaBS;OmegaBackTest];
if ~isempty(find(ii == [3:13:MonteCarloRuns]))
fprintf('\n')
end
end
a = toc;
fprintf('Completed Bootstrapping!\n')
fprintf('Total time elapsed --> %.2f\n',a)
fprintf('============================================================\n')
figure(888);plot(WealthBS.')
title(sprintf('50 Monte Carlo runs for Stock ATI using ETF approach (Bootstrapping)'),'fontsize',12)
ylabel('Capital $','fontsize',12)
xlabel('Time (Days)','fontsize',12)
set(gca,'linewidth',1.2)
set(gca,'fontsize',10)
grid on
figure(889);plot(OmegaBS,'linewidth',3)
title(sprintf('Omega Stock ATI using ETF approach with mean of 1.0485 (Bootstrapping)'),'fontsize',12)
ylabel('Omega','fontsize',12)
xlabel('No. of Monte Carlo Runs','fontsize',12)
set(gca,'linewidth',1.2)
set(gca,'fontsize',10)
grid on
end
PlotProfit
function [Sigtmp,wealthtmp1,OmegaRatios] = outSampleTest(ETFData,StockData,StockInd,OptTradingPara)
SSO = OptTradingPara(1);
SSC = OptTradingPara(2);
SBO = OptTradingPara(3);
SBC = OptTradingPara(4);
Sbo = SBO;
Sso = SSO;
Sbc = SBC;
Ssc = SSC;
% Number of Stocks and ETF used
NoOfStock = length(StockData);
NoOfETF = length(ETFData);
%Optmization starts here
NoOfTradingDays = length(StockData(1).Date);
StockPortfolio = 0;
lastTransactionDay = 0; %stores the index of the last day when stock was bought or sold
ETFBetas = zeros(NoOfETF,1); %Define the initial set of betas as Zeros.
wealthtmp1 = [];
Sigtmp = [];
PortfolioReturn = ones(NoOfTradingDays,1);
%Optimzation w.r.t Omega for getting the best set of boundary values for the given stock
Wealth = 1e6;
StockPortfolio = 0;
ETFReturn = 1;
PortfolioReturn = ones(NoOfTradingDays,1);
for i = 61:NoOfTradingDays
IndexReturn(i) = 0;
%Calculate the ETF Return for the current position
for k=1:NoOfETF
IndexReturn(i) = IndexReturn(i)+ ETFData(k).Return(i)*ETFBetas(k);
end
stockReturn = 1;
IndexRet = 1;
stockReturn = stockReturn * (1+StockData(StockInd).Return(i));
IndexRet = IndexRet*(IndexReturn(i)+1);
%Mark to market if a there is an exposure
if(StockPortfolio == 1)
Wealth = Wealth*(1-IndexRet+stockReturn);
elseif(StockPortfolio == -1)
Wealth = Wealth*(1+IndexRet-stockReturn);
end
%This function call need to be MODIFIED according to the interface
[Signal, Betas,ssssssss] = ETFregression(ETFData, StockData(StockInd).Return, i, Sbo, Sso, Sbc, Ssc, StockPortfolio);
if(Signal == 1)
if (StockPortfolio == -1)
StockPortfolio = 0;
%Update PandL for transaction cost
Wealth = Wealth*(1-.0005);
elseif(StockPortfolio == 0)
% Go Long
StockPortfolio = 1;
ETFBetas = Betas;
%Update PandL for transaction cost
Wealth = Wealth*(1-.0005);
end
elseif(Signal == -1)
if(StockPortfolio == 0)
% Steps for Going Short
StockPortfolio = -1;
ETFBetas = Betas;
%Update PandL for transaction cost
Wealth = Wealth*(1-.0005);
elseif(StockPortfolio == 1)
StockPortfolio = 0;
%Update PandL for transaction cost
Wealth = Wealth*(1-.0005);
end
end
wealthtmp1 = [wealthtmp1,Wealth];
Sigtmp = [Sigtmp,Signal];
end
%Portfolio return on each day
PortfolioReturn = wealthtmp1(2:end)./wealthtmp1(1:end-1)-1;
%Get the PandL and Omega for the corresponding strategy
%Omega calculation
iAbove = 0;
iBelow = 0;
iAboveMeanCount = 0;
iBelowMeanCount = 0;
for i=1:size(wealthtmp1,2)-1
if(PortfolioReturn(i) > 0)
iAbove = iAbove + PortfolioReturn(i);
iAboveMeanCount = iAboveMeanCount + 1;
elseif(PortfolioReturn(i) < 0)
iBelow = iBelow - PortfolioReturn(i);
iBelowMeanCount = iBelowMeanCount + 1;
end
end
OmegaRatios = ((iAbove/iAboveMeanCount)*(iAboveMeanCount/(iAboveMeanCount+iBelowMeanCount)))/((iBelow/iBelowMeanCount)*(iBelowMeanCount/(iAboveMeanCount+iBelowMeanCount)));
%Profit and Loss update
PandL = Wealth - 1e6;
function [ETFused,Stocksused] = SampleBootstrap(ETF,Stocks,SampleNo,NoOfStock,NoOfETF)
a = 1;
b = length(Stocks(1).Return);
sampleInd = round(a + (b-a).*rand(SampleNo,1));
for ii = 1:NoOfETF
ETFused(ii).name = ETF(ii).name;
ETFused(ii).Return = ETF(ii).Return(sampleInd);
ETFused(ii).Date = ETF(ii).Date(sampleInd);
end
for ii = 1:NoOfStock
Stocksused(ii).name = Stocks(ii).name;
Stocksused(ii).Return = Stocks(ii).Return(sampleInd);
Stocksused(ii).Date = Stocks(ii).Date(sampleInd);
end