Beispiel #1
0
void Weave::_calculate(const Indicator& ind) {
    size_t total = ind.size();
    if (m_result_num != 0 && total != size()) {
        HKU_ERROR("ind's size must be equal weave's size! [Weave::_calculate]");
        return;
    }

    if (total == 0) {
        return;
    }

    size_t old_m_result_num = m_result_num;
    m_result_num = ind.getResultNumber() + m_result_num;
    if (m_result_num > MAX_RESULT_NUM) {
        HKU_WARN("Weave only can contains " << MAX_RESULT_NUM <<
                 "reult_num! [Weave::_calculate]");
        m_result_num = MAX_RESULT_NUM;
    }

    if (m_discard < ind.discard()) {
        m_discard = ind.discard();
    }

    price_t null_price = Null<price_t>();
    for (size_t i = old_m_result_num; i < m_result_num; ++i) {
        m_pBuffer[i] = new PriceList(total, null_price);
        for (size_t j = m_discard; j < total; ++j) {
            (*m_pBuffer[i])[j] = ind.get(j, i-old_m_result_num);
        }
    }
}
Beispiel #2
0
void LowLine::_calculate(const Indicator& data) {
    size_t total = data.size();

    int n = getParam<int>("n");

    m_discard = data.discard() + n - 1;

    size_t pos = m_discard + 1 - n;
    price_t min = 0;
    for (size_t i = m_discard; i < total; ++i) {
        size_t j = i + 1 - n;
        if (pos > j) {
            j = pos;
        } else {
            min = data[j];
        }
        for (; j <= i; ++j) {
            if (data[j] < min) {
                min = data[j];
                pos = j;
            }
        }
        _set(min, i);
    }
}
Beispiel #3
0
void SingleSignal::_calculate() {
    int filter_n = getParam<int>("filter_n");
    double filter_p = getParam<double>("filter_p");
    string kpart(getParam<string>("kpart"));

    Indicator ind = m_ind(KDATA_PART(m_kdata, kpart));
    Indicator dev = STDEV(DIFF(ind), filter_n);

    size_t start = dev.discard();
    if (start < 3) {
        return;
    }

    size_t total = dev.size();
    for (size_t i = start; i < total; ++i) {
        double dama = ind[i] - ind[i-1];
        double dama2 = ind[i] - ind[i-2];
        double dama3 = ind[i] - ind[i-3];
        double sdama = dev[i] * filter_p;
        if (dama > 0 && (dama > sdama || dama2 > sdama || dama3 > sdama)) {
            _addBuySignal(m_kdata[i].datetime);
        } else if (dama < 0 && (dama < sdama || dama2 < sdama || dama3 < sdama)) {
            _addSellSignal(m_kdata[i].datetime);
        }
    }
}
Beispiel #4
0
HKU_API Indicator operator+(const Indicator& ind1, const Indicator& ind2) {
    if (!ind1.getImp() || !ind2.getImp()) {
        return Indicator();
    }

    IndicatorImpPtr p = make_shared<IndicatorImp>();
    p->add(IndicatorImp::ADD, ind1.getImp(), ind2.getImp());
    return p->calculate();
}
Beispiel #5
0
Indicator HKU_API WEAVE(const Indicator& ind1, const Indicator& ind2) {
    if (!ind1.getImp() || !ind2.getImp()) {
        HKU_ERROR("ind1 or ind2 is Null Indicator! [WEAVE]");
        return Indicator();
    }
    IndicatorImpPtr p = make_shared<IndicatorImp>();
    p->add(IndicatorImp::WEAVE, ind1.getImp(), ind2.getImp());
    return p->calculate();
}
Beispiel #6
0
void RightShift::_calculate(const Indicator& data)  {
    size_t total = data.size();
    int n = getParam<int>("n");

    m_discard = data.discard() + n;
    for (size_t i = m_discard; i < total; ++i) {
        _set(data[i-n], i);
    }
}
Beispiel #7
0
Indicator * ExScript::calculate ()
{
  Indicator *output = new Indicator;
  output->setDateFlag(dateFlag);
  output->setLogScale(logScale);

  output->addLine(doScript());

  return output;
}
Beispiel #8
0
void AxisInteractor::updateIndicator(double value)
{
    QPoint *pos = this->scalePicker->getLocation(value);
    QList<QGraphicsItem *> list = this->scene->selectedItems();
    if (list.count() > 0)
    {
        Indicator *item = static_cast<Indicator *>(list.at(0));
        item->updatePos(*pos);
    }
}
Beispiel #9
0
void ConstantValue::_calculate(const Indicator& data) {
    size_t total = data.size();

    double value = getParam<double>("value");
    m_discard = data.discard();

    for (size_t i = m_discard; i < total; ++i) {
        _set(value, i, 0);
    }
}
Beispiel #10
0
Indicator Indicator::operator()(const Indicator& ind) {
    if (!m_imp)
        return Indicator();

    if (!ind.getImp())
        return Indicator(m_imp);
    
    IndicatorImpPtr p = m_imp->clone();
    p->add(IndicatorImp::OP, IndicatorImpPtr(), ind.getImp());
    return p->calculate();
}
Beispiel #11
0
void ISqrt::_calculate(const Indicator& data) {
    size_t total = data.size();
    m_discard = data.discard();
    if (m_discard >= total) {
        m_discard = total;
        return;
    }

    for (size_t i = m_discard; i < total; ++i) {
        _set(std::sqrt(data[i]), i);
    }
}
Beispiel #12
0
void Diff::_calculate(const Indicator& data) {
    size_t total = data.size();

    m_discard = data.discard() + 1;
    if (total <= m_discard) {
        return;
    }

    for (size_t i = discard(); i < total; ++i) {
        _set(data[i] - data[i-1], i);
    }
}
Beispiel #13
0
void IRound::_calculate(const Indicator& data) {
    size_t total = data.size();
    m_discard = data.discard();
    if (m_discard >= total) {
        m_discard = total;
        return;
    }

    int n = getParam<int>("ndigits");
    for (size_t i = m_discard; i < total; ++i) {
        _set(roundEx(data[i], n), i);
    }
}
Beispiel #14
0
void IReverse::_calculate(const Indicator& data) {
    size_t total = data.size();
    m_discard = data.discard();
    if (m_discard >= total) {
        m_discard = total;
        return;
    }

    for (size_t i = m_discard; i < total; ++i) {
        _set(-data[i], i);
    }

}
int main(int argc, char *argv[])
{
    platform_initialize();
    platform_add_objectset(new RollerRobot());

    Indicator *ir = new Indicator(0, 1);
    difference_indicator_id = ir->id();
    platform_add_objectset(ir);

    platform_add_objectset(new SlopeField());
    platform_start(argc, argv);

    return 0;
}
Beispiel #16
0
void SaftyLoss::_calculate(const Indicator& data) {
    size_t total = data.size();
    if (total == 0) {
        return;
    }
    _readyBuffer(total, 1);

    int n1 = getParam<int>("n1");
    int n2 = getParam<int>("n2");
    double p = getParam<double>("p");

    m_discard = data.discard() + n1 + n2 - 2;
    if (m_discard >= total) {
        m_discard = total;
        return;
    }

    price_t sum = 0.0;
    size_t num = 0;
    price_t result = 0.0;

    size_t start = discard();
    for (size_t i = start; i < total; ++i) {
        result = 0.0;
        for (size_t j = i + 1 - n2; j <= i; ++j) {
            sum = 0.0;
            num = 0;
            for (size_t k = j + 2 -n1; k <=j; ++k) {
                price_t pre = data[k-1];
                price_t cur = data[k];
                if (pre > cur) {
                    sum += pre - cur;
                    ++num;
                }
            }

            price_t temp = data[j];
            if (num != 0) {
                temp = temp - (p * sum / num);
            }

            if (temp > result) {
                result = temp;
            }
        }

        _set(result, i);
    }
}
Beispiel #17
0
void INot::_calculate(const Indicator& data) {
    size_t total = data.size();
    m_discard = data.discard();
    if (m_discard >= total) {
        m_discard = total;
        return;
    }

    for (size_t i = m_discard; i < total; ++i) {
        if (data[i] == 0.0) {
            _set(1.0, i);
        } else {
            _set(0.0, i);
        }
    }
}
Beispiel #18
0
Indicator * THERM::calculate ()
{
  Indicator *output = new Indicator;
  output->setDateFlag(dateFlag);
  output->setLogScale(logScale);

  QPtrList<PlotLine> pll;
  pll.setAutoDelete(FALSE);
  getTHERM(pll);

  int loop;
  for (loop = 0; loop < (int) pll.count(); loop++)
    output->addLine(pll.at(loop));

  return output;
}
bool TesterStopPage::loadCustomLongStop (BarData *recordList)
{
  if (customLongStopLine)
  {
    delete customLongStopLine;
    customLongStopLine = 0;
  }
  
  if (! customLongStopEdit->getLines() || ! customLongStopCheck->isChecked())
    return FALSE;

  QString s;
  customLongStopEdit->getText(s);
  QStringList l = QStringList::split("\n", s, FALSE);
  
  QString plugin("CUS");
  Config config;
  IndicatorPlugin *plug = config.getIndicatorPlugin(plugin);
  if (! plug)
  {
    config.closePlugin(plugin);
    return TRUE;
  }

  plug->setCustomFunction(l);
  
  // load the CUS plugin and calculate
  plug->setIndicatorInput(recordList);
  Indicator *i = plug->calculate();
  PlotLine *line = i->getLine(0);
  if (! line)
  {
    qDebug("Tester::loadCustomShortStop: no PlotLine returned");
    config.closePlugin(plugin);
    delete i;
    return TRUE;
  }
    
  customLongStopLine = new PlotLine;
  customLongStopLine->copy(line);
  delete i;
    
  config.closePlugin(plugin);
  
  return FALSE;
}
Beispiel #20
0
Indicator * BARS::calculate ()
{
  Indicator *output = new Indicator;
  output->setDateFlag(dateFlag);
  output->setLogScale(logScale);

  if (! method.compare("OHLC"))
  {
    output->addLine(calculateOHLC());
    calculateMA(output);
  }

  if (! method.compare("Candle"))
  {
    output->addLine(calculateCandle());
    calculateMA(output);
  }

  if (! method.compare("HACandle"))
  {
    output->addLine(calculateHACandle());
    calculateMA(output);
  }

  if (! method.compare("PF"))
    output->addLine(calculatePF());

  return output;
}
Beispiel #21
0
void IVarp::_calculate(const Indicator& data) {
    size_t total = data.size();
    int n = getParam<int>("n");

    m_discard = data.discard() + n - 1;
    if (m_discard >= total) {
        m_discard = total;
        return;
    }

    Indicator ma = MA(data, n);
    for (size_t i = discard(); i < total; ++i) {
        price_t mean = ma[i];
        price_t sum = 0.0;
        for (size_t j = i + 1 - n; j <= i; ++j) {
            sum += std::pow(data[j] - mean, 2);
        }
        _set(sum/n, i);
    }
}
Beispiel #22
0
void Macd::_calculate(const Indicator& data) {
    size_t total = data.size();
    if (total == 0) {
        return;
    }
    
    _readyBuffer(total, 3);

    int n1 = getParam<int>("n1");
    int n2 = getParam<int>("n2");
    int n3 = getParam<int>("n3");

    m_discard = data.discard();
    if (total <= m_discard) {
        m_discard = total;
        return;
    }

    price_t m1 = 2.0 / (n1 + 1);
    price_t m2 = 2.0 / (n2 + 1);
    price_t m3 = 2.0 / (n3 + 1);
    price_t ema1 = data[0];
    price_t ema2 = data[0];
    price_t diff = 0.0;
    price_t dea = 0.0;
    price_t bar = 0.0;
    _set(bar, 0, 0);
    _set(diff, 0, 1);
    _set(dea, 0, 2);

    for (size_t  i = 1; i < total; ++i) {
        ema1 = (data[i] - ema1) * m1 + ema1;
        ema2 = (data[i] - ema2) * m2 + ema2;
        diff = ema1 - ema2;
        dea = diff * m3 + dea - dea * m3;
        bar = diff - dea;
        _set(bar, i, 0);
        _set(diff, i, 1);
        _set(dea, i, 2);
    }
}
Beispiel #23
0
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;
}
Beispiel #24
0
void File_v1::loadIndicator(CrochetTab *tab, QXmlStreamReader *stream)
{
    Indicator *i = new Indicator();

    qreal x = 0, y = 0;
    QString textColor, bgColor;
    QString text;

    while(!(stream->isEndElement() && stream->name() == "indicator")) {
        stream->readNext();
        QString tag = stream->name().toString();

        if(tag == "x") {
            x = stream->readElementText().toDouble();
        } else if(tag == "y") {
            y = stream->readElementText().toDouble();
        } else if(tag == "text") {
            text = stream->readElementText();
			//the text might be html formatted in old saves, so we need to strip it. A regex could work,
			//but is hard to make performant with inline css, and wouldn't work well with text that has
			//brackets in it.
			QTextDocument doc;
			doc.setHtml( text );
			text = doc.toPlainText();
        } else if(tag == "textColor") {
            textColor = stream->readElementText();
        } else if(tag == "bgColor") {
            bgColor = stream->readElementText();
        }
    }

    tab->scene()->addItem(i);
    i->setPos(x,y);
    i->setText(text);
    i->setTextColor(textColor);
    i->setBgColor(bgColor);
	ChartItemTools::recalculateTransformations(i);
}
Beispiel #25
0
void ConstantValue::_calculate(const Indicator& data) {
    double value = getParam<double>("value");
    int discard = getParam<int>("discard");

    size_t total = 0;
    if (isLeaf()) {
        //叶子节点
        KData k = getContext();
        if (k.getStock().isNull()) {
            _readyBuffer(1, 1);
            if (discard < 1) {
                m_discard = 0;
                _set(value, 0, 0);
            } else {
                m_discard = 1;
            }
            return;
        }

        total = k.size();
        if (0 == total) {
            return;
        }

        _readyBuffer(total, 1);
    
    } else {
        //非叶子节点
        total = data.size();
        discard = data.discard() > discard ? data.discard() : discard;
    }

    m_discard = discard > total ? total : discard;

    for (size_t i = m_discard; i < total; ++i) {
        _set(value, i, 0);
    }
}
Beispiel #26
0
void IPriceList::_calculate(const Indicator& data) {
    //如果在叶子节点,直接取自身的data参数
    if (isLeaf()) {
        PriceList x = getParam<PriceList>("data");
        int discard = getParam<int>("discard");

        size_t total = x.size();
        _readyBuffer(total, 1);

        //更新抛弃数量
        m_discard = discard > total ? total : discard;

        for (size_t i = m_discard; i < total; ++i) {
            _set(x[i], i);
        }

        return;
    }

    //不在叶子节点上,则忽略本身的data参数,认为其输入实际为函数入参中的data
    int result_index = getParam<int>("result_index");
    if (result_index < 0 || result_index >= data.getResultNumber()) {
        HKU_ERROR("result_index out of range! [IPriceList::IPriceList]");
        return;
    }

    size_t total = data.size();
    _readyBuffer(total, 1);

    for (size_t i = data.discard(); i < total; ++i) {
        _set(data.get(i, result_index), i);
    }

    //更新抛弃数量
    m_discard = data.discard();
}
Beispiel #27
0
Indicator HKU_API IF(const Indicator& ind1, 
        const Indicator& ind2, const Indicator& ind3) {
    if (!ind1.getImp() || !ind2.getImp() || !ind3.getImp()) {
        HKU_ERROR("Exists null indicator! [IF]");
        return Indicator();
    }

    IndicatorImpPtr p = make_shared<IndicatorImp>();
    p->add_if(ind1.getImp(), ind2.getImp(), ind3.getImp());
    return p->calculate();
}
Beispiel #28
0
Indicator Indicator::operator()(const KData& k) {
    Indicator result = clone();
    result.setContext(k);
    return result;
}
Beispiel #29
0
Indicator HKU_API AmaSpecial(const Block& block, KQuery query,
        Indicator ama) {
    Indicator result;
    StockManager& sm = StockManager::instance();

    //计算每日股票总数
    DatetimeList dateList = sm.getTradingCalendar(query, "SH");

    size_t dayTotal = dateList.size();
    if (dayTotal == 0) {
        result = PRICELIST(PriceList());
        result.name("POS");
        return result;
    }

    vector<size_t> numberPerDay(dayTotal);
    for (size_t i = 0; i < dayTotal; ++i) {
        numberPerDay[i] = 0;
        for (auto stk_iter = block.begin(); stk_iter != block.end(); ++stk_iter) {
            if (stk_iter->startDatetime() <= dateList[i]
                  && dateList[i] <= stk_iter->lastDatetime()) {
                numberPerDay[i]++;
            }
        }
    }

    vector<size_t> position(dayTotal);
    size_t discard = ama.discard();
    for (auto stk_iter = block.begin(); stk_iter != block.end(); ++stk_iter) {
        KData kdata = stk_iter->getKData(query);
        if (kdata.empty())
            continue;
        SignalPtr sg(SG_Single(ama));
        sg->setTO(kdata);
        bool isHold = false;
        size_t n_dis = 0;
        for (size_t i = 0; i < dayTotal; ++i) {
            if (isHold) {
                if (sg->shouldSell(dateList[i])) {
                    isHold = false;
                } else {
                    position[i]++;
                }

            } else {
                if (sg->shouldBuy(dateList[i])) {
                    position[i]++;
                    isHold = true;
                }
            }

            if (dateList[i] >= kdata[0].datetime) {
                if (n_dis < discard) {
                    n_dis++;
                    numberPerDay[i]--;
                }
            }

        }
    }

    PriceList tmp_result(dayTotal, Null<price_t>());
    for (auto i = discard; i < dayTotal; ++i) {
        tmp_result[i] = numberPerDay[i]
                  ? (double)position[i]/(double)numberPerDay[i] : 1.0;
    }

    result = PRICELIST(tmp_result);
    result.name("POS");
    return PRICELIST(result);
}
Beispiel #30
0
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;
}