View Full Version : Three New Variations of the BuySellVolume Indicator
There were a couple of recent requests for volume displays, and here are three new variations of the BuySellVolume indicator.
(Note these do not work for 6.0 -- For 6.5 only.)
grd974
12-29-2007, 05:22 AM
I've been trying to code some variations of the same indicator and spent a lot of hours, got plenty of errors for eventually a poor result : when I replay market data backward the plot returns to its original style !
Thanks ever so much, KBJ.
sbgtrading
12-29-2007, 07:57 AM
Excellent KBJ...I had been looking for a way to do this as well...thank you!
grd974
12-30-2007, 12:51 PM
I want to code a further variation of BuySellCentered indicator but the following code :
private DataSeries AskTrades;
private DataSeries BidTrades;
AskTrades = new DataSeries(this);
BidTrades = new DataSeries(this);
AskTrades.Set((double) alBuys[CurrentBar]);
BidTrades.Set((double) alSells[CurrentBar]);
Print("Buys: " + alBuys[CurrentBar] + " / Sells: " + alSells[CurrentBar]);
Print("Ask: " + AskTrades[0] + " / Bid: " + BidTrades[0]);
gives this result :
Buys: 0 / Sells: 0
Ask: 0 / Bid: 0
What I want to do is that :
if (AskTrades[0] > (BidTrades[0]*3.5) && BidTrades[1] > (AskTrades[1]*3.5))
{
PlaySound(@"E:\type.wav");
}
else if (BidTrades[0] > (AskTrades[0]*3.5) && AskTrades[1] > (BidTrades[1]*3.5))
{
PlaySound(@"E:\online.wav");
};
I welcome any help.
It looks like you've found a bug in the indicator.
This bug is also in the original indicator that NinjaTrader distributes, and that I copied for this modified version of BuySellVolume.
In another look at the original BuySellVolume.cs code, I noticed that about 1/2 of the indicator's code is never used. I commented it out (see below) and it doesn't change the indicator behavior...
private int activeBar = -1;
//if (CurrentBar < activeBar)
//{
// Values[0].Set((double)alSells[CurrentBar]);
// Values[1].Set((double)alSells[CurrentBar] + (double)alBuys[CurrentBar]);
// return;
//}
//else
if (CurrentBar != activeBar)
{
// alBuys.Insert(Math.Max(activeBar, 0), Historical ? 0 : buys);
// alSells.Insert(Math.Max(activeBar, 0), Historical ? 0 : sells);
buys = 0;
sells = 0;
activeBar = CurrentBar;
}
Since CurrentBar can never be less than activeBar, all the code relating to setting alBuys and alSells just never gets done, thus your display of these values always ends up being zero.
I'm guessing (no comments) that the alBuys and alSells were there to allow the persistence of old buy-sell-volume values if the screen got refreshed (such as happens when another indicator is added to a chart). However, if that's what it's supposed to do, it doesn't work.
So, grd974, for now, you could try just referencing the "buys" and "sells" values instead of the alBuys and alSells.
The bug-fix on this is to change several variables to "static", then they aren't re-initialized when the indicator is refreshed, and the display doesn't disappear when another indicator is added to the chart.
Thus, changing the following variables fixes the problem:
private static int activeBar = -1;
private static System.Collections.ArrayList alBuys = new System.Collections.ArrayList();
private static System.Collections.ArrayList alSells = new System.Collections.ArrayList();
private static bool firstPaint = true;
These changes apply to all variations that I made to the BuySellVolume indicator that was distributed by NinjaTrader.
There is, however, a side-effect of declaring the data to be "static", and that is that the indicator can only be used once. If it is used on more than one chart, or if the indicator for the chart is changed, or if running market replay the data is re-wound and run again, nothing will get displayed. Also if the timeframe is changed to use less bars, nothing gets displayed. I haven't come up with any way around this that doesn't break the saving of data when a refresh is done.
Therefore, it's probably not a good idea to add these mods to an indicator on a permanent basis.
grd974
01-06-2008, 02:21 AM
I modified again the BuySellCentered in order to scan trade size but the outcome is puzzling as one can see from the image file attached.
I added these two Print statements :
if (askPrice > 0 && e.Price >= askPrice)
{
buys += e.Volume;
if (e.Volume >= 50) Print(e.Time + " " + e.Price + " " + e.Volume + " BIG green");
else Print(e.Time + " " + e.Price + " " + e.Volume + " green");
}
else if (bidPrice > 0 && e.Price <= bidPrice)
{
sells += e.Volume;
if (e.Volume >= 50) Print(e.Time + " " + e.Price + " " + e.Volume + " BIG red");
else Print(e.Time + " " + e.Price + " " + e.Volume + " red");
}
and I got two errors :
the first two trades from 18:25:22 (price=1442,50 and sizes=3 then 18) which appear green in the T&S window get red-stamped in the Output window.
Any clue to fix that bug ?
NinjaTrader_Josh
01-06-2008, 02:37 AM
What are red and green suppose to represent on your T&S?
grd974
01-06-2008, 03:35 AM
According to my set up T&S properties, red shows trades at bid price and green shows trades at ask price.
NinjaTrader_Josh
01-06-2008, 03:57 AM
I think to further assess your situation it would be best to print the values of the bid and ask price.
if (e.MarketDataType == MarketDataType.Ask)
Print(e.Time + " Ask Price: " + e.Price);
else if (e.MarketDataType == MarketDataType.Bid)
Print(e.Time + " Bid Price: " + e.Price);
grd974
01-06-2008, 04:36 AM
Hi Josh,
Here the image file and the modified code.
if (e.MarketDataType == MarketDataType.Ask)
Print(e.Time + " Ask Price: " + e.Price);
// askPrice = e.Price;
else if (e.MarketDataType == MarketDataType.Bid)
Print(e.Time + " Bid Price: " + e.Price);
// bidPrice = e.Price;
else if (e.MarketDataType == MarketDataType.Last)
NinjaTrader_Josh
01-06-2008, 04:48 AM
You are no longer outputting the red/green lines anymore? Basically the path I am leading you down is just to try and correlate what you are printing and what you are seeing on the T&S. With the lines you are currently outputting we can gauge what the ask/bid prices are. We might as well also print the last prices since those are what are shown on the T&S. After printing those we will also want to print the lines you had originally (the ones with the tidbit of logic). With all those pieces of information then we can compare behavior between the two.
grd974
01-06-2008, 07:55 AM
Ok, now I got it. Here they are.
The modified code:
protected override void OnMarketData(MarketDataEventArgs e)
{
if (e.MarketDataType == MarketDataType.Ask)
{
Print(e.Time + " Ask Price: " + e.Price);
askPrice = e.Price;
}
else if (e.MarketDataType == MarketDataType.Bid)
{
Print(e.Time + " Bid Price: " + e.Price);
bidPrice = e.Price;
}
else if (e.MarketDataType == MarketDataType.Last)
{
if (askPrice > 0 && e.Price >= askPrice)
{
buys += e.Volume;
if (e.Volume >= 50) Print(e.Time + " " + e.Price + " " + e.Volume + " BIG green");
else Print(e.Time + " " + e.Price + " " + e.Volume + " green");
}
else if (bidPrice > 0 && e.Price <= bidPrice)
{
sells += e.Volume;
if (e.Volume >= 50) Print(e.Time + " " + e.Price + " " + e.Volume + " BIG red");
else Print(e.Time + " " + e.Price + " " + e.Volume + " red");
}
}
}
The outcome looks better now.
NinjaTrader_Josh
01-06-2008, 01:15 PM
Everything looks in sync to me.