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

Message ListMessage List     Post MessagePost Message

  Update realtime data
Posted by Mikz on Jan-23-2019 21:53
Hi there

I have an issue with updating realtime data of candlesticks
I have a datafeed and need to draw a lot of candles correctly and quickly
I've used the "finance demo" example as a base

So I create a FinanceChart object and use "setData" function for passing OHLCVT data
But the "setData" function uses "deepCopy" function inside, so once I have a new data so it looks like that I have to copy all previous data again and I can't just say update chart
it isn't effective, I have pointers to datafeed arrays and I need to have possibility to update the pointers if arrays sizes are changed or just update previous values

How to update values correctly that don't need to copy all previous data again?

One more question
Let's say I need to have many candle series in one chart, how can I do it?
FinanceChart object allows to point one candle series only
FinanceChart has "addCandleStick" which allows to create CandleStickLayer but CandleStickLayer doesn't have any possibility for adding a separated candle series
So only FinanceChart object allows to add one candle series
How can I add many candle series in one chart?
How can I do it correctly if scales are different and I need to compare series dynamic?

Thank you

  Re: Update realtime data
Posted by Peter Kwan on Jan-25-2019 02:38
Hi Mikz,

Internally, ChartDirector deep copies the data, which takes negligible time so it has no effect to efficiency. It takes negligible time because the time needed to process one data point and draw the graphics are much much more than the time needed to copy one data point. In our own testing, there is no difference in performance. On the other hand, deep copying is much easier to use in many code structures, such as in multi-threading code.

In a realtime chart, when new data comes in, your code can append them to your data arrays. Then you can just redraw the chart. This keeps the code simple because you can use exactly the same code to draw the chart in the first place and subsequently update it.

For multiple candlestick layers, see:

https://www.chartdir.com/forum/download_thread.php?bn=chartdir_support&pattern=addCandleStickLayer&thread=1470144808#N1470154097

The FinanceChart.addCandleStick adds candlesticks to the main price chart using the data provided with "setData". ChartDirector also has an API XYChart.addCandleStickLayer in which you can specify another set of open/high/low/close data arrays.

For comparison, there is a built-in method FinanceChart.addComparison that can add a comparison data series to the main price chart. The axis scale will be such that the comparison data series will start at the same point as the main data series.

The comparison data series is drawn as a line. If you want to draw the comparison as candlesticks, may be you can copy the source code of FinanceChart.addComparison to your project, and modify it to add a candlestick layer instead of a line layer. The FinanecChart source code is included in the ChartDirector distribution. The exact location depends on your programming language edition of ChartDirector. Please refer to the "FinanceChart' documentation of your programming langauge edition of ChartDirector for details. For example, for C++, it is at:

https://www.advsofteng.com/doc/cdcpp.htm#FinanceChart.htm

Regards
Peter Kwan

  Re: Update realtime data
Posted by Mikz on Jan-25-2019 21:54
Dear Peter Kwan,

Thank you for your reply
I have one more question
How can I remove or hide one of layers?

Regards, Mikhail

  Re: Update realtime data
Posted by Mikz on Jan-25-2019 22:26
Unfortunately I don't understand how to update data correctly still

I create a FinanceChart object (I use Qt)

m_pChart = new FinanceChart(WW);
m_pChart->setLegendStyle("normal", 8, Chart::Transparent, Chart::Transparent);
m_pChart->addMainChart(HH);
m_pChart->addCandleStick(0x00ff00, 0xff0000);
m_pChart->addVolBars(75, 0x99ff99, 0xff9999, 0x808080);
m_ChartViewer->setChart(m_pChart);

and when data is ready so I try to pass it

(t, h, l, o, c, v) are arrays and they contains all values
m_pChart->setData(t, h, l, o, c, v, 0);

startDate is the first time value and endDate is the last time value

m_ChartViewer->updateFullRangeH("x", startDate, endDate, Chart::ScrollWithMax);
m_ChartViewer->updateViewPort(true, false);

But there is no any data in the chart
What have I done wrongly?

And I'm trying to add one more layer by this code
There are other (t, h, l, o, c) arrays

XYChart *p = dynamic_cast<XYChart *>(m_pChart->getChart(0));
CandleStickLayer *pl = p->addCandleStickLayer(h, l, o, c);
pl->setXData(t);

How can I update values in this layer (pl)?
I've not found any suitable method in CandleStickLayer

Thank you

  Re: Update realtime data
Posted by Peter Kwan on Jan-28-2019 16:02
Hi Mikz,

To hide a layer, simply do not add the layer to the chart.

You may refer to the Interactive Finance Chart sample code for an example. For Qt, it is at "ChartDirector/qtdemo/financedemo". In this example, the user can interactive add or remove indicators. To hide an indicator, the method is to not add the indicator to the chart in the first place.

In brief, the code structure is like:

void FinanceDemo::drawChart(QChartViewer *viewer)
{
....... code to obtain the data .......

    FinanceChart m(width);

......, code to add the data and main price chart, etc .....

// Add the parabolic SAR only if user selects it.
if (m_ParabolicSAR->isChecked())
    m.addParabolicSAR(0.02, 0.02, 0.2, Chart::DiamondShape, 5, 0x008800, 0x000000);

.......

     // Set the chart to the viewer
    viewer->setChart(&m);
}


When the user clicks on the checkbox, the code just calls drawChart. In fact, no matter what the user has changed, just calls drawChart.

Regards
Peter Kwan

  Re: Update realtime data
Posted by Peter Kwan on Jan-28-2019 16:07
Hi Mikz.

To display the data, your data must be added before the chart is drawn and displayed (when it is set to the m_ChartViewer). If you add the data after the chart has already been drawn and displayed, it will have no effect.

Your code should be like:

void drawChart()
{
    m_pChart = new FinanceChart(WW);
    m_pChart->setData(m_t, m_h, m_l, m_o, m_c, m_v, 0);
    m_pChart->setLegendStyle("normal", 8, Chart::Transparent, Chart::Transparent);
    m_pChart->addMainChart(HH);
    m_pChart->addCandleStick(0x00ff00, 0xff0000);
    m_pChart->addVolBars(75, 0x99ff99, 0xff9999, 0x808080);
    m_ChartViewer->setChart(m_pChart);
}

When you have updated the data (the arrays m_t, m_h, ....), just call drawChart. Like in my previous post, if the chart is changed, just call drawChart.

Hope this can help.

Regards
Peter Kwan

  Re: Update realtime data
Posted by Mikz on Jan-29-2019 19:22
Hello Peter

Thank you for your replies
Now I understand the logic of the library

One more question (it's offtopic but I hope that it isn't a problem)
How can I add custom graphical objects like vertical lines, labels and rectangles linked to some candle?
In other words I need to create a subchart where I can draw some specific markers corresponded to some of candles

A sketch of desired view
https://yadi.sk/i/CMILWcxTsGYnyw

What is the best way to do it?

Regards, Mikz

  Re: Update realtime data
Posted by Peter Kwan on Jan-31-2019 02:09
Hi Mikz,

May be you can use BaseChart.addText and BaseChart.addLine to add custom text box and lines to the chart.

I am not sure what is your chart configuration (eg. can your chart contains multiple indicator charts, or just the main price chart), and where you want the vertical line to appear (eg. if there are multiple indicator charts, should the line shoot through the indicator charts up to the candlestick?). In the following example, I assume there is just the main price chart as in your image:

// Create finance chart object as usual
FinanceChart *c = new FinanceChart(....);

// Change the bottom margin to 100 pixels to leave space for the text boxes
c->setMargins(40, 30, 40, 100);

c->setData(timeStamps, highData, lowData, openData, closeData, volData, extraDays);

//Add the main chart as usual
XYChart *mainChart = c->addMainChart(...);

.... add the candlesticks and other indicators inside the main price chart ....

// auto-scale the axis
c->layout();

// Add a line and text box at the 20th visible candlestick on the chart
int xPos = 20;

// x and y coordinates of the TextBox
int xCoor = mainChart->getXCoor(xPos);
int yCoor = c->getHeight() - 60;

// Add the textbox
c->addText(xCoor, yCoor, "ABCDEFn123456", "arial.ttf", 10, 0x333333, Chart::Top)->setBackground(0xffffcc, 0x888866);

// Add the line
c->addLine(xCoor, yCoor, xCoor, mainChart->getYCoor(lowData[xPos + extraDays]) + mainChart->getAbsOffsetY() + 5, 0x888888);

.... output the chart as usual .....