PlotLine * LOWPASS::raise2Power(PlotLine *x, double pad) { // Raise the caller's n up to the next power of two // pad remainder with pad, default = 0; PlotLine *result = new PlotLine; int length = x->getSize(); int n = 0; int i = 0; for (n = 2 ; n < MAXNUM / 2 ; n *= 2) { if (n >= length) break ; } for (i = 0; i < n; i++) { if (i < length) result->append(x->getData(i)); else result->append(pad); // pad with zero } return result; }
/* Modified/Relative Japanese Candlesticks */ PlotLine * BARS::calculateCandle () { PlotLine *line = new PlotLine; for (int loop = 0; loop < (int) data->count(); loop++) { double O = data->getOpen(loop); double C = data->getClose(loop); QColor color = barNeutralColor; if (loop > 0) { if (C > data->getClose(loop - 1)) color = barUpColor; if (C < data->getClose(loop - 1)) color = barDownColor; } bool fillFlag = C < O ? TRUE : FALSE; line->append(color, O, data->getHigh(loop), data->getLow(loop), C, fillFlag); QDateTime dt; data->getDate(loop, dt); line->append(dt); } line->setType(PlotLine::Candle); line->setLabel(label); return line; }
PlotLine * IndicatorPlugin::getWilderMA (PlotLine *d, int period) { PlotLine *wilderma = new PlotLine; if (period >= (int) d->getSize()) return wilderma; if (period < 1) return wilderma; double t = 0; int loop; for (loop = 0; loop < period; loop++) t = t + d->getData(loop); double yesterday = t / period; wilderma->append(yesterday); for (; loop < (int) d->getSize(); loop++) { double t = (yesterday * (period - 1) + d->getData(loop))/period; yesterday = t; wilderma->append(t); } return wilderma; }
PlotLine * LOWPASS::detrend(PlotLine *x, double &slope, double &intercept, bool detrend) { // detrend = true (default) = detrebd x , return slope/intercept // detrend = false = undo detrend using slope/intercept provided int length = x->getSize(); int i = 0; PlotLine *result = new PlotLine; if (detrend) { intercept = x->getData(0) ; slope = (x->getData(length-1) - intercept) / (length-1) ; for(i = 0; i < length; i++) result->append(x->getData(i) - intercept - slope * i) ; } else //retrend { for(i = 0; i < length; i++) result->append(x->getData(i) + intercept + slope * i ) ; } return result; }
IndicatorPlugin::IndicatorPlugin() { saveFlag = FALSE; dateFlag = FALSE; logScale = FALSE; PlotLine pl; pl.getLineTypes(lineTypes); BarData it(pluginName); it.getInputFields(inputTypeList); opList.append("EQ"); opList.append("LT"); opList.append("LTEQ"); opList.append("GT"); opList.append("GTEQ"); opList.append("AND"); opList.append("OR"); opList.append("XOR"); maList.append("SMA"); // TA_MAType_SMA =0, maList.append("EMA"); // TA_MAType_EMA =1, maList.append("WMA"); // TA_MAType_WMA =2, maList.append("DEMA"); // TA_MAType_DEMA =3, maList.append("TEMA"); // TA_MAType_TEMA =4, maList.append("TRIMA"); // TA_MAType_TRIMA =5, maList.append("KAMA"); // TA_MAType_KAMA =6, maList.append("MAMA"); // TA_MAType_MAMA =7, maList.append("T3"); // TA_MAType_T3 =8 maList.append("Wilder"); }
PlotLine * TALIB::getMA (PlotLine *in, int type, int period) { PlotLine *ma = new PlotLine; TA_Real input[in->getSize()]; TA_Real out[in->getSize()]; TA_Integer outBeg; TA_Integer count; TA_RetCode rc = TA_SUCCESS; int loop; for (loop = 0; loop < in->getSize(); loop++) input[loop] = (TA_Real) in->getData(loop); switch (type) { case 0: rc = TA_MA(0, in->getSize()- 1, &input[0], period, TA_MAType_SMA, &outBeg, &count, &out[0]); break; case 1: rc = TA_MA(0, in->getSize()- 1, &input[0], period, TA_MAType_EMA, &outBeg, &count, &out[0]); break; case 2: rc = TA_MA(0, in->getSize()- 1, &input[0], period, TA_MAType_WMA, &outBeg, &count, &out[0]); break; case 3: rc = TA_MA(0, in->getSize()- 1, &input[0], period, TA_MAType_DEMA, &outBeg, &count, &out[0]); break; case 4: rc = TA_MA(0, in->getSize()- 1, &input[0], period, TA_MAType_TEMA, &outBeg, &count, &out[0]); break; case 5: rc = TA_MA(0, in->getSize()- 1, &input[0], period, TA_MAType_TRIMA, &outBeg, &count, &out[0]); break; case 6: rc = TA_MA(0, in->getSize()- 1, &input[0], period, TA_MAType_KAMA, &outBeg, &count, &out[0]); break; case 7: rc = TA_MA(0, in->getSize()- 1, &input[0], period, TA_MAType_MAMA, &outBeg, &count, &out[0]); break; case 8: rc = TA_MA(0, in->getSize()- 1, &input[0], period, TA_MAType_T3, &outBeg, &count, &out[0]); break; default: break; } if (rc != TA_SUCCESS) { qDebug("TALIB::getMA:error on TALIB function call"); return ma; } for (loop = 0; loop < count; loop++) ma->append((double) out[loop]); return ma; }
/* Heiken Ashi Candlesticks */ PlotLine * BARS::calculateHACandle () { PlotLine *line = new PlotLine; double pO, pC, xO; for (int loop = 0; loop < (int) data->count(); loop++) { double O = data->getOpen(loop); double H = data->getHigh(loop); double L = data->getLow(loop); double C = data->getClose(loop); // xClose = (Open + High + Low + Close) / 4 double xC = (O + H + L + C) / 4; QColor color = candleColor; if (loop < 1) // xO[Prev] and xC[Prev] are not available xO = (O + C) / 2; else { // xOpen = (xO[Prev] + xC[Prev]) / 2 xO = (pO + pC) / 2; if (xC > xO) color = barUpColor; if (xC < xO) color = barDownColor; } pO = xO; pC = xC; // xHigh = Max(High, xOpen, xClose) double xH = xO > H ? xO : H; xH = xC > xH ? xC : xH; // xLow = Min(Low, xOpen, xClose) double xL = xO < L ? xO : L; xL = xC < xL ? xC : xL; bool fillFlag = C < O ? TRUE : FALSE; line->append(color, xO, xH, xL, xC, fillFlag); QDateTime dt; data->getDate(loop, dt); line->append(dt); } line->setType(PlotLine::Candle); line->setLabel(label); return line; }
PlotLine *qtsFFT::do_iFFTqts(PlotLine *f) { PlotLine * result = new PlotLine; int i = 0; for (i = 0; i < length; i++) { fftFreq[i] = f->getData(i); } _ftt_Real.do_ifft(fftFreq, fftReal); _ftt_Real.rescale(fftReal); for (i = 0; i < length; i++) { result->append(fftReal[i]); } return result; }
Indicator * LOWPASS::calculate () { Indicator *output = new Indicator; output->setDateFlag(dateFlag); output->setLogScale(logScale); PlotLine *in = data->getInput(input); if (! in) { qDebug("LOWPASS::calculate: no input"); return output; } PlotLine *line = getLowpass(in, freq, width); line->setColor(color); line->setType(lineType); line->setLabel(label); output->addLine(line); delete in; return output; }
PlotLine * PP::calculateCustom (QString &p, QPtrList<PlotLine> &d) { // format1: PP_TYPE if (checkFormat(p, d, 1, 1)) return 0; int t = ppList.findIndex(formatStringList[0]); if (t == -1) { qDebug("PP::calculateCustom: invalid PP_TYPE parm"); return 0; } QPtrList<PlotLine> pll; pll.setAutoDelete(TRUE); getPP(pll); PlotLine *line = new PlotLine; PlotLine *tline = pll.at(t); line->copy(tline); return line; }
void CUS::createPlot (QString &d, QDict<PlotLine> &lines, Indicator *output) { if (! d.contains("plot")) return; QStringList l = QStringList::split("(", d, FALSE); if (l.count() != 2) { qDebug("CUS::createPlot: bad plot format: %s", d.ascii()); return; } QString parms = l[1]; parms.truncate(parms.find(")", -1, TRUE)); l = QStringList::split(",", parms, FALSE); if (l.count() != 4) { qDebug("CUS::createPlot: missing plot parms: %s",d.ascii()); return; } // 1.var name l[0] = l[0].stripWhiteSpace(); PlotLine *pl = lines.find(l[0]); if (! pl) { qDebug("CUS::createPlot: bad plot parm 1: %s",d.ascii()); return; } // 2.color l[1] = l[1].stripWhiteSpace(); pl->setColor(l[1]); // 3.label l[2] = l[2].stripWhiteSpace(); pl->setLabel(l[2]); // 4.linetype l[3] = l[3].stripWhiteSpace(); pl->setType(l[3]); PlotLine *tline = new PlotLine; tline->copy(pl); output->addLine(tline); }
void BARS::calculateMA (Indicator *output) { if (maPeriod > 1) { PlotLine *in = data->getInput(maInput); if (in) { PlotLine *ma = getMA(in, maType, maPeriod); ma->setColor(maColor); ma->setType(maLineType); ma->setLabel(maLabel); output->addLine(ma); delete in; } } if (maPeriod2 > 1) { PlotLine *in = data->getInput(maInput2); if (in) { PlotLine *ma = getMA(in, maType2, maPeriod2); ma->setColor(maColor2); ma->setType(maLineType2); ma->setLabel(maLabel2); output->addLine(ma); delete in; } } if (maPeriod3 > 1) { PlotLine *in = data->getInput(maInput3); if (in) { PlotLine *ma = getMA(in, maType3, maPeriod3); ma->setColor(maColor3); ma->setType(maLineType3); ma->setLabel(maLabel3); output->addLine(ma); delete in; } } if (maPeriod4 > 1) { PlotLine *in = data->getInput(maInput4); if (in) { PlotLine *ma = getMA(in, maType4, maPeriod4); ma->setColor(maColor4); ma->setType(maLineType4); ma->setLabel(maLabel4); output->addLine(ma); delete in; } } }
/* Pont and Figure */ PlotLine * BARS::calculatePF () { PlotLine *line = new PlotLine; // determine start either x or o if (data->count() < 2) return line; getPFSettings(); bool XOFlag = FALSE; if (data->getHigh(1) > data->getHigh(0)) XOFlag = TRUE; // prices rising, we start with x's double high = 0; double d = data->getHigh(0) / pfBoxSize; int t = (int) d; if (t * pfBoxSize <= data->getHigh(0)) high = (t + 1) * pfBoxSize; else high = t * pfBoxSize; double low = 0; t = (int) (data->getLow(0) / pfBoxSize); low = t * pfBoxSize; int loop; for (loop = 1; loop < (int) data->count(); loop++) { if (XOFlag) { if (data->getHigh(loop) > high) { // new high d = data->getHigh(loop) / pfBoxSize; t = (int) d; if (t * pfBoxSize <= data->getHigh(loop)) high = (t + 1) * pfBoxSize; else high = t * pfBoxSize; } double reversal = high - (pfBoxSize * pfReversal); if (data->getLow(loop) < reversal) { // reversal to O's line->append(pfXColor, pfBoxSize, high, low, low, XOFlag); high = high - pfBoxSize; // lower high 1 box t = (int) (data->getLow(loop) / pfBoxSize); low = t * pfBoxSize; XOFlag = FALSE; } } else { if (data->getLow(loop) < low) { // new low t = (int) (data->getLow(loop) / pfBoxSize); low = t * pfBoxSize; } double reversal = low + (pfBoxSize * pfReversal); if (data->getHigh(loop) > reversal) { // reversal to X's line->append(pfOColor, pfBoxSize, high, low, low, XOFlag); low = low + pfBoxSize; // raise low 1 box d = data->getHigh(loop) / pfBoxSize; t = (int) d; if (t * pfBoxSize <= data->getHigh(loop)) high = (t + 1) * pfBoxSize; else high = t * pfBoxSize; XOFlag = TRUE; } } } if (XOFlag) line->append(pfXColor, pfBoxSize, high, low, low, XOFlag); else line->append(pfOColor, pfBoxSize, high, low, low, XOFlag); line->setType(PlotLine::PF); line->setLabel(label); return line; }
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 PP::getPP (QPtrList<PlotLine> &pll) { double high = data->getHigh(data->count() - 1); double low = data->getLow(data->count() - 1); double close = data->getClose(data->count() - 1); PlotLine *fr = new PlotLine(); fr->setColor(resColor); fr->setType(resLineType); fr->setLabel(resLabel); double pp = (high + low + close) / 3; double t = (2 * pp) - low; fr->append(t); PlotLine *sr = new PlotLine(); sr->setColor(resColor); sr->setType(resLineType); sr->setLabel(resLabel2); pp = (high + low + close) / 3; t = pp + (high - low); sr->append(t); PlotLine *thr = new PlotLine(); thr->setColor(resColor); thr->setType(resLineType); thr->setLabel(resLabel3); pp = (high + low + close) / 3; t = (2 * pp) + (high - (2 * low)); thr->append(t); PlotLine *fs = new PlotLine(); fs->setColor(supColor); fs->setType(supLineType); fs->setLabel(supLabel); pp = (high + low + close) / 3; t = (2 * pp) - high; fs->append(t); PlotLine *ss = new PlotLine(); ss->setColor(supColor); ss->setType(supLineType); ss->setLabel(supLabel2); pp = (high + low + close) / 3; t = pp - (high - low); ss->append(t); PlotLine *ts = new PlotLine(); ts->setColor(supColor); ts->setType(supLineType); ts->setLabel(supLabel3); pp = (high + low + close) / 3; t = (2 * pp) - ((2 * high) - low); ts->append(t); pll.append(fr); pll.append(sr); pll.append(thr); pll.append(fs); pll.append(ss); pll.append(ts); }
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; }
Indicator * TALIB::calculate () { Indicator *output = new Indicator; output->setDateFlag(dateFlag); output->setLogScale(logScale); // open a TALIB handle const TA_FuncHandle *handle; QString ts = "method"; QString ts2; parms.getData(ts, ts2); TA_RetCode retCode = TA_GetFuncHandle(ts2, &handle); if (retCode != TA_SUCCESS) { qDebug("TALIB::calculate:can't open handle"); return output; } // get info on the function const TA_FuncInfo *theInfo; retCode = TA_GetFuncInfo(handle, &theInfo); if (retCode != TA_SUCCESS) { qDebug("TALIB::calculate:can't get function info"); return output; } // create parm holder TA_ParamHolder *parmHolder; retCode = TA_ParamHolderAlloc(handle, &parmHolder); if (retCode != TA_SUCCESS) { qDebug("TALIB::calculate:can't create parm holder"); return output; } // create and populate the 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]; for (loop = 0; loop < data->count(); loop++) { open[loop] = (TA_Real) data->getOpen(loop); high[loop] = (TA_Real) data->getHigh(loop); low[loop] = (TA_Real) data->getLow(loop); close[loop] = (TA_Real) data->getClose(loop); volume[loop] = (TA_Real) data->getVolume(loop); oi[loop] = (TA_Real) data->getOI(loop); } // setup the input arrays const TA_InputParameterInfo *inputParms; for (loop = 0; loop < (int) theInfo->nbInput; loop++ ) { TA_GetInputParameterInfo(theInfo->handle, loop, &inputParms); QString s; int tint = 3; switch (inputParms->type) { case TA_Input_Price: retCode = TA_SetInputParamPricePtr(parmHolder, loop, &open[0], &high[0], &low[0], &close[0], &volume[0], &oi[0]); if (retCode != TA_SUCCESS) qDebug("TALIB::calculate:cannot set input prices"); break; case TA_Input_Real: s = QObject::tr("input") + QString::number(loop + 1); tint = parms.getInt(s); switch (tint) { case 0: retCode = TA_SetInputParamRealPtr(parmHolder, loop, &open[0]); if (retCode != TA_SUCCESS) qDebug("TALIB::calculate:cannot set real price"); break; case 1: retCode = TA_SetInputParamRealPtr(parmHolder, loop, &high[0]); if (retCode != TA_SUCCESS) qDebug("TALIB::calculate:cannot set real price"); break; case 2: retCode = TA_SetInputParamRealPtr(parmHolder, loop, &low[0]); if (retCode != TA_SUCCESS) qDebug("TALIB::calculate:cannot set real price"); break; case 3: retCode = TA_SetInputParamRealPtr(parmHolder, loop, &close[0]); if (retCode != TA_SUCCESS) qDebug("TALIB::calculate:cannot set real price"); break; case 4: retCode = TA_SetInputParamRealPtr(parmHolder, loop, &volume[0]); if (retCode != TA_SUCCESS) qDebug("TALIB::calculate:cannot set integer price"); break; case 5: retCode = TA_SetInputParamRealPtr(parmHolder, loop, &oi[0]); if (retCode != TA_SUCCESS) qDebug("TALIB::calculate:cannot set integer price"); break; default: break; } break; case TA_Input_Integer: break; default: break; } } // setup the optinput parms const TA_OptInputParameterInfo *optInfo; for (loop = 0; loop < (int) theInfo->nbOptInput; loop++ ) { TA_GetOptInputParameterInfo(theInfo->handle, loop, &optInfo); QString s = optInfo->displayName; switch (optInfo->type) { case TA_OptInput_RealRange: retCode = TA_SetOptInputParamReal(parmHolder, loop, (TA_Real) parms.getDouble(s)); if (retCode != TA_SUCCESS) qDebug("TALIB::calculate:cannot set inputopt real"); break; case TA_OptInput_IntegerRange: retCode = TA_SetOptInputParamInteger(parmHolder, loop, (TA_Integer) parms.getInt(s)); if (retCode != TA_SUCCESS) qDebug("TALIB::calculate:cannot set inputopt integer"); break; case TA_OptInput_IntegerList: retCode = TA_SetOptInputParamInteger(parmHolder, loop, (TA_Integer) parms.getInt(s)); if (retCode != TA_SUCCESS) qDebug("TALIB::calculate:cannot set inputopt integerlist"); 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::calculate:cannot get output info"); continue; } switch (loop) { case 0: if (outInfo->type == TA_Output_Integer) { retCode = TA_SetOutputParamIntegerPtr(parmHolder, loop, &out4[0]); if (retCode != TA_SUCCESS) qDebug("TALIB::calculate:cannot set output4"); } else { retCode = TA_SetOutputParamRealPtr(parmHolder, loop, &out1[0]); if (retCode != TA_SUCCESS) qDebug("TALIB::calculate:cannot set output1"); } break; case 1: retCode = TA_SetOutputParamRealPtr(parmHolder, loop, &out2[0]); if (retCode != TA_SUCCESS) qDebug("TALIB::calculate:cannot set output2"); break; case 2: retCode = TA_SetOutputParamRealPtr(parmHolder, loop, &out3[0]); if (retCode != TA_SUCCESS) qDebug("TALIB::calculate:cannot set output3"); break; default: break; } } // call the function TA_Integer start = 0; TA_Integer end = data->count() - 1; TA_Integer outstart; TA_Integer count; retCode = TA_CallFunc(parmHolder, start, end, &outstart, &count); if (retCode != TA_SUCCESS) qDebug("TALIB::calculate:call function failed"); else { // create the plotlines const TA_OutputParameterInfo *outInfo; for (loop = 0; loop < (int) theInfo->nbOutput; loop++ ) { TA_GetOutputParameterInfo(theInfo->handle, loop, &outInfo); QString base = outInfo->paramName; base = base.right(base.length() - 3); if (! base.left(4).compare("Real")) base = base.right(base.length() - 4); if (! base.left(7).compare("Integer")) base = base.right(base.length() - 7); if (! base.length()) base = QObject::tr("Plot"); PlotLine *line = new PlotLine; QString s = base + " " + QObject::tr("Color"); parms.getData(s, ts); QColor color(ts); line->setColor(color); s = base + " " + QObject::tr("Label"); parms.getData(s, ts); line->setLabel(ts); s = base + " " + QObject::tr("Line Type"); line->setType((PlotLine::LineType)parms.getInt(s)); retCode = TA_GetOutputParameterInfo(handle, loop, &outInfo); if (retCode != TA_SUCCESS) { qDebug("TALIB::calculate:cannot get output info"); delete line; continue; } int loop2; switch (loop) { case 0: if (outInfo->type == TA_Output_Integer) { for (loop2 = 0; loop2 < count; loop2++) line->append((double) out4[loop2]); } else { for (loop2 = 0; loop2 < count; loop2++) line->append((double) out1[loop2]); } break; case 1: for (loop2 = 0; loop2 < count; loop2++) line->append((double) out2[loop2]); break; case 2: for (loop2 = 0; loop2 < count; loop2++) line->append((double) out3[loop2]); break; default: break; } if (line->getType() == PlotLine::Histogram || line->getType() == PlotLine::HistogramBar) output->prependLine(line); else output->addLine(line); } } retCode = TA_ParamHolderFree(parmHolder); if (retCode != TA_SUCCESS) qDebug("TALIB::calculate:can't delete parm holder"); return output; }
PlotLine * ExScript::doScript () { if (proc) { delete proc; proc = 0; } PlotLine *line = new PlotLine(); if (! scriptPath.length()) { qDebug("ExScript::calculate: no script path"); return line; } proc = new QProcess(this); connect(proc, SIGNAL(readyReadStdout()), this, SLOT(readFromStdout())); proc->setCommunication(QProcess::Stdin|QProcess::Stdout|QProcess::Stderr); proc->addArgument(scriptPath); QStringList l = QStringList::split(" ", comlineParms, FALSE); int loop; for (loop = 0; loop < (int) l.count(); loop++) proc->addArgument(l[loop]); buffer.truncate(0); QString s; if (dateFlag || openFlag || highFlag || lowFlag || closeFlag || volumeFlag || oiFlag) getInput(s); QByteArray ba(s.length()); if (s.length()) { for (loop = 0; loop < (int) s.length(); loop++) ba[loop] = s.at(loop).latin1(); } if (! proc->launch(ba, NULL)) { qDebug("ExScript::calculate: error starting script"); delete proc; proc = 0; return line; } timer->start(seconds * 1000, FALSE); wakeup(); while (proc->isRunning()) { usleep(100); wakeup(); } timer->stop(); if (proc) { delete proc; proc = 0; } if (! buffer.length()) { qDebug("ExScript::createOutput: output buffer empty"); return line; } l = QStringList::split(",", buffer, FALSE); for (loop = 0; loop < (int) l.count(); loop++) line->append(l[loop].toDouble()); line->setColor(color); line->setType(lineType); line->setLabel(label); return line; }
PlotLine * SYMBOL::getSYMBOL () { QString s; Config config; config.getData(Config::IndexPath, s); DBIndex index; index.open(s); PlotLine *line = new PlotLine(); DbPlugin db; if (db.open(symbol, &index)) { db.close(); index.close(); return line; } QDateTime date; data->getDate(0, date); QString ts; config.getData(Config::BarLength, ts); db.setBarLength((BarData::BarLength) ts.toInt()); config.getData(Config::Bars, ts); db.setBarRange(ts.toInt()); BarData *recordList = new BarData(symbol); QDateTime dt = QDateTime::currentDateTime(); db.getHistory(recordList, dt); QDict<Setting> dict; dict.setAutoDelete(TRUE); int loop; ts = "Close"; QString ts2; for (loop = 0; loop < (int) recordList->count(); loop++) { Setting *r = new Setting; ts2 = QString::number(recordList->getClose(loop)); r->setData(ts, ts2); recordList->getDate(loop, dt); QString s = dt.toString("yyyyMMddhhmmss"); dict.insert(s, r); } double val = 0; for (loop = 0; loop < (int) data->count(); loop++) { data->getDate(loop, dt); QString s = dt.toString("yyyyMMddhhmmss"); Setting *r2 = dict[s]; if (r2) { val = r2->getDouble(ts); line->append(val); } } delete recordList; db.close(); index.close(); line->setScaleFlag(TRUE); return line; }
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--; } }
FormulaEdit::FormulaEdit (QWidget *w, int t) : QWidget(w) { type = (FormulaEditType) t; /* FIXME: take no effect, outdated or not yet implemented? config.getPluginList(Config::IndicatorPluginPath, functionList); */ PlotLine pl; pl.getLineTypes(lineTypes); QHBoxLayout *hbox = new QHBoxLayout(this); hbox->setMargin(0); hbox->setSpacing(1); QTabWidget *tab = new QTabWidget(this); hbox->addWidget(tab); // create formula page QWidget *tw = new QWidget(this); QHBoxLayout *thbox = new QHBoxLayout(tw); thbox->setMargin(5); thbox->setSpacing(0); formula = new QTextEdit(tw); thbox->addWidget(formula); ftoolbar = new Toolbar(tw, Toolbar::Vertical); thbox->addWidget(ftoolbar); QString s = "open"; QString s2 = tr("Open Rule"); ftoolbar->addButton(s, openchart, s2); QObject::connect(ftoolbar->getButton(s), SIGNAL(clicked()), this, SLOT(openRule())); s = "include"; s2 = tr("Include Rule"); ftoolbar->addButton(s, include, s2); QObject::connect(ftoolbar->getButton(s), SIGNAL(clicked()), this, SLOT(includeRule())); s = "add"; s2 = tr("Function Dialog"); ftoolbar->addButton(s, insert, s2); QObject::connect(ftoolbar->getButton(s), SIGNAL(clicked()), this, SLOT(functionDialog())); tab->addTab(tw, tr("Formula")); // create plot page tw = new QWidget(this); thbox = new QHBoxLayout(tw); thbox->setMargin(5); thbox->setSpacing(0); plot = new QListBox(tw); connect(plot, SIGNAL(doubleClicked(QListBoxItem *)), this, SLOT(slotDoubleClicked(QListBoxItem *))); thbox->addWidget(plot); ptoolbar = new Toolbar(tw, Toolbar::Vertical); thbox->addWidget(ptoolbar); s = "insert"; s2 = tr("Insert"); ptoolbar->addButton(s, insert, s2); QObject::connect(ptoolbar->getButton(s), SIGNAL(clicked()), this, SLOT(insertPlotItem())); s = "edit"; s2 = tr("Edit"); ptoolbar->addButton(s, edit, s2); QObject::connect(ptoolbar->getButton(s), SIGNAL(clicked()), this, SLOT(editPlotItem())); s = "delete"; s2 = tr("Delete"); ptoolbar->addButton(s, deleteitem, s2); QObject::connect(ptoolbar->getButton(s), SIGNAL(clicked()), this, SLOT(deletePlotItem())); tab->addTab(tw, tr("Plot")); }
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 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); }