static ErrorNumber do_test( const TA_History *history, const TA_Test *test ) { TA_RetCode retCode; ErrorNumber errNb; TA_Integer outBegIdx; TA_Integer outNbElement; TA_RangeTestParam testParam; /* Set to NAN all the elements of the gBuffers. */ clearAllBuffers(); /* Build the input. */ setInputBuffer( 0, history->high, history->nbBars ); setInputBuffer( 1, history->low, history->nbBars ); /* Make a simple first call. */ switch( test->theFunction ) { case TA_AROON_UP_TEST: retCode = TA_AROON( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[1].out0, gBuffer[0].out0 ); break; case TA_AROON_DOWN_TEST: retCode = TA_AROON( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[0].out0, gBuffer[1].out0 ); break; case TA_AROONOSC_TEST: retCode = TA_AROONOSC( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[0].out0 ); break; case TA_CORREL_TEST: retCode = TA_CORREL( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[0].out0 ); break; default: retCode = TA_INTERNAL_ERROR(133); } /* Check that the input were preserved. */ errNb = checkDataSame( gBuffer[0].in, history->high,history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; errNb = checkDataSame( gBuffer[1].in, history->low, history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; CHECK_EXPECTED_VALUE( gBuffer[0].out0, 0 ); outBegIdx = outNbElement = 0; /* Make another call where one of the input and one of the output * are the same buffer. */ switch( test->theFunction ) { case TA_AROON_UP_TEST: retCode = TA_AROON( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[1].out1, gBuffer[0].in ); break; case TA_AROON_DOWN_TEST: retCode = TA_AROON( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[0].in, gBuffer[1].out1 ); break; case TA_AROONOSC_TEST: retCode = TA_AROONOSC( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[0].in ); break; case TA_CORREL_TEST: retCode = TA_CORREL( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[0].in ); break; default: retCode = TA_INTERNAL_ERROR(134); } /* Check that the other input was preserved. */ errNb = checkDataSame( gBuffer[1].in, history->low, history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; /* The previous call should have the same output * as this call. * * checkSameContent verify that all value different than NAN in * the first parameter is identical in the second parameter. */ errNb = checkSameContent( gBuffer[0].out0, gBuffer[0].in ); if( errNb != TA_TEST_PASS ) return errNb; errNb = checkSameContent( gBuffer[1].out1, gBuffer[1].out0 ); if( errNb != TA_TEST_PASS ) return errNb; CHECK_EXPECTED_VALUE( gBuffer[0].in, 0 ); setInputBuffer( 0, history->high, history->nbBars ); setInputBuffer( 1, history->low, history->nbBars ); /* Make another call where the input and the output are the * same buffer. */ switch( test->theFunction ) { case TA_AROON_UP_TEST: retCode = TA_AROON( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[1].out2, gBuffer[1].in ); break; case TA_AROON_DOWN_TEST: retCode = TA_AROON( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[1].in, gBuffer[1].out2 ); break; case TA_AROONOSC_TEST: retCode = TA_AROONOSC( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[1].in ); break; case TA_CORREL_TEST: retCode = TA_CORREL( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[1].in ); break; default: retCode = TA_INTERNAL_ERROR(135); } /* Check that the other input were preserved. */ errNb = checkDataSame( gBuffer[0].in, history->high, history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; /* The previous call should have the same output as this call. * * checkSameContent verify that all value different than NAN in * the first parameter is identical in the second parameter. */ errNb = checkSameContent( gBuffer[0].out0, gBuffer[1].in ); if( errNb != TA_TEST_PASS ) return errNb; /* Do a systematic test of most of the * possible startIdx/endIdx range. */ testParam.test = test; testParam.high = history->high; testParam.low = history->low; if( test->doRangeTestFlag ) { errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_NONE, (void *)&testParam, 1, 0 ); if( errNb != TA_TEST_PASS ) return errNb; } return TA_TEST_PASS; }
int AROON::getAROON (int period, QString ukey, QString dkey) { if (! g_symbol) return 0; TA_RetCode rc = TA_Initialize(); if (rc != TA_SUCCESS) qDebug() << "AROON::AROON: error on TA_Initialize"; QList<int> keys = g_symbol->keys(); TA_Real high[MAX_SIZE]; TA_Real low[MAX_SIZE]; TA_Real out[MAX_SIZE]; TA_Real out2[MAX_SIZE]; TA_Integer outBeg; TA_Integer outNb; BarType bt; QString highKey = bt.indexToString(BarType::_HIGH); QString lowKey = bt.indexToString(BarType::_LOW); int dpos = 0; for (int kpos = 0; kpos < keys.size(); kpos++) { CBar *bar = g_symbol->bar(keys.at(kpos)); double h; if (! bar->get(highKey, h)) continue; double l; if (! bar->get(lowKey, l)) continue; high[dpos] = (TA_Real) h; low[dpos] = (TA_Real) l; dpos++; } rc = TA_AROON(0, dpos - 1, &high[0], &low[0], period, &outBeg, &outNb, &out[0], &out2[0]); if (rc != TA_SUCCESS) { qDebug() << "AROON::getAROON: TA-Lib error" << rc; return 0; } int keyLoop = keys.size() - 1; int outLoop = outNb - 1; while (keyLoop > -1 && outLoop > -1) { CBar *bar = g_symbol->bar(keys.at(keyLoop)); bar->set(dkey, out[outLoop]); bar->set(ukey, out2[outLoop]); keyLoop--; outLoop--; } return 1; }
/**** Local functions definitions. ****/ static TA_RetCode rangeTestFunction( TA_Integer startIdx, TA_Integer endIdx, TA_Real *outputBuffer, TA_Integer *outputBufferInt, TA_Integer *outBegIdx, TA_Integer *outNbElement, TA_Integer *lookback, void *opaqueData, unsigned int outputNb, unsigned int *isOutputInteger ) { TA_RetCode retCode; TA_RangeTestParam *testParam; double *dummyBuffer; (void)outputNb; (void)outputBufferInt; *isOutputInteger = 0; testParam = (TA_RangeTestParam *)opaqueData; /* Allocate a buffer for the output who is going * to be ignored (make it slightly larger to play * safe) */ dummyBuffer = TA_Malloc( sizeof(double) * (endIdx-startIdx+100) ); switch( testParam->test->theFunction ) { case TA_AROON_UP_TEST: retCode = TA_AROON( startIdx, endIdx, testParam->high, testParam->low, testParam->test->optInTimePeriod, outBegIdx, outNbElement, &dummyBuffer[20], outputBuffer ); *lookback = TA_AROON_Lookback( testParam->test->optInTimePeriod ); break; case TA_AROON_DOWN_TEST: retCode = TA_AROON( startIdx, endIdx, testParam->high, testParam->low, testParam->test->optInTimePeriod, outBegIdx, outNbElement, outputBuffer, &dummyBuffer[20] ); *lookback = TA_AROON_Lookback( testParam->test->optInTimePeriod ); break; case TA_AROONOSC_TEST: retCode = TA_AROONOSC( startIdx, endIdx, testParam->high, testParam->low, testParam->test->optInTimePeriod, outBegIdx, outNbElement, outputBuffer ); *lookback = TA_AROONOSC_Lookback( testParam->test->optInTimePeriod ); break; case TA_CORREL_TEST: retCode = TA_CORREL( startIdx, endIdx, testParam->high, testParam->low, testParam->test->optInTimePeriod, outBegIdx, outNbElement, outputBuffer ); *lookback = TA_CORREL_Lookback( testParam->test->optInTimePeriod ); break; default: retCode = TA_INTERNAL_ERROR(132); } TA_Free( dummyBuffer ); return retCode; }