Failed to create signal form successive values

1 view (last 30 days)
hi,
I'm trying to create a signal of 1 and -1 with a for loop but getting an error of "Subscript indices must either be real positive integers or logicals." My code is like this
for i=1:length(data)
if (MACD(i-1)>0) && (MACD(i)<0)
s(i,:)=-1; % Sell (short)
end
if (MACD(i-1)<0) && (MACD(i)>0)
s(i,:)=1; % buy (long)
end
end
Could you tell me where is the mistake please.
  1 Comment
aggelos
aggelos on 27 Dec 2016
Hi KSVV,
I'm expecting a vector with zeros when there is no zero cross, with ones when MACD crosses zero from below (from negative to positive) and with minus ones when MACD crosses zero from above (from positive to negative).
Thanks for your help

Sign in to comment.

Accepted Answer

Star Strider
Star Strider on 27 Dec 2016
You can do it without the loop:
zci = @(v) find(v(:).*circshift(v(:), [-1 0]) <= 0); % Returns Approximate Zero-Crossing Indices Of Argument Vector
MACD = rand(1, 25)-0.5; % Create ‘MACD’ Data
zx = zci(MACD); % Find Zero-Crossings
zx = zx(1:end-1); % Eliminate Wrap-Around ‘End Effect’
sx = sign(MACD(zx+1)); % Set Signs Of Zero-Crossings
s = zeros(size(MACD)); % Define ‘s’
s(zx+1) = sx; % Insert Sign Vector Into ‘s’
My code uses the ‘zci’ anonymous function to return the zero-crossing indices of your ‘MACD’ vector, then assigns the sign by looking at the next value in the vector in the ‘sx’ vector. It then creates ‘s’ and assigns ‘sx’ to the appropriate positions in it to create the desired output for ‘s’.
  6 Comments
Damo Nair
Damo Nair on 29 Dec 2016
Works well. I need to go over the logic carefully.
Thanks Damo.
Star Strider
Star Strider on 29 Dec 2016
My pleasure.
The logic is actually straightforward. The ‘zci’ utility function circularly shifts the column vector ‘v(:)’ up by one position, then multiplies it by itself. The result is a negative value at the approximate index where a zero-crossing occurs, and positive values everywhere else, because real values of like signs multiplied together are always positive, so a zero-crossing will always be a negative value. (Complex values behave differently and my simple function will not work for them.) Beyond that, the code assigns the signs as you want them, and shifts them to be in the appropriate places.
The ‘end-effect’ results when the end value of the vector is of one sign and the beginning value is another. Because of the circular shifting, this is not an actual zero-crossing, although it will initially be evaluated as one. The if block logic detects that condition and eliminates the ‘end-effect’ false zero-crossing.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!