PDA

View Full Version : QCustomPlot using timestamp to set Date along one axis



bandito
5th March 2016, 01:55
I am having trouble setting the date properly. Basically I have timestamp, open, close, high, low, volume stored line by line in a text file (downloaded using Yahoo API). My program then reads each line and converts it to a QStringList. It then puts each item in the list into the appropriate QVector<double> (dates[], open[], close[], high[], low[], volume[]) converting each item to a double. Here is where the problem is. It appears that the precision is lost during the conversion. The dates always show as periods back in 1970 when the actually timestamp is in fact a date from a few days ago.


#include "dialog.h"
#include "ui_dialog.h"
#include<QFile>
#include<QTextStream>
#include<string>
#include<iostream>
using namespace std;

Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
QStringList lines;
QString line;

QVector<double> dates;
QVector<double> high;
QVector<double> low;
QVector<double> open;
QVector<double> close;
QVector<double> volume;

QFile file ("YHOO.cvs");
if(file.open(QIODevice::ReadOnly))
{


QTextStream in(&file);
while (!in.atEnd())
{

line = in.readLine();
lines = line.split(",");
dates.append(lines[0].toDouble());
close.append(lines[1].toDouble());
high.append(lines[2].toDouble());
low.append(lines[3].toDouble());
open.append(lines[4].toDouble());
volume.append(lines[5].toInt());
}
file.close();
}
else{

QMessageBox::information(0,"info",file.errorString());
}


ui->plot->addGraph();

ui->plot->graph(0)->setData(dates, high);


ui->plot->xAxis->setTickLabelType(QCPAxis::ltDateTime);
ui->plot->xAxis->setDateTimeFormat("MM/dd/yyyy");

QPen pen;
pen.setColor(QColor(200,200,200));

ui->plot->graph(0)->setPen(pen);
ui->plot->graph(0)->setLineStyle(QCPGraph::lsLine);
ui->plot->graph(0)->setBrush(QBrush(QColor(160,50,150)));

ui->plot->xAxis->setRange(dates[0], dates[dates.length()-1]);
ui->plot->yAxis->setRange(*std::min_element(high.begin(), high.end()),*std::max_element(high.begin(),high.en d()));

}

Dialog::~Dialog()
{
delete ui;
}

YHOO.cvs



20140227,30.1000,30.1600,28.4100,29.7000,2351300
20140228,28.3000,32.0000,27.0000,29.2000,3781000
20140303,28.1900,28.9100,26.8900,27.3000,1664900
20140304,30.0400,30.3800,28.6300,28.8500,2341700
20140305,28.5500,29.5000,28.4900,29.2400,7314100
20140306,27.1700,29.0100,27.1500,28.7600,3007300
20140307,27.2000,28.3200,26.7100,27.8400,2961800
20140310,28.2400,28.5000,27.3500,27.7200,1622100
20140311,27.5300,28.7400,27.1800,28.4400,1745200
20140312,28.5400,28.7400,27.3500,27.4700,2206300

anda_skoa
5th March 2016, 11:06
The first column looks like a date formatted as a YYYYMMDD string.

Cheers,
_

bandito
5th March 2016, 17:35
The first column looks like a date formatted as a YYYYMMDD string.

Cheers,
_

You are correct. Thanks!

I came up with this function to convert the QString to a double value timestamp.



double timeStamp(QString qs){
char tempDate[10];
memcpy(tempDate, qs.toStdString().c_str(), 10);
char date[] = " ";
date[0] = tempDate[0];
date[1] = tempDate[1];
date[2] = tempDate[2];
date[3] = tempDate[3];
date[4] = '\0';
date[5] = tempDate[4];
date[6] = tempDate[5];
date[7] = '\0';
date[8] = tempDate[6];
date[9] = tempDate[7];

struct tm tmdate = {0};
tmdate.tm_year = atoi(&date[0]) - 1900;
tmdate.tm_mon = atoi(&date[5]) - 1;
tmdate.tm_mday = atoi(&date[8]);
time_t t = mktime( &tmdate );

double actual_time_sec = difftime(t,0);

return actual_time_sec;
}

Lesiok
5th March 2016, 17:49
In one line :
double timeStamp(QString qs){
return QDateTime(QDate::fromString(qs,"yyyyMMdd"),QTime(0,0,0)).toTime_t();
}

bandito
5th March 2016, 18:32
In one line :
double timeStamp(QString qs){
return QDateTime(QDate::fromString(qs,"yyyyMMdd"),QTime(0,0,0)).toTime_t();
}

Wow that's sexy. Thanks!