00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "StocksDialog.h"
00023 #include "Bar.h"
00024 #include "HelpWindow.h"
00025 #include "DBIndexItem.h"
00026 #include "COBase.h"
00027 #include "Exchange.h"
00028 #include "RcFile.h"
00029 #include <qsize.h>
00030 #include <qlabel.h>
00031 #include <qlayout.h>
00032 #include <qmessagebox.h>
00033 #include <qfileinfo.h>
00034
00035 StocksDialog::StocksDialog (QString p, DbPlugin *d, DBIndex *i) : QTabDialog (0, "StocksDialog", TRUE)
00036 {
00037 helpFile = p;
00038 db = d;
00039 index = i;
00040 reloadFlag = FALSE;
00041 currentDate = QDateTime::currentDateTime();
00042
00043 setCaption(tr("Qtstalker: Edit Stock"));
00044
00045 QString s;
00046 d->getSymbol(s);
00047 QFileInfo fi(s);
00048 symbol = fi.fileName();
00049
00050 createDetailsPage();
00051 createDataPage();
00052 createFundamentalsPage();
00053 createSplitPage();
00054
00055 setOkButton(tr("&OK"));
00056 setCancelButton(tr("&Cancel"));
00057 connect(this, SIGNAL(applyButtonPressed()), this, SLOT(saveChart()));
00058
00059 setHelpButton();
00060 QObject::connect(this, SIGNAL(helpButtonPressed()), this, SLOT(help()));
00061
00062 RcFile rcfile;
00063 QSize sz;
00064 rcfile.loadSize(RcFile::EditStockWindowSize, sz);
00065 resize(sz);
00066 }
00067
00068 StocksDialog::~StocksDialog ()
00069 {
00070 RcFile rcfile;
00071 rcfile.saveSize(RcFile::EditStockWindowSize, size());
00072 }
00073
00074 void StocksDialog::createDetailsPage ()
00075 {
00076 QWidget *w = new QWidget(this);
00077
00078 QVBoxLayout *vbox = new QVBoxLayout(w);
00079 vbox->setMargin(5);
00080 vbox->setSpacing(5);
00081
00082 QGridLayout *grid = new QGridLayout(vbox);
00083 grid->setMargin(0);
00084 grid->setSpacing(5);
00085
00086 QLabel *label = new QLabel(tr("Symbol"), w);
00087 grid->addWidget(label, 0, 0);
00088
00089 QString s;
00090 DBIndexItem item;
00091 index->getIndexItem(symbol, item);
00092 item.getSymbol(s);
00093 label = new QLabel(s, w);
00094 label->setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
00095 grid->addWidget(label, 0, 1);
00096
00097 label = new QLabel(tr("Name"), w);
00098 grid->addWidget(label, 1, 0);
00099
00100 item.getTitle(s);
00101 title = new QLineEdit(s, w);
00102 grid->addWidget(title, 1, 1);
00103
00104 label = new QLabel(tr("Exchange"), w);
00105 grid->addWidget(label, 2, 0);
00106
00107 item.getExchange(s);
00108 Exchange ex;
00109 ex.getExchange(s.toInt(), s);
00110 label = new QLabel(s, w);
00111 label->setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
00112 grid->addWidget(label, 2, 1);
00113
00114 label = new QLabel(tr("Type"), w);
00115 grid->addWidget(label, 3, 0);
00116
00117 item.getType(s);
00118 label = new QLabel(s, w);
00119 label->setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
00120 grid->addWidget(label, 3, 1);
00121
00122 label = new QLabel(tr("First Date"), w);
00123 grid->addWidget(label, 4, 0);
00124
00125 Bar bar;
00126 db->getFirstBar(bar);
00127 if (! bar.getEmptyFlag())
00128 {
00129 bar.getDateTimeString(TRUE, s);
00130 label = new QLabel(s, w);
00131 label->setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
00132 grid->addWidget(label, 4, 1);
00133 }
00134
00135 label = new QLabel(tr("Last Date"), w);
00136 grid->addWidget(label, 5, 0);
00137
00138 Bar bar2;
00139 db->getLastBar(bar2);
00140 if (! bar2.getEmptyFlag())
00141 {
00142 bar2.getDateTimeString(TRUE, s);
00143 label = new QLabel(s, w);
00144 label->setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
00145 grid->addWidget(label, 5, 1);
00146 }
00147
00148 grid->expand(grid->numRows() + 1, grid->numCols());
00149 grid->setColStretch(1, 1);
00150
00151 vbox->addStretch(1);
00152
00153 addTab(w, tr("Details"));
00154 }
00155
00156 void StocksDialog::createDataPage ()
00157 {
00158 QWidget *w = new QWidget(this);
00159
00160 QVBoxLayout *vbox = new QVBoxLayout(w);
00161 vbox->setMargin(5);
00162 vbox->setSpacing(0);
00163
00164 barEdit = new BarEdit(w);
00165 QString s = tr("Open");
00166 QString s2 = "Open";
00167 barEdit->createField(s, s2, FALSE);
00168 s = tr("High");
00169 s2 = "High";
00170 barEdit->createField(s, s2, FALSE);
00171 s = tr("Low");
00172 s2 = "Low";
00173 barEdit->createField(s, s2, FALSE);
00174 s = tr("Close");
00175 s2 = "Close";
00176 barEdit->createField(s, s2, FALSE);
00177 s = tr("Volume");
00178 s2 = "Volume";
00179 barEdit->createField(s, s2, FALSE);
00180 connect(barEdit, SIGNAL(signalDeleteRecord()), this, SLOT(deleteRecord()));
00181 connect(barEdit, SIGNAL(signalSaveRecord()), this, SLOT(saveRecord()));
00182 connect(barEdit, SIGNAL(signalSearch(QDateTime)), this, SLOT(slotDateSearch(QDateTime)));
00183 connect(barEdit, SIGNAL(signalFirstRecord()), this, SLOT(slotFirstRecord()));
00184 connect(barEdit, SIGNAL(signalLastRecord()), this, SLOT(slotLastRecord()));
00185 connect(barEdit, SIGNAL(signalPrevRecord()), this, SLOT(slotPrevRecord()));
00186 connect(barEdit, SIGNAL(signalNextRecord()), this, SLOT(slotNextRecord()));
00187 vbox->addWidget(barEdit);
00188
00189 addTab(w, tr("Data"));
00190 }
00191
00192 void StocksDialog::createFundamentalsPage ()
00193 {
00194 QWidget *w = new QWidget(this);
00195
00196 QVBoxLayout *vbox = new QVBoxLayout(w);
00197 vbox->setMargin(5);
00198 vbox->setSpacing(5);
00199
00200 Setting fund;
00201 QString s, s2;
00202 index->getFundamentals(symbol, s2);
00203 fund.parse(s2);
00204
00205 s = tr("Fundamentals: last updated ");
00206 s2 = "updateDate";
00207 QString s3;
00208 fund.getData(s2, s3);
00209 s.append(s3);
00210 fund.remove(s2);
00211 QStringList key;
00212 fund.getKeyList(key);
00213 key.sort();
00214
00215 vbox->addSpacing(10);
00216 QLabel *label = new QLabel(s, w);
00217 vbox->addWidget(label);
00218
00219 fundView = new QListView(w);
00220 fundView->addColumn(tr("Description"));
00221 fundView->addColumn(tr("Value"));
00222 vbox->addWidget(fundView);
00223
00224 int loop;
00225 for (loop = 0; loop < (int) key.count(); loop++)
00226 {
00227 fund.getData(key[loop], s);
00228 new QListViewItem(fundView, key[loop], s);
00229 }
00230
00231 if (! key.count())
00232 new QListViewItem(fundView, tr("No data available."));
00233
00234 addTab(w, tr("Fundamentals"));
00235 }
00236
00237 void StocksDialog::createSplitPage ()
00238 {
00239 QWidget *w = new QWidget(this);
00240
00241 QVBoxLayout *vbox = new QVBoxLayout(w);
00242 vbox->setMargin(5);
00243 vbox->setSpacing(5);
00244
00245 QGridLayout *grid = new QGridLayout(vbox);
00246 grid->setMargin(0);
00247 grid->setSpacing(5);
00248
00249 QLabel *label = new QLabel(tr("Split Date"), w);
00250 grid->addWidget(label, 0, 0);
00251
00252 Bar bar;
00253 db->getLastBar(bar);
00254 QDateTime dt;
00255 bar.getDate(dt);
00256 if (! bar.getEmptyFlag())
00257 splitDate = new QDateEdit(dt.date(), w);
00258 else
00259 splitDate = new QDateEdit(QDate::currentDate(), w);
00260 splitDate->setOrder(QDateEdit::YMD);
00261 grid->addWidget(splitDate, 0, 1);
00262
00263 label = new QLabel(tr("Split Ratio"), w);
00264 grid->addWidget(label, 1, 0);
00265
00266 splitRatio = new QLineEdit("2:1", w);
00267 grid->addWidget(splitRatio, 1, 1);
00268
00269 QPushButton *button = new QPushButton(tr("Perform Split"), w);
00270 connect(button, SIGNAL(clicked()), this, SLOT(split()));
00271 vbox->addWidget(button);
00272
00273 vbox->addStretch(1);
00274
00275 addTab(w, tr("Split"));
00276 }
00277
00278 void StocksDialog::deleteRecord ()
00279 {
00280 Bar bar;
00281 QString s;
00282 barEdit->getDate(s);
00283 if (bar.setDate(s))
00284 return;
00285 bar.getDateTimeString(FALSE, s);
00286 db->deleteData(s);
00287
00288 reloadFlag = TRUE;
00289 }
00290
00291 void StocksDialog::saveRecord ()
00292 {
00293 Bar bar;
00294 QString s, s2;
00295 barEdit->getDate(s);
00296 bar.setDate(s);
00297
00298 s = "Open";
00299 barEdit->getField(s, s2);
00300 bar.setOpen(s2.toDouble());
00301
00302 s = "High";
00303 barEdit->getField(s, s2);
00304 bar.setHigh(s2.toDouble());
00305
00306 s = "Low";
00307 barEdit->getField(s, s2);
00308 bar.setLow(s2.toDouble());
00309
00310 s = "Close";
00311 barEdit->getField(s, s2);
00312 bar.setClose(s2.toDouble());
00313
00314 s = "Volume";
00315 barEdit->getField(s, s2);
00316 bar.setVolume(s2.toDouble());
00317 db->setBar(bar);
00318
00319 reloadFlag = TRUE;
00320 }
00321
00322 void StocksDialog::slotDateSearch (QDateTime dt)
00323 {
00324 Bar record;
00325 db->getSearchBar(dt, record);
00326 if (record.getEmptyFlag())
00327 return;
00328 updateFields(record);
00329 }
00330
00331 void StocksDialog::saveChart ()
00332 {
00333 QString s = title->text();
00334 DBIndexItem item;
00335 index->getIndexItem(symbol, item);
00336 item.setTitle(s);
00337 index->setIndexItem(symbol, item);
00338
00339 if (barEdit->getSaveFlag())
00340 {
00341 int rc = QMessageBox::warning(this,
00342 tr("Warning"),
00343 tr("Record has been modified.\nSave changes?"),
00344 QMessageBox::Yes,
00345 QMessageBox::No,
00346 QMessageBox::NoButton);
00347
00348 if (rc == QMessageBox::Yes)
00349 saveRecord();
00350 }
00351
00352 reloadFlag = TRUE;
00353 accept();
00354 }
00355
00356 void StocksDialog::help ()
00357 {
00358 HelpWindow *hw = new HelpWindow(this, helpFile);
00359 hw->show();
00360 }
00361
00362 void StocksDialog::split ()
00363 {
00364 int rc = QMessageBox::warning(this,
00365 tr("Warning"),
00366 tr("Are you sure you want split the stock?"),
00367 QMessageBox::Yes,
00368 QMessageBox::No,
00369 QMessageBox::NoButton);
00370
00371 if (rc == QMessageBox::No)
00372 return;
00373
00374 QDate dt = splitDate->date();
00375
00376
00377 Bar bar;
00378 db->getFirstBar(bar);
00379 if (! bar.getEmptyFlag())
00380 {
00381 QDateTime td;
00382 bar.getDate(td);
00383 if (dt < td.date())
00384 {
00385 QMessageBox::information(this, tr("Qtstalker: Error"), tr("Invalid split date."));
00386 return;
00387 }
00388 }
00389
00390
00391 Bar bar2;
00392 db->getLastBar(bar2);
00393 if (! bar.getEmptyFlag())
00394 {
00395 QDateTime td;
00396 bar2.getDate(td);
00397 if (dt > td.date())
00398 {
00399 QMessageBox::information(this, tr("Qtstalker: Error"), tr("Invalid split date."));
00400 return;
00401 }
00402 }
00403
00404
00405 QStringList l = QStringList::split(":", splitRatio->text(), FALSE);
00406 if (l.count() != 2)
00407 {
00408 QMessageBox::information(this, tr("Qtstalker: Error"), tr("Invalid split ratio format.\neg. 2:1"));
00409 return;
00410 }
00411
00412 double plyer = l[1].toDouble() / l[0].toDouble();
00413 double volplyer = l[0].toDouble() / l[1].toDouble();
00414
00415 QString s;
00416 db->getSymbol(s);
00417 BarData *bars = new BarData(s);
00418 db->getAllBars(bars);
00419
00420 int loop;
00421 for (loop = 0; loop < bars->count(); loop++)
00422 {
00423 Bar bar;
00424 bars->getBar(loop, bar);
00425
00426 QDateTime td;
00427 bar.getDate(td);
00428 if (td.date() < dt)
00429 {
00430 bar.setOpen(bar.getOpen() * plyer);
00431 bar.setHigh(bar.getHigh() * plyer);
00432 bar.setLow(bar.getLow() * plyer);
00433 bar.setClose(bar.getClose() * plyer);
00434 bar.setVolume(bar.getVolume() * volplyer);
00435 db->setBar(bar);
00436 }
00437 }
00438
00439 delete bars;
00440
00441
00442 QDateTime adt(dt, QTime(0,0,0,0));
00443 QString fn;
00444 db->getIndexKey(fn);
00445 index->getChartObjects(fn, l);
00446 for (loop = 0; loop < (int) l.count(); loop++)
00447 {
00448 Setting set;
00449 set.parse(l[loop]);
00450 COBase tco;
00451 COBase *co = tco.getCO(set);
00452 if (! co)
00453 continue;
00454
00455 co->adjustForSplit(adt, plyer);
00456
00457 set.clear();
00458 co->getSettings(set);
00459 s = "Name";
00460 QString s2;
00461 set.getData(s, s2);
00462 index->setChartObject(fn, s2, set);
00463 }
00464
00465 QMessageBox::information(this, tr("Qtstalker: Split Complete"), tr("Split complete."));
00466
00467 reloadFlag = TRUE;
00468 }
00469
00470 void StocksDialog::slotFirstRecord ()
00471 {
00472 Bar record;
00473 db->getFirstBar(record);
00474 if (record.getEmptyFlag())
00475 return;
00476 updateFields(record);
00477 }
00478
00479 void StocksDialog::slotLastRecord ()
00480 {
00481 Bar record;
00482 db->getLastBar(record);
00483 if (record.getEmptyFlag())
00484 return;
00485 updateFields(record);
00486 }
00487
00488 void StocksDialog::slotNextRecord ()
00489 {
00490 Bar record;
00491 db->getNextBar(currentDate, record);
00492 if (record.getEmptyFlag())
00493 return;
00494 updateFields(record);
00495 }
00496
00497 void StocksDialog::slotPrevRecord ()
00498 {
00499 Bar record;
00500 db->getPrevBar(currentDate, record);
00501 if (record.getEmptyFlag())
00502 return;
00503 updateFields(record);
00504 }
00505
00506 void StocksDialog::updateFields (Bar &record)
00507 {
00508 record.getDate(currentDate);
00509
00510 QString s;
00511 record.getDateTimeString(TRUE, s);
00512 barEdit->setDate(s, record.getTickFlag());
00513
00514 s = "Open";
00515 QString s2 = QString::number(record.getOpen());
00516 barEdit->setField(s, s2);
00517
00518 s = "High";
00519 s2 = QString::number(record.getHigh());
00520 barEdit->setField(s, s2);
00521
00522 s = "Low";
00523 s2 = QString::number(record.getLow());
00524 barEdit->setField(s, s2);
00525
00526 s = "Close";
00527 s2 = QString::number(record.getClose());
00528 barEdit->setField(s, s2);
00529
00530 s = "Volume";
00531 s2 = QString::number(record.getVolume(), 'f', 0);
00532 barEdit->setField(s, s2);
00533
00534 barEdit->clearButtons();
00535 }
00536
00537 bool StocksDialog::getReloadFlag ()
00538 {
00539 return reloadFlag;
00540 }
00541