lib/ExScript.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 "ExScript.h"
00023 #include "PrefDialog.h"
00024 #include <qdict.h>
00025 #include <qcstring.h>
00026 #include <qmessagebox.h>
00027 
00028 ExScript::ExScript ()
00029 {
00030   pluginName = "ExScript";
00031   helpFile = "exscript.html";
00032   colorLabel = "color";
00033   labelLabel = "label"; 
00034   lineTypeLabel = "lineType";   
00035   scriptPathLabel = "scriptPath";       
00036   comlineParmsLabel = "comlineParms";   
00037   pluginLabel = "plugin";
00038   dateLabel = "dateCheck";
00039   openLabel = "openCheck";
00040   highLabel = "highCheck";
00041   lowLabel = "lowCheck";
00042   closeLabel = "closeCheck";
00043   volumeLabel = "volumeCheck";
00044   oiLabel = "oiCheck";
00045   timeoutLabel = "timeout";
00046 
00047   formatList.append(FormatString);
00048   formatList.append(FormatString);
00049   formatList.append(FormatBool);
00050   formatList.append(FormatBool);
00051   formatList.append(FormatBool);
00052   formatList.append(FormatBool);
00053   formatList.append(FormatBool);
00054   formatList.append(FormatBool);
00055   formatList.append(FormatBool);
00056 
00057   proc = 0;
00058 
00059   timer = new QTimer(this);
00060   connect(timer, SIGNAL(timeout()), this, SLOT(timerDone()));
00061 
00062   setDefaults();
00063 }
00064 
00065 ExScript::~ExScript ()
00066 {
00067   if (proc)
00068     delete proc;
00069 
00070   delete timer;
00071 }
00072 
00073 void ExScript::setDefaults ()
00074 {
00075   color.setNamedColor("red");
00076   lineType = PlotLine::Line;
00077   label = pluginName;
00078   dateFlag = FALSE;
00079   openFlag = FALSE;
00080   highFlag = FALSE;
00081   lowFlag = FALSE;
00082   closeFlag = FALSE;
00083   volumeFlag = FALSE;
00084   oiFlag = FALSE;
00085   seconds = 10;
00086 }
00087 
00088 Indicator * ExScript::calculate ()
00089 {
00090   Indicator *output = new Indicator;
00091   output->setDateFlag(dateFlag);
00092   output->setLogScale(logScale);
00093 
00094   output->addLine(doScript());
00095 
00096   return output;
00097 }
00098 
00099 PlotLine * ExScript::doScript ()
00100 {
00101   if (proc)
00102   {
00103     delete proc;
00104     proc = 0;
00105   }
00106 
00107   PlotLine *line = new PlotLine();
00108 
00109   if (! scriptPath.length())
00110   {
00111     qDebug("ExScript::calculate: no script path");
00112     return line;
00113   }
00114 
00115   proc = new QProcess(this);
00116   connect(proc, SIGNAL(readyReadStdout()), this, SLOT(readFromStdout()));
00117   proc->setCommunication(QProcess::Stdin|QProcess::Stdout|QProcess::Stderr);
00118   proc->addArgument(scriptPath);
00119 
00120   QStringList l = QStringList::split(" ", comlineParms, FALSE);
00121   int loop;
00122   for (loop = 0; loop < (int) l.count(); loop++)
00123     proc->addArgument(l[loop]);
00124 
00125   buffer.truncate(0);
00126 
00127   QString s;
00128   if (dateFlag || openFlag || highFlag || lowFlag || closeFlag || volumeFlag || oiFlag)
00129     getInput(s);
00130 
00131   QByteArray ba(s.length());
00132   if (s.length())
00133   {
00134     for (loop = 0; loop < (int) s.length(); loop++)
00135       ba[loop] = s.at(loop).latin1();
00136   }
00137 
00138   if (! proc->launch(ba, NULL))
00139   {
00140     qDebug("ExScript::calculate: error starting script");
00141     delete proc;
00142     proc = 0;
00143     return line;
00144   }
00145 
00146   timer->start(seconds * 1000, FALSE);
00147 
00148   wakeup();
00149 
00150   while (proc->isRunning())
00151   {
00152     usleep(100);
00153     wakeup();
00154   }
00155 
00156   timer->stop();
00157 
00158   if (proc)
00159   {
00160     delete proc;
00161     proc = 0;
00162   }
00163 
00164   if (! buffer.length())
00165   {
00166     qDebug("ExScript::createOutput: output buffer empty");
00167     return line;
00168   }
00169 
00170   l = QStringList::split(",", buffer, FALSE);
00171   for (loop = 0; loop < (int) l.count(); loop++)
00172     line->append(l[loop].toDouble());
00173 
00174   line->setColor(color);
00175   line->setType(lineType);
00176   line->setLabel(label);
00177   return line;
00178 }
00179 
00180 void ExScript::getInput (QString &ss)
00181 {
00182   int loop;
00183   QString s;
00184   for (loop = 0; loop < data->count(); loop++)
00185   {
00186     Bar bar;
00187     data->getBar(loop, bar);
00188 
00189     if (dateFlag)
00190     {
00191       bar.getDateTimeString(FALSE, s);
00192       ss.append(s + ",");
00193     }
00194 
00195     if (openFlag)
00196       ss.append(QString::number(bar.getOpen()) + ",");
00197 
00198     if (highFlag)
00199       ss.append(QString::number(bar.getHigh()) + ",");
00200 
00201     if (lowFlag)
00202       ss.append(QString::number(bar.getLow()) + ",");
00203 
00204     if (closeFlag)
00205       ss.append(QString::number(bar.getClose()) + ",");
00206 
00207     if (volumeFlag)
00208       ss.append(QString::number(bar.getVolume(), 'f', 0) + ",");
00209 
00210     if (oiFlag)
00211       ss.append(QString::number(bar.getOI()) + ",");
00212 
00213     ss.truncate(ss.length() - 1);
00214     ss.append("\n");
00215   }
00216 }
00217 
00218 void ExScript::readFromStdout ()
00219 {
00220   QByteArray ba = proc->readStdout();
00221   int loop;
00222   for (loop = 0; loop < (int) ba.size(); loop++)
00223     buffer.append(ba[loop]);
00224 }
00225 
00226 int ExScript::indicatorPrefDialog (QWidget *w)
00227 {
00228   QString pl2 = QObject::tr("Output");
00229   QString cl = QObject::tr("Color");
00230   QString ll = QObject::tr("Label");
00231   QString ltl = QObject::tr("Line Type");
00232   QString spl = QObject::tr("Script Path");
00233   QString clsl = QObject::tr("Switches");
00234   QString pl = QObject::tr("Input");
00235   QString dl = QObject::tr("Date");
00236   QString ol = QObject::tr("Open");
00237   QString hl = QObject::tr("High");
00238   QString lol = QObject::tr("Low");
00239   QString cll = QObject::tr("Close");
00240   QString vl = QObject::tr("Volume");
00241   QString oil = QObject::tr("Open Interest");
00242   QString tol = QObject::tr("Timeout Seconds");
00243 
00244   PrefDialog *dialog = new PrefDialog(w);
00245   dialog->setCaption(QObject::tr("ExScript Indicator"));
00246   dialog->setHelpFile(helpFile);
00247 
00248   dialog->createPage (pl);
00249   QStringList l;
00250   l.append(scriptPath);
00251   dialog->addFileItem(spl, pl, l, scriptPath);
00252   dialog->addTextItem(clsl, pl, comlineParms);
00253   dialog->addIntItem(tol, pl, seconds, 1, 999);
00254   dialog->addCheckItem(dl, pl, dateFlag);
00255   dialog->addCheckItem(ol, pl, openFlag);
00256   dialog->addCheckItem(hl, pl, highFlag);
00257   dialog->addCheckItem(lol, pl, lowFlag);
00258   dialog->addCheckItem(cll, pl, closeFlag);
00259   dialog->addCheckItem(vl, pl, volumeFlag);
00260   dialog->addCheckItem(oil, pl, oiFlag);
00261 
00262   dialog->createPage(pl2);
00263   dialog->addColorItem(cl, pl2, color);
00264   dialog->addTextItem(ll, pl2, label);
00265   dialog->addComboItem(ltl, pl2, lineTypes, lineType);
00266   
00267   int rc = dialog->exec();
00268   
00269   if (rc == QDialog::Accepted)
00270   {
00271     dialog->getFile(spl, l);
00272     if (l.count())
00273       scriptPath = l[0];
00274     dialog->getText(clsl, comlineParms);
00275     seconds = dialog->getInt(tol);
00276     dateFlag = dialog->getCheck(dl);
00277     openFlag = dialog->getCheck(ol);
00278     highFlag = dialog->getCheck(hl);
00279     lowFlag = dialog->getCheck(lol);
00280     closeFlag = dialog->getCheck(cll);
00281     volumeFlag = dialog->getCheck(vl);
00282     oiFlag = dialog->getCheck(oil);
00283 
00284     dialog->getColor(cl, color);
00285     dialog->getText(ll, label);
00286     lineType = (PlotLine::LineType) dialog->getComboIndex(ltl);
00287     rc = TRUE;
00288   }
00289   else
00290     rc = FALSE;
00291   
00292   delete dialog;
00293   return rc;
00294 }
00295 
00296 void ExScript::setIndicatorSettings (Setting &dict)
00297 {
00298   setDefaults();
00299   
00300   if (! dict.count())
00301     return;
00302   
00303   QString s;
00304   dict.getData(colorLabel, s);
00305   if (s.length())
00306     color.setNamedColor(s);
00307 
00308   dict.getData(labelLabel, s);
00309   if (s.length())
00310     label = s;
00311 
00312   dict.getData(lineTypeLabel, s);
00313   if (s.length())
00314     lineType = (PlotLine::LineType) s.toInt();
00315 
00316   dict.getData(scriptPathLabel, s);
00317   if (s.length())
00318     scriptPath = s;
00319 
00320   dict.getData(comlineParmsLabel, s);
00321   if (s.length())
00322     comlineParms = s;
00323 
00324   dict.getData(dateLabel, s);
00325   if (s.length())
00326     dateFlag = s.toInt();
00327 
00328   dict.getData(openLabel, s);
00329   if (s.length())
00330     openFlag = s.toInt();
00331 
00332   dict.getData(highLabel, s);
00333   if (s.length())
00334     highFlag = s.toInt();
00335 
00336   dict.getData(lowLabel, s);
00337   if (s.length())
00338     lowFlag = s.toInt();
00339 
00340   dict.getData(closeLabel, s);
00341   if (s.length())
00342     closeFlag = s.toInt();
00343 
00344   dict.getData(volumeLabel, s);
00345   if (s.length())
00346     volumeFlag = s.toInt();
00347 
00348   dict.getData(oiLabel, s);
00349   if (s.length())
00350     oiFlag = s.toInt();
00351 
00352   dict.getData(timeoutLabel, s);
00353   if (s.length())
00354     seconds = s.toInt();
00355 }
00356 
00357 void ExScript::getIndicatorSettings (Setting &dict)
00358 {
00359   QString ts = color.name();
00360   dict.setData(colorLabel, ts);
00361   dict.setData(labelLabel, label);
00362   ts = QString::number(lineType);
00363   dict.setData(lineTypeLabel, ts);
00364   dict.setData(scriptPathLabel, scriptPath);
00365   dict.setData(comlineParmsLabel, comlineParms);
00366   ts = QString::number(dateFlag);
00367   dict.setData(dateLabel, ts);
00368   ts = QString::number(openFlag);
00369   dict.setData(openLabel, ts);
00370   ts = QString::number(highFlag);
00371   dict.setData(highLabel, ts);
00372   ts = QString::number(lowFlag);
00373   dict.setData(lowLabel, ts);
00374   ts = QString::number(closeFlag);
00375   dict.setData(closeLabel, ts);
00376   ts = QString::number(volumeFlag);
00377   dict.setData(volumeLabel, ts);
00378   ts = QString::number(oiFlag);
00379   dict.setData(oiLabel, ts);
00380   ts = QString::number(seconds);
00381   dict.setData(timeoutLabel, ts);
00382   dict.setData(pluginLabel, pluginName);
00383 }
00384 
00385 PlotLine * ExScript::calculateCustom (QString &p, QPtrList<PlotLine> &d)
00386 {
00387   // format1: SCRIPT_PATH, COMMAND_LINE_SWITCHES, DATE, OPEN, HIGH, LOW, CLOSE, VOLUME, OI
00388 
00389   if (checkFormat(p, d, 9, 9))
00390     return 0;
00391 
00392   scriptPath = formatStringList[0];
00393   comlineParms = formatStringList[1];
00394 
00395   if (! formatStringList[2].compare("TRUE"))
00396     dateFlag = TRUE;
00397   else
00398     dateFlag = FALSE;
00399 
00400   if (! formatStringList[3].compare("TRUE"))
00401     openFlag = TRUE;
00402   else
00403     openFlag = FALSE;
00404 
00405   if (! formatStringList[4].compare("TRUE"))
00406     highFlag = TRUE;
00407   else
00408     highFlag = FALSE;
00409 
00410   if (! formatStringList[5].compare("TRUE"))
00411     lowFlag = TRUE;
00412   else
00413     lowFlag = FALSE;
00414 
00415   if (! formatStringList[6].compare("TRUE"))
00416     closeFlag = TRUE;
00417   else
00418     closeFlag = FALSE;
00419 
00420   if (! formatStringList[7].compare("TRUE"))
00421     volumeFlag = TRUE;
00422   else
00423     volumeFlag = FALSE;
00424 
00425   if (! formatStringList[8].compare("TRUE"))
00426     oiFlag = TRUE;
00427   else
00428     oiFlag = FALSE;
00429 
00430   return doScript();
00431 }
00432 
00433 void ExScript::formatDialog (QStringList &, QString &rv, QString &rs)
00434 {
00435   rs.truncate(0);
00436   rv.truncate(0);
00437   QString pl = QObject::tr("Parms");
00438   QString vnl = QObject::tr("Variable Name");
00439   QString spl = QObject::tr("Script Path");
00440   QString clsl = QObject::tr("Switches");
00441   QString dl = QObject::tr("Date");
00442   QString ol = QObject::tr("Open");
00443   QString hl = QObject::tr("High");
00444   QString lol = QObject::tr("Low");
00445   QString cll = QObject::tr("Close");
00446   QString vl = QObject::tr("Volume");
00447   QString oil = QObject::tr("Open Interest");
00448 
00449   PrefDialog *dialog = new PrefDialog(0);
00450   dialog->setCaption(QObject::tr("ExScript Format"));
00451   dialog->createPage (pl);
00452   dialog->setHelpFile(helpFile);
00453 
00454   QString s;
00455   dialog->addTextItem(vnl, pl, s);
00456   QStringList l;
00457   dialog->addFileItem(spl, pl, l, scriptPath);
00458   dialog->addTextItem(clsl, pl, comlineParms);
00459   dialog->addCheckItem(dl, pl, dateFlag);
00460   dialog->addCheckItem(ol, pl, openFlag);
00461   dialog->addCheckItem(hl, pl, highFlag);
00462   dialog->addCheckItem(lol, pl, lowFlag);
00463   dialog->addCheckItem(cll, pl, closeFlag);
00464   dialog->addCheckItem(vl, pl, volumeFlag);
00465   dialog->addCheckItem(oil, pl, oiFlag);
00466 
00467   int rc = dialog->exec();
00468   
00469   if (rc == QDialog::Accepted)
00470   {
00471     dialog->getText(vnl, rv);
00472     dialog->getFile(spl, l);
00473     if (l.count())
00474       rs = l[0];
00475     dialog->getText(clsl, comlineParms);
00476     rs.append("," + comlineParms);
00477 
00478     bool t = dialog->getCheck(dl);
00479     if (t)
00480       rs.append(",TRUE");
00481     else
00482       rs.append(",FALSE");
00483     
00484     t = dialog->getCheck(ol);
00485     if (t)
00486       rs.append(",TRUE");
00487     else
00488       rs.append(",FALSE");
00489 
00490     t = dialog->getCheck(hl);
00491     if (t)
00492       rs.append(",TRUE");
00493     else
00494       rs.append(",FALSE");
00495 
00496     t = dialog->getCheck(lol);
00497     if (t)
00498       rs.append(",TRUE");
00499     else
00500       rs.append(",FALSE");
00501 
00502     t = dialog->getCheck(cll);
00503     if (t)
00504       rs.append(",TRUE");
00505     else
00506       rs.append(",FALSE");
00507 
00508     t = dialog->getCheck(vl);
00509     if (t)
00510       rs.append(",TRUE");
00511     else
00512       rs.append(",FALSE");
00513 
00514     t = dialog->getCheck(oil);
00515     if (t)
00516       rs.append(",TRUE");
00517     else
00518       rs.append(",FALSE");
00519   }
00520 
00521   delete dialog;
00522 }
00523 
00524 void ExScript::timerDone ()
00525 {
00526   if (! proc->isRunning())
00527     return;
00528 
00529   int rc = QMessageBox::warning(0,
00530                                 tr("ExScript Warning"),
00531                                 tr("Script timeout. Cancel process?"),
00532                                 QMessageBox::Yes,
00533                                 QMessageBox::No,
00534                                 QMessageBox::NoButton);
00535 
00536   if (rc == QMessageBox::No)
00537   {
00538     timer->start(seconds * 1000, FALSE);
00539     return;
00540   }
00541 
00542   proc->kill();
00543   delete proc;
00544   proc = 0;
00545 }
00546