Saving multiple output in one variable from loop

Dear all,
could somebody please help me with my following problem(s). I'm currently coding a moving average crossover trading rule. This rule needs to generate a buy signal (value "1") when the fast moving average is above the slow moving average and sell signals (value "-1") vice versa. Where a slow moving average (variable "n" days) is calculated over a greater number of days than the fast moving average (variable "m" days).
Question: How can I store all those different fast-slow combinations of "n" and "m" in one variable (in this case the "tr_ma_cross" variable)? So I would like that each fast-slow combination is written in a new column in the same variable.
The code at this moment:
%Moving average crossovers
for n=[2 5 10 15 20 25 30 40 50 75 100 125 150 200 250];
for m=[2 5 10 15 20 25 30 40 50 75 100 125 150 200 250];
if n==m; continue, end
MA_slow=tsmovavg(price,'s',n,1);
MA_fast=tsmovavg(price,'s',m,1);
for k=1:31225;
if MA_fast(k,1)>MA_slow(k,1)
tr_ma_cross(k,:)=1; %Buy
elseif MA_fast(k,1)<MA_slow(k,1)
tr_ma_cross(k,:)=-1; %Sell
else
tr_ma_cross(k,:)=0; %Neutral
end
end
end
end
Additional question: I also would like the code to only put a buy ("1") or sell ("-1") signal at the positive or negative move through the "intersection" of the fast and slow moving average (so when the fast moving average is the first time above the slow moving average put a "1" and then just zeros till the opposite happens, the slow moving average is above the fast moving average than I want it to put a "-1").
Thanks and have a nice day,
Wildman

3 件のコメント

dpb
dpb 2015 年 6 月 21 日
You doing this in real time or simply analyzing historical data?
Wildman
Wildman 2015 年 6 月 29 日
Sorry for my late response. Unfortunately I didn't saw your comment/got no e-mail notification.
I'm doing this on historical data.
dpb
dpb 2015 年 6 月 30 日
OK, in that case you have all the data already so can vectorize at least pieces; maybe all. If you were doing this in real time where didn't get the last observation until did the computation, have to wait...

サインインしてコメントする。

 採用された回答

dpb
dpb 2015 年 6 月 30 日
編集済み: dpb 2015 年 7 月 1 日

0 投票

OK, as per the comment, firstly, you're computing the n moving average m*n times...move it out of the loop over which it's invariant--
%Moving average crossovers
for n=[2 5 10 15 20 25 30 40 50 75 100 125 150 200 250];
MA_slow=tsmovavg(price,'s',n,1);
for m=[2 5 10 15 20 25 30 40 50 75 100 125 150 200 250];
if n==m; continue, end
MA_fast=tsmovavg(price,'s',m,1);
Then, there's no point in using a loop to do the computation over the two vectors; use a logical comparison instead--
tr_ma_cross=sign(MA_fast-MA_slow);
end
end
It also appears this should be symmetric, shouldn't it? If so, then F(n,m)==F(m,n) so could run the inner loop only over m>n instead of all m for every n.
I've got a meeting in a few minutes so don't have time to try to finish any further cleanup at the moment but see if that doesn't help and get back on the further clarification and I'll try to get back again later today/evening also.
ADDENDUM
Well, after fighting an unknown bug bite that "swoll up" my forearm about 2X its normal size for a couple of days, it's now improved to the point I can type again so--continuing on
To store the results of vector tr_ma_cross, simply use a cell array and a separate counter variable. You need a cell array since owing to the moving average (I presume) the length returned is shorter than the input vector by the number of elements averaged. Otherwise you would need to offset the starting point and fill with NaN say, to make a square array.
Prior to the loop over n
k=0; % initialize counter
then replace the computation with
k=k+1; % increment the counter
tr_ma_cross(k)={sign(MA_fast-MA_slow)}; % store as cell
For the last question regarding only saving the transition points, diff is your friend
cross=[0 diff(sign(MA_fast-MA_slow))]; % compute diff of signal
ix=abs(cross==2);
cross(ix)=(ix)/2; % scale transitions to +/-1
tr_ma_cross(k)=cross; % store as cell
NB: Can't just divide by 2 as that would scale any 0-1 transitions to 0.5.

9 件のコメント

Wildman
Wildman 2015 年 7 月 2 日
Firstly many thanks for your help, I will take a extensive look at this tomorrow right away! Unfortunately busy with work at the moment...
Good luck with your arm man! Their are some nasty bugs around...
dpb
dpb 2015 年 7 月 2 日
Thanks...a steroid shot Tuesday AM really helped and I even have knuckles on the back of that hand this AM again!!! :) Think by tomorrow it'll all be a past memory. I still have no klew what it might have been; still no sign whatsoever of a location altho I do know where the initial stinging sensation was located on the back of the wrist area...
Anyway, back on subject--one last comment; the last step of using diff to find the crossings is the reason I asked initially if you were doing this in real time or on historical data. If it's on an observation basis, then the full vector wouldn't be available and a comparison by element is needed whereas if it is past data one can make use of the Matlab vectorization as above.
Wildman
Wildman 2015 年 7 月 3 日
Good to hear it is going better with your arm!
Again, many thanks for all your efforts! You helped me a lot with cleaning up/improving the code.
Indeed moving the "n moving averages part" out of the loop and using a logical comparison is much smarter! Also thanks to you I finally understand how I can save multiple vectors in one variable (and do calculation with them afterwards).
------------------------------------------
It also appears this should be symmetric, shouldn't it? If so, then F(n,m)==F(m,n) so could run the inner loop only over m>n instead of all m for every n.
------------------------------------------
Indeed, I need to get all unique combinations of n with m (where n>m). So in the end I need to get 105 vectors in the cell array. Thanks for pointing me on that, I fixed it.
At the moment I got this code:
%Moving average crossovers
k=0; % initialize counter
for n=[2 5 10 15 20 25 30 40 50 75 100 125 150 200 250];
MA_slow=tsmovavg(price,'s',n,1);
for m=[2 5 10 15 20 25 30 40 50 75 100 125 150 200 250];
if n<=m; continue, end
MA_fast=tsmovavg(price,'s',m,1);
k=k+1; % increment the counter
cross=[0 diff(sign(MA_fast-MA_slow))]; % compute diff of signal
ix=abs(cross==2);
cross(ix)=(ix)/2; % scale transitions to +/-1
tr_ma_cross(k)=cross; % store as cell
end
end
However I get a error when running the diff line:
------------------------------------------
Error using horzcat Dimensions of matrices being concatenated are not consistent.
------------------------------------------
I can't figure out what this error exactly means/how to solve this? Also it isn't yet clear for me what the following does:
ix=abs(cross==2);
It returns the absolute (the non-negative value) when cross is equal to "2", but the number 2 is already non-negative? But I think I'm completely on the wrong thinking path?
If I replace the last step of using "diff" with:
tr_ma_cross(k)={sign(MA_fast-MA_slow)}; % store as cell
Everything works fine!
Have a nice sunny weekend!
dpb
dpb 2015 年 7 月 3 日
編集済み: dpb 2015 年 7 月 3 日
"ix=abs(cross==2);"
Typo (misplaced closing parens)...it's intended as
ix=abs(cross)==2;
which is the logical address of the +/-1 transitions of either direction.
The "horzcat" error indicates probably I made an erroneous assumption on a storage direction and one is a column and another a row vector. Dinner is ready at the moment so I'll have to come and look a little more later if you can't uncover it yourself with a hint...
ADDENDUM
Indeed, in looking back to refresh memory I did assume the MA_xxx vectors were row vectors; if they are are columns then use
cross=[0; diff(sign(MA_fast-MA_slow))]; % compute diff of signal
instead. Again, after that to retain the transition locations only as nonzero, use the logical test to find the +/-2 locations that result from the diff where there's a transition that's a flip but not where there was simply a change from no action to an action that is a difference of only +/-1 already. This assumes, of course, that it is indeed possible for there to be a change from +/-1 to -/+1 in a single step; if it is such that there's only ever a change that includes 0 between changing signs then the case will never occur.
dpb
dpb 2015 年 7 月 3 日
%Moving average crossovers
k=0; % initialize counter
for n=[2 5 10 15 20 25 30 40 50 75 100 125 150 200 250];
MA_slow=tsmovavg(price,'s',n,1);
for m=[2 5 10 15 20 25 30 40 50 75 100 125 150 200 250];
if n<=m; continue, end
...
This is simply stylistic choice; to me it's simpler as
NM=[2 5 10 15 20 25 30 40 50 75 100 125 150 200 250];
k=0; % initialize counter
for n=1:length(NM)
MA_slow=tsmovavg(price,'s',NM(n),1);
for m=n+1:length(NM)
...
It substitutes an array reference to the value in place of the iterated array but has an explicit looping range in place of the repeated logical test.
Not sure if it could be seen if there's really any performance difference at all for such a small sample size...
Wildman
Wildman 2015 年 7 月 4 日
Thanks! Indeed they are column vectors, my bad.
cross=[0; diff(sign(MA_fast-MA_slow))]; % compute diff of signal
ix=abs(cross)==2;
cross(ix)=(ix)/2; % scale transitions to +/-1
tr_ma_cross(k)=cross; % store as cell
As you mentioned early, "can't just divide by 2 as that would scale any 0-1 transitions to 0.5" . If I run that code, I get the error: "In an assignment A(I) = B, the number of elements in B and I must be the same. Shouldn't the last part be:
cross(ix)=cross(ix)/2; % scale transitions to +/-1
tr_ma_cross{k}=cross; % store as cell
At the moment it seems like the code is working with this small change(?). [Of course I'm going to double check this "manually", to be sure the code does what it should do.]
The stylistic suggestion is indeed better (and indeed maybe even faster). But at the moment I prefer the old notation which is easier to understand for me (due to my inexperience with Matlab) and to change later on (among others: I will add a time delay filter and a number of days a position has to be hold condition - to avoid extensive transactions costs).
dpb
dpb 2015 年 7 月 4 日
OK; wasn't sure about which transitions were/were not possible.
Indeed, you're correct on the latter; I forgot to write to store the cell syntax even though wrote the comment. It's the same end result; I tend to write the index as (k) and the RHS as {RHS} to force the cell storage; I just forgotted the curlies this time, sorry.
Wildman
Wildman 2015 年 7 月 5 日
No problem! Indeed writing the RHS as {RHS} gives the same results (I'm using that now instead of the "{k}").
Thanks for all your help! I can now proceed with my project by adding more conditions to this moving average trading rule and even coding some other trading rules. Due to my inexperience with Matlab that will be a harsh task, but because of you the basis is their!
Have a great day!
Wildman
Wildman 2015 年 8 月 20 日
Follow up on this topic (for the interested readers):
If somebody has some suggestions to the "adding filter" problems described in the above forum post it would be much appreciated!

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

ヘルプ センター および File ExchangeMathematics についてさらに検索

タグ

タグが未入力です。

質問済み:

2015 年 6 月 21 日

コメント済み:

2015 年 8 月 20 日

Community Treasure Hunt

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

Start Hunting!

Translated by