ASE Home Page Products Download Purchase Support About ASE
ChartDirector Support
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

  Please support to draw Volume profile chart. (Market profile)
Posted by kevin on Nov-24-2019 12:15
Attachments:
Dear. Peter Kwan
At first, I need to say Thank you so much for Great library.

Recently, I need to show Volume profile chart but it's a little hard to me.
And This is my first asking you for help since I bought license on May.

First(Sample) picture is the chart what I'd like to draw.

And I tried to draw same chart using ChartDirector library.

this is my code.

PlotArea * pArea = mainChart->getPlotArea();

XYChart * tChart = new XYChart(pArea->getWidth() / 5, pArea->getHeight());
tChart->setPlotArea(0, 0, tChart->getWidth(), tChart->getHeight(), Chart::Transparent, -1, Chart::Transparent, Chart::Transparent);

int wid = pArea->getWidth();

tChart->swapXY();
BarLayer * barLayer = tChart->addBarLayer(DoubleArray(m_volumeProfile_vol, m_volumeProfile_size), 0xffdddd);
barLayer->setBorderColor(0xdddddd);
barLayer->setXData(DoubleArray(m_volumeProfile_pri, m_volumeProfile_size));
barLayer->setBarGap(TouchBar);

tChart->xAxis()->syncAxis(mainChart->yAxis());
tChart->xAxis()->setMargin(tChart->getWidth() / 2);

tChart->yAxis()->setReverse();

m->layout();
pArea->setBackground(Transparent, Transparent, 0x888888);
//mainChart->getDrawArea()->merge(tChart->makeChart(), pArea->getLeftX(), pArea->getTopY(), TopLeft, 0);
mainChart->getDrawArea()->merge(tChart->makeChart(), wid - wid/5 + pArea->getLeftX(), pArea->getTopY(), TopLeft, 0);


it's really difficult and I don't know what should I do in the future.

So could you please give me some example for Volume chart?

I'm using MFC with Visual studio 2018.

Thank you in advance and I'll be waiting for your positive response.
BRs.
sample.png
mychart.png

  Re: Please support to draw Volume profile chart. (Market profile)
Posted by Peter Kwan on Nov-25-2019 16:42
Hi Kevin,

I think you have already written most of the code. The method to create one volume profile bar layer, and multiple volume bar layers are essentially the same. You can just put the code in a subroutine and call it repeatedly with different data.

I will probably use one chart with multiple bar layers for all the volume profile bars, the use the chart as the background image of the main chart plot area.

Please give me some time. I can write a simple example for you.

Regards
Peter Kwan

  Re: Please support to draw Volume profile chart. (Market profile)
Posted by Peter Kwan on Nov-26-2019 03:38
Attachments:
Hi Kevin,

Below please find an example I have written.

Basically, I started with the Finance Chart (1) sample code included in ChartDirector. I use a XYChart to contain all the bar layers. I created a subroutine that can add a bar layer into the XYChart at the given horizontal position in the chart. The XYChart is then used as the plot area background of the main price chart. In the code below, I just call the subroutine 3 times with some hard coded test data as an example.


BarLayer *addPriceVolLayer(XYChart* c, int startPos, int endPos, DoubleArray xData, DoubleArray yData, int color)
{
BarLayer* layer = c->addBarLayer(yData, color);
layer->setBorderColor(Chart::SameAsMainColor);
layer->setXData(xData);
layer->setBarGap(TouchBar);
Axis* a = c->addAxis(Chart::Bottom, 10);
layer->setUseYAxis(a);

if (startPos < endPos)
a->setMargin(c->getPlotArea()->getWidth() - endPos, startPos);
else {
a->setReverse();
a->setMargin(c->getPlotArea()->getWidth() - startPos, endPos);
}

a->setAutoScale(0, 0, 1);
a->setRounding(false, false);
return layer;
}


BaseChart *finance(int /* chartIndex */, const char ** /* imageMap */)
{
    // Create a finance chart demo containing 100 days of data
    int noOfDays = 100;

    // To compute moving averages starting from the first day, we need to get extra data points
    // before the first day
    int extraDays = 30;

    // In this exammple, we use a random number generator utility to simulate the data. We set up
    // the random table to create 6 cols x (noOfDays + extraDays) rows, using 9 as the seed.
    RanTable *rantable = new RanTable(9, 6, noOfDays + extraDays);

    // Set the 1st col to be the timeStamp, starting from Sep 4, 2002, with each row representing
    // one day, and counting week days only (jump over Sat and Sun)
    rantable->setDateCol(0, Chart::chartTime(2002, 9, 4), 86400, true);

    // Set the 2nd, 3rd, 4th and 5th columns to be high, low, open and close data. The open value
    // starts from 100, and the daily change is random from -5 to 5.
    rantable->setHLOCCols(1, 100, -5, 5);

    // Set the 6th column as the vol data from 5 to 25 million
    rantable->setCol(5, 50000000, 250000000);

    // Now we read the data from the table into arrays
    DoubleArray timeStamps = rantable->getCol(0);
    DoubleArray highData = rantable->getCol(1);
    DoubleArray lowData = rantable->getCol(2);
    DoubleArray openData = rantable->getCol(3);
    DoubleArray closeData = rantable->getCol(4);
    DoubleArray volData = rantable->getCol(5);

    // Create a FinanceChart object of width 640 pixels
    FinanceChart *c = new FinanceChart(640);

    // Add a title to the chart
    c->addTitle("Finance Chart Demonstration");

    // Set the data into the finance chart object
    c->setData(timeStamps, highData, lowData, openData, closeData, volData, extraDays);

    // Add the main chart with 240 pixels in height
    XYChart *mainChart = c->addMainChart(240);

    // Add a 5 period simple moving average to the main chart, using brown color
    c->addSimpleMovingAvg(5, 0x663300);

    // Add a 20 period simple moving average to the main chart, using purple color
    c->addSimpleMovingAvg(20, 0x9900ff);

    // Add HLOC symbols to the main chart, using green/red for up/down days
    c->addHLOC(0x008000, 0xcc0000);

    // Add 20 days bollinger band to the main chart, using light blue (9999ff) as the border and
    // semi-transparent blue (c06666ff) as the fill color
    c->addBollingerBand(20, 2, 0x9999ff, 0xc06666ff);

    // Add a 75 pixels volume bars sub-chart to the bottom of the main chart, using green/red/grey
    // for up/down/flat days
    c->addVolBars(75, 0x99ff99, 0xff9999, 0x808080);

// Set up the price volue chart
PlotArea* p = mainChart->getPlotArea();
XYChart* pvChart = new XYChart(p->getWidth(), p->getHeight(), Chart::Transparent);
pvChart->setPlotArea(0, 0, pvChart->getWidth() - 1, pvChart->getHeight() - 1);
pvChart->swapXY();
pvChart->xAxis()->syncAxis(mainChart->yAxis());

// Add price vol layers to the pyChart
double testDataY[] = { 0, 100, 200, 300, 200, 100, 0 };
double testDataX[] = { 100, 110, 120, 130, 140, 150, 160 };
int pointCount = 7;
addPriceVolLayer(pvChart, 0, 100, DoubleArray(testDataX, pointCount), DoubleArray(testDataY, pointCount), 0xffcccc);

double testDataY2[] = { 0, 300, 200, 300, 100, 50, 0 };
double testDataX2[] = { 80, 85, 90, 95, 100, 105, 115 };
int pointCount2 = 7;
addPriceVolLayer(pvChart, 200, 300, DoubleArray(testDataX2, pointCount2), DoubleArray(testDataY2, pointCount2), 0xffcccc);

double testDataY3[] = { 0, 300, 200, 300, 100, 500, 0 };
double testDataX3[] = { 100, 110, 120, 130, 140, 150, 160 };
int pointCount3 = 7;
addPriceVolLayer(pvChart, p->getWidth(), p->getWidth() - 100, DoubleArray(testDataX3, pointCount2), DoubleArray(testDataY3, pointCount2), 0xccffcc);

// use the price volume chart as the mainChart background
mainChart->layoutAxes();
mainChart->setResource("pvChart", pvChart->makeChart());
p->setBackground("@/pvChart", Chart::TopLeft);

    // Append a 14-days RSI indicator chart (75 pixels high) after the main chart. The main RSI line
    // is purple (800080). Set threshold region to +/- 20 (that is, RSI = 50 +/- 25). The
    // upper/lower threshold regions will be filled with red (ff0000)/blue (0000ff).
    c->addRSI(75, 14, 0x800080, 20, 0xff0000, 0x0000ff);

    // Append a 12-days momentum indicator chart (75 pixels high) using blue (0000ff) color.
    c->addMomentum(75, 12, 0x0000ff);

    // Output the chart
    c->makeChart();

    //free up resources
    delete rantable;
    delete pvChart;

    return c;
}


Regards
Peter Kwan
priceVol.png

  Re: Please support to draw Volume profile chart. (Market profile)
Posted by kevin on Dec-01-2019 00:02
Hi Peter Kwan,
Thank you for good example.
It works fine if there is no Zooming and Scrolling.
Because it used absolute coordinate in Chart.

So, I'd like to ask you another example code.

Could you plz provide example that is based on Zooming and Scrolling in ChartDirector?

I think it will make my program perfect!

Thank you in advance.
Best Regards.

  Re: Please support to draw Volume profile chart. (Market profile)
Posted by kevin on Dec-01-2019 00:08
Hi Peter Kwan,
Thank you for good example.
It works fine if there is no Zooming and Scrolling.
Because it used absolute coordinate in Chart.

So, I'd like to ask you additional example code.

Could you plz provide add Zooming and Scrolling example based on your original example?

I think it will make my program perfect!

Thank you in advance.
Best Regards.

  Re: Please support to draw Volume profile chart. (Market profile)
Posted by Peter Kwan on Dec-02-2019 16:16
Hi kevin,

By "absolute coordinate", are you referring to the coordinates 200 and 300 in the code below?

addPriceVolLayer(pvChart, 200, 300, DoubleArray(testDataX2, pointCount2), DoubleArray(testDataY2, pointCount2), 0xffcccc);

The hard coded numbers 200 and 300 are just used as an example. In practice, you can put the bars at other positions. For example, if you want to put the bars to start at the timeStamp with array index aaa and ends at array index bbb, the x-coordinates must be:

int startX = (int)(((double)aaa - startIndex - extraPoints) / (duration - extraPoints) * p->getWidth() + 0.5);

int endX = (int)(((double)bbb - startIndex - extraPoints) / (duration - extraPoints) * p->getWidth() + 0.5);

addPriceVolLayer(pvChart, startX , endX , DoubleArray(testDataX2, pointCount2), DoubleArray(testDataY2, pointCount2), 0xffcccc);

(The variables startIndex, duration and extraPoints refers to the variables in my previous post for the Zoomable and Scrollable financial chart

https://www.chartdir.com/forum/download_thread.php?site=chartdir&bn=chartdir_support&thread=1558271457
)

Note that in your real code, you would also need to check if the aaa and bbb are within visible range. (The user can zoom in and scroll the chart so that it is totally or partially outside the visible chart.)

Regards
Peter Kwan

  Re: Please support to draw Volume profile chart. (Market profile)
Posted by kevin on Dec-03-2019 22:05
Hi, Peter Kwan

Great~!!!
Your guide is working fine.

Thanks alot.