From: Jean-Philip Dumont on
Hi,

I have a structure below that is called "ResultsAll" that contains series depending on the horizon of the a financial product, on the type of clients and on the trend of the market.
Horizon Type of client Trend
ResultsAll : - 1 Month : - K10 : - B1 (T days x1)
- B2 (Tx1)
...
H1
...
S1
- K15
- K20
- K30
- K50
- K75
- 3 Month
- 6 Month
- 12 Month
The same information repeats itself for every horizon and for every type of client.

The code below finds the strike price that is required in order to have a "zero cost collar" for every day, in every series (B1, B2...H1...S1), for every type of clients, for every horizon and depending if the client buys or sell the collar.

i (I) --> identifies if the client buy or sell the strategie
k (Echeances) --> every horizon
l (Cnames) --> every type of client
m (names) --> every series that contains a trend (upward, downward, stable market)
o (days) --> every day in each series
RAnames = fieldnames(ResultsAll); % this is similar to the different horizon.

for i=1:length(I)
for k=1:length(Echeances)
names = fieldnames(ResultsAll.(RAnames{k,1}).Trend);
for l=1:length(Cnames)
for m=1:length(names)
for o=1:length(ResultsAll.(RAnames{k,1}).Trend.(names{m,1}))-...
Echeances(k,1)
St = ResultsAll.(RAnames{k,1}).Trend.(names{m,1})(o,1);
r = ResultsAll.(RAnames{k,1}).TBill_Can.(names{m,1})(o,1);
rf = ResultsAll.(RAnames{k,1}).TBill_US.(names{m,1})(o,1);
Vol = ResultsAll.(RAnames{k,1}).Vol.(names{m,1})(o,1);
if I(1,i)==0
K = St*(1-B);
elseif I(1,i)==1
K = St*(1+B);
end
K0 = St; % starting value of the optimization
Ks.(Inames{1,i}).(Dnames{1,k}).(Cnames{1,l}).(names{m,1})...
(o,1)=fzero(@ZCC,K0,Options,CoutO(l,1)*N,N,r,rf,Vol,...
St,EcheancesFD(k,1)/360,K,I(1,i));
Ks.(Inames{1,i}).(Dnames{1,k}).(Cnames{1,l}).(names{m,1})...
(o,2)=K;
end
end
end
end
end

Running this loop takes me about 6 to 7 minutes which I consider very long. Is there a way to make it more efficient? Is it because I work with structures that make so long or because I find a zero (with fzero.m) to a function about 20 000 times!?

Thank you for your help!

JP
From: Jan Simon on
Dear Jean-Philip,

you can use the profile to find the most time consuming lines:
profile on
<start your program>
profile report

KInd regards, Jan
From: us on
"Jean-Philip Dumont" <jean-philip.dumont(a)hec.ca> wrote in message <i3cgf1$mid$1(a)fred.mathworks.com>...
> Hi,
>
> I have a structure below that is called "ResultsAll" that contains series depending on the horizon of the a financial product, on the type of clients and on the trend of the market.
> Horizon Type of client Trend
> ResultsAll : - 1 Month : - K10 : - B1 (T days x1)
> - B2 (Tx1)
> ...
> H1
> ...
> S1
> - K15
> - K20
> - K30
> - K50
> - K75
> - 3 Month
> - 6 Month
> - 12 Month
> The same information repeats itself for every horizon and for every type of client.
>
> The code below finds the strike price that is required in order to have a "zero cost collar" for every day, in every series (B1, B2...H1...S1), for every type of clients, for every horizon and depending if the client buys or sell the collar.
>
> i (I) --> identifies if the client buy or sell the strategie
> k (Echeances) --> every horizon
> l (Cnames) --> every type of client
> m (names) --> every series that contains a trend (upward, downward, stable market)
> o (days) --> every day in each series
> RAnames = fieldnames(ResultsAll); % this is similar to the different horizon.
>
> for i=1:length(I)
> for k=1:length(Echeances)
> names = fieldnames(ResultsAll.(RAnames{k,1}).Trend);
> for l=1:length(Cnames)
> for m=1:length(names)
> for o=1:length(ResultsAll.(RAnames{k,1}).Trend.(names{m,1}))-...
> Echeances(k,1)
> St = ResultsAll.(RAnames{k,1}).Trend.(names{m,1})(o,1);
> r = ResultsAll.(RAnames{k,1}).TBill_Can.(names{m,1})(o,1);
> rf = ResultsAll.(RAnames{k,1}).TBill_US.(names{m,1})(o,1);
> Vol = ResultsAll.(RAnames{k,1}).Vol.(names{m,1})(o,1);
> if I(1,i)==0
> K = St*(1-B);
> elseif I(1,i)==1
> K = St*(1+B);
> end
> K0 = St; % starting value of the optimization
> Ks.(Inames{1,i}).(Dnames{1,k}).(Cnames{1,l}).(names{m,1})...
> (o,1)=fzero(@ZCC,K0,Options,CoutO(l,1)*N,N,r,rf,Vol,...
> St,EcheancesFD(k,1)/360,K,I(1,i));
> Ks.(Inames{1,i}).(Dnames{1,k}).(Cnames{1,l}).(names{m,1})...
> (o,2)=K;
> end
> end
> end
> end
> end
>
> Running this loop takes me about 6 to 7 minutes which I consider very long. Is there a way to make it more efficient? Is it because I work with structures that make so long or because I find a zero (with fzero.m) to a function about 20 000 times!?
>
> Thank you for your help!
>
> JP

a hint:
- first, find the hot spots...

help profile;

us
From: Jean-Philip Dumont on
"us " <us(a)neurol.unizh.ch> wrote in message <i3cjo1$kln$1(a)fred.mathworks.com>...
> "Jean-Philip Dumont" <jean-philip.dumont(a)hec.ca> wrote in message <i3cgf1$mid$1(a)fred.mathworks.com>...
> > Hi,
> >
> > I have a structure below that is called "ResultsAll" that contains series depending on the horizon of the a financial product, on the type of clients and on the trend of the market.
> > Horizon Type of client Trend
> > ResultsAll : - 1 Month : - K10 : - B1 (T days x1)
> > - B2 (Tx1)
> > ...
> > H1
> > ...
> > S1
> > - K15
> > - K20
> > - K30
> > - K50
> > - K75
> > - 3 Month
> > - 6 Month
> > - 12 Month
> > The same information repeats itself for every horizon and for every type of client.
> >
> > The code below finds the strike price that is required in order to have a "zero cost collar" for every day, in every series (B1, B2...H1...S1), for every type of clients, for every horizon and depending if the client buys or sell the collar.
> >
> > i (I) --> identifies if the client buy or sell the strategie
> > k (Echeances) --> every horizon
> > l (Cnames) --> every type of client
> > m (names) --> every series that contains a trend (upward, downward, stable market)
> > o (days) --> every day in each series
> > RAnames = fieldnames(ResultsAll); % this is similar to the different horizon.
> >
> > for i=1:length(I)
> > for k=1:length(Echeances)
> > names = fieldnames(ResultsAll.(RAnames{k,1}).Trend);
> > for l=1:length(Cnames)
> > for m=1:length(names)
> > for o=1:length(ResultsAll.(RAnames{k,1}).Trend.(names{m,1}))-...
> > Echeances(k,1)
> > St = ResultsAll.(RAnames{k,1}).Trend.(names{m,1})(o,1);
> > r = ResultsAll.(RAnames{k,1}).TBill_Can.(names{m,1})(o,1);
> > rf = ResultsAll.(RAnames{k,1}).TBill_US.(names{m,1})(o,1);
> > Vol = ResultsAll.(RAnames{k,1}).Vol.(names{m,1})(o,1);
> > if I(1,i)==0
> > K = St*(1-B);
> > elseif I(1,i)==1
> > K = St*(1+B);
> > end
> > K0 = St; % starting value of the optimization
> > Ks.(Inames{1,i}).(Dnames{1,k}).(Cnames{1,l}).(names{m,1})...
> > (o,1)=fzero(@ZCC,K0,Options,CoutO(l,1)*N,N,r,rf,Vol,...
> > St,EcheancesFD(k,1)/360,K,I(1,i));
> > Ks.(Inames{1,i}).(Dnames{1,k}).(Cnames{1,l}).(names{m,1})...
> > (o,2)=K;
> > end
> > end
> > end
> > end
> > end
> >
> > Running this loop takes me about 6 to 7 minutes which I consider very long. Is there a way to make it more efficient? Is it because I work with structures that make so long or because I find a zero (with fzero.m) to a function about 20 000 times!?
> >
> > Thank you for your help!
> >
> > JP
>
> a hint:
> - first, find the hot spots...
>
> help profile;
>
> us

I ran the profiler and here are the time consuming functions :

fzero comes first with a time of 6 minutes (165 792 calls)
ZCC comes second with a time of 4.6 minutes (1 745 713 calls)
normcdf comes third with a time of 3.7 minutes (7 314 436 calls)
erfc comes fourth with 1.5 minutes (7 314 436 calls)
optimget comes fifth with 30 seconds (828 960 calls)
erfcore (MEX-function) comes sixth with 30 seconds (7 314 436 calls)

After that it becomes negligeable.

Like I said before, I have a complexe structure so it is evaluating a strategy a lot of time (because I have several scenarios).

Is there a way to make it better and faster or because of the complexity of my work it has to take that long?

Thanks again!

JP
From: Jan Simon on
Dear Jean-Philip,

> I ran the profiler and here are the time consuming functions :
>
> fzero comes first with a time of 6 minutes (165 792 calls)
> ZCC comes second with a time of 4.6 minutes (1 745 713 calls)
> normcdf comes third with a time of 3.7 minutes (7 314 436 calls)
> erfc comes fourth with 1.5 minutes (7 314 436 calls)
> optimget comes fifth with 30 seconds (828 960 calls)
> erfcore (MEX-function) comes sixth with 30 seconds (7 314 436 calls)
>
> After that it becomes negligeable.
>
> Like I said before, I have a complexe structure so it is evaluating a strategy a lot of time (because I have several scenarios).

After you have used the profiler, it is worth to read the results. They tell you, that the most time is spent in FZERO, ZCC, normcdf and erfc.
As you can see by the negligible other parts, the complicated structs are not the problem!

It is a promissing strategy to accelerate the most time-consuming functions, so you should concentrate on ZCC, while FZERO and NORMCDF should not be touched, because they are built-in function. But if you call NORMCDF with a well defined set of inputs, you could try to create a local copy (with modified name) and omit the error checking parts.

It is surprising that ERFC takes 1.5 min, while the actual calulations ind erfcore need 30 seconds only. The overhead of ERFC looks really small. Is it possible to call ERFCORE directly?

Kind regards, Jan