PlotLine * TALIB::calculateCustom (QString &p, QPtrList<PlotLine> &d) { // format: METHOD, ..., ...., ..... etc (first parm must be the method) QStringList l = QStringList::split(",", p, FALSE); if (! l.count()) { qDebug("TALIB::calculateCustom: no method parm"); return 0; } TA_Integer start = 0; TA_Integer end = data->count() - 1; if (d.count()) end = d.at(0)->getSize() - 1; TA_Integer outstart; TA_Integer count; PlotLine *line = new PlotLine; // sometimes are not enough data available // to calc anything if(end < 0) return line; // open a TALIB handle const TA_FuncHandle *handle; TA_RetCode retCode = TA_GetFuncHandle(l[0], &handle); if (retCode != TA_SUCCESS) { qDebug("TALIB::calculateCustom:can't open handle"); return 0; } // get info on the function const TA_FuncInfo *theInfo; retCode = TA_GetFuncInfo(handle, &theInfo); if (retCode != TA_SUCCESS) { qDebug("TALIB::calculateCustom:can't get function info"); return 0; } // create parm holder TA_ParamHolder *parmHolder; retCode = TA_ParamHolderAlloc(handle, &parmHolder); if (retCode != TA_SUCCESS) { qDebug("TALIB::calculateCustom:can't create parm holder"); return 0; } // create and input arrays int loop = data->count(); TA_Real open[loop]; TA_Real high[loop]; TA_Real low[loop]; TA_Real close[loop]; TA_Real volume[loop]; TA_Real oi[loop]; TA_Real treal[loop]; int sparmIndex = 1; // setup the input arrays const TA_InputParameterInfo *inputParms; for (loop = 0; loop < (int) theInfo->nbInput; loop++ ) { TA_GetInputParameterInfo(theInfo->handle, loop, &inputParms); if (inputParms->type == TA_Input_Price) { // populate the input arrays int loop2; for (loop2 = 0; loop2 < data->count(); loop2++) { open[loop2] = (TA_Real) data->getOpen(loop2); high[loop2] = (TA_Real) data->getHigh(loop2); low[loop2] = (TA_Real) data->getLow(loop2); close[loop2] = (TA_Real) data->getClose(loop2); volume[loop2] = (TA_Real) data->getVolume(loop2); oi[loop2] = (TA_Real) data->getOI(loop2); } retCode = TA_SetInputParamPricePtr(parmHolder, loop, &open[0], &high[0], &low[0], &close[0], &volume[0], &oi[0]); if (retCode != TA_SUCCESS) { qDebug("TALIB::calculateCustom:cannot set input prices"); return 0; } } if (inputParms->type == TA_Input_Real) { if (! d.count()) { qDebug("TALIB::calculateCustom: no input"); return 0; } if (sparmIndex >= (int) l.count()) { qDebug("TALIB::calculateCustom: input invalid number of parms"); return 0; } PlotLine *line = d.at(0); int loop2; for (loop2 = 0; loop2 < line->getSize(); loop2++) treal[loop2] = (TA_Real) line->getData(loop2); retCode = TA_SetInputParamRealPtr(parmHolder, loop, &treal[0]); if (retCode != TA_SUCCESS) { qDebug("TALIB::calculateCustom:cannot set real price"); return 0; } sparmIndex++; } } if (sparmIndex < (int) l.count()) { QStringList mal; getMATypes(mal); mal.remove("Wilder"); int t = 0; // setup the optinput parms const TA_OptInputParameterInfo *optInfo; for (loop = 0; loop < (int) theInfo->nbOptInput; loop++ ) { TA_GetOptInputParameterInfo(theInfo->handle, loop, &optInfo); switch (optInfo->type) { case TA_OptInput_RealRange: if (sparmIndex >= (int) l.count()) { qDebug("TALIB::calculateCustom: optinput real invalid number of parms"); return 0; } retCode = TA_SetOptInputParamReal(parmHolder, loop, (TA_Real) l[sparmIndex].toDouble()); if (retCode != TA_SUCCESS) { qDebug("TALIB::calculateCustom:cannot set inputopt real"); return 0; } sparmIndex++; break; case TA_OptInput_IntegerRange: if (sparmIndex >= (int) l.count()) { qDebug("TALIB::calculateCustom: optinput integer invalid number of parms"); return 0; } retCode = TA_SetOptInputParamInteger(parmHolder, loop, (TA_Integer) l[sparmIndex].toInt()); if (retCode != TA_SUCCESS) { qDebug("TALIB::calculateCustom:cannot set inputopt integer"); return 0; } sparmIndex++; break; case TA_OptInput_IntegerList: if (sparmIndex >= (int) l.count()) { qDebug("TALIB::calculateCustom: optinput integerList invalid number of parms"); return 0; } t = mal.findIndex(l[sparmIndex]); if (t == -1) t = 0; retCode = TA_SetOptInputParamInteger(parmHolder, loop, (TA_Integer) t); if (retCode != TA_SUCCESS) { qDebug("TALIB::calculateCustom:cannot set inputopt integer"); return 0; } sparmIndex++; break; default: break; } } } // setup the output arrays TA_Real out1[data->count()]; TA_Real out2[data->count()]; TA_Real out3[data->count()]; TA_Integer out4[data->count()]; const TA_OutputParameterInfo *outInfo; for (loop = 0; loop < (int) theInfo->nbOutput; loop++) { retCode = TA_GetOutputParameterInfo(handle, loop, &outInfo); if (retCode != TA_SUCCESS) { qDebug("TALIB::calculateCustom:cannot get output info"); return 0; } switch (loop) { case 0: if (outInfo->type == TA_Output_Integer) { retCode = TA_SetOutputParamIntegerPtr(parmHolder, loop, &out4[0]); if (retCode != TA_SUCCESS) { qDebug("TALIB::calculateCustom:cannot set output4"); return 0; } } else { retCode = TA_SetOutputParamRealPtr(parmHolder, loop, &out1[0]); if (retCode != TA_SUCCESS) { qDebug("TALIB::calculateCustom:cannot set output1"); return 0; } } break; case 1: retCode = TA_SetOutputParamRealPtr(parmHolder, loop, &out2[0]); if (retCode != TA_SUCCESS) { qDebug("TALIB::calculateCustom:cannot set output2"); return 0; } break; case 2: retCode = TA_SetOutputParamRealPtr(parmHolder, loop, &out3[0]); if (retCode != TA_SUCCESS) { qDebug("TALIB::calculateCustom:cannot set output3"); return 0; } break; default: break; } } // call the function /* TA_Integer start = 0; TA_Integer end = data->count() - 1; if (d.count()) end = d.at(0)->getSize() - 1; TA_Integer outstart; TA_Integer count; PlotLine *line = new PlotLine; */ retCode = TA_CallFunc(parmHolder, start, end, &outstart, &count); if (retCode != TA_SUCCESS) { printError(QString("TALIB::calculateCustom:TA_CallFunc"), retCode); qDebug("p=%s start=%d end=%d",p.ascii(), start, end); } else { // create the plotlines int loop2; retCode = TA_GetOutputParameterInfo(handle, 0, &outInfo); if (retCode != TA_SUCCESS) { qDebug("TALIB::calculateCustom:cannot get output info"); return 0; } if (outInfo->type == TA_Output_Integer) { for (loop2 = 0; loop2 < count; loop2++) line->append((double) out4[loop2]); } else { if (theInfo->nbOutput > 1) { bool ok; l[l.count() - 1].toInt(&ok); if (! ok) { qDebug("TALIB::calculateCustom: parm #%i invalid, not an INTEGER", loop + 1); return 0; } switch (l[l.count() - 1].toInt(&ok)) { case 2: for (loop2 = 0; loop2 < count; loop2++) line->append((double) out2[loop2]); break; case 3: for (loop2 = 0; loop2 < count; loop2++) line->append((double) out3[loop2]); break; default: for (loop2 = 0; loop2 < count; loop2++) line->append((double) out1[loop2]); break; } } else { for (loop2 = 0; loop2 < count; loop2++) line->append((double) out1[loop2]); } } } retCode = TA_ParamHolderFree(parmHolder); if (retCode != TA_SUCCESS) qDebug("TALIB::calculateCustom:can't delete parm holder"); return line; }
PlotLine * LOWPASS::getLowpass (PlotLine *in, double fre, double wid) { PlotLine *out = new PlotLine; if (in->getSize() == 0) return out; // ---------------------------------------------------------------------- double slope = 0; // will be modified on call to detrend double intercept = 0; int length = 0; // original caller size int n = 0; // size raised to next power of 2 for fft int i = 0; length = in->getSize(); // Detrend input series PlotLine *series = detrend(in, slope, intercept, true); // Raise length to next power of 2, pad with zero PlotLine *series2 = raise2Power(series, 0); n = series2->getSize(); //qtsFFT fft(n); // construct fft object fft = new qtsFFT(n); // do fft PlotLine * fftFreq = fft->do_FFTqts(series2); //PlotLine * fftFreq = fft.do_FFTqts(series2); // apply low pass filter double f = 0; double dist = 0; double wt = 0; int halfn = n/2; double freqSave = fftFreq->getData(halfn); for (i = 0 ; i < halfn ; i++) { f = (double) i / (double) n ; // Frequency if (f <= fre) // Flat response wt = 1.0 ; else { dist = (f - fre) / wid; wt = exp ( -dist * dist ) ; } fftFreq->setData(i, fftFreq->getData(i) * wt) ; fftFreq->setData(halfn + i, fftFreq->getData(halfn + i) * wt) ; } dist = (0.5 - fre) / wid; // Do Nyquist in fftFreq[0] fftFreq->setData(halfn, freqSave * exp ( -dist * dist )) ; // Do inverse FFT to recover real domain PlotLine *fftReal = fft->do_iFFTqts(fftFreq); //PlotLine *fftReal = fft.do_iFFTqts(fftFreq); // Retrend input series, n.b. original length PlotLine *series3 = detrend(fftReal, slope, intercept, false); for (i = 0; i < length; i++) out->append(series3->getData(i)); delete series; delete series2; delete series3; delete fftReal; delete fftFreq; delete fft; return out; }
void Scanner::scan () { if (! fileList.count() && ! allSymbols->isChecked()) { QMessageBox::information(this, tr("Qtstalker: Error"), tr("No symbols selected.")); return; } // open the CUS plugin QString iplugin("CUS"); IndicatorPlugin *plug = config.getIndicatorPlugin(iplugin); if (! plug) { config.closePlugin(iplugin); return; } QString s; list->getText(s); QStringList l = QStringList::split("\n", s, FALSE); plug->setCustomFunction(l); this->setEnabled(FALSE); // clear dir for scan symbols QDir dir; config.getData(Config::GroupPath, s); s.append("/Scanner"); if (! dir.exists(s, TRUE)) dir.mkdir(s, TRUE); s.append("/" + scannerName); if (! dir.exists(s, TRUE)) dir.mkdir(s, TRUE); else { int loop; dir.setPath(s); for (loop = 2; loop < (int) dir.count(); loop++) { QString s2 = dir.absPath() + "/" + dir[loop]; if (! dir.remove(s2, TRUE)) qDebug("%s not removed", s2.latin1()); } } if (allSymbols->isChecked()) { QString ts; if (! basePath->currentText().compare(tr("Chart"))) config.getData(Config::DataPath, ts); else config.getData(Config::GroupPath, ts); Traverse trav(Traverse::File); trav.traverse(ts); trav.getList(fileList); } QProgressDialog prog(tr("Scanning..."), tr("Cancel"), fileList.count(), this, "progress", TRUE); prog.show(); int minBars = bars->value(); emit message(QString("Scanning...")); int loop; for (loop = 0; loop < (int) fileList.count(); loop++) { prog.setProgress(loop); emit message(QString()); if (prog.wasCancelled()) { emit message(QString("Scan cancelled")); break; } QFileInfo fi(fileList[loop]); if (fi.isDir()) continue; DbPlugin db; QDir dir; if (! dir.exists(fileList[loop])) continue; db.open(fileList[loop], chartIndex); db.setBarRange(minBars); db.setBarLength((BarData::BarLength) barLengthList.findIndex(period->currentText())); BarData *recordList = new BarData(fileList[loop]); QDateTime dt = QDateTime::currentDateTime(); db.getHistory(recordList, dt); db.close(); // load the CUS plugin and calculate plug->setIndicatorInput(recordList); Indicator *i = plug->calculate(); if (! i->getLines()) { delete recordList; delete i; continue; } PlotLine *line = i->getLine(0); if (line && line->getSize() > 0) { if (line->getData(line->getSize() - 1) > 0) { QString ts; config.getData(Config::GroupPath, ts); QString s = "ln -s \"" + fileList[loop] + "\" " + ts + "/Scanner/" + scannerName; system(s); } } delete recordList; delete i; emit message(QString()); } if (! prog.wasCancelled()) emit message(QString("Scan complete")); config.closePlugin(iplugin); this->setEnabled(TRUE); emit scanComplete(); }
void THERM::getTHERM (QPtrList<PlotLine> &pll) { PlotLine *therm = new PlotLine(); int loop; double thermometer = 0; for (loop = 1; loop < (int) data->count(); loop++) { double high = fabs(data->getHigh(loop) - data->getHigh(loop - 1)); double lo = fabs(data->getLow(loop - 1) - data->getLow(loop)); if (high > lo) thermometer = high; else thermometer = lo; therm->append(thermometer); } if (smoothing > 1) { PlotLine *ma = getMA(therm, smoothType, smoothing); pll.append(ma); delete therm; therm = ma; } else pll.append(therm); PlotLine *therm_ma = getMA(therm, maType, maPeriod); therm_ma->setColor(maColor); therm_ma->setType(maLineType); therm_ma->setLabel(maLabel); pll.append(therm_ma); // assign the therm colors therm->setColorFlag(TRUE); therm->setType(lineType); therm->setLabel(label); int thermLoop = therm->getSize() - 1; int maLoop = therm_ma->getSize() - 1; while (thermLoop > -1) { if (maLoop > -1) { double thrm = therm->getData(thermLoop); double thrmma = therm_ma->getData(maLoop); if (thrm > (thrmma * threshold)) therm->setColorBar(thermLoop, threshColor); else { if (thrm > thrmma) therm->setColorBar(thermLoop, upColor); else therm->setColorBar(thermLoop, downColor); } } else therm->setColorBar(thermLoop, downColor); thermLoop--; maLoop--; } }
void SINWAV::getSINWAV (Q3PtrList<PlotLine> &pll) { // Ehler's sine wave PlotLine *Price = new PlotLine; int i = 0; // price = (h + l) / 2 for (i = 0; i < (int) data->count(); i++) Price->append((data->getHigh(i) + data->getLow(i)) / 2); //! VERSION 2 QVector<double> *smooth = new QVector<double>(Price->getSize()); smooth->fill(0.0); QVector<double> *detrender = new QVector<double>(Price->getSize()); detrender->fill(0.0); QVector<double> *period = new QVector<double>(Price->getSize()); period->fill(0.0); QVector<double> *Q1 = new QVector<double>(Price->getSize()); Q1->fill(0.0); QVector<double> *I1 = new QVector<double>(Price->getSize()); I1->fill(0.0); QVector<double> *jI = new QVector<double>(Price->getSize()); jI->fill(0.0); QVector<double> *jQ = new QVector<double>(Price->getSize()); jQ->fill(0.0); QVector<double> *I2 = new QVector<double>(Price->getSize()); I2->fill(0.0); QVector<double> *Q2 = new QVector<double>(Price->getSize()); Q2->fill(0.0); QVector<double> *Re = new QVector<double>(Price->getSize()); Re->fill(0.0); QVector<double> *Im = new QVector<double>(Price->getSize()); Im->fill(0.0); QVector<double> *SmoothPrice = new QVector<double>(Price->getSize()); SmoothPrice->fill(0.0); QVector<double> *DCPhase = new QVector<double>(Price->getSize()); DCPhase->fill(0.0); PlotLine *out1 = new PlotLine; PlotLine *out2 = new PlotLine; double SmoothPeriod = 0; double DCPeriod = 0; for (i = 6; i< Price->getSize(); i++) { // Weighted price (*smooth)[i] = ( 4 * Price->getData(i) + 3 * Price->getData(i-1) + 2 * Price->getData(i-2) + Price->getData(i-3)) /10.0; (*detrender)[i] = (0.0962 * smooth->at(i) + 0.5769 * smooth->at(i-2) - 0.5769 * smooth->at(i-4) - 0.0962 * smooth->at(i-6)) * (0.075 * period->at(i-1) + 0.54); // Compute InPhase and Quadrature components (*Q1)[i] = (0.0962 * detrender->at(i) + 0.5769 * detrender->at(i-2) - 0.5769 * detrender->at(i-4) - 0.0962 * detrender->at(i-6)) * (0.075 * period->at(i-1) + 0.54); (*I1)[i] = detrender->at(i-3); //Advance the phase of I1 and Q1 by 90 degrees (*jI)[i] = (0.0962 * I1->at(i) + 0.5769 * I1->at(i-2) - 0.5769 * I1->at(i-4) - 0.0962 * I1->at(i-6)) * (0.075 * period->at(i-1) + 0.54); (*Q1)[i] = (0.0962 * Q1->at(i) + 0.5769 * Q1->at(i-2) - 0.5769 * Q1->at(i-4) - 0.0962 * Q1->at(i-6)) * (0.075 * period->at(i-1) + 0.54); // Phasor addition for 3-bar averaging (*I2)[i] = I1->at(i) - jQ->at(i); (*Q2)[i] = Q1->at(i) + jI->at(i); // Smooth the I and Q components before applying the discriminator (*I2)[i] = 0.2 * I2->at(i) + 0.8 * I2->at(i-1); (*Q2)[i] = 0.2 * Q2->at(i) + 0.8 * Q2->at(i-1); // Homodyne Discriminator (*Re)[i] = I2->at(i) * I2->at(i-1) + Q2->at(i) * Q2->at(i-1); (*Im)[i] = I2->at(i) * Q2->at(i-1) - Q2->at(i) * I2->at(i-1); (*Re)[i] = 0.2 * Re->at(i) + 0.8 * Re->at(i-1); (*Im)[i] = 0.2 * Im->at(i) + 0.8 * Im->at(i-1); if (Im->at(i) != 0 && Re->at(i) != 0 ) (*period)[i] = 360/(atan(Im->at(i) / Re->at(i)) * (180/PI)); if (period->at(i) > 1.5 * period->at(i-1)) (*period)[i] = 1.5 * period->at(i-1); if (period->at(i) < 0.67 * period->at(i-1)) (*period)[i] = 0.67 * period->at(i-1); if (period->at(i) < 6) (*period)[i] = 6; if (period->at(i) > 50) (*period)[i] = 50; (*period)[i] = 0.2 * period->at(i) + 0.8 * period->at(i-1); SmoothPeriod = 0.33 * period->at(i) + 0.67 * SmoothPeriod; // Compute Dominant CyclePhase (*SmoothPrice)[i] = (4 * Price->getData(i) + 3 * Price->getData(i-1) + 2 * Price->getData(i-2) + Price->getData(i-3)) /10.0; DCPeriod = (int)(SmoothPeriod + 0.5); double RealPart = 0; double ImagPart = 0; int j = 0; if (i >= (int)DCPeriod) { for (j = 0; j < (int)DCPeriod; j++) { RealPart = RealPart + sin((360 * (double)j / DCPeriod) * (PI/180)) * (SmoothPrice->at(i - j)); ImagPart = ImagPart + cos((360 * (double)j / DCPeriod) * (PI/180)) * (SmoothPrice->at(i - j)); } } if (fabs(ImagPart) > 0.001) (*DCPhase)[i] = atan(RealPart / ImagPart) * (180/PI); if( fabs(ImagPart) <= 0.001 ) (*DCPhase)[i] = 90.0 * sin(RealPart * (PI/180)); (*DCPhase)[i] = DCPhase->at(i) + 90.0; // Compensate for one bar lag of the Weighted Moving Average (*DCPhase)[i] = DCPhase->at(i) + 360.0 / SmoothPeriod; if (ImagPart < 0) (*DCPhase)[i] = DCPhase->at(i) + 180.0; if (DCPhase->at(i) > 315.0) (*DCPhase)[i] = DCPhase->at(i) - 360.0; // we're done.... out1->append(sin(DCPhase->at(i) * (PI/180))); out2->append(sin((DCPhase->at(i) + 45.0) * (PI/180))); } delete smooth; delete detrender; delete period; delete Q1; delete I1; delete jI; delete jQ; delete I2; delete Q2; delete Re; delete Im; delete SmoothPrice; delete DCPhase; delete Price; out1->setColor(colorSin); out1->setLabel(labelSin); out1->setType(lineTypeSin); pll.append(out1); out2->setColor(colorLead); out2->setLabel(labelLead); out2->setType(lineTypeLead); pll.append(out2); }