For loop with moving window

Hi
I want to create a for-loop that calculates the weights of portfolios using a moving window for the period I am investigating. The moving window should move one day at a time and there are 1000 days in the window.
For example, compute the optimal weights on day1001 based on observations for period 1-1000days. Then you move on to day 1002, and re-calculate the weights, based on observations for period 2-1001days, etc.
I have a matrix of returns (Rets) that is 3740x6. The first column has the dates and the rest of the columns have daily returns for five different asset classes.
Thanks!

Antworten (4)

Image Analyst
Image Analyst am 31 Jul. 2014

1 Stimme

Simply use conv()
kernel = [zeros(1,999), ones(1,1000)]; % Look backward 1000 elements.
output = conv(observations, kernel, 'valid'); % Get sliding means

5 Kommentare

Ahmet Cecen
Ahmet Cecen am 31 Jul. 2014
This is a very optimized answer. However you won't be able to appreciate what you are doing of you don't have a signal processing background. I am assuming it is not the case here.
civs
civs am 31 Jul. 2014
I am not sure how to use conv(). I have never used it. But let me try...
Why is kernel composed of zeros and ones? BTW, Rets is a 3740 x 6 matrix where the first column has the dates and the rest are the returns of 5 different asset classes.
Date Equity FI Hedge Funds Currency Libor
.
.
. etc... (until row 3740)
In that case wouldn't the kernel be? kernel= [zeros(999,1), ones(1,1000);
civs
civs am 31 Jul. 2014
I am reading about conv() .. but I don't really understand it ...
Evan
Evan am 31 Jul. 2014
Bearbeitet: Evan am 31 Jul. 2014
Googling "convolution" may help you to get an overall idea of the operation before getting into the MATLAB implementation of it. You might find the wikipedia entry helpful, although I often find that I drown in notation when trying to read through mathematics wiki articles.
Basically, conv() will slide the kernel over the vector, progressing one element at a time, and multiply then sum corresponding values that fall within the window. It "pads" the array with zeros in order to start with the first element. Here's an example:
A = [1 2 3 4 5];
B = [1 1];
conv(A,B)
ans =
1 3 5 7 9 5
So here's the progression:
[ 0 1 2 3 4 5 0]
[ 1 1 ]
1*0 + 1*1 = 1;
__________________
[ 0 1 2 3 4 5 0 ]
[ 1 1 ]
1*1 + 1*2 = 3
__________________
[ 0 1 2 3 4 5 0 ]
[ 1 1 ]
1*2 + 1*3 = 5
__________________
[ 0 1 2 3 4 5 0]
[ 1 1 ]
1*3 + 1*4 = 7
__________________
[ 0 1 2 3 4 5 0]
[ 1 1 ]
1*4 + 1*5 = 9
__________________
[ 0 1 2 3 4 5 0]
[ 1 1 ]
1*5 + 1*0 = 5
Image Analyst
Image Analyst am 31 Jul. 2014
Bearbeitet: Image Analyst am 31 Jul. 2014
Convolution basically gives you a weighted sum in a sliding window. It would give you the average value (price?) of your signal over the past 1000 days. I'm a scientist, not a financial person, so perhaps you don't want that - I don't know. If you do want a weighted sum in a sliding window (like the 20 day or 50 day moving stock price average) then convolution is for you, though there may be some functions in the Financial Toolbox that are better suited, like with more options and using the terminology financial people are familiar with.
There is also a conv2() function that deals with 2D arrays. If you just wanted to sum up going down columns, then the kernel would be a column vector. If you wanted to average across columns, then the kernel would be a row vector.

Melden Sie sich an, um zu kommentieren.

Ahmet Cecen
Ahmet Cecen am 30 Jul. 2014
Bearbeitet: Ahmet Cecen am 30 Jul. 2014

0 Stimmen

If I understand you correctly, you have an indexing problem. Try an indexing scheme like this:
for i=1:N
Weights(i)=function(Rets(i:(i+1000),2));
end

20 Kommentare

civs
civs am 31 Jul. 2014
I don't completely understand this.
Why is there a 2 there? I need to start from day 1002 because I already have the weights for the day 1001 which are weights calculated with returns from day 1 to day 1000. By the way there are 4 portfolios I need to calculate the weights of. The weights are coming from 2 different functions: mean_var_portopt2 and mean_ES_portopt1
This is what I have:
% Reoptimization of portfolio weights using moving-window time frame
Rets_reopt=data(:,[2,3,4,5,6]);
n= length(Rets);
start = 1
for i= 1:n
for j= start+1:1000:n
mu_p= 0.01;
%Determine weights of global min-var portfolio
wmin_var= mean_var_portopt2(-10, Rets_reopt);
%Determine weights of min-variance efficient portfolio given mu_p
[W_var,vars]= mean_var_portopt2(mu_p, Rets_reopt);
%Determine the weight of global-minimum ES portfolio
[wmin_ES, ES]= mean_ES_portopt1(-10, Rets_reopt, Beta);
%Determine the weights of min-ES efficient portfolio given mu_p
[W_ES, ES]= mean_ES_portopt1(mu_p, Rets_reopt, Beta);
end
end
Ahmet Cecen
Ahmet Cecen am 31 Jul. 2014
Bearbeitet: Ahmet Cecen am 31 Jul. 2014
I am still unclear on how your code actually works, that is why I gave you a moving window indexing. I now understand you also want it to be recursive such that the value calculated in the previous loop is included in the current loop. In that case:
for i=1:N
Weights(i+1000)=function(Weights(i:(i+999),2)); %Starts from 1001
end
2 being the portfolio # so change that as you like. While function is an arbitrary function you are using to calculate the weights. You can also initialize (pre-allocate with zeros) the Weights matrix to gain some speed.
civs
civs am 31 Jul. 2014
Yes, the set of weights calculated in the first loop should be used in the next loop as the window of dates keeps moving. So the weights calculated in day 1001 (which used the data from day1-1000) should be used for the calculation of weights at day 1002 (will use data from day2-1001). I attached the entire code so you can see what I mean.
I still don't understand that 2 there, why do I need the number of the portfolio?. For example for the first portfolio in the loop the code is:
% Reoptimization of portfolio weights using moving-window time frame
Rets=data(:,[2,3,4,5,6]);
n= length(Rets);
for i= 1:n
mu_p= 0.01;
%Determine weights of global min-var portfolio
wmin_var(i)= mean_var_portopt2(-10, Rets(i:(i+999),2));
end
Is this what you mean?
I think my lack of background in your particular analysis prevents me from understanding what you are trying to do. I will give it one final shot. So here I think for 1 of your portfolio values:
n= length(Rets);
for day=1001:n
wmin_var = mean_var_portopt2(-10, Rets(i-1000,i-1));
port_glo_min_var(day)= Rets(i-1000,i-1) * w_min_var;
end
So for each day, calculate wmin_var using the previous 1000 days. Then use the new wmin_var to get the portfolio return. w_min_var is overwritten each time and is not stored. You get the port_glo_min_var for everyday starting day 1001.
civs
civs am 31 Jul. 2014
Hi Ahmet, in the code you just wrote what is i? is it the same as defined before? i.e. i=1:n?
My bad, i is "day".
for i=1001:n
wmin_var = mean_var_portopt2(-10, Rets(i-1000,i-1));
port_glo_min_var(day)= Rets(i-1000,i-1) * w_min_var;
end
civs
civs am 31 Jul. 2014
Thanks for the clarification! Why is Rets(i-1000, i-1)? I understand i-1000, but why i-1? In the Rets matrix there is only 6 columns, the first column is the date, the rest are asset returns of each of the 5 asset classes.
civs
civs am 31 Jul. 2014
Here is the file of Rets matrix.
Because I have been sleep deprived for too long. Those commas are supposed to be colons. And then another colon on the column side to pick all columns. And also you defined Rets earlier as Rets=data(:,[2,3,4,5,6]); already so you only have 5 columns by the time you get to this for loop.
for i=1001:n
wmin_var = mean_var_portopt2(-10, Rets(i-1000:i-1,:));
port_glo_min_var(day)= Rets(i-1000:i-1,:) * w_min_var;
end
civs
civs am 31 Jul. 2014
Oooohhh.. I see!!! yeah that makes sense!!
civs
civs am 31 Jul. 2014
Just one last question. You wrote: "So for each day, calculate wmin_var using the previous 1000 days. Then use the new wmin_var to get the portfolio return. w_min_var is overwritten each time and is not stored. You get the port_glo_min_var for everyday starting day 1001."
Is there a way to store all the w_min_var that are generated so that I multiply these daily weights by its corresponding row of daily returns?
For example: on day1001 I calculate the optimal weights for the period from day1-1000 then these weights are multiplied by returns on row corresponding to day1001 in the matrix Rets.
Ahmet Cecen
Ahmet Cecen am 1 Aug. 2014
Bearbeitet: Ahmet Cecen am 1 Aug. 2014
wmin_var=cell(N,1) %you are going to have to figure out that N.
for i=1001:n
wmin_var{i-1000}= mean_var_portopt2(-10, Rets(i-1000:i-1,:));
port_glo_min_var(day)= Rets(i-1000:i-1,:) * w_min_var{i-1000};
end
It is wmin_var{i-1000} so that you start storing from 1. So wmin_var{1} will be your day 1001. wmin_var{N} will be your last day.
civs
civs am 1 Aug. 2014
Aah, ok I see. Just to confirm the port_glo_min_var(day) is actually port_glo_min_var(i), correct?
for wmin_var= cell(N,1) ... I guess the results are stored here, so N will be the rows of the stored answer?
Ahmet Cecen
Ahmet Cecen am 1 Aug. 2014
day=i that is true. N is the number of days you want to calculate the port_glo_min_var for. Since you need 1000 days of data to calculate it, I am assuming your N will be the number of days you have data for - 1000.
civs
civs am 5 Aug. 2014
Thank you for your answer. Based on this I think N is 2740 (I have 3740 rows i.e. dates). I attached the code here. I am now saving the weights but for example I could have also chosen to save the portfolio returns directly right? in that case the code would be:
port_glo_min_var=cell(2740,1)
for i=1001:n
wmin_var{i-1000}= mean_var_portopt2(-10, Rets(i-1000:i-1,:));
port_glo_min_var(i)= Rets(i-1000:i-1,:) * w_min_var{i-1000};
end
Am I correct in saying this?
civs
civs am 5 Aug. 2014
Oops here is the code! (attached)
civs
civs am 5 Aug. 2014
Oh wait... when I run the code I get this error:
Conversion to cell from double is not possible.
Error in Backtesting (line 37) port_glo_min_var(i)= Rets(i-1000:i-1,:) * wmin_var{i-1000};
Image Analyst
Image Analyst am 5 Aug. 2014
Why are you using cells instead of just normal numerical arrays?
civs
civs am 5 Aug. 2014
To store all the results from the loop (weights)... I tried changing this to portfolio returns and it doesn't work. Can I just store it in a vector?
civs
civs am 5 Aug. 2014
When I store the weights instead of the portfolio returns this is the error I get:
In an assignment A(I) = B, the number of elements in B and I must be the same.
Error in Backtesting (line 37) port_glo_min_var(i)= Rets(i-1000:i-1,:) * wmin_var{i-1000};

Melden Sie sich an, um zu kommentieren.

Arijit Ghosh
Arijit Ghosh am 9 Mär. 2017

0 Stimmen

Hello I need to design a sliding window of time t=5 sec. to slide all over the signal without overlap and thereby perform CWT from each window. Can anyone help please..
Alejandra Pena-Ordieres
Alejandra Pena-Ordieres am 29 Jul. 2024

0 Stimmen

Hello,
You might want to consider using the backtesting workflow available in the Financial Toolbox, Backtest Investment Strategies Using Financial Toolbox. In your case, you'd need to convert your data into a timetable and define your optimization strategy as a backtestStrategy with RebalanceFrequency=1 and a LookbackWindow = [1000 1000].

Kategorien

Mehr zu Portfolio Optimization and Asset Allocation finden Sie in Hilfe-Center und File Exchange

Gefragt:

am 30 Jul. 2014

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by