lib/DbPlugin.cpp

Go to the documentation of this file.
00001 /*
00002  *  Qtstalker stock charter
00003  *
00004  *  Copyright (C) 2001-2007  Stefan S. Stratigakos
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00019  *  USA.
00020  */
00021 
00022 #include "DbPlugin.h"
00023 #include "StocksDialog.h"
00024 #include "FuturesDialog.h"
00025 #include "IndexDialog.h"
00026 #include "Config.h"
00027 #include "PrefDialog.h"
00028 #include "FuturesData.h"
00029 #include "Setting.h"
00030 #include "DBIndexItem.h"
00031 #include <qfileinfo.h>
00032 #include <qfile.h>
00033 #include <qdir.h>
00034 #include <qinputdialog.h>
00035 #include <qmessagebox.h>
00036 #include <qobject.h>
00037 #include <qvaluelist.h>
00038 #include <qstringlist.h>
00039 
00040 
00041 DbPlugin::DbPlugin ()
00042 {
00043   barLength = BarData::DailyBar;
00044   barRange = 275;
00045   type = Stock1;
00046 }
00047 
00048 DbPlugin::~DbPlugin ()
00049 {
00050   close();
00051 }
00052 
00053 bool DbPlugin::open (QString &d, DBIndex *i)
00054 {
00055   if (DBBase::open(d))
00056     return TRUE;
00057 
00058   chartIndex = i;
00059 
00060   QString s;
00061   DBIndexItem item;
00062   chartIndex->getIndexItem(indexKey, item);
00063   item.getType(s);
00064   type = getType(s);
00065 
00066   item.getPath(s);
00067   if (! s.length())
00068   {
00069     item.setPath(d);
00070     chartIndex->setIndexItem(indexKey, item);
00071   }
00072 
00073   return FALSE;
00074 }
00075 
00076 void DbPlugin::setBarLength (BarData::BarLength d)
00077 {
00078   barLength = d;
00079 }
00080 
00081 void DbPlugin::setBarRange (int d)
00082 {
00083   barRange = d;
00084 }
00085 
00086 void DbPlugin::getHelpFile (QString &d)
00087 {
00088   d = helpFile;
00089 }
00090 
00091 void DbPlugin::setType (DbPlugin::DbType d)
00092 {
00093   type = d;
00094 }
00095 
00096 void DbPlugin::dump (QString &d, bool f)
00097 {
00098   QFile outFile(d);
00099   if (! outFile.open(IO_WriteOnly))
00100     return;
00101   QTextStream outStream(&outFile);
00102   
00103   DBT key, data;
00104   DBC *cur;
00105   memset(&key, 0, sizeof(DBT));
00106   memset(&data, 0, sizeof(DBT));
00107 
00108   DBBar dbbar;
00109   memset(&dbbar, 0, sizeof(DBBar));
00110   data.data = &dbbar;
00111   data.ulen = sizeof(DBBar); 
00112   data.flags = DB_DBT_USERMEM;  
00113 
00114   db->cursor(db, NULL, &cur, 0);
00115 
00116   QFileInfo fi(symbol);
00117 
00118   while (! cur->c_get(cur, &key, &data, DB_NEXT))
00119   {
00120     if (f)
00121     {
00122       outStream << fi.fileName() << "," << (char *) key.data << "," << QString::number(dbbar.open) << ","
00123       << QString::number(dbbar.high) << "," << QString::number(dbbar.low) << "," 
00124       << QString::number(dbbar.close) << "," << QString::number(dbbar.volume, 'f', 0) << ","
00125       << QString::number(dbbar.oi) << "\n";
00126     }
00127     else
00128     {
00129       outStream << (char *) key.data << "=" << QString::number(dbbar.open) << ","
00130       << QString::number(dbbar.high) << "," << QString::number(dbbar.low) << "," 
00131       << QString::number(dbbar.close) << "," << QString::number(dbbar.volume, 'f', 0) << ","
00132       << QString::number(dbbar.oi) << "\n";
00133     }
00134   }
00135   cur->c_close(cur);
00136 
00137   outFile.close();
00138 }
00139 
00140 void DbPlugin::getFirstBar (Bar &bar)
00141 {
00142   DBT key, data;
00143   DBC *cur;
00144   memset(&key, 0, sizeof(DBT));
00145   memset(&data, 0, sizeof(DBT));
00146 
00147   DBBar dbbar;
00148   memset(&dbbar, 0, sizeof(DBBar));
00149   data.data = &dbbar;
00150   data.ulen = sizeof(DBBar); 
00151   data.flags = DB_DBT_USERMEM;  
00152 
00153   db->cursor(db, NULL, &cur, 0);
00154   cur->c_get(cur, &key, &data, DB_NEXT);
00155   QString k = (char *) key.data;
00156   getBar(dbbar, k, bar);
00157   cur->c_close(cur);
00158 }
00159 
00160 void DbPlugin::getLastBar (Bar &bar)
00161 {
00162   DBT key, data;
00163   DBC *cur;
00164   memset(&key, 0, sizeof(DBT));
00165   memset(&data, 0, sizeof(DBT));
00166 
00167   DBBar dbbar;
00168   memset(&dbbar, 0, sizeof(DBBar));
00169   data.data = &dbbar;
00170   data.ulen = sizeof(DBBar); 
00171   data.flags = DB_DBT_USERMEM;  
00172 
00173   db->cursor(db, NULL, &cur, 0);
00174   cur->c_get(cur, &key, &data, DB_PREV);
00175   QString k = (char *) key.data;
00176   getBar(dbbar, k, bar);
00177   cur->c_close(cur);
00178 }
00179 
00180 void DbPlugin::getPrevBar (QDateTime &startDate, Bar &bar)
00181 {
00182   DBT key, data;
00183   DBC *cur;
00184   memset(&key, 0, sizeof(DBT));
00185   memset(&data, 0, sizeof(DBT));
00186 
00187   DBBar dbbar;
00188   memset(&dbbar, 0, sizeof(DBBar));
00189   data.data = &dbbar;
00190   data.ulen = sizeof(DBBar); 
00191   data.flags = DB_DBT_USERMEM;  
00192 
00193   db->cursor(db, NULL, &cur, 0);
00194 
00195   QString s = startDate.toString("yyyyMMddhhmmss");
00196   key.data = (char *) s.latin1();
00197   key.size = s.length() + 1;
00198   cur->c_get(cur, &key, &data, DB_SET_RANGE);
00199   int ret = cur->c_get(cur, &key, &data, DB_PREV);
00200   if (ret)
00201   {
00202 //    char *err = db_strerror(ret);
00203 //    qDebug("%s %s", s.latin1(), err);
00204     cur->c_close(cur);
00205     return;
00206   }
00207   s = (char *) key.data;
00208   getBar(dbbar, s, bar);
00209   cur->c_close(cur);
00210 }
00211 
00212 void DbPlugin::getNextBar (QDateTime &startDate, Bar &bar)
00213 {
00214   DBT key, data;
00215   DBC *cur;
00216   memset(&key, 0, sizeof(DBT));
00217   memset(&data, 0, sizeof(DBT));
00218 
00219   DBBar dbbar;
00220   memset(&dbbar, 0, sizeof(DBBar));
00221   data.data = &dbbar;
00222   data.ulen = sizeof(DBBar); 
00223   data.flags = DB_DBT_USERMEM;  
00224 
00225   db->cursor(db, NULL, &cur, 0);
00226 
00227   QString s = startDate.toString("yyyyMMddhhmmss");
00228   key.data = (char *) s.latin1();
00229   key.size = s.length() + 1;
00230   cur->c_get(cur, &key, &data, DB_SET_RANGE);
00231   int ret = cur->c_get(cur, &key, &data, DB_NEXT);
00232   if (ret)
00233   {
00234 //    char *err = db_strerror(ret);
00235 //    qDebug("%s %s", s.latin1(), err);
00236     cur->c_close(cur);
00237     return;
00238   }
00239   s = (char *) key.data;
00240   getBar(dbbar, s, bar);
00241   cur->c_close(cur);
00242 }
00243 
00244 void DbPlugin::getSearchBar (QDateTime &startDate, Bar &bar)
00245 {
00246   DBT key, data;
00247   DBC *cur;
00248   memset(&key, 0, sizeof(DBT));
00249   memset(&data, 0, sizeof(DBT));
00250 
00251   DBBar dbbar;
00252   memset(&dbbar, 0, sizeof(DBBar));
00253   data.data = &dbbar;
00254   data.ulen = sizeof(DBBar); 
00255   data.flags = DB_DBT_USERMEM;  
00256 
00257   db->cursor(db, NULL, &cur, 0);
00258 
00259   QString s = startDate.toString("yyyyMMddhhmmss");
00260   key.data = (char *) s.latin1();
00261   key.size = s.length() + 1;
00262   cur->c_get(cur, &key, &data, DB_SET_RANGE);
00263   s = (char *) key.data;
00264   getBar(dbbar, s, bar);
00265   cur->c_close(cur);
00266 }
00267 
00268 void DbPlugin::getHistory (BarData *barData, QDateTime &startDate)
00269 {
00270   switch (type)
00271   {
00272     case Index1:
00273       getIndexHistory(barData, startDate);
00274       barData->createDateList();
00275       return;
00276       break;
00277     case Spread1:
00278       getSpreadHistory(barData, startDate);
00279       barData->createDateList();
00280       return;
00281       break;
00282     case CC1:
00283       getCCHistory(barData, startDate);
00284       barData->createDateList();
00285       return;
00286       break;
00287     default:
00288       break;
00289   }
00290 
00291   DBT key, data;
00292   DBC *cur;
00293   memset(&key, 0, sizeof(DBT));
00294   memset(&data, 0, sizeof(DBT));
00295 
00296   DBBar dbbar;
00297   memset(&dbbar, 0, sizeof(DBBar));
00298   data.data = &dbbar;
00299   data.ulen = sizeof(DBBar); 
00300   data.flags = DB_DBT_USERMEM;  
00301 
00302   db->cursor(db, NULL, &cur, 0);
00303 
00304   QString s = startDate.toString("yyyyMMddhhmmss");
00305   key.data = (char *) s.latin1();
00306   key.size = s.length() + 1;
00307   cur->c_get(cur, &key, &data, DB_SET_RANGE);
00308 
00309   while (! cur->c_get(cur, &key, &data, DB_PREV))
00310   {
00311     if (barData->count() >= barRange)
00312       break;
00313     Bar bar;
00314     s = (char *) key.data;
00315     getBar(dbbar, s, bar);
00316     bar.setTickFlag(barData->getBarType());
00317     barData->prepend(bar);
00318   }
00319   
00320   cur->c_close(cur);
00321   barData->createDateList();
00322 }
00323 
00324 void DbPlugin::getAllBars (BarData *bars)
00325 {
00326   DBT key, data;
00327   DBC *cur;
00328   memset(&key, 0, sizeof(DBT));
00329   memset(&data, 0, sizeof(DBT));
00330 
00331   DBBar dbbar;
00332   memset(&dbbar, 0, sizeof(DBBar));
00333   data.data = &dbbar;
00334   data.ulen = sizeof(DBBar); 
00335   data.flags = DB_DBT_USERMEM;  
00336 
00337   db->cursor(db, NULL, &cur, 0);
00338 
00339   while (! cur->c_get(cur, &key, &data, DB_PREV))
00340   {
00341     Bar bar;
00342     QString s = (char *) key.data;
00343     getBar(dbbar, s, bar);
00344     bar.setTickFlag(bars->getBarType());
00345     bars->prependRaw(bar);
00346   }
00347 
00348   cur->c_close(cur);
00349 }
00350 
00351 DbPlugin::DbType DbPlugin::getType (QString &d)
00352 {
00353   DbPlugin::DbType t = Stock1;
00354 
00355   while (1)
00356   {
00357     if (! d.compare("Stock"))
00358     {
00359       t = Stock1;
00360       break;
00361     }
00362 
00363     if (! d.compare("Futures"))
00364     {
00365       t = Futures1;
00366       break;
00367     }
00368 
00369     if (! d.compare("Spread"))
00370     {
00371       t = Spread1;
00372       break;
00373     }
00374 
00375     if (! d.compare("Index"))
00376     {
00377       t = Index1;
00378       break;
00379     }
00380 
00381     if (! d.compare("CC"))
00382     {
00383       t = CC1;
00384       break;
00385     }
00386 
00387     break;
00388   }
00389 
00390   return t;
00391 }
00392 
00393 void DbPlugin::getBar (DBBar &d, QString &k, Bar &bar)
00394 {
00395   if (bar.setDate(k))
00396     return;
00397   bar.setOpen(d.open);
00398   bar.setHigh(d.high);
00399   bar.setLow(d.low);
00400   bar.setClose(d.close);
00401   bar.setVolume(d.volume);
00402   bar.setOI(d.oi);
00403 }
00404 
00405 void DbPlugin::setBar (Bar &bar)
00406 {
00407   DBT key, data;
00408   memset(&key, 0, sizeof(DBT));
00409   memset(&data, 0, sizeof(DBT));
00410 
00411   DBBar dbbar;
00412   memset(&dbbar, 0, sizeof(DBBar));
00413   data.data = &dbbar;
00414   data.size = sizeof(DBBar); 
00415   
00416   QString s;
00417   bar.getDateTimeString(FALSE, s);
00418   key.data = (char *) s.latin1();
00419   key.size = s.length() + 1;
00420   dbbar.open = bar.getOpen();
00421   dbbar.high = bar.getHigh();
00422   dbbar.low = bar.getLow();
00423   dbbar.close = bar.getClose();
00424   dbbar.volume = bar.getVolume();
00425   dbbar.oi = (int) bar.getOI();
00426 
00427   db->put(db, NULL, &key, &data, 0);
00428 }
00429 
00430 bool DbPlugin::createNewStock ()
00431 {
00432   QString s;
00433   DBIndexItem item;
00434   chartIndex->getIndexItem(indexKey, item);
00435   item.getSymbol(s);
00436   if (s.length())
00437   {
00438     qDebug("DbPlugin::createNewStock: duplicate symbol %s", s.latin1());
00439     return TRUE;
00440   }
00441 
00442   type = Stock1;
00443   s = "Stock";
00444   item.setType(s);
00445   item.setTitle(indexKey);
00446   item.setSymbol(indexKey);
00447   chartIndex->setIndexItem(indexKey, item);
00448   return FALSE;
00449 }
00450 
00451 bool DbPlugin::createNewFutures ()
00452 {
00453   QString s;
00454   DBIndexItem item;
00455   chartIndex->getIndexItem(indexKey, item);
00456   item.getSymbol(s);
00457   if (s.length())
00458   {
00459     qDebug("DbPlugin::createNewStock: duplicate symbol %s", s.latin1());
00460     return TRUE;
00461   }
00462 
00463   type = Futures1;
00464   FuturesData fd;
00465   if (fd.setSymbolPath(symbol))
00466     return TRUE;
00467 
00468   s = "Futures";
00469   item.setType(s);
00470 
00471   fd.getName(s);
00472   item.setTitle(s);
00473 
00474   item.setSymbol(indexKey);
00475       
00476   fd.getSymbol(s);
00477   item.setFuturesType(s);
00478       
00479   s = symbol.right(1);
00480   item.setFuturesMonth(s);
00481 
00482   chartIndex->setIndexItem(indexKey, item);
00483 
00484   return FALSE;
00485 }
00486 
00487 bool DbPlugin::createNewIndex (DBIndex *i)
00488 {
00489   bool ok = FALSE;
00490   QString sym = QInputDialog::getText(QObject::tr("New Index"),
00491                                       QObject::tr("Enter symbol name for the new Index"),
00492                                       QLineEdit::Normal,
00493                                       QString::null,
00494                                       &ok,
00495                                       0);
00496   if (! sym.length() || ok == FALSE)
00497     return TRUE;
00498 
00499   QDir dir;
00500   Config config;
00501   QString s;
00502   config.getData(Config::DataPath, s);
00503   s.append("/Index");
00504   if (! dir.exists(s))
00505   {
00506     if (! dir.mkdir(s, TRUE))
00507     {
00508       QMessageBox::information(0,
00509                                QObject::tr("Qtstalker: Error"),
00510                                QObject::tr("Could not create ~/.qtstalker/data/Index directory."));
00511       return TRUE;
00512     }
00513   }
00514   
00515   s.append("/" + sym);
00516   if (dir.exists(s))
00517   {
00518     QMessageBox::information(0,
00519                              QObject::tr("Qtstalker: Error"),
00520                              QObject::tr("This Index already exists."));
00521     return TRUE;
00522   }
00523 
00524   DBIndexItem item;
00525   QString ts;
00526   chartIndex->getIndexItem(sym, item);
00527   item.getSymbol(ts);
00528   if (ts.length())
00529   {
00530     qDebug("DbPlugin::createNewStock: duplicate symbol %s", ts.latin1());
00531     return TRUE;
00532   }
00533 
00534   if (open(s, i))
00535   {
00536     QMessageBox::information(0,
00537                              QObject::tr("Qtstalker: Error"),
00538                              QObject::tr("Disk error, cannot create chart"));
00539     return TRUE;
00540   }
00541 
00542   type = Index1;
00543   item.setSymbol(sym);
00544   s = "Index";
00545   item.setType(s);
00546   item.setTitle(sym);
00547   chartIndex->setIndexItem(indexKey, item);
00548 
00549   indexPref();
00550   return FALSE;
00551 }
00552 
00553 bool DbPlugin::createNewSpread (DBIndex *i)
00554 {
00555   bool ok = FALSE;
00556   QString sn = QInputDialog::getText(QObject::tr("New Spread"),
00557                                      QObject::tr("Enter symbol name for the new Spread"),
00558                                      QLineEdit::Normal,
00559                                      QString::null,
00560                                      &ok,
00561                                      0);
00562   if (! sn.length() || ok == FALSE)
00563     return TRUE;
00564 
00565   QDir dir;
00566   Config config;
00567   QString s;
00568   config.getData(Config::DataPath, s);
00569   s.append("/Spread");
00570   if (! dir.exists(s))
00571   {
00572     if (! dir.mkdir(s, TRUE))
00573     {
00574       QMessageBox::information(0, QObject::tr("Qtstalker: Error"), QObject::tr("Could not create Spread directory."));
00575       return TRUE;
00576     }
00577   }
00578  
00579   s.append("/" + sn);
00580   if (dir.exists(s))
00581   {
00582     QMessageBox::information(0, QObject::tr("Qtstalker: Error"), QObject::tr("This Spread already exists."));
00583     return TRUE;
00584   }
00585 
00586   DBIndexItem item;
00587   QString ts;
00588   chartIndex->getIndexItem(sn, item);
00589   item.getSymbol(ts);
00590   if (ts.length())
00591   {
00592     qDebug("DbPlugin::createNewStock: duplicate symbol %s", sn.latin1());
00593     return TRUE;
00594   }
00595 
00596 
00597   if (open(s, i))
00598   {
00599     QMessageBox::information(0,
00600                              QObject::tr("Qtstalker: Error"),
00601                              QObject::tr("Disk error, cannot create chart"));
00602     return TRUE;
00603   }
00604 
00605   type = Spread1;
00606   item.setSymbol(indexKey);
00607   s = "Spread";
00608   item.setType(s);
00609   item.setTitle(indexKey);
00610   chartIndex->setIndexItem(indexKey, item);
00611 
00612   spreadPref();
00613   return FALSE;
00614 }
00615 
00616 bool DbPlugin::createNewCC (DBIndex *i)
00617 {
00618   FuturesData fd;
00619   QStringList l;
00620   fd.getSymbolList(l);
00621 
00622   QString pl = QObject::tr("Parms");
00623   QString fsl = QObject::tr("Futures Symbol");
00624   QString gl = QObject::tr("Gapless");
00625 
00626   PrefDialog *dialog = new PrefDialog(0);
00627   dialog->setCaption(QObject::tr("New CC"));
00628   dialog->createPage (pl);
00629   dialog->setHelpFile(helpFile);
00630 
00631   dialog->addComboItem(fsl, pl, l, 0);
00632   dialog->addCheckItem(gl, pl, TRUE);
00633 
00634   int rc = dialog->exec();
00635   if (rc != QDialog::Accepted)
00636   {
00637     delete dialog;
00638     return TRUE;
00639   }
00640 
00641   QString sym;
00642   dialog->getCombo(fsl, sym);
00643   bool f = dialog->getCheck(gl);
00644 
00645   delete dialog;
00646 
00647   QDir dir;
00648   Config config;
00649   QString s;
00650   config.getData(Config::DataPath, s);
00651   s.append("/CC");
00652   if (! dir.exists(s))
00653   {
00654     if (! dir.mkdir(s, TRUE))
00655     {
00656       QMessageBox::information(0,
00657                                QObject::tr("Qtstalker: Error"),
00658                                QObject::tr("Could not create ~/.qtstalker/data/CC directory."));
00659       return TRUE;
00660     }
00661   }
00662 
00663   DBIndexItem item;
00664   QString ts;
00665   chartIndex->getIndexItem(sym, item);
00666   item.getSymbol(ts);
00667   if (ts.length())
00668   {
00669     qDebug("DbPlugin::createNewStock: duplicate symbol %s", ts.latin1());
00670     return TRUE;
00671   }
00672 
00673   
00674   s.append("/" + sym);
00675   if (open(s, i))
00676   {
00677     QMessageBox::information(0,
00678                              QObject::tr("Qtstalker: Error"),
00679                              QObject::tr("Disk error, cannot create chart"));
00680     return TRUE;
00681   }
00682 
00683   type = CC1;
00684   item.setSymbol(sym);
00685   s = "CC";
00686   item.setType(s);
00687   s = sym + " - " + QObject::tr("Continuous Adjusted");
00688   item.setTitle(s);
00689   chartIndex->setIndexItem(indexKey, item);
00690 
00691   s = QString::number(f);
00692   sym = "Adjustment";
00693   setData(sym, s);
00694 
00695   return FALSE;
00696 }
00697 
00698 int DbPlugin::dbPrefDialog ()
00699 {
00700   int rc = 0;
00701 
00702   switch (type)
00703   {
00704     case Futures1:
00705       rc = futuresPref();
00706       break;
00707     case Index1:
00708       rc = indexPref();
00709       break;
00710     case Spread1:
00711       rc = spreadPref();
00712       break;
00713     case CC1:
00714       rc = ccPref();
00715       break;
00716     default:
00717       rc = stockPref();
00718       break;
00719   }
00720 
00721   return rc;
00722 }
00723 
00724 int DbPlugin::stockPref ()
00725 {
00726   int rc = 0;
00727   // FIXME: "helpFile" should not be set here, 
00728   // I don't know right now where better placed
00729   helpFile = "stocksplugin.html";
00730   StocksDialog *dialog = new StocksDialog(helpFile, this, chartIndex);
00731   dialog->exec();
00732   rc = dialog->getReloadFlag();
00733   delete dialog;
00734   chartIndex->flush();
00735   return rc;
00736 }
00737 
00738 int DbPlugin::futuresPref ()
00739 {
00740   int rc = 0;
00741   FuturesDialog *dialog = new FuturesDialog(helpFile, this, chartIndex);
00742   dialog->exec();
00743   rc = dialog->getReloadFlag();
00744   delete dialog;
00745   chartIndex->flush();
00746   return rc;
00747 }
00748 
00749 int DbPlugin::indexPref ()
00750 {
00751   int rc = 0;
00752   QString nam, il;
00753   DBIndexItem item;
00754   chartIndex->getIndexItem(indexKey, item);
00755   item.getTitle(nam);
00756 
00757   QString s = "List";
00758   getData(s, il);
00759 
00760   IndexDialog *dialog = new IndexDialog(nam, il);
00761   int trc = dialog->exec();
00762   if (trc == QDialog::Accepted)
00763   {
00764     dialog->getName(nam);
00765     item.setTitle(nam);
00766     dialog->getList(il);
00767     setData(s, il);
00768     chartIndex->setIndexItem(indexKey, item);
00769     rc = TRUE;
00770   }
00771   delete dialog;
00772   return rc;
00773 }
00774 
00775 int DbPlugin::spreadPref ()
00776 {
00777   int rc = 0;
00778   QString pl = QObject::tr("Parms");
00779   QString fsl = QObject::tr("First Symbol");
00780   QString ssl = QObject::tr("Second Symbol");
00781   PrefDialog *dialog = new PrefDialog(0);
00782   dialog->setCaption(QObject::tr("Edit Spread"));
00783   dialog->createPage (pl);
00784   dialog->setHelpFile(helpFile);
00785 
00786   Config config;
00787   QString s, s3;
00788   config.getData(Config::DataPath, s);
00789 
00790   QString s2 = "FirstSymbol";
00791   getData(s2, s3);
00792   dialog->addSymbolItem(fsl, pl, s, s3);
00793 
00794   s2 = "SecondSymbol";
00795   getData(s2, s3);
00796   dialog->addSymbolItem(ssl, pl, s, s3);
00797 
00798   int trc = dialog->exec();
00799   if (trc == QDialog::Accepted)
00800   {
00801     dialog->getSymbol(fsl, s);
00802     s2 = "FirstSymbol";
00803     setData(s2, s);
00804 
00805     dialog->getSymbol(ssl, s);
00806     s2 = "SecondSymbol";
00807     setData(s2, s);
00808     rc = TRUE;
00809   }
00810 
00811   delete dialog;
00812   return rc;
00813 }
00814 
00815 int DbPlugin::ccPref ()
00816 {
00817   int rc = 0;
00818   QString pl = QObject::tr("Parms");
00819   QString gl = QObject::tr("Gapless");
00820   PrefDialog *dialog = new PrefDialog(0);
00821   dialog->setCaption(QObject::tr("Edit CC"));
00822   dialog->createPage (pl);
00823   dialog->setHelpFile(helpFile);
00824 
00825   QString s = "Adjustment";
00826   QString s2;
00827   getData(s, s2);
00828   dialog->addCheckItem(gl, pl, s2.toInt());
00829 
00830   int trc = dialog->exec();
00831   if (trc == QDialog::Accepted)
00832   {
00833     s2 = QString::number(dialog->getCheck(gl));
00834     setData(s, s2);
00835     rc = TRUE;
00836   }
00837 
00838   delete dialog;
00839   return rc;
00840 }
00841 
00842 void DbPlugin::getIndexHistory (BarData *barData, QDateTime &startDate)
00843 {
00844   QString s = "List";
00845   QString s2;
00846   getData(s, s2);
00847   QStringList l = QStringList::split(":", s2, FALSE);
00848   if (! l.count())
00849     return;
00850     
00851   QDict<Bar> lookup;
00852   lookup.setAutoDelete(TRUE);
00853   int loop;
00854   int count = 0;
00855   for (loop = 0; loop < (int) l.count(); loop = loop + 2)
00856   {
00857     float weight = l[loop + 1].toFloat();
00858     if (weight == 0)
00859       weight = 1;
00860 
00861     loadIndexData(l[loop], lookup, startDate, weight, barRange, barLength);
00862     count++;
00863   }
00864 
00865   l.clear();
00866   QDictIterator<Bar> it(lookup);
00867   for (; it.current(); ++it)
00868   {
00869     Bar *r = it.current();
00870     if (r->getOI() == count)
00871     {
00872       r->setOpen(r->getOpen() / count);
00873       r->setHigh(r->getHigh() / count);
00874       r->setLow(r->getLow() / count);
00875       r->setClose(r->getClose() / count);
00876       
00877       if (r->getOpen() > r->getHigh())
00878         r->setHigh(r->getOpen());
00879       if (r->getOpen() < r->getLow())
00880         r->setLow(r->getOpen());
00881 
00882       if (r->getClose() > r->getHigh())
00883         r->setHigh(r->getClose());
00884       if (r->getClose() < r->getLow())
00885         r->setLow(r->getClose());
00886 
00887       r->getDateTimeString(FALSE, s);
00888       l.append(s);
00889     }
00890     else
00891       lookup.remove(it.currentKey());
00892   }
00893 
00894   l.sort();
00895   for (loop = l.count() - 1; loop > -1; loop--)
00896   {
00897     Bar *r = lookup.find(l[loop]);
00898     if (r)
00899     {
00900       QDateTime dt;
00901       r->getDate(dt);
00902       Bar tr;
00903       tr.setDate(dt);
00904       tr.setOpen(r->getOpen());
00905       tr.setHigh(r->getHigh());
00906       tr.setLow(r->getLow());
00907       tr.setClose(r->getClose());
00908       barData->prepend(tr);
00909     }
00910   }
00911 }
00912 
00913 void DbPlugin::loadIndexData (QString &symbol, QDict<Bar> &lookup, QDateTime &startDate, float weight,
00914                            int barRange, BarData::BarLength barLength)
00915 {
00916   QFileInfo fi(symbol);
00917   QString fn = fi.fileName();
00918 
00919   DbPlugin db;
00920   if (db.open(symbol, chartIndex))
00921   {
00922     qDebug("Index::getIndexHistory: cannot open symbol chart");
00923     return;
00924   }
00925 
00926   BarData *bar = new BarData(symbol);
00927   bar->setBarLength(barLength);
00928   db.setBarRange(barRange);
00929   db.getHistory(bar, startDate);
00930   db.close();
00931   
00932   int loop;
00933   for (loop = 0; loop < (int) bar->count(); loop++)
00934   {
00935     QDateTime dt;
00936     bar->getDate(loop, dt);
00937     QString s = dt.toString("yyyyMMddhhmmss");
00938     Bar *r = lookup.find(s);
00939     if (! r)
00940     {
00941       r = new Bar;
00942       r->setDate(dt);
00943       r->setOpen(bar->getOpen(loop) * weight);
00944       r->setHigh(bar->getHigh(loop) * weight);
00945       r->setLow(bar->getLow(loop) * weight);
00946       r->setClose(bar->getClose(loop) * weight);
00947       r->setOI(1);
00948       r->getDateTimeString(FALSE, s);
00949       lookup.insert(s, r);
00950     }
00951     else
00952     {
00953       r->setOpen(r->getOpen() + (bar->getOpen(loop) * weight));
00954       r->setHigh(r->getHigh() + (bar->getHigh(loop) * weight));
00955       r->setLow(r->getLow() + (bar->getLow(loop) * weight));
00956       r->setClose(r->getClose() + (bar->getClose(loop) * weight));
00957       r->setOI((int) r->getOI() + 1);
00958     }
00959   }
00960 
00961   delete bar;
00962 }
00963 
00964 void DbPlugin::getSpreadHistory (BarData *barData, QDateTime &startDate)
00965 {
00966   QString s = "FirstSymbol";
00967   QString fs;
00968   getData(s, fs);
00969 
00970   QString ss;
00971   s = "SecondSymbol";
00972   getData(s, ss);
00973 
00974   // get the first symbol bars
00975   QFileInfo fi(fs);
00976   QString fn = fi.fileName();
00977 
00978   DbPlugin db;
00979   if (db.open(fs, chartIndex))
00980   {
00981     qDebug("Spread::getSpreadHistory: cannot open first symbol chart");
00982     return;
00983   }
00984 
00985   BarData *bar = new BarData(fs);
00986   bar->setBarLength(barLength);
00987   db.setBarRange(barRange);
00988   db.getHistory(bar, startDate);
00989   db.close();
00990 
00991   // get the second symbol bars
00992   QFileInfo fi2(ss);
00993   fn = fi2.fileName();
00994 
00995   if (db.open(ss, chartIndex))
00996   {
00997     qDebug("Spread::getSpreadHistory: cannot open second symbol chart");
00998     delete bar;
00999     return;
01000   }
01001 
01002   BarData *bar2 = new BarData(ss);
01003   bar2->setBarLength(barLength);
01004   db.setBarRange(barRange);
01005   db.getHistory(bar2, startDate);
01006   db.close();
01007 
01008   // create lookup dict for first symbol bars
01009   QDict<Bar> lookup;
01010   lookup.setAutoDelete(TRUE);
01011   int loop;
01012   for (loop = 0; loop < bar->count(); loop++)
01013   {
01014     Bar *r = new Bar;
01015     QDateTime dt;
01016     bar->getDate(loop, dt);
01017     r->setDate(dt);
01018     r->setClose(bar->getClose(loop));
01019     r->getDateTimeString(FALSE, s);
01020     lookup.insert(s, r);
01021   }
01022 
01023   // match all second symbol bars
01024   for (loop = bar2->count() - 1; loop > -1; loop--)
01025   {
01026     Bar r;
01027     QDateTime dt;
01028     bar2->getDate(loop, dt);
01029     s = dt.toString("yyyyMMddhhmmss");
01030     Bar *tr = lookup.find(s);
01031     if (tr)
01032     {
01033       double t = tr->getClose() - bar2->getClose(loop);
01034       r.setDate(dt);
01035       r.setOpen(t);
01036       r.setHigh(t);
01037       r.setLow(t);
01038       r.setClose(t);
01039       barData->prepend(r);
01040     }
01041   }
01042 
01043   delete bar;
01044   delete bar2;
01045 }
01046 
01047 void DbPlugin::getCCHistory (BarData *barData, QDateTime &startDate)
01048 {
01049   FuturesData fd;
01050   if (fd.setSymbol(indexKey))
01051   {
01052     qDebug("CC::getCCHistory: invalid futures symbol");
01053     return;
01054   }
01055     
01056   Config config;
01057   QString s;
01058   QString baseDir;
01059   config.getData(Config::DataPath, baseDir);
01060   baseDir.append("/Futures/");
01061   fd.getExchange(s);
01062   baseDir.append(s + "/");
01063   fd.getSymbol(s);
01064   baseDir.append(s);
01065   QDir dir(baseDir);
01066   if (! dir.exists(baseDir, TRUE))
01067     return;
01068   QStringList dirList = dir.entryList();
01069 
01070   QString lastChart;
01071   fd.getCurrentContract(startDate, lastChart);
01072   QString ey = lastChart.right(5);
01073   ey.truncate(4);
01074 
01075   QValueList<Bar> indexList;
01076   int indexCount = -1;
01077 
01078   int dirLoop = dirList.findIndex(lastChart);
01079   if (dirLoop == -1)
01080     dirLoop = dirList.count() - 1;
01081   lastChart = dirList[dirLoop];
01082 
01083   s = "Adjustment";
01084   QString s2;
01085   getData(s, s2);
01086   bool adjustFlag = s2.toInt();
01087 
01088   while (dirLoop > 1)
01089   {
01090     if (indexCount >= barRange)
01091       break;
01092 
01093     s = baseDir + "/" + dirList[dirLoop];
01094 
01095     DbPlugin tdb;
01096     if (tdb.open(s, chartIndex))
01097     {
01098       tdb.close();
01099       dirLoop--;
01100       lastChart = dirList[dirLoop];
01101       continue;
01102     }
01103 
01104     BarData *recordList = new BarData(s);
01105     tdb.setBarRange(barRange);
01106     tdb.setBarLength(barLength);
01107     tdb.getHistory(recordList, startDate);
01108     tdb.close();
01109 
01110     int loop;
01111     QDateTime dt = startDate;
01112     int lastBar = -1;
01113     bool dataFlag = FALSE;
01114     for (loop = recordList->count() - 1; loop > -1; loop--)
01115     {
01116       if (indexCount >= barRange)
01117         break;
01118 
01119       recordList->getDate(loop, dt);
01120       fd.getCurrentContract(dt, s);
01121       if (! s.compare(lastChart))
01122       {
01123         Bar bar;
01124         recordList->getBar(loop, bar);
01125         indexList.prepend(bar);
01126         indexCount++;
01127         startDate = dt;
01128         lastBar = loop;
01129         dataFlag = TRUE;
01130       }
01131     }
01132 
01133     if (dataFlag)
01134     {
01135       if (adjustFlag)
01136       {
01137         Bar bar;
01138         double t = 0;
01139         if (lastBar - 1 > -1)
01140           t = recordList->getClose(lastBar) - recordList->getClose(lastBar - 1);
01141         bar.setClose(t);
01142         bar.setEmptyFlag(TRUE);
01143         indexList.prepend(bar);
01144       }
01145     }
01146 
01147     delete recordList;
01148 
01149     dirLoop--;
01150     lastChart = dirList[dirLoop];
01151   }
01152 
01153   if (! adjustFlag)
01154   {
01155     int loop;
01156     for (loop = 0; loop < (int) indexList.count(); loop++)
01157     {
01158       Bar bar = indexList[loop];
01159       barData->appendRaw(bar);
01160     }
01161 
01162     return;
01163   }
01164 
01165   // adjust the data
01166   double adjust = 0;
01167   double t = 0;
01168   bool flag = FALSE;
01169   Bar prevBar;
01170   int loop;
01171   for (loop = 1; loop < (int) indexList.count(); loop++)
01172   {
01173     Bar bar = indexList[loop];
01174 
01175     if (bar.getEmptyFlag())
01176     {
01177       t = bar.getClose();
01178       flag = TRUE;
01179       continue;
01180     }
01181 
01182     if (flag)
01183     {
01184       adjust = prevBar.getClose() - bar.getClose();
01185       bar.setOpen(bar.getOpen() + t);
01186       bar.setHigh(bar.getHigh() + t);
01187       bar.setLow(bar.getLow() + t);
01188       bar.setClose(bar.getClose() + t);
01189       flag = FALSE;
01190       t = 0;
01191     }
01192 
01193     bar.setOpen(bar.getOpen() + adjust);
01194     bar.setHigh(bar.getHigh() + adjust);
01195     bar.setLow(bar.getLow() + adjust);
01196     bar.setClose(bar.getClose() + adjust);
01197     barData->appendRaw(bar);
01198     prevBar = bar;
01199   }
01200 }
01201 
01202