lib/IndicatorSummary.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 "IndicatorSummary.h"
00023 #include "DbPlugin.h"
00024 #include "IndicatorPlugin.h"
00025 #include "Setting.h"
00026 #include "DataWindow.h"
00027 #include "PrefDialog.h"
00028 #include "Traverse.h"
00029 #include <qdir.h>
00030 #include <qdatetime.h>
00031 #include <qfileinfo.h>
00032 #include <qmessagebox.h>
00033 #include <qfile.h>
00034 #include <math.h> // only for fabs()
00035 #include "XmlWriter.h"
00036 
00037 IndicatorSummary::IndicatorSummary (QStringList &l, int mb, BarData::BarLength bl, DBIndex *i)
00038 {
00039   helpFile = "indicatorsummary.html";
00040   indicatorList = l;
00041   minBars = mb;
00042   barLength = bl;
00043   chartIndex = i;
00044 
00045   indicators.setAutoDelete(TRUE);
00046 }
00047 
00048 IndicatorSummary::~IndicatorSummary ()
00049 {
00050 }
00051 
00052 void IndicatorSummary::run ()
00053 {
00054   PrefDialog *dialog = new PrefDialog;
00055   dialog->setCaption(QObject::tr("Indicator Summary Parms"));
00056   dialog->setHelpFile(helpFile);
00057   
00058   QString pl = QObject::tr("Details");
00059   QString sl = QObject::tr("Group");
00060   
00061   dialog->createPage(pl);
00062 
00063   // get the groups list
00064   QString s;
00065   config.getData(Config::GroupPath, s);
00066   Traverse trav(Traverse::Dir);
00067   trav.traverse(s);
00068   emit signalWakeup();
00069   QStringList l;
00070   trav.getList(l);
00071   dialog->addComboItem(sl, pl, l, l[0]);
00072   
00073   int rc = dialog->exec();
00074   
00075   if (rc != QDialog::Accepted)
00076   {
00077     delete dialog;
00078     return;
00079   }
00080 
00081   loadIndicators();
00082 
00083   QString group;
00084   dialog->getCombo(sl, group);
00085   delete dialog;
00086 
00087   QPtrList<Setting> setList;
00088   setList.setAutoDelete(TRUE);
00089 
00090   int loop;
00091   QDir dir(group);
00092   for (loop = 2; loop < (int) dir.count(); loop++)
00093   {
00094     s = dir.absPath() + "/" + dir[loop];
00095     QFileInfo fi(s);
00096     if (fi.isDir())
00097       continue;
00098 
00099     DbPlugin db;
00100     if (db.open(s, chartIndex))
00101       continue;
00102 
00103     db.setBarRange(minBars);
00104     db.setBarLength(barLength);
00105 
00106     BarData *recordList = new BarData(s);
00107     QDateTime dt = QDateTime::currentDateTime();
00108     db.getHistory(recordList, dt);
00109     db.close();
00110 
00111     emit signalWakeup();
00112 
00113     Setting *fd = new Setting;
00114     setList.append(fd);
00115     QString ts = "Symbol";
00116     s = dir[loop];
00117     fd->setData(ts, s);
00118 
00119     int loop2;
00120     for (loop2 = 0; loop2 < (int) indicators.count(); loop2++)
00121     {
00122       Indicator *i = indicators.at(loop2);
00123       i->getType(s);
00124       IndicatorPlugin *plug = config.getIndicatorPlugin(s);
00125       if (! plug)
00126         continue;
00127 
00128       i->getFile(s);
00129       plug->loadIndicatorSettings(s);
00130       plug->setIndicatorInput(recordList);
00131       Indicator *ri = plug->calculate();
00132 
00133       emit signalWakeup();
00134   
00135       int loop3;
00136       for (loop3 = 0; loop3 < ri->getLines(); loop3++)
00137       {
00138         PlotLine *line = ri->getLine(loop3);
00139         if (! line)
00140           continue;
00141 
00142         if (line->getSize() < 1)
00143           continue;
00144 
00145         if (line->getType() == PlotLine::Bar || line->getType() == PlotLine::Candle ||
00146             line->getType() == PlotLine::Horizontal || line->getType() == PlotLine::Invisible)
00147           continue;
00148 
00149         line->strip(line->getData(line->getSize() - 1), 4, s);
00150         line->getLabel(ts);
00151         fd->setData(ts, s);
00152       }
00153 
00154       delete ri;
00155       emit signalWakeup();
00156     }
00157 
00158     delete recordList;
00159   }
00160 
00161   if (! setList.count())
00162   {
00163     QMessageBox::information(0, tr("Qtstalker: Warning"), tr("No files in group."));
00164     return;
00165   }
00166 
00167   createDataWindow(setList, group);
00168 }
00169 
00170 void IndicatorSummary::loadIndicators ()
00171 {
00172   int loop;
00173   for (loop = 0; loop < (int) indicatorList.count(); loop++)
00174   {
00175     Setting set;
00176     config.getIndicator(indicatorList[loop], set);
00177     if (! set.count())
00178       continue;
00179     
00180     Indicator *i = new Indicator;
00181     i->setIndicator(set, indicatorList[loop]);
00182     if (! i->getEnable())
00183     {
00184       delete i;
00185       continue;
00186     }
00187 
00188     QString plugin;
00189     i->getType(plugin);  
00190     IndicatorPlugin *plug = config.getIndicatorPlugin(plugin);
00191     if (! plug)
00192     {
00193       delete i;
00194       continue;
00195     }
00196 
00197     indicators.append(i);
00198   }
00199 }
00200 
00201 void IndicatorSummary::createDataWindow (QPtrList<Setting> &list, QString &group)
00202 {
00203   DataWindow *dw = new DataWindow(0);
00204   QFileInfo fi(group);
00205 
00206   QString bls;
00207   BarData bd(bls);
00208   QStringList bll;
00209   bd.getBarLengthList(bll);
00210   bls = bll[(int) barLength];
00211 
00212   QDir dir;
00213   QString exportPath;
00214   config.getData(Config::Home, exportPath);
00215   exportPath.append("/export");
00216   if (! dir.exists(exportPath, TRUE))
00217     dir.mkdir(exportPath, TRUE);
00218   QString xmlFileName = exportPath + "/summary-" + fi.fileName() + "-" + bls + ".xml";
00219   QFile xmlFile(xmlFileName);
00220   xmlFile.open(IO_WriteOnly);
00221   XmlWriter xw(&xmlFile);
00222   xw.setAutoNewLine(true);
00223   xw.setIndentSize(2);
00224   xw.writeRaw( "<?xml version=\"1.0\"?>" );
00225   xw.newLine();
00226   xw.writeOpenTag("indicator-summary", AttrMap("xmlns", "http://qtstalker.sourceforge.net/ns/indicator-summary-1.0"));
00227   xw.writeOpenTag("metadata");
00228   xw.writeTaggedString("date-exported", QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
00229   xw.writeTaggedString("group", fi.fileName());
00230   xw.writeTaggedString("bar-length", bls);
00231 // FIXME: How to determine datetime of last bar
00232   xw.writeTaggedString("bar-current", "FIXME: yyyy-MM-dd hh:mm");
00233   xw.writeCloseTag("metadata");
00234   xw.writeOpenTag("data");
00235 
00236   QString s = QObject::tr("Indicator Summary - ") + fi.fileName() + " - " + bls;
00237   dw->setCaption(s);
00238 
00239   int loop;
00240   QStringList klist;
00241   for (loop = 0; loop < (int) list.count(); loop++)
00242   {
00243     Setting *set = list.at(loop);
00244     QStringList l;
00245     set->getKeyList(l);
00246 
00247     int loop2;
00248     for (loop2 = 0; loop2 < (int) l.count(); loop2++)
00249     {
00250       if (klist.findIndex(l[loop2]) == -1)
00251         klist.append(l[loop2]);
00252     }
00253   }
00254 
00255   s = tr("Symbol");
00256   dw->setHeader(0, s);
00257   klist.remove(s);
00258   klist.sort();
00259   klist.prepend(s);
00260   klist.append(s);
00261   for (loop = 0; loop < (int) klist.count(); loop++)
00262   {
00263     s = klist[loop];
00264     dw->setHeader(loop, s);
00265   }
00266 
00267   for (loop = 0; loop < (int) list.count(); loop++)
00268   {
00269     Setting *set = list.at(loop);
00270     QString x = klist[0];
00271     QString x2;
00272     set->getData(x, x2);
00273     xw.writeOpenTag("symbol", AttrMap("name", x2));
00274     int loop2;
00275     for (loop2 = 0; loop2 < (int) klist.count(); loop2++)
00276     {
00277       s = klist[loop2];
00278       QString s2;
00279       set->getData(s, s2);
00280       // If it is a big number, then use zero precision.
00281       bool ok;
00282       double sn = s2.toDouble(&ok);
00283       if (ok) {
00284         if (fabs(sn) > 1000)
00285           s2 = QString::number(sn, 'f', 0);
00286       }
00287       // Write the indicator columns,
00288       // but skip the symbol column which is the first and final columns
00289       if ( (loop2 > 0) && (loop2 < (int) klist.count()-1) )
00290         xw.writeTaggedString("indicator", s2, AttrMap("variable", s));
00291       if (! s2.length())
00292         continue;
00293       dw->setData(loop, loop2, s2);
00294     }
00295     xw.writeCloseTag("symbol");
00296   }
00297 
00298   xw.writeCloseTag("data");
00299   xw.writeCloseTag("indicator-summary");
00300   xmlFile.close();
00301 
00302   dw->show();
00303 }
00304