How to find Up-Down Volume Ratio

Hi all,

I want to find Up-Down Volume ratio for last 50 days. The ratio is derived from the past 50 trading days by dividing the total volume on up days by the total volume on down days.

So far I tried to code something like this which is improper syntax as Volume is not a function:

upvol = Sum( V(C>Ref(C,-1), 50);
downvol = Sum( V(C<Ref(C,-1), 50);
udratio = upvol/downvol;

Pl help.
Thanks in advance.

You have to use code tags when inserting code. Please follow forum rules.


Just use

up = ROC(C,1)>0;
dn = NOT up;
upvol = Sum(up*V,50);
downvol = Sum(dn*V,50);
udratio = upvol/downvol;
4 Likes

Thank you very much for quick reply. It solves my problem.

Would keep in mind next time to follow rules.

So you have solved it now? Where is your post having done so?

Thanks for this conversation. As an addition or idea, here is my solution how I solved that:

I'm not sure if the function with Sum is appropriate in this case. But would also not say that my solution is better. I know there is a big mistake in it (you should not assume no. of bars in "barcount"). But it works for me and has an advantage that it also works on IPO's if there are not already 50 bars available. I also define upday/downday slightly different.

upday = O < C;
downday = O > C;
upvol = 0;
downvol = 0;

for ( i = Max(0, BarCount-50); i < BarCount; i++ )
{
	if(upday[i]) {
		upvol += V;
	} else if (downday[i]) {
		downvol += V;
	}
	
	udRatio = upvol / downvol;
}

Cheers, Patrick

Is this some kind of troll attempt of the month?
Why is the Sum function in post #2 not supposed to be appropriate in case of post #1?
Are you kidding me?

Here is some enlightenment to you... your code is complete applesauce. It is one of the most awful things I have seen in months.

You should rather read here instead of coming up with "genius" ideas:

BTW, that code is doing same thing as following one just without pointless barcount loop:

upday = O < C;
downday = O > C;
upvol = LastValue(Sum(upday,50))*V;
downvol = LastValue(Sum(downday,50))*V;
udratio = upvol/downvol;

Do even understand what it is doing?
I'm telling you... what it does is that it simply multiplies a single SAME number with ENTIRE Volume array. What kind of sense is that one supposed to make?

Instead of playing Mr. Smart who (falsely) thinks that he has found out something being extremely awesome (while it is complete opposite of it) and believing that code of post #2 is not appropriate you should rather study that code of post #2 carefully in what it is actually doing.

2 Likes

Obviously a wrong click. Corrected.

Wow.... I think I put myself wrong or used the wrong words. I'm sorry, english is not my mother tongue. Otherwise sorry for sharing.

I did not pretend to be a genius! The word "appropriate" was meant in relation to the idea of IBD and not of how you solved it.

As mentioned, I know my solution is not optimal. I tried a different approach similar to your last code. I only switched to the cumbersome for-loop, because I received an "inf" amount for IPO stocks.

I would appreciate it if we could continue to discuss creatively and politely. I will also pay more attention to my choice of words.

Thanks for your post but the code written by @fxshrat is tidy and elegant. It just multiplies the volume array with boolean condition array and that solves it.

For IPO stocks, I added few lines. Pls check if that serves the purpose.

if( BarCount < 50 )
    period = BarCount;
else
    period = 50;

up = ROC(C,1)>0;
dn = NOT up;
upvol = Sum(up*V,period);
downvol = Sum(dn*V,period);
udratio = upvol/downvol;

Absolutely, the way @fxshrat did, is a much more elegant solution!

The thing about what an update is "O < C" or "ROC(C, 1)>0" is more of a philosophical question.

I like your simple approach with "if" and have adapted mine accordingly.
To get the latest bar, just use "barcount -1". With this change it should also fit for IPO's.

if( BarCount-1 < 50 )
    period = BarCount-1;
else
    period = 50;

Thanks for your input. I am learning to use Barcount now. :slightly_smiling_face:

1 Like

Your loop code is not a solution (neither is my non loop response to your loop version).
A solution is something that makes sense and works (everywhere) and is optimal.

You still don't seem to understand what your loop (and my non-loop code response) are doing.

Both just add up same volume element n-times for entire volume array. n -> up/down occurrences at last bar. (Note: there may occur small differences between loop and non loop code because of floating point rounding).

Anyway here is picture. Maybe then you understand that it makes no sense and is off topic to 1st post in addition.
14


If you got inf then denominator was zero because of zero down bar occurrences.
So to prevent inf we may use SafeDivide() function of AB 6.35, for example.


You do not need if-else statement.

If you have less bars than set period then:
period = Min(50,BarCount-1);

or you may use

period = Min(50,BarIndex()); as once posted by @Tomasz (note: BarIndex() is different to BarCount).

/// @link https://forum.amibroker.com/t/how-to-find-up-down-volume-ratio/22470/12
Version(6.35);// because of SafeDivide function
period = Min(50,BarCount-1);
up = ROC(C,1)>0;
dn = NOT up;
upvol = Sum(up*V,period);
downvol = Sum(dn*V,period);
udratio = SafeDivide(upvol,downvol);
Plot(udratio, "udratio", colorRed);
1 Like

Thanks for making code further neat and tidy and now I got your point it's always better to use Safedivide to prevent Inf.

1 Like

I see the problem now in my wording. I should have used "approach" instead of "solution".

But thanks for your input that helps to understand and I also wasn't familiar with safedivide yet. :+1:

1 Like

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.