|
Once more a scrolling candlestick problem |
Posted by Sinan on Feb-06-2011 10:10 |
|
First of all: wonderfull library! Very usefull and supporting all required features which I was searching for, so far.
Unfortunately I cannot find the solution for my problem in the distinct examples arround.
The problem is the Y-Axis in of a scrollable candlestick layer: It does not change (adopt) it's scale when scrolling ( see attached example ).
If the following is too much code, let me know - I can reduce if needed.
I wanted, that you can see (almost) the complete thing.
Btw. In this code both a line and a candlechart is shown, but I tried also candle alone.
I would be very glad if I could get your help.
Tanks in advance!!
ChartWindowDlg::drawChart(CChartViewer *viewer)
{
// Get the line data
int* pTmpTimes = 0;
double* pData = 0;
int nCount = (int)m_pDomain->getLst(&pTmpTimes, &pData );
if( nCount == 0 )
{
return;
}
// get the time data for the line
double* pTimes = new double[nCount];
itod( pTimes, pTmpTimes, nCount ); // convert time_t to doubles
delete [] pTmpTimes;
// convert times to chartdirector times
for( int i = 0; i < nCount; i++ )
{
struct tm ts;
const time_t x = time_t(pTimes[i]);
localtime_r(&x, &ts );
pTimes[i] = Chart::chartTime(ts.tm_year + 1900,
ts.tm_mon,
ts.tm_mday,
ts.tm_hour,
ts.tm_min,
ts.tm_sec);
}
// copied from examples
double viewPortStartDate = m_lfMinDate +
(__int64)(viewer->getViewPortLeft() * m_lfDateRange + 0.5);
double viewPortEndDate = viewPortStartDate +
(__int64)(viewer->getViewPortWidth() * m_lfDateRange + 0.5);
// Get the starting index of the array using the start date ( from examples )
int startIndex = (int)(std::lower_bound( pTimes,
pTimes + nCount,
viewPortStartDate) - pTimes);
if ((startIndex > 0) && (pTimes[startIndex] != viewPortStartDate))
{
--startIndex;
}
// Get the ending index of the array using the end date
int endIndex = (int)(std::upper_bound( pTimes,
pTimes + nCount,
viewPortEndDate) - pTimes );
if (endIndex > nCount - 1 )
{
endIndex = nCount - 1;
}
// Get the length
int noOfPoints = endIndex - startIndex + 1;
double* viewPortTimeStamps = pTimes + startIndex;
double* viewPortData = pData + startIndex;
CRect clientRect;
m_oChartViewer.GetClientRect(&clientRect);
int nWidth = clientRect.Width();
XYChart *c = new XYChart(clientRect.Width(),
clientRect.Height(),
0xa3c0b3,
0x0000FF,
1);
// create the plot area
c->setPlotArea( 50,
40,
clientRect.Width()-50,
clientRect.Height()-80,
Chart::Transparent,
-1,
-1,
0xcccccc,
0xcccccc);
c->setClipping();
// Display contract name
std::string strTitle;
m_pDomain->getContractDisplayName( strTitle );
c->addTitle( strTitle.c_str(),
"timesbi.ttf",
10)->setBackground(0xCCCC99,
0x000000,
Chart::glassEffect());
c->xAxis()->setTickDensity(50, 25);
c->xAxis()->setWidth(2);
c->yAxis()->setWidth(2);
double lfFirstTime = pTimes[0];
double lfLastTime = pTimes[nCount-1];
// Set up the x-axis to show the time range in the data buffer
c->xAxis()->setDateScale(lfFirstTime, lfLastTime);
// Set the x-axis label format
c->xAxis()->setLabelFormat("{value|hh:nn}");
// Create a line layer to plot the lines
LineLayer *layer = c->addLineLayer();
// BEGIN CANDLE ------------------
double* open = 0;
double* high = 0;
double* low = 0;
double* close = 0;
double* pOhlcTimes = 0;
int* pTmpOhlcTimes = 0;
int nOhlcCount = (int)m_pDomain->getOhlc(&open,
&high,
&low,
&close,
&pTmpOhlcTimes );
if( nOhlcCount > 0 )
{
// debug only: candle y-axis is shown in 2nd axis --> change plot area
c->setPlotArea( 50, 40,
clientRect.Width()-110, clientRect.Height()-80,
Chart::Transparent, -1, -1, 0xcccccc, 0xcccccc);
// transform candle times
pOhlcTimes = new double[nOhlcCount];
itod( pOhlcTimes, pTmpOhlcTimes, nOhlcCount );
delete [] pTmpOhlcTimes;
// build chart director times
for( int i = 0; i < nOhlcCount; i++ )
{
struct tm ts;
const time_t x = time_t(pOhlcTimes[i]);
localtime_r(&x, &ts );
pOhlcTimes[i] = Chart::chartTime(ts.tm_year + 1900,
ts.tm_mon,
ts.tm_mday,
ts.tm_hour,
ts.tm_min,
ts.tm_sec);
}
CandleStickLayer *candle = 0;
if( nOhlcCount > 2 )
{
candle =
c->addCandleStickLayer(DoubleArray(high, nOhlcCount),
DoubleArray(low, nOhlcCount),
DoubleArray(open, nOhlcCount),
DoubleArray(close, nOhlcCount),
0x88ff88, 0xff8888);
candle->setXData(DoubleArray(pOhlcTimes, nOhlcCount-1));
candle->setUseYAxis2(true);
}
}
// END CANDLE --------------------
// The x-coordinates are the timeStamps.
layer->setXData(DoubleArray(viewPortTimeStamps, noOfPoints));
layer->addDataSet(DoubleArray(viewPortData, noOfPoints), 0x000088, "Test1");
// Set x-axis date scale to the view port date range.
// ---> with this line, I did try lot's of ideas, none worked <---
c->xAxis()->setDateScale(viewPortStartDate, viewPortEndDate);
c->yAxis()->setAutoScale(0, 0);
c->yAxis2()->setAutoScale(0, 0);
// Set up y-axis scale
if (viewer->getZoomDirection() == Chart::DirectionHorizontal)
{
// y-axis is auto-scaled - save the chosen y-axis scaled to support xy-zoom mode
c->layout();
}
// Set the chart image to the WinChartViewer
viewer->setChart(c);
|
Re: Once more a scrolling candlestick problem |
Posted by Peter Kwan on Feb-07-2011 23:53 |
|
Hi Sinan,
From your code, is it true that the high, low, open, close and pOhlcTimes are always the same irrespective of where the chart has scrolled to? I am guessing this because it seems m_pDomain->getOhlc would not consider the current view port settings when retrieve the data.
If the candlestick always contains the same data, ChartDirector auto-scaling always pick the same scale for the candlestick layer. This is even if some of the candlesticks are not actually visible.
If the above is the cause of the problem, the solution is to pass only the data visible in the chart to candlestick layer. You may modify m_pDomain->getOhlc so that it only retrieves data within the viewPortStartDate and viewPortEndDate.
Hope this can help.
Regards
Peter Kwan |
Re: Once more a scrolling candlestick problem |
Posted by Sinan on Feb-10-2011 01:21 |
|
Thank you!
You are right - Even if you didn't say it: it was a bug in my code
I corrected it the same way as the previous start- and endindex calculations of the main array - and it worked! Sorry for having bothered - I will double(tripple) check before next post.
Sinan |
Re: Once more a scrolling candlestick problem |
Posted by Sinan on Feb-10-2011 01:25 |
|
Thank you!
You are right - Even if you didn't say it: it was a bug in my code
I corrected it the same way as the previous start- and endindex calculations of the main array - and it worked! Sorry for having bothered - I will double(tripple) check before next post.
Sinan |
|