lib/TALIB.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 "TALIB.h"
00023 #include "PrefDialog.h"
00024 #include <qdict.h>
00025 #include <qobject.h>
00026 #include <qinputdialog.h>
00027 
00028 TALIB::TALIB ()
00029 {
00030   pluginName = "TALIB";
00031   helpFile = "talib.html";
00032 
00033   setDefaults();
00034 }
00035 
00036 TALIB::~TALIB ()
00037 {
00038   TA_Shutdown();  
00039 }
00040 
00041 void TALIB::setDefaults ()
00042 {
00043   getIndicatorList(methodList);
00044 
00045   TA_RetCode rc = TA_Initialize();
00046   if (rc != TA_SUCCESS)
00047     qDebug("TALIB::setDefaults:error on TA_Initialize");
00048 }
00049 
00050 Indicator * TALIB::calculate ()
00051 {
00052   Indicator *output = new Indicator;
00053   output->setDateFlag(dateFlag);
00054   output->setLogScale(logScale);
00055 
00056   // open a TALIB handle
00057   const TA_FuncHandle *handle;
00058   QString ts = "method";
00059   QString ts2;
00060   parms.getData(ts, ts2);
00061   TA_RetCode retCode = TA_GetFuncHandle(ts2, &handle);
00062   if (retCode != TA_SUCCESS)
00063   {
00064     qDebug("TALIB::calculate:can't open handle");
00065     return output;
00066   }
00067 
00068   // get info on the function
00069   const TA_FuncInfo *theInfo;
00070   retCode = TA_GetFuncInfo(handle, &theInfo);
00071   if (retCode != TA_SUCCESS)
00072   {
00073     qDebug("TALIB::calculate:can't get function info");
00074     return output;
00075   }
00076 
00077   // create parm holder
00078   TA_ParamHolder *parmHolder;
00079   retCode = TA_ParamHolderAlloc(handle, &parmHolder);
00080   if (retCode != TA_SUCCESS)
00081   {
00082     qDebug("TALIB::calculate:can't create parm holder");
00083     return output;
00084   }
00085 
00086   // create and populate the input arrays
00087   int loop = data->count();
00088   TA_Real open[loop];
00089   TA_Real high[loop];
00090   TA_Real low[loop];
00091   TA_Real close[loop];
00092   TA_Real volume[loop];
00093   TA_Real oi[loop];
00094   for (loop = 0; loop < data->count(); loop++)
00095   {
00096     open[loop] = (TA_Real) data->getOpen(loop);
00097     high[loop] = (TA_Real) data->getHigh(loop);
00098     low[loop] = (TA_Real) data->getLow(loop);
00099     close[loop] = (TA_Real) data->getClose(loop);
00100     volume[loop] = (TA_Real) data->getVolume(loop);
00101     oi[loop] = (TA_Real) data->getOI(loop);
00102   }
00103 
00104   // setup the input arrays
00105   const TA_InputParameterInfo *inputParms;
00106   for (loop = 0; loop < (int) theInfo->nbInput; loop++ )
00107   {
00108     TA_GetInputParameterInfo(theInfo->handle, loop, &inputParms);
00109     QString s;
00110     int tint = 3;
00111     switch (inputParms->type)
00112     {
00113       case TA_Input_Price:
00114         retCode = TA_SetInputParamPricePtr(parmHolder, loop, &open[0], &high[0], &low[0],
00115                                            &close[0], &volume[0], &oi[0]);
00116         if (retCode != TA_SUCCESS)
00117           qDebug("TALIB::calculate:cannot set input prices");
00118         break;
00119       case TA_Input_Real:
00120         s = QObject::tr("input") + QString::number(loop + 1);
00121         tint = parms.getInt(s);
00122         switch (tint)
00123         {
00124           case 0:
00125             retCode = TA_SetInputParamRealPtr(parmHolder, loop, &open[0]);
00126             if (retCode != TA_SUCCESS)
00127               qDebug("TALIB::calculate:cannot set real price");
00128             break;
00129           case 1:
00130             retCode = TA_SetInputParamRealPtr(parmHolder, loop, &high[0]);
00131             if (retCode != TA_SUCCESS)
00132               qDebug("TALIB::calculate:cannot set real price");
00133             break;
00134           case 2:
00135             retCode = TA_SetInputParamRealPtr(parmHolder, loop, &low[0]);
00136             if (retCode != TA_SUCCESS)
00137               qDebug("TALIB::calculate:cannot set real price");
00138             break;
00139           case 3:
00140             retCode = TA_SetInputParamRealPtr(parmHolder, loop, &close[0]);
00141             if (retCode != TA_SUCCESS)
00142               qDebug("TALIB::calculate:cannot set real price");
00143             break;
00144           case 4:
00145             retCode = TA_SetInputParamRealPtr(parmHolder, loop, &volume[0]);
00146             if (retCode != TA_SUCCESS)
00147               qDebug("TALIB::calculate:cannot set integer price");
00148             break;
00149           case 5:
00150             retCode = TA_SetInputParamRealPtr(parmHolder, loop, &oi[0]);
00151             if (retCode != TA_SUCCESS)
00152               qDebug("TALIB::calculate:cannot set integer price");
00153             break;
00154           default:
00155             break;
00156         }
00157         break;
00158       case TA_Input_Integer:
00159         break;
00160       default:
00161         break;
00162     }
00163   }
00164 
00165   // setup the optinput parms
00166   const TA_OptInputParameterInfo *optInfo;
00167   for (loop = 0; loop < (int) theInfo->nbOptInput; loop++ )
00168   {
00169     TA_GetOptInputParameterInfo(theInfo->handle, loop, &optInfo);
00170     QString s = optInfo->displayName;
00171     switch (optInfo->type)
00172     {
00173       case TA_OptInput_RealRange:
00174         retCode = TA_SetOptInputParamReal(parmHolder, loop, (TA_Real) parms.getDouble(s));
00175         if (retCode != TA_SUCCESS)
00176           qDebug("TALIB::calculate:cannot set inputopt real");
00177         break;
00178       case TA_OptInput_IntegerRange:
00179         retCode = TA_SetOptInputParamInteger(parmHolder, loop, (TA_Integer) parms.getInt(s));
00180         if (retCode != TA_SUCCESS)
00181           qDebug("TALIB::calculate:cannot set inputopt integer");
00182         break;
00183       case TA_OptInput_IntegerList:
00184         retCode = TA_SetOptInputParamInteger(parmHolder, loop, (TA_Integer) parms.getInt(s));
00185         if (retCode != TA_SUCCESS)
00186           qDebug("TALIB::calculate:cannot set inputopt integerlist");
00187         break;
00188       default:
00189         break;
00190     }
00191   }
00192 
00193   // setup the output arrays
00194   TA_Real out1[data->count()];
00195   TA_Real out2[data->count()];
00196   TA_Real out3[data->count()];
00197   TA_Integer out4[data->count()];
00198   const TA_OutputParameterInfo *outInfo;
00199   for (loop = 0; loop < (int) theInfo->nbOutput; loop++)
00200   {
00201     retCode = TA_GetOutputParameterInfo(handle, loop, &outInfo);
00202     if (retCode != TA_SUCCESS)
00203     {
00204       qDebug("TALIB::calculate:cannot get output info");
00205       continue;
00206     }
00207 
00208     switch (loop)
00209     {
00210       case 0:
00211         if (outInfo->type == TA_Output_Integer)
00212         {
00213           retCode = TA_SetOutputParamIntegerPtr(parmHolder, loop, &out4[0]);
00214           if (retCode != TA_SUCCESS)
00215             qDebug("TALIB::calculate:cannot set output4");
00216         }
00217         else
00218         {
00219           retCode = TA_SetOutputParamRealPtr(parmHolder, loop, &out1[0]);
00220           if (retCode != TA_SUCCESS)
00221             qDebug("TALIB::calculate:cannot set output1");
00222         }
00223         break;      
00224       case 1:
00225         retCode = TA_SetOutputParamRealPtr(parmHolder, loop, &out2[0]);
00226         if (retCode != TA_SUCCESS)
00227           qDebug("TALIB::calculate:cannot set output2");
00228         break;      
00229       case 2:
00230         retCode = TA_SetOutputParamRealPtr(parmHolder, loop, &out3[0]);
00231         if (retCode != TA_SUCCESS)
00232           qDebug("TALIB::calculate:cannot set output3");
00233         break;
00234       default:
00235         break;
00236     }
00237   }
00238 
00239   // call the function
00240   TA_Integer start = 0;
00241   TA_Integer end = data->count() - 1;
00242   TA_Integer outstart;
00243   TA_Integer count;
00244   retCode = TA_CallFunc(parmHolder, start, end, &outstart, &count);
00245   if (retCode != TA_SUCCESS)
00246     qDebug("TALIB::calculate:call function failed");
00247   else
00248   {
00249     // create the plotlines
00250     const TA_OutputParameterInfo *outInfo;
00251     for (loop = 0; loop < (int) theInfo->nbOutput; loop++ )
00252     {
00253       TA_GetOutputParameterInfo(theInfo->handle, loop, &outInfo);
00254       QString base = outInfo->paramName;
00255       base = base.right(base.length() - 3);
00256       if (! base.left(4).compare("Real"))
00257         base = base.right(base.length() - 4);
00258       if (! base.left(7).compare("Integer"))
00259         base = base.right(base.length() - 7);
00260       if (! base.length())
00261         base = QObject::tr("Plot");
00262 
00263       PlotLine *line = new PlotLine;
00264 
00265       QString s = base + " " + QObject::tr("Color");
00266       parms.getData(s, ts);
00267       QColor color(ts);
00268       line->setColor(color);
00269 
00270       s = base + " " + QObject::tr("Label");
00271       parms.getData(s, ts);
00272       line->setLabel(ts);
00273 
00274       s = base + " " + QObject::tr("Line Type");
00275       line->setType((PlotLine::LineType)parms.getInt(s));
00276 
00277       retCode = TA_GetOutputParameterInfo(handle, loop, &outInfo);
00278       if (retCode != TA_SUCCESS)
00279       {
00280         qDebug("TALIB::calculate:cannot get output info");
00281         delete line;
00282         continue;
00283       }
00284 
00285       int loop2;
00286       switch (loop)
00287       {
00288         case 0:
00289           if (outInfo->type == TA_Output_Integer)
00290           {
00291             for (loop2 = 0; loop2 < count; loop2++)
00292               line->append((double) out4[loop2]);
00293           }
00294           else
00295           {
00296             for (loop2 = 0; loop2 < count; loop2++)
00297               line->append((double) out1[loop2]);
00298           }
00299           break;      
00300         case 1:
00301           for (loop2 = 0; loop2 < count; loop2++)
00302             line->append((double) out2[loop2]);
00303           break;      
00304         case 2:
00305           for (loop2 = 0; loop2 < count; loop2++)
00306             line->append((double) out3[loop2]);
00307           break;
00308         default:
00309           break;
00310       }
00311 
00312       if (line->getType() == PlotLine::Histogram || line->getType() == PlotLine::HistogramBar)
00313         output->prependLine(line);
00314       else
00315         output->addLine(line);
00316     }
00317   }
00318 
00319   retCode = TA_ParamHolderFree(parmHolder);
00320   if (retCode != TA_SUCCESS)
00321     qDebug("TALIB::calculate:can't delete parm holder");
00322 
00323   return output;
00324 }
00325 
00326 int TALIB::indicatorPrefDialog (QWidget *w)
00327 {
00328   const TA_FuncHandle *handle;
00329   const TA_FuncInfo *theInfo;
00330  
00331   // open a TALIB handle
00332   QString ts = "method";
00333   QString ts2;
00334   parms.getData(ts, ts2);
00335   TA_RetCode retCode = TA_GetFuncHandle(ts2, &handle);
00336   if (retCode != TA_SUCCESS)
00337   {
00338     qDebug("TALIB::indicatorPrefDialog:can't open handle");
00339     return FALSE;
00340   }
00341 
00342   // get info on the function
00343   retCode = TA_GetFuncInfo(handle, &theInfo);
00344   if (retCode != TA_SUCCESS)
00345   {
00346     qDebug("TALIB::indicatorPrefDialog:can't get function info");
00347     return FALSE;
00348   }
00349 
00350   QString pl = QObject::tr("Parms");
00351   PrefDialog *dialog = new PrefDialog(w);
00352   dialog->setCaption(QObject::tr("TALIB Indicator"));
00353   dialog->createPage (pl);
00354   dialog->setHelpFile(helpFile);
00355 
00356   QStringList mal;
00357   getMATypes(mal);
00358   mal.remove("Wilder");
00359 
00360   // get the input parms
00361   const TA_OptInputParameterInfo *optInfo;
00362   int loop;
00363   for (loop = 0; loop < (int) theInfo->nbOptInput; loop++ )
00364   {
00365     TA_GetOptInputParameterInfo(theInfo->handle, loop, &optInfo);
00366     QString s = optInfo->displayName;
00367     switch (optInfo->type)
00368     {
00369       case TA_OptInput_RealRange:
00370         parms.getData(s, ts);
00371         if (! ts.length())
00372         {
00373           dialog->addDoubleItem(s, pl, (double) optInfo->defaultValue, 0, 99999999);
00374           ts = QString::number((double) optInfo->defaultValue);
00375           parms.setData(s, ts);
00376         }
00377         else
00378           dialog->addDoubleItem(s, pl, parms.getDouble(s), 0, 99999999);
00379         break;
00380       case TA_OptInput_IntegerRange:
00381         parms.getData(s, ts);
00382         if (! ts.length())
00383         {
00384           dialog->addIntItem(s, pl, (int) optInfo->defaultValue, 1, 999999);
00385           ts = QString::number((int) optInfo->defaultValue);
00386           parms.setData(s, ts);
00387         }
00388         else
00389           dialog->addIntItem(s, pl, parms.getInt(s), 1, 999999);
00390         break;
00391       case TA_OptInput_IntegerList:
00392         parms.getData(s, ts);
00393         if (! ts.length())
00394         {
00395           dialog->addComboItem(s, pl, mal, (int) optInfo->defaultValue);
00396           ts = QString::number((int) optInfo->defaultValue);
00397           parms.setData(s, ts);
00398         }
00399         else
00400           dialog->addComboItem(s, pl, mal, parms.getInt(s));
00401         break;
00402       case TA_OptInput_RealList:
00403         break;
00404       default:
00405         break;
00406     }
00407   }
00408 
00409   // check for any array inputs
00410   const TA_InputParameterInfo *inputParms;
00411   for (loop = 0; loop < (int) theInfo->nbInput; loop++ )
00412   {
00413     QString s = QObject::tr("input") + QString::number(loop + 1);
00414     TA_GetInputParameterInfo(theInfo->handle, loop, &inputParms);
00415     switch (inputParms->type)
00416     {
00417       case TA_Input_Real:
00418         parms.getData(s, ts);
00419         if (! ts.length())
00420         {
00421           dialog->addComboItem(s, pl, inputTypeList, (int) BarData::Close);
00422           ts = QString::number(BarData::Close);
00423           parms.setData(s, ts);
00424         }
00425         else
00426           dialog->addComboItem(s, pl, inputTypeList, parms.getInt(s));
00427         break;
00428       default:
00429         break;
00430     }
00431   }
00432 
00433   // setup the output plots
00434   const TA_OutputParameterInfo *outInfo;
00435   for (loop = 0; loop < (int) theInfo->nbOutput; loop++ )
00436   {
00437     TA_GetOutputParameterInfo(theInfo->handle, loop, &outInfo);
00438 
00439     pl = outInfo->paramName;
00440     pl = pl.right(pl.length() - 3);
00441     if (! pl.left(4).compare("Real"))
00442       pl = pl.right(pl.length() - 4);
00443     if (! pl.left(7).compare("Integer"))
00444       pl = pl.right(pl.length() - 7);
00445     if (! pl.length())
00446       pl = QObject::tr("Plot");
00447     dialog->createPage (pl);
00448 
00449     QString s = pl + " " + QObject::tr("Color");
00450     QColor color;
00451     if (loop == 0)
00452       color.setNamedColor("red");
00453     else
00454     {
00455       if (loop == 1)
00456         color.setNamedColor("yellow");
00457       else
00458         color.setNamedColor("blue");
00459     }
00460     parms.getData(s, ts);
00461     if (! ts.length())
00462     {
00463       dialog->addColorItem(s, pl, color);
00464       ts = color.name();
00465       parms.setData(s, ts);
00466     }
00467     else
00468     {
00469       parms.getData(s, ts);
00470       color.setNamedColor(ts);
00471       dialog->addColorItem(s, pl, color);
00472     }
00473 
00474     s = pl + " " + QObject::tr("Label");
00475     parms.getData(s, ts);
00476     if (! ts.length())
00477     {
00478       dialog->addTextItem(s, pl, pl);
00479       parms.setData(s, pl);
00480     }
00481     else
00482     {
00483       parms.getData(s, ts);
00484       dialog->addTextItem(s, pl, ts);
00485     }
00486 
00487     s = pl + " " + QObject::tr("Line Type");
00488     parms.getData(s, ts);
00489     if (! ts.length()) 
00490     {
00491       switch (outInfo->flags)
00492       {
00493         case TA_OUT_DOT_LINE:
00494           ts = QString::number(PlotLine::Dot);
00495           break;
00496         case TA_OUT_DASH_LINE:
00497           ts = QString::number(PlotLine::Dash);
00498           break;
00499         case TA_OUT_HISTO:
00500           ts = QString::number(PlotLine::Histogram);
00501           break;
00502         default:
00503           ts = QString::number(PlotLine::Line);
00504           break;
00505       }
00506 
00507       dialog->addComboItem(s, pl, lineTypes, ts.toInt());
00508       parms.setData(s, ts);
00509     }
00510     else
00511       dialog->addComboItem(s, pl, lineTypes, parms.getInt(s));
00512   }
00513 
00514   int rc = dialog->exec();
00515   
00516   if (rc == QDialog::Accepted)
00517   {
00518     QStringList l;
00519     parms.getKeyList(l);
00520     int loop;
00521     for (loop = 0; loop < (int) l.count(); loop++)
00522     {
00523       QString s;
00524       dialog->getItem(l[loop], s);
00525       if (s.length())
00526         parms.setData(l[loop], s);
00527     }
00528 
00529     rc = TRUE;
00530   }
00531   else
00532     rc = FALSE;
00533   
00534   delete dialog;
00535   return rc;
00536 }
00537 
00538 void TALIB::getIndicatorSettings (Setting &dict)
00539 {
00540   QString s;
00541   parms.getString(s);
00542   dict.parse(s);
00543   s = "plugin";
00544   dict.setData(s, pluginName);
00545 }
00546 
00547 void TALIB::setIndicatorSettings (Setting &dict)
00548 {
00549   setDefaults();
00550   
00551   if (! dict.count())
00552     return;
00553 
00554   QString s;
00555   dict.getString(s);
00556   parms.parse(s);
00557 }
00558 
00559 void TALIB::getIndicatorList (QStringList &l)
00560 {
00561   l.clear();
00562 
00563   TA_StringTable *table;
00564   int loop;
00565   QStringList cl;
00566 
00567   TA_RetCode retCode = TA_GroupTableAlloc(&table);
00568   if (retCode == TA_SUCCESS)
00569   {
00570     for (loop = 0; loop < (int) table->size; loop++)
00571       cl.append(table->string[loop]);
00572 
00573     TA_GroupTableFree(table);
00574   }
00575 
00576   for (loop = 0; loop < (int) cl.count(); loop++)
00577   {
00578     retCode = TA_FuncTableAlloc(cl[loop], &table);
00579     if (retCode == TA_SUCCESS)
00580     {
00581       int loop2;
00582       for (loop2 = 0; loop2 < (int) table->size; loop2++ )
00583         l.append(table->string[loop2]);
00584 
00585       TA_FuncTableFree(table);
00586     }
00587   }
00588 
00589   l.sort();
00590 }
00591 
00592 PlotLine * TALIB::calculateCustom (QString &p, QPtrList<PlotLine> &d)
00593 {
00594   // format: METHOD, ..., ...., ..... etc (first parm must be the method)
00595 
00596   QStringList l = QStringList::split(",", p, FALSE);
00597 
00598   if (! l.count())
00599   {
00600     qDebug("TALIB::calculateCustom: no method parm");
00601     return 0;
00602   }
00603   
00604   TA_Integer start = 0;
00605   TA_Integer end = data->count() - 1;
00606   if (d.count())
00607     end = d.at(0)->getSize() - 1;
00608   TA_Integer outstart;
00609   TA_Integer count;
00610   PlotLine *line = new PlotLine;
00611   // sometimes are not enough data available
00612   // to calc anything
00613   if(end < 0) 
00614     return line;
00615   
00616   // open a TALIB handle
00617   const TA_FuncHandle *handle;
00618   TA_RetCode retCode = TA_GetFuncHandle(l[0], &handle);
00619   if (retCode != TA_SUCCESS)
00620   {
00621     qDebug("TALIB::calculateCustom:can't open handle");
00622     return 0;
00623   }
00624 
00625   // get info on the function
00626   const TA_FuncInfo *theInfo;
00627   retCode = TA_GetFuncInfo(handle, &theInfo);
00628   if (retCode != TA_SUCCESS)
00629   {
00630     qDebug("TALIB::calculateCustom:can't get function info");
00631     return 0;
00632   }
00633 
00634   // create parm holder
00635   TA_ParamHolder *parmHolder;
00636   retCode = TA_ParamHolderAlloc(handle, &parmHolder);
00637   if (retCode != TA_SUCCESS)
00638   {
00639     qDebug("TALIB::calculateCustom:can't create parm holder");
00640     return 0;
00641   }
00642 
00643   // create and input arrays
00644   int loop = data->count();
00645   TA_Real open[loop];
00646   TA_Real high[loop];
00647   TA_Real low[loop];
00648   TA_Real close[loop];
00649   TA_Real volume[loop];
00650   TA_Real oi[loop];
00651   TA_Real treal[loop];
00652 
00653   int sparmIndex = 1;
00654 
00655   // setup the input arrays
00656   const TA_InputParameterInfo *inputParms;
00657   for (loop = 0; loop < (int) theInfo->nbInput; loop++ )
00658   {
00659     TA_GetInputParameterInfo(theInfo->handle, loop, &inputParms);
00660 
00661     if (inputParms->type == TA_Input_Price)
00662     {
00663       // populate the input arrays
00664       int loop2;
00665       for (loop2 = 0; loop2 < data->count(); loop2++)
00666       {
00667         open[loop2] = (TA_Real) data->getOpen(loop2);
00668         high[loop2] = (TA_Real) data->getHigh(loop2);
00669         low[loop2] = (TA_Real) data->getLow(loop2);
00670         close[loop2] = (TA_Real) data->getClose(loop2);
00671         volume[loop2] = (TA_Real) data->getVolume(loop2);
00672         oi[loop2] = (TA_Real) data->getOI(loop2);
00673       }
00674 
00675       retCode = TA_SetInputParamPricePtr(parmHolder, loop, &open[0], &high[0], &low[0], &close[0],
00676                                          &volume[0], &oi[0]);
00677       if (retCode != TA_SUCCESS)
00678       {
00679         qDebug("TALIB::calculateCustom:cannot set input prices");
00680         return 0;
00681       }
00682     }
00683 
00684     if (inputParms->type == TA_Input_Real)
00685     {
00686       if (! d.count())
00687       {
00688         qDebug("TALIB::calculateCustom: no input");
00689         return 0;
00690       }
00691 
00692       if (sparmIndex >= (int) l.count())
00693       {
00694         qDebug("TALIB::calculateCustom: input invalid number of parms");
00695         return 0;
00696       }
00697 
00698       PlotLine *line =  d.at(0);
00699       int loop2;
00700       for (loop2 = 0; loop2 < line->getSize(); loop2++)
00701         treal[loop2] = (TA_Real) line->getData(loop2);
00702 
00703       retCode = TA_SetInputParamRealPtr(parmHolder, loop, &treal[0]);
00704       if (retCode != TA_SUCCESS)
00705       {
00706         qDebug("TALIB::calculateCustom:cannot set real price");
00707         return 0;
00708       }
00709 
00710       sparmIndex++;
00711     }
00712   }
00713 
00714   if (sparmIndex < (int) l.count())
00715   {
00716     QStringList mal;
00717     getMATypes(mal);
00718     mal.remove("Wilder");
00719     int t = 0;
00720 
00721     // setup the optinput parms
00722     const TA_OptInputParameterInfo *optInfo;
00723     for (loop = 0; loop < (int) theInfo->nbOptInput; loop++ )
00724     {
00725       TA_GetOptInputParameterInfo(theInfo->handle, loop, &optInfo);
00726       switch (optInfo->type)
00727       {
00728         case TA_OptInput_RealRange:
00729           if (sparmIndex >= (int) l.count())
00730           {
00731             qDebug("TALIB::calculateCustom: optinput real invalid number of parms");
00732             return 0;
00733           }
00734 
00735           retCode = TA_SetOptInputParamReal(parmHolder, loop, (TA_Real) l[sparmIndex].toDouble());
00736           if (retCode != TA_SUCCESS)
00737           {
00738             qDebug("TALIB::calculateCustom:cannot set inputopt real");
00739             return 0;
00740           }
00741           sparmIndex++;
00742           break;
00743         case TA_OptInput_IntegerRange:
00744           if (sparmIndex >= (int) l.count())
00745           {
00746             qDebug("TALIB::calculateCustom: optinput integer invalid number of parms");
00747             return 0;
00748           }
00749 
00750           retCode = TA_SetOptInputParamInteger(parmHolder, loop, (TA_Integer) l[sparmIndex].toInt());
00751           if (retCode != TA_SUCCESS)
00752           {
00753             qDebug("TALIB::calculateCustom:cannot set inputopt integer");
00754             return 0;
00755           }
00756           sparmIndex++;
00757           break;
00758 
00759         case TA_OptInput_IntegerList:
00760           if (sparmIndex >= (int) l.count())
00761           {
00762             qDebug("TALIB::calculateCustom: optinput integerList invalid number of parms");
00763             return 0;
00764           }
00765     
00766           t = mal.findIndex(l[sparmIndex]);
00767           if (t == -1)
00768             t = 0;
00769           retCode = TA_SetOptInputParamInteger(parmHolder, loop, (TA_Integer) t);
00770           if (retCode != TA_SUCCESS)
00771           {
00772             qDebug("TALIB::calculateCustom:cannot set inputopt integer");
00773             return 0;
00774           }
00775           sparmIndex++;
00776           break;
00777         default:
00778           break;
00779       }
00780     }
00781   }
00782 
00783   // setup the output arrays
00784   TA_Real out1[data->count()];
00785   TA_Real out2[data->count()];
00786   TA_Real out3[data->count()];
00787   TA_Integer out4[data->count()];
00788   const TA_OutputParameterInfo *outInfo;
00789   for (loop = 0; loop < (int) theInfo->nbOutput; loop++)
00790   {
00791     retCode = TA_GetOutputParameterInfo(handle, loop, &outInfo);
00792     if (retCode != TA_SUCCESS)
00793     {
00794       qDebug("TALIB::calculateCustom:cannot get output info");
00795       return 0;
00796     }
00797 
00798     switch (loop)
00799     {
00800       case 0:
00801         if (outInfo->type == TA_Output_Integer)
00802         {
00803           retCode = TA_SetOutputParamIntegerPtr(parmHolder, loop, &out4[0]);
00804           if (retCode != TA_SUCCESS)
00805           {
00806             qDebug("TALIB::calculateCustom:cannot set output4");
00807             return 0;
00808           }
00809         }
00810         else
00811         {
00812           retCode = TA_SetOutputParamRealPtr(parmHolder, loop, &out1[0]);
00813           if (retCode != TA_SUCCESS)
00814           {
00815             qDebug("TALIB::calculateCustom:cannot set output1");
00816             return 0;
00817           }
00818         }
00819         break;      
00820       case 1:
00821         retCode = TA_SetOutputParamRealPtr(parmHolder, loop, &out2[0]);
00822         if (retCode != TA_SUCCESS)
00823         {
00824           qDebug("TALIB::calculateCustom:cannot set output2");
00825           return 0;
00826         }
00827         break;      
00828       case 2:
00829         retCode = TA_SetOutputParamRealPtr(parmHolder, loop, &out3[0]);
00830         if (retCode != TA_SUCCESS)
00831         {
00832           qDebug("TALIB::calculateCustom:cannot set output3");
00833           return 0;
00834         }
00835         break;
00836       default:
00837         break;
00838     }
00839   }
00840 
00841   // call the function
00842   /*
00843   TA_Integer start = 0;
00844   TA_Integer end = data->count() - 1;
00845   if (d.count())
00846     end = d.at(0)->getSize() - 1;
00847   TA_Integer outstart;
00848   TA_Integer count;
00849   PlotLine *line = new PlotLine;
00850   */
00851   retCode = TA_CallFunc(parmHolder, start, end, &outstart, &count);
00852   if (retCode != TA_SUCCESS)
00853   {
00854     printError(QString("TALIB::calculateCustom:TA_CallFunc"), retCode);
00855     qDebug("p=%s  start=%d  end=%d",p.ascii(), start, end);
00856   }
00857   else
00858   {
00859     // create the plotlines
00860     int loop2;
00861     retCode = TA_GetOutputParameterInfo(handle, 0, &outInfo);
00862     if (retCode != TA_SUCCESS)
00863     {
00864       qDebug("TALIB::calculateCustom:cannot get output info");
00865       return 0;
00866     }
00867     
00868     if (outInfo->type == TA_Output_Integer)
00869     {
00870       for (loop2 = 0; loop2 < count; loop2++)
00871         line->append((double) out4[loop2]);
00872     }
00873     else
00874     {
00875       if (theInfo->nbOutput > 1)
00876       {
00877         bool ok;
00878         l[l.count() - 1].toInt(&ok);
00879         if (! ok)
00880         {
00881           qDebug("TALIB::calculateCustom: parm #%i invalid, not an INTEGER", loop + 1);
00882           return 0;
00883         }
00884 
00885         switch (l[l.count() - 1].toInt(&ok))
00886         {
00887           case 2:
00888             for (loop2 = 0; loop2 < count; loop2++)
00889               line->append((double) out2[loop2]);
00890             break;
00891           case 3:
00892             for (loop2 = 0; loop2 < count; loop2++)
00893               line->append((double) out3[loop2]);
00894             break;
00895           default:
00896             for (loop2 = 0; loop2 < count; loop2++)
00897               line->append((double) out1[loop2]);
00898             break;
00899         }
00900       }
00901       else
00902       {
00903         for (loop2 = 0; loop2 < count; loop2++)
00904           line->append((double) out1[loop2]);
00905       }
00906     }
00907   }
00908 
00909   retCode = TA_ParamHolderFree(parmHolder);
00910   if (retCode != TA_SUCCESS)
00911     qDebug("TALIB::calculateCustom:can't delete parm holder");
00912 
00913   return line;
00914 }
00915 
00916 PlotLine * TALIB::getMA (PlotLine *in, int type, int period)
00917 {
00918   PlotLine *ma = new PlotLine;
00919 
00920   TA_Real input[in->getSize()];
00921   TA_Real out[in->getSize()];
00922   TA_Integer outBeg;
00923   TA_Integer count;
00924   TA_RetCode rc = TA_SUCCESS;
00925 
00926   int loop;
00927   for (loop = 0; loop < in->getSize(); loop++)
00928     input[loop] = (TA_Real) in->getData(loop);
00929 
00930   switch (type)
00931   {
00932     case 0:
00933       rc = TA_MA(0, in->getSize()- 1, &input[0], period, TA_MAType_SMA, &outBeg, &count, &out[0]);
00934       break;
00935     case 1:
00936       rc = TA_MA(0, in->getSize()- 1, &input[0], period, TA_MAType_EMA, &outBeg, &count, &out[0]);
00937       break;
00938     case 2:
00939       rc = TA_MA(0, in->getSize()- 1, &input[0], period, TA_MAType_WMA, &outBeg, &count, &out[0]);
00940       break;
00941     case 3:
00942       rc = TA_MA(0, in->getSize()- 1, &input[0], period, TA_MAType_DEMA, &outBeg, &count, &out[0]);
00943       break;
00944     case 4:
00945       rc = TA_MA(0, in->getSize()- 1, &input[0], period, TA_MAType_TEMA, &outBeg, &count, &out[0]);
00946       break;
00947     case 5:
00948       rc = TA_MA(0, in->getSize()- 1, &input[0], period, TA_MAType_TRIMA, &outBeg, &count, &out[0]);
00949       break;
00950     case 6:
00951       rc = TA_MA(0, in->getSize()- 1, &input[0], period, TA_MAType_KAMA, &outBeg, &count, &out[0]);
00952       break;
00953     case 7:
00954       rc = TA_MA(0, in->getSize()- 1, &input[0], period, TA_MAType_MAMA, &outBeg, &count, &out[0]);
00955       break;
00956     case 8:
00957       rc = TA_MA(0, in->getSize()- 1, &input[0], period, TA_MAType_T3, &outBeg, &count, &out[0]);
00958       break;
00959     default:
00960       break;    
00961   }
00962 
00963   if (rc != TA_SUCCESS)
00964   {
00965     qDebug("TALIB::getMA:error on TALIB function call");
00966     return ma;
00967   }
00968 
00969   for (loop = 0; loop < count; loop++)
00970     ma->append((double) out[loop]);
00971 
00972   return ma;  
00973 }
00974 
00975 void TALIB::formatDialog (QStringList &vl, QString &rv, QString &rs)
00976 {
00977   rs.truncate(0);
00978   rv.truncate(0);
00979 
00980   const TA_FuncHandle *handle;
00981   const TA_FuncInfo *theInfo;
00982  
00983   // open a TALIB handle
00984   TA_RetCode retCode = TA_GetFuncHandle(formatMethod, &handle);
00985   if (retCode != TA_SUCCESS)
00986   {
00987     qDebug("TALIB::getFormatList:can't open handle");
00988     return;
00989   }
00990 
00991   // get info on the function
00992   retCode = TA_GetFuncInfo(handle, &theInfo);
00993   if (retCode != TA_SUCCESS)
00994   {
00995     qDebug("TALIB::getFormatList:can't get function info");
00996     return;
00997   }
00998 
00999   QString pl = QObject::tr("Parms");
01000   QString vnl = QObject::tr("Variable Name");
01001   PrefDialog *dialog = new PrefDialog(0);
01002   dialog->setCaption(QObject::tr("TALIB Format"));
01003   dialog->createPage (pl);
01004   dialog->setHelpFile(helpFile);
01005 
01006   QString s;
01007   dialog->addTextItem(vnl, pl, s);
01008 
01009   // check for any array inputs
01010   const TA_InputParameterInfo *inputParms;
01011   int loop;
01012   for (loop = 0; loop < (int) theInfo->nbInput; loop++ )
01013   {
01014     s = QObject::tr("Input") + QString::number(loop + 1);
01015     TA_GetInputParameterInfo(theInfo->handle, loop, &inputParms);
01016     switch (inputParms->type)
01017     {
01018       case TA_Input_Real:
01019         dialog->addComboItem(s, pl, vl, (int) BarData::Close);
01020         break;
01021       default:
01022         break;
01023     }
01024   }
01025 
01026   QStringList mal;
01027   getMATypes(mal);
01028   mal.remove("Wilder");
01029 
01030   // get the input parms
01031   const TA_OptInputParameterInfo *optInfo;
01032   for (loop = 0; loop < (int) theInfo->nbOptInput; loop++ )
01033   {
01034     TA_GetOptInputParameterInfo(theInfo->handle, loop, &optInfo);
01035     s = optInfo->displayName;
01036     switch (optInfo->type)
01037     {
01038       case TA_OptInput_RealRange:
01039         dialog->addDoubleItem(s, pl, (double) optInfo->defaultValue, 0, 99999999);
01040         break;
01041       case TA_OptInput_IntegerRange:
01042         dialog->addIntItem(s, pl, (int) optInfo->defaultValue, 1, 999999);
01043         break;
01044       case TA_OptInput_IntegerList:
01045         dialog->addComboItem(s, pl, mal, (int) optInfo->defaultValue);
01046         break;
01047       case TA_OptInput_RealList:
01048         break;
01049       default:
01050         break;
01051     }
01052   }
01053 
01054   if (theInfo->nbOutput > 1)
01055   {
01056     s = "Plot";
01057     dialog->addIntItem(s, pl, 1, 1, theInfo->nbOutput);
01058   }
01059 
01060   int rc = dialog->exec();
01061   
01062   if (rc == QDialog::Accepted)
01063   {
01064     dialog->getText(vnl, rv);
01065     rs = formatMethod;
01066 
01067     QString ts;
01068     for (loop = 0; loop < (int) theInfo->nbInput; loop++ )
01069     {
01070       s = QObject::tr("Input") + QString::number(loop + 1);
01071       TA_GetInputParameterInfo(theInfo->handle, loop, &inputParms);
01072       switch (inputParms->type)
01073       {
01074         case TA_Input_Real:
01075           dialog->getCombo(s, ts);
01076           rs.append("," + ts);
01077           break;
01078         default:
01079           break;
01080       }
01081     }
01082 
01083     double d = 0;
01084     int t = 0;
01085     for (loop = 0; loop < (int) theInfo->nbOptInput; loop++ )
01086     {
01087       TA_GetOptInputParameterInfo(theInfo->handle, loop, &optInfo);
01088       s = optInfo->displayName;
01089       switch (optInfo->type)
01090       {
01091         case TA_OptInput_RealRange:
01092           d = dialog->getDouble(s);
01093           rs.append("," + QString::number(d));
01094           break;
01095         case TA_OptInput_IntegerRange:
01096           t = dialog->getInt(s);
01097           rs.append("," + QString::number(t));
01098           break;
01099         case TA_OptInput_IntegerList:
01100           dialog->getCombo(s, ts);
01101           rs.append("," + ts);
01102           break;
01103         case TA_OptInput_RealList:
01104           break;
01105         default:
01106           break;
01107       }
01108     }
01109 
01110     if (theInfo->nbOutput > 1)
01111     {
01112       s = "Plot";
01113       t = dialog->getInt(s);
01114       rs.append("," + QString::number(t));
01115     }
01116   }
01117 
01118   delete dialog;
01119 }
01120 
01121 void TALIB::printError (QString es, TA_RetCode rc)
01122 {
01123   TA_RetCodeInfo info;
01124   TA_SetRetCodeInfo(rc, &info);
01125   qDebug("%s:%d(%s): %s", es.latin1(), rc, info.enumStr, info.infoStr);
01126 }
01127