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->open, history->nbBars ); setInputBuffer( 1, history->high, history->nbBars ); setInputBuffer( 2, history->low, history->nbBars ); setInputBuffer( 3, history->close, history->nbBars ); /* Make a simple first call. */ switch( test->theFunction ) { case TA_BOP_TEST: retCode = TA_BOP( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, gBuffer[3].in, &outBegIdx, &outNbElement, gBuffer[0].out0 ); break; case TA_AVGPRICE_TEST: retCode = TA_AVGPRICE( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, gBuffer[3].in, &outBegIdx, &outNbElement, gBuffer[0].out0 ); break; default: retCode = TA_INTERNAL_ERROR(172); } /* Check that the input were preserved. */ errNb = checkDataSame( gBuffer[0].in, history->open,history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; errNb = checkDataSame( gBuffer[1].in, history->high, history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; errNb = checkDataSame( gBuffer[2].in, history->low,history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; errNb = checkDataSame( gBuffer[3].in, history->close,history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; CHECK_EXPECTED_VALUE( gBuffer[0].out0, 0 ); outBegIdx = outNbElement = 0; /* Make another call where the input and the output are the * same buffer. */ switch( test->theFunction ) { case TA_BOP_TEST: retCode = TA_BOP( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, gBuffer[3].in, &outBegIdx, &outNbElement, gBuffer[0].in ); break; case TA_AVGPRICE_TEST: retCode = TA_AVGPRICE( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, gBuffer[3].in, &outBegIdx, &outNbElement, gBuffer[0].in ); break; default: retCode = TA_INTERNAL_ERROR(173); } /* Check that the input were preserved. */ errNb = checkDataSame( gBuffer[1].in, history->high, history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; errNb = checkDataSame( gBuffer[2].in, history->low,history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; errNb = checkDataSame( gBuffer[3].in, history->close,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; CHECK_EXPECTED_VALUE( gBuffer[0].in, 0 ); setInputBuffer( 0, history->open, history->nbBars ); /* Make another call where the input and the output are the * same buffer. */ switch( test->theFunction ) { case TA_BOP_TEST: retCode = TA_BOP( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, gBuffer[3].in, &outBegIdx, &outNbElement, gBuffer[1].in ); break; case TA_AVGPRICE_TEST: retCode = TA_AVGPRICE( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, gBuffer[3].in, &outBegIdx, &outNbElement, gBuffer[1].in ); break; default: retCode = TA_INTERNAL_ERROR(174); } /* Check that the input were preserved. */ errNb = checkDataSame( gBuffer[0].in, history->open,history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; errNb = checkDataSame( gBuffer[2].in, history->low,history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; errNb = checkDataSame( gBuffer[3].in, history->close,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; CHECK_EXPECTED_VALUE( gBuffer[1].in, 0 ); setInputBuffer( 1, history->high, history->nbBars ); /* Make another call where the input and the output are the * same buffer. */ switch( test->theFunction ) { case TA_BOP_TEST: retCode = TA_BOP( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, gBuffer[3].in, &outBegIdx, &outNbElement, gBuffer[2].in ); break; case TA_AVGPRICE_TEST: retCode = TA_AVGPRICE( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, gBuffer[3].in, &outBegIdx, &outNbElement, gBuffer[2].in ); break; default: retCode = TA_INTERNAL_ERROR(175); } /* Check that the input were preserved. */ errNb = checkDataSame( gBuffer[0].in, history->open,history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; errNb = checkDataSame( gBuffer[1].in, history->high, history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; errNb = checkDataSame( gBuffer[3].in, history->close, 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[2].in ); if( errNb != TA_TEST_PASS ) return errNb; CHECK_EXPECTED_VALUE( gBuffer[2].in, 0 ); setInputBuffer( 2, history->low, history->nbBars ); /* Make another call where the input and the output are the * same buffer. */ switch( test->theFunction ) { case TA_BOP_TEST: retCode = TA_BOP( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, gBuffer[3].in, &outBegIdx, &outNbElement, gBuffer[3].in ); break; case TA_AVGPRICE_TEST: retCode = TA_AVGPRICE( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, gBuffer[3].in, &outBegIdx, &outNbElement, gBuffer[3].in ); break; default: retCode = TA_INTERNAL_ERROR(176); } /* Check that the input were preserved. */ errNb = checkDataSame( gBuffer[0].in, history->open,history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; errNb = checkDataSame( gBuffer[1].in, history->high, history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; errNb = checkDataSame( gBuffer[2].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[3].in ); if( errNb != TA_TEST_PASS ) return errNb; CHECK_EXPECTED_VALUE( gBuffer[3].in, 0 ); setInputBuffer( 3, history->close, history->nbBars ); /* Do a systematic test of most of the * possible startIdx/endIdx range. */ testParam.test = test; testParam.open = history->open; testParam.high = history->high; testParam.low = history->low; testParam.close = history->close; 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; }
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; const TA_Real *referenceInput; /* Set to NAN all the elements of the gBuffers. */ clearAllBuffers(); /* Build the input. */ setInputBuffer( 0, history->close, history->nbBars ); setInputBuffer( 1, history->close, history->nbBars ); setInputBuffer( 2, history->close, history->nbBars ); /* Change the input to MEDPRICE for some tests. */ switch( test->theFunction ) { case TA_HT_PHASOR_TEST: case TA_HT_SINE_TEST: TA_MEDPRICE( 0, history->nbBars-1, history->high, history->low, &outBegIdx, &outNbElement, gBuffer[0].in ); TA_MEDPRICE( 0, history->nbBars-1, history->high, history->low, &outBegIdx, &outNbElement, gBuffer[1].in ); /* Will be use as reference */ TA_MEDPRICE( 0, history->nbBars-1, history->high, history->low, &outBegIdx, &outNbElement, gBuffer[2].in ); referenceInput = gBuffer[2].in; break; default: referenceInput = history->close; } /* Make a simple first call. */ switch( test->theFunction ) { case TA_HT_PHASOR_TEST: retCode = TA_HT_PHASOR( test->startIdx, test->endIdx, gBuffer[0].in, &outBegIdx, &outNbElement, gBuffer[0].out0, gBuffer[0].out1 ); break; case TA_HT_SINE_TEST: retCode = TA_HT_SINE( test->startIdx, test->endIdx, gBuffer[0].in, &outBegIdx, &outNbElement, gBuffer[0].out0, gBuffer[0].out1 ); break; default: retCode = TA_INTERNAL_ERROR(133); } /* Check that the inputs were preserved. */ errNb = checkDataSame( gBuffer[0].in, referenceInput, history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; errNb = checkDataSame( gBuffer[1].in, referenceInput, history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; CHECK_EXPECTED_VALUE( gBuffer[0].out0, 0 ); CHECK_EXPECTED_VALUE( gBuffer[0].out1, 1 ); outBegIdx = outNbElement = 0; /* Make another call where the input and the output * are the same buffer. */ switch( test->theFunction ) { case TA_HT_PHASOR_TEST: retCode = TA_HT_PHASOR( test->startIdx, test->endIdx, gBuffer[0].in, &outBegIdx, &outNbElement, gBuffer[0].in, gBuffer[1].out1 ); break; case TA_HT_SINE_TEST: retCode = TA_HT_SINE( test->startIdx, test->endIdx, gBuffer[0].in, &outBegIdx, &outNbElement, gBuffer[0].in, gBuffer[1].out1 ); break; default: retCode = TA_INTERNAL_ERROR(134); } /* 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[0].out1, gBuffer[1].out1 ); if( errNb != TA_TEST_PASS ) return errNb; CHECK_EXPECTED_VALUE( gBuffer[0].in, 0 ); CHECK_EXPECTED_VALUE( gBuffer[1].out1, 1 ); /* Make another call where the input and the output * are the same buffer. */ switch( test->theFunction ) { case TA_HT_PHASOR_TEST: retCode = TA_HT_PHASOR( test->startIdx, test->endIdx, gBuffer[1].in, &outBegIdx, &outNbElement, gBuffer[1].out0, gBuffer[1].in ); break; case TA_HT_SINE_TEST: retCode = TA_HT_SINE( test->startIdx, test->endIdx, gBuffer[1].in, &outBegIdx, &outNbElement, gBuffer[1].out0, gBuffer[1].in ); break; default: retCode = TA_INTERNAL_ERROR(134); } /* 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].out1, gBuffer[1].in ); if( errNb != TA_TEST_PASS ) return errNb; errNb = checkSameContent( gBuffer[0].out0, gBuffer[1].out0 ); if( errNb != TA_TEST_PASS ) return errNb; CHECK_EXPECTED_VALUE( gBuffer[1].in, 1 ); CHECK_EXPECTED_VALUE( gBuffer[1].out0, 0 ); /* Do a systematic test of most of the * possible startIdx/endIdx range. */ testParam.test = test; testParam.price = referenceInput; if( test->doRangeTestFlag ) { switch( test->theFunction ) { case TA_HT_PHASOR_TEST: errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_HT_PHASOR, (void *)&testParam, 1, 0 ); break; case TA_HT_SINE_TEST: errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_HT_SINE, (void *)&testParam, 1, 10 ); break; default: errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_NONE, (void *)&testParam, 1, 0 ); } if( errNb != TA_TEST_PASS ) return errNb; } return TA_TEST_PASS; }
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 ); setInputBuffer( 2, history->close, history->nbBars ); /* Clear the unstable periods from previous tests. */ retCode = TA_SetUnstablePeriod( TA_FUNC_UNST_MFI, 0 ); if( retCode != TA_SUCCESS ) return TA_TEST_TFRR_SETUNSTABLE_PERIOD_FAIL; /* Make a simple first call. */ switch( test->theFunction ) { case TA_MFI_TEST: retCode = TA_MFI( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, history->volume, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[0].out0 ); break; case TA_AD_TEST: retCode = TA_AD( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, history->volume, &outBegIdx, &outNbElement, gBuffer[0].out0 ); break; case TA_ADOSC_3_10_TEST: retCode = TA_ADOSC( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, history->volume, 3, 10, &outBegIdx, &outNbElement, gBuffer[0].out0 ); break; case TA_ADOSC_5_2_TEST: retCode = TA_ADOSC( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, history->volume, 5, 2, &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; errNb = checkDataSame( gBuffer[2].in, history->close,history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; CHECK_EXPECTED_VALUE( gBuffer[0].out0, 0 ); outBegIdx = outNbElement = 0; /* Make another call where the input and the output are the * same buffer. */ switch( test->theFunction ) { case TA_MFI_TEST: retCode = TA_MFI( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, history->volume, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[0].in ); break; case TA_AD_TEST: retCode = TA_AD( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, history->volume, &outBegIdx, &outNbElement, gBuffer[0].in ); break; case TA_ADOSC_3_10_TEST: retCode = TA_ADOSC( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, history->volume, 3, 10, &outBegIdx, &outNbElement, gBuffer[0].in ); break; case TA_ADOSC_5_2_TEST: retCode = TA_ADOSC( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, history->volume, 5, 2, &outBegIdx, &outNbElement, gBuffer[0].in ); break; default: retCode = TA_INTERNAL_ERROR(134); } /* Check that the input were preserved. */ errNb = checkDataSame( gBuffer[1].in, history->low, history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; errNb = checkDataSame( gBuffer[2].in, history->close,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; CHECK_EXPECTED_VALUE( gBuffer[0].in, 0 ); setInputBuffer( 0, history->high, history->nbBars ); /* Make another call where the input and the output are the * same buffer. */ switch( test->theFunction ) { case TA_MFI_TEST: retCode = TA_MFI( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, history->volume, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[1].in ); break; case TA_AD_TEST: retCode = TA_AD( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, history->volume, &outBegIdx, &outNbElement, gBuffer[1].in ); break; case TA_ADOSC_3_10_TEST: retCode = TA_ADOSC( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, history->volume, 3, 10, &outBegIdx, &outNbElement, gBuffer[1].in ); break; case TA_ADOSC_5_2_TEST: retCode = TA_ADOSC( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, history->volume, 5, 2, &outBegIdx, &outNbElement, gBuffer[1].in ); break; default: retCode = TA_INTERNAL_ERROR(135); } /* 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[2].in, history->close,history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; /* The previous call to TA_MA 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; CHECK_EXPECTED_VALUE( gBuffer[1].in, 0 ); setInputBuffer( 1, history->low, history->nbBars ); /* Make another call where the input and the output are the * same buffer. */ switch( test->theFunction ) { case TA_MFI_TEST: retCode = TA_MFI( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, history->volume, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[2].in ); break; case TA_AD_TEST: retCode = TA_AD( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, history->volume, &outBegIdx, &outNbElement, gBuffer[2].in ); break; case TA_ADOSC_3_10_TEST: retCode = TA_ADOSC( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, history->volume, 3, 10, &outBegIdx, &outNbElement, gBuffer[2].in ); break; case TA_ADOSC_5_2_TEST: retCode = TA_ADOSC( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, history->volume, 5, 2, &outBegIdx, &outNbElement, gBuffer[2].in ); break; default: retCode = TA_INTERNAL_ERROR(136); } /* 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; /* 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[2].in ); if( errNb != TA_TEST_PASS ) return errNb; CHECK_EXPECTED_VALUE( gBuffer[2].in, 0 ); setInputBuffer( 2, history->close, history->nbBars ); if( test->doRangeTestFlag ) { /* Do a systematic test of most of the * possible startIdx/endIdx range. */ testParam.test = test; testParam.high = history->high; testParam.low = history->low; testParam.close = history->close; testParam.volume = history->volume; switch( test->theFunction ) { case TA_MFI_TEST: errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_MFI, (void *)&testParam, 1, 0 ); if( errNb != TA_TEST_PASS ) return errNb; break; case TA_AD_TEST: errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_NONE, (void *)&testParam, 1, TA_DO_NOT_COMPARE ); if( errNb != TA_TEST_PASS ) return errNb; break; case TA_ADOSC_3_10_TEST: case TA_ADOSC_5_2_TEST: errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_EMA, (void *)&testParam, 1, TA_DO_NOT_COMPARE ); if( errNb != TA_TEST_PASS ) return errNb; break; default: break; } } /* Check for fix #1359452 - AD RAnge not working as expected. */ if( test->theFunction == TA_AD_TEST ) { gBuffer[0].out0[0] = -1.0; gBuffer[0].out0[1] = -1.0; retCode = TA_AD( 0, 0, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, history->volume, &outBegIdx, &outNbElement, &gBuffer[0].out0[0] ); if( retCode != TA_SUCCESS ) { printf( "Failed AD call for fix #1359452 [%d]\n", retCode ); return TA_TEST_FAIL_BUG1359452_1; } if( gBuffer[0].out0[0] == -1.0 ) { printf( "Failed AD call for fix #1359452 out0[0] == -1\n" ); return TA_TEST_FAIL_BUG1359452_2; } retCode = TA_AD( 1, 1, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, history->volume, &outBegIdx, &outNbElement, &gBuffer[0].out0[1] ); if( retCode != TA_SUCCESS ) { printf( "Failed AD call for fix #1359452 [%d]\n", retCode ); return TA_TEST_FAIL_BUG1359452_3; } if( gBuffer[0].out0[1] == -1.0 ) { printf( "Failed AD call for fix #1359452 out0[1] == -1\n" ); return TA_TEST_FAIL_BUG1359452_4; } /* The two values are to be different. */ if( gBuffer[0].out0[1] == gBuffer[0].out0[0] ) { printf( "Failed AD logic for fix #1359452\n" ); return TA_TEST_FAIL_BUG1359452_5; } } return TA_TEST_PASS; }
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->open, history->nbBars ); setInputBuffer( 1, history->open, history->nbBars ); CLEAR_EXPECTED_VALUE(0); /* Do a systematic test of most of the * possible startIdx/endIdx range. */ testParam.test = test; testParam.close = history->close; if( test->doRangeTestFlag ) { errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_NONE, (void *)&testParam, 1, 0 ); if( errNb != TA_TEST_PASS ) return errNb; } /* Make a simple first call. */ if( test->theFunction == TA_MIN_TEST ) { retCode = TA_MIN( test->startIdx, test->endIdx, gBuffer[0].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[0].out0 ); } else if( test->theFunction == TA_MAX_TEST ) { retCode = TA_MAX( test->startIdx, test->endIdx, gBuffer[0].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[0].out0 ); } else { /* For now, tests only MIN and MAX. Only range check tests implemented. */ return TA_TEST_PASS; } errNb = checkDataSame( gBuffer[0].in, history->open,history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; CHECK_EXPECTED_VALUE( gBuffer[0].out0, 0 ); outBegIdx = outNbElement = 0; /* Make another call where the input and the output are the * same buffer. */ CLEAR_EXPECTED_VALUE(0); if( test->theFunction == TA_MIN_TEST ) { retCode = TA_MIN( test->startIdx, test->endIdx, gBuffer[1].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[1].in ); } else if( test->theFunction == TA_MAX_TEST ) { retCode = TA_MAX( test->startIdx, test->endIdx, gBuffer[1].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[1].in ); } /* 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; CHECK_EXPECTED_VALUE( gBuffer[1].in, 0 ); if( errNb != TA_TEST_PASS ) return errNb; return TA_TEST_PASS; }
static ErrorNumber testCompareToReference( const TA_Real *input, int nbElement ) { TA_Integer outBegIdx, outNbElement; TA_RetCode retCode; TA_Integer outBegIdxRef, outNbElementRef; TA_RetCode retCodeRef; int period, startIdx, endIdx, testNb; ErrorNumber errNb; /* Do a systematic tests, even for failure cases. */ for( testNb=0; testNb <= 1; testNb++ ) /* 0=TA_MIN, 1=TA_MAX */ { for( period=2; period <= nbElement; period++ ) { for( startIdx=0; startIdx < nbElement; startIdx++ ) { for( endIdx=0; (endIdx < nbElement) && (startIdx <= endIdx); endIdx++ ) { /* Set to NAN all the elements of the gBuffers. * Note: These buffer are used as an attempt to detect * out-of-bound writing in the output. */ clearAllBuffers(); /* Build the input. */ setInputBuffer( 0, input, nbElement ); /* Get the reference output. */ if( testNb == 0 ) retCodeRef = referenceMin( startIdx, endIdx, input, period, &outBegIdxRef, &outNbElementRef, gBuffer[0].out0 ); else retCodeRef = referenceMax( startIdx, endIdx, input, period, &outBegIdxRef, &outNbElementRef, gBuffer[0].out0 ); /* Verify that the input was preserved */ errNb = checkDataSame( gBuffer[0].in, input, nbElement ); if( errNb != TA_TEST_PASS ) return errNb; /* Get the TA-Lib implementation output. */ if( testNb == 0 ) retCode = TA_MIN( startIdx, endIdx, input, period, &outBegIdx, &outNbElement, gBuffer[1].out0 ); else retCode = TA_MAX( startIdx, endIdx, input, period, &outBegIdx, &outNbElement, gBuffer[1].out0 ); /* Verify that the input was preserved */ errNb = checkDataSame( gBuffer[0].in, input, nbElement ); if( errNb != TA_TEST_PASS ) return errNb; /* The reference and TA-LIB should have the same output. */ if( retCode != retCodeRef ) { printf( "Failure: retCode != retCodeRef\n" ); return TA_REGTEST_OPTIMIZATION_REF_ERROR; } if( outBegIdx != outBegIdxRef ) { printf( "Failure: outBegIdx != outBegIdxRef\n" ); return TA_REGTEST_OPTIMIZATION_REF_ERROR; } if( outNbElement != outNbElementRef ) { printf( "Failure: outNbElement != outNbElementRef\n" ); return TA_REGTEST_OPTIMIZATION_REF_ERROR; } /* 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].out0 ); if( errNb != TA_TEST_PASS ) return errNb; if( retCode == TA_SUCCESS ) { /* Make another test using the same input/output buffer. * The output should still be the same. */ if( testNb == 0 ) retCode = TA_MIN( startIdx, endIdx, gBuffer[0].in, period, &outBegIdx, &outNbElement, gBuffer[0].in ); else retCode = TA_MAX( startIdx, endIdx, gBuffer[0].in, period, &outBegIdx, &outNbElement, gBuffer[0].in ); /* The reference and TA-LIB should have the same output. */ if( retCode != retCodeRef ) { printf( "Failure: retCode != retCodeRef (2)\n" ); return TA_REGTEST_OPTIMIZATION_REF_ERROR; } if( outBegIdx != outBegIdxRef ) { printf( "Failure: outBegIdx != outBegIdxRef (2)\n" ); return TA_REGTEST_OPTIMIZATION_REF_ERROR; } if( outNbElement != outNbElementRef ) { printf( "Failure: outNbElement != outNbElementRef (2)\n" ); return TA_REGTEST_OPTIMIZATION_REF_ERROR; } /* 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; } } } } } return TA_SUCCESS; }
static ErrorNumber do_test_ma( const TA_History *history, const TA_Test *test ) { TA_RetCode retCode; ErrorNumber errNb; TA_Integer outBegIdx; TA_Integer outNbElement; TA_RangeTestParam testParam; TA_Integer temp, temp2; const TA_Real *referenceInput; TA_SetCompatibility( test->compatibility ); /* Set to NAN all the elements of the gBuffers. */ clearAllBuffers(); /* Build the input. */ setInputBuffer( 0, history->close, history->nbBars ); setInputBuffer( 1, history->close, history->nbBars ); /* Re-initialize all the unstable period to zero. */ TA_SetUnstablePeriod( TA_FUNC_UNST_ALL, 0 ); /* Set the unstable period requested for that test. */ switch( test->optInMAType_1 ) { case TA_MAType_TEMA: case TA_MAType_DEMA: case TA_MAType_EMA: retCode = TA_SetUnstablePeriod( TA_FUNC_UNST_EMA, test->unstablePeriod ); break; case TA_MAType_KAMA: retCode = TA_SetUnstablePeriod( TA_FUNC_UNST_KAMA, test->unstablePeriod ); break; case TA_MAType_MAMA: retCode = TA_SetUnstablePeriod( TA_FUNC_UNST_MAMA, test->unstablePeriod ); break; case TA_MAType_T3: retCode = TA_SetUnstablePeriod( TA_FUNC_UNST_T3, test->unstablePeriod ); break; default: retCode = TA_SUCCESS; break; } if( retCode != TA_SUCCESS ) return TA_TEST_TFRR_SETUNSTABLE_PERIOD_FAIL; /* Transform the inputs for MAMA (it is an AVGPRICE in John Ehlers book). */ if( test->optInMAType_1 == TA_MAType_MAMA ) { TA_MEDPRICE( 0, history->nbBars-1, history->high, history->low, &outBegIdx, &outNbElement, gBuffer[0].in ); TA_MEDPRICE( 0, history->nbBars-1, history->high, history->low, &outBegIdx, &outNbElement, gBuffer[1].in ); /* Will be use as reference */ TA_MEDPRICE( 0, history->nbBars-1, history->high, history->low, &outBegIdx, &outNbElement, gBuffer[2].in ); referenceInput = gBuffer[2].in; } else referenceInput = history->close; /* Make a simple first call. */ switch( test->id ) { case TA_ANY_MA_TEST: retCode = TA_MA( test->startIdx, test->endIdx, gBuffer[0].in, test->optInTimePeriod_0, test->optInMAType_1, &outBegIdx, &outNbElement, gBuffer[0].out0 ); break; case TA_MAMA_TEST: retCode = TA_MAMA( test->startIdx, test->endIdx, gBuffer[0].in, 0.5, 0.05, &outBegIdx, &outNbElement, gBuffer[0].out0, gBuffer[0].out2 ); break; case TA_FAMA_TEST: retCode = TA_MAMA( test->startIdx, test->endIdx, gBuffer[0].in, 0.5, 0.05, &outBegIdx, &outNbElement, gBuffer[0].out2, gBuffer[0].out0 ); break; } errNb = checkDataSame( gBuffer[0].in, referenceInput, history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; errNb = checkExpectedValue( gBuffer[0].out0, retCode, test->expectedRetCode, outBegIdx, test->expectedBegIdx, outNbElement, test->expectedNbElement, test->oneOfTheExpectedOutReal, test->oneOfTheExpectedOutRealIndex ); if( errNb != TA_TEST_PASS ) return errNb; outBegIdx = outNbElement = 0; /* Make another call where the input and the output are the * same buffer. */ switch( test->id ) { case TA_ANY_MA_TEST: retCode = TA_MA( test->startIdx, test->endIdx, gBuffer[1].in, test->optInTimePeriod_0, test->optInMAType_1, &outBegIdx, &outNbElement, gBuffer[1].in ); break; case TA_MAMA_TEST: retCode = TA_MAMA( test->startIdx, test->endIdx, gBuffer[1].in, 0.5, 0.05, &outBegIdx, &outNbElement, gBuffer[1].in, gBuffer[0].out2 ); break; case TA_FAMA_TEST: retCode = TA_MAMA( test->startIdx, test->endIdx, gBuffer[1].in, 0.5, 0.05, &outBegIdx, &outNbElement, gBuffer[0].out2, gBuffer[1].in ); break; } /* The previous call to TA_MA 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; errNb = checkExpectedValue( gBuffer[1].in, retCode, test->expectedRetCode, outBegIdx, test->expectedBegIdx, outNbElement, test->expectedNbElement, test->oneOfTheExpectedOutReal, test->oneOfTheExpectedOutRealIndex ); if( errNb != TA_TEST_PASS ) return errNb; /* Verify that the "all-purpose" TA_MA_Lookback is consistent * with the corresponding moving average lookback function. */ switch( test->optInMAType_1 ) { case TA_MAType_WMA: temp = TA_WMA_Lookback( test->optInTimePeriod_0 ); break; case TA_MAType_SMA: temp = TA_SMA_Lookback( test->optInTimePeriod_0 ); break; case TA_MAType_EMA: temp = TA_EMA_Lookback( test->optInTimePeriod_0 ); break; case TA_MAType_DEMA: temp = TA_DEMA_Lookback( test->optInTimePeriod_0 ); break; case TA_MAType_TEMA: temp = TA_TEMA_Lookback( test->optInTimePeriod_0 ); break; case TA_MAType_KAMA: temp = TA_KAMA_Lookback( test->optInTimePeriod_0 ); break; case TA_MAType_MAMA: temp = TA_MAMA_Lookback( 0.5, 0.05 ); break; case TA_MAType_TRIMA: temp = TA_TRIMA_Lookback( test->optInTimePeriod_0 ); break; case TA_MAType_T3: temp = TA_T3_Lookback( test->optInTimePeriod_0, 0.7 ); break; default: return TA_TEST_TFRR_BAD_MA_TYPE; } temp2 = TA_MA_Lookback( test->optInTimePeriod_0, test->optInMAType_1 ); if( temp != temp2 ) return TA_TEST_TFFR_BAD_MA_LOOKBACK; /* Do a systematic test of most of the * possible startIdx/endIdx range. */ testParam.test = test; testParam.close = referenceInput; if( test->doRangeTestFlag ) { switch( test->optInMAType_1 ) { case TA_MAType_TEMA: case TA_MAType_DEMA: case TA_MAType_EMA: errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_EMA, (void *)&testParam, 1, 0 ); break; case TA_MAType_T3: errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_T3, (void *)&testParam, 1, 0 ); break; case TA_MAType_KAMA: errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_KAMA, (void *)&testParam, 1, 0 ); break; case TA_MAType_MAMA: errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_MAMA, (void *)&testParam, 2, 0 ); break; default: errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_NONE, (void *)&testParam, 1, 0 ); } if( errNb != TA_TEST_PASS ) return errNb; } return TA_TEST_PASS; }
static ErrorNumber do_test_per_ema( 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->close, history->nbBars ); setInputBuffer( 1, history->close, history->nbBars ); /* Set the unstable period requested for that test. */ retCode = TA_SetUnstablePeriod( TA_FUNC_UNST_EMA, test->unstablePeriod ); if( retCode != TA_SUCCESS ) return TA_TEST_TFRR_SETUNSTABLE_PERIOD_FAIL; /* Make a simple first call. */ switch( test->theFunction ) { case TA_TRIX_TEST: retCode = TA_TRIX( test->startIdx, test->endIdx, gBuffer[0].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[0].out0 ); } errNb = checkDataSame( gBuffer[0].in, history->close,history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; errNb = checkExpectedValue( gBuffer[0].out0, retCode, test->expectedRetCode, outBegIdx, test->expectedBegIdx, outNbElement, test->expectedNbElement, test->oneOfTheExpectedOutReal, test->oneOfTheExpectedOutRealIndex ); if( errNb != TA_TEST_PASS ) return errNb; outBegIdx = outNbElement = 0; /* Make another call where the input and the output are the * same buffer. */ switch( test->theFunction ) { case TA_TRIX_TEST: retCode = TA_TRIX( test->startIdx, test->endIdx, gBuffer[1].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[1].in ); } /* The previous call to TA_MA 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; errNb = checkExpectedValue( gBuffer[1].in, retCode, test->expectedRetCode, outBegIdx, test->expectedBegIdx, outNbElement, test->expectedNbElement, test->oneOfTheExpectedOutReal, test->oneOfTheExpectedOutRealIndex ); if( errNb != TA_TEST_PASS ) return errNb; /* Do a systematic test of most of the * possible startIdx/endIdx range. */ testParam.test = test; testParam.close = history->close; if( test->doRangeTestFlag ) { errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_EMA, (void *)&testParam, 1, 0 ); if( errNb != TA_TEST_PASS ) return errNb; } return TA_TEST_PASS; }
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; retCode = TA_SetUnstablePeriod( TA_FUNC_UNST_EMA, 0 ); if( retCode != TA_SUCCESS ) return TA_TEST_TFRR_SETUNSTABLE_PERIOD_FAIL; /* Set to NAN all the elements of the gBuffers. */ clearAllBuffers(); /* Build the input. */ setInputBuffer( 0, history->close, history->nbBars ); setInputBuffer( 1, history->close, history->nbBars ); setInputBuffer( 2, history->close, history->nbBars ); setInputBuffer( 3, history->close, history->nbBars ); TA_SetCompatibility( (TA_Compatibility)test->compatibility ); /* Make a simple first call. */ retCode = TA_BBANDS( test->startIdx, test->endIdx, gBuffer[0].in, test->optInTimePeriod, test->optInNbDevUp, test->optInNbDevDn, (TA_MAType)test->optInMethod_3, &outBegIdx, &outNbElement, gBuffer[0].out0, gBuffer[0].out1, gBuffer[0].out2 ); errNb = checkDataSame( gBuffer[0].in, history->close, history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; CHECK_EXPECTED_VALUE( gBuffer[0].out0, 0 ); CHECK_EXPECTED_VALUE( gBuffer[0].out1, 1 ); CHECK_EXPECTED_VALUE( gBuffer[0].out2, 2 ); outBegIdx = outNbElement = 0; /* Make another call where the input and the output are the * same buffer. */ retCode = TA_BBANDS( test->startIdx, test->endIdx, gBuffer[1].in, test->optInTimePeriod, test->optInNbDevUp, test->optInNbDevDn, (TA_MAType)test->optInMethod_3, &outBegIdx, &outNbElement, gBuffer[1].in, gBuffer[1].out1, gBuffer[1].out2 ); /* 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; CHECK_EXPECTED_VALUE( gBuffer[1].in, 0 ); CHECK_EXPECTED_VALUE( gBuffer[1].out1, 1 ); CHECK_EXPECTED_VALUE( gBuffer[1].out2, 2 ); outBegIdx = outNbElement = 0; /* Make another call where the input and the output are the * same buffer. */ retCode = TA_BBANDS( test->startIdx, test->endIdx, gBuffer[2].in, test->optInTimePeriod, test->optInNbDevUp, test->optInNbDevDn, (TA_MAType)test->optInMethod_3, &outBegIdx, &outNbElement, gBuffer[2].out1, gBuffer[2].in, gBuffer[2].out2 ); /* 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[1].out1, gBuffer[2].in ); if( errNb != TA_TEST_PASS ) return errNb; CHECK_EXPECTED_VALUE( gBuffer[2].out1, 0 ); CHECK_EXPECTED_VALUE( gBuffer[2].in, 1 ); CHECK_EXPECTED_VALUE( gBuffer[2].out2, 2 ); outBegIdx = outNbElement = 0; /* Make another call where the input and the output are the * same buffer. */ retCode = TA_BBANDS( test->startIdx, test->endIdx, gBuffer[3].in, test->optInTimePeriod, test->optInNbDevUp, test->optInNbDevDn, (TA_MAType)test->optInMethod_3, &outBegIdx, &outNbElement, gBuffer[3].out0, gBuffer[3].out1, gBuffer[3].in ); /* 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[2].out2, gBuffer[3].in ); if( errNb != TA_TEST_PASS ) return errNb; CHECK_EXPECTED_VALUE( gBuffer[3].out0, 0 ); CHECK_EXPECTED_VALUE( gBuffer[3].out1, 1 ); CHECK_EXPECTED_VALUE( gBuffer[3].in, 2 ); /* Do a systematic test of most of the * possible startIdx/endIdx range. */ testParam.test = test; testParam.close = history->close; if( test->doRangeTestFlag ) { if( test->optInMethod_3 == TA_MAType_EMA ) { errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_EMA, (void *)&testParam, 3, 0 ); } else { errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_NONE, (void *)&testParam, 3, 0 ); } if( errNb != TA_TEST_PASS ) return errNb; } return TA_TEST_PASS; }
static ErrorNumber do_test( TA_Libc *libHandle, 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->close, history->nbBars ); setInputBuffer( 1, history->close, history->nbBars ); TA_SetUnstablePeriod( libHandle, TA_FUNC_UNST_EMA, 0 ); /* Make a simple first call. */ if( test->doPercentage ) { retCode = TA_PPO( libHandle, test->startIdx, test->endIdx, gBuffer[0].in, test->optInFastPeriod_0, test->optInSlowPeriod_1, test->optInMethod_2, test->optInCompatibility_3, &outBegIdx, &outNbElement, gBuffer[0].out0 ); } else { retCode = TA_APO( libHandle, test->startIdx, test->endIdx, gBuffer[0].in, test->optInFastPeriod_0, test->optInSlowPeriod_1, test->optInMethod_2, test->optInCompatibility_3, &outBegIdx, &outNbElement, gBuffer[0].out0 ); } errNb = checkDataSame( gBuffer[0].in, history->close, history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; errNb = checkExpectedValue( gBuffer[0].out0, retCode, test->expectedRetCode, outBegIdx, test->expectedBegIdx, outNbElement, test->expectedNbElement, test->oneOfTheExpectedOutReal, test->oneOfTheExpectedOutRealIndex ); if( errNb != TA_TEST_PASS ) return errNb; outBegIdx = outNbElement = 0; /* Make another call where the input and the output are the * same buffer. */ if( test->doPercentage ) { retCode = TA_PPO( libHandle, test->startIdx, test->endIdx, gBuffer[0].in, test->optInFastPeriod_0, test->optInSlowPeriod_1, test->optInMethod_2, test->optInCompatibility_3, &outBegIdx, &outNbElement, gBuffer[1].in ); } else { retCode = TA_APO( libHandle, test->startIdx, test->endIdx, gBuffer[1].in, test->optInFastPeriod_0, test->optInSlowPeriod_1, test->optInMethod_2, test->optInCompatibility_3, &outBegIdx, &outNbElement, gBuffer[1].in ); } /* 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; errNb = checkExpectedValue( gBuffer[1].in, retCode, test->expectedRetCode, outBegIdx, test->expectedBegIdx, outNbElement, test->expectedNbElement, test->oneOfTheExpectedOutReal, test->oneOfTheExpectedOutRealIndex ); if( errNb != TA_TEST_PASS ) return errNb; /* Do a systematic test of most of the * possible startIdx/endIdx range. */ testParam.test = test; testParam.close = history->close; if( test->doRangeTestFlag ) { if( test->optInMethod_2 == TA_MA_EXPONENTIAL ) { errNb = doRangeTest( libHandle, rangeTestFunction, TA_FUNC_UNST_EMA, (void *)&testParam, 1, 0 ); if( errNb != TA_TEST_PASS ) return errNb; } else { errNb = doRangeTest( libHandle, rangeTestFunction, TA_FUNC_UNST_NONE, (void *)&testParam, 1, 0 ); if( errNb != TA_TEST_PASS ) return errNb; } } return TA_TEST_PASS; }
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 ); setInputBuffer( 2, history->close, history->nbBars ); if( test->doAverage ) { TA_SetUnstablePeriod( TA_FUNC_UNST_ATR, test->unstablePeriod ); retCode = TA_ATR( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[0].out0 ); } else { retCode = TA_TRANGE( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, &outBegIdx, &outNbElement, gBuffer[0].out0 ); } 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; errNb = checkDataSame( gBuffer[2].in, history->close, history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; errNb = checkExpectedValue( gBuffer[0].out0, retCode, test->expectedRetCode, outBegIdx, test->expectedBegIdx, outNbElement, test->expectedNbElement, test->oneOfTheExpectedOutReal, test->oneOfTheExpectedOutRealIndex ); if( errNb != TA_TEST_PASS ) return errNb; outBegIdx = outNbElement = 0; /* Make another call where the input and the output are the * same buffer. */ if( test->doAverage ) { TA_SetUnstablePeriod( TA_FUNC_UNST_ATR, test->unstablePeriod ); retCode = TA_ATR( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[0].in ); } else { retCode = TA_TRANGE( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, &outBegIdx, &outNbElement, gBuffer[0].in ); } /* The previous call to TA_MA 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 = checkExpectedValue( gBuffer[0].in, retCode, test->expectedRetCode, outBegIdx, test->expectedBegIdx, outNbElement, test->expectedNbElement, test->oneOfTheExpectedOutReal, test->oneOfTheExpectedOutRealIndex ); 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; testParam.close = history->close; if( test->doRangeTestFlag ) { errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_ATR, (void *)&testParam, 1, 0 ); if( errNb != TA_TEST_PASS ) return errNb; } return TA_TEST_PASS; }
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 ); setInputBuffer( 2, history->close, history->nbBars ); setInputBuffer( 3, history->high, history->nbBars ); /* Make a simple first call. */ switch( test->id ) { case TST_MINUS_DM: retCode = TA_SetUnstablePeriod( TA_FUNC_UNST_MINUS_DM, test->unstablePeriod ); if( retCode != TA_SUCCESS ) return TA_TEST_TFRR_SETUNSTABLE_PERIOD_FAIL; retCode = TA_MINUS_DM( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[0].out0 ); break; case TST_MINUS_DI: retCode = TA_SetUnstablePeriod( TA_FUNC_UNST_MINUS_DI, test->unstablePeriod ); if( retCode != TA_SUCCESS ) return TA_TEST_TFRR_SETUNSTABLE_PERIOD_FAIL; retCode = TA_MINUS_DI( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[0].out0 ); break; case TST_DX: retCode = TA_SetUnstablePeriod( TA_FUNC_UNST_DX, test->unstablePeriod ); if( retCode != TA_SUCCESS ) return TA_TEST_TFRR_SETUNSTABLE_PERIOD_FAIL; retCode = TA_DX( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[0].out0 ); break; case TST_ADX: retCode = TA_SetUnstablePeriod( TA_FUNC_UNST_ADX, test->unstablePeriod ); if( retCode != TA_SUCCESS ) return TA_TEST_TFRR_SETUNSTABLE_PERIOD_FAIL; retCode = TA_ADX( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[0].out0 ); break; case TST_PLUS_DM: retCode = TA_SetUnstablePeriod( TA_FUNC_UNST_PLUS_DM, test->unstablePeriod ); if( retCode != TA_SUCCESS ) return TA_TEST_TFRR_SETUNSTABLE_PERIOD_FAIL; retCode = TA_PLUS_DM( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[0].out0 ); break; case TST_PLUS_DI: retCode = TA_SetUnstablePeriod( TA_FUNC_UNST_PLUS_DI, test->unstablePeriod ); if( retCode != TA_SUCCESS ) return TA_TEST_TFRR_SETUNSTABLE_PERIOD_FAIL; retCode = TA_PLUS_DI( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[0].out0 ); break; case TST_ADXR: retCode = TA_SetUnstablePeriod( TA_FUNC_UNST_ADX, test->unstablePeriod ); if( retCode != TA_SUCCESS ) return TA_TEST_TFRR_SETUNSTABLE_PERIOD_FAIL; retCode = TA_ADXR( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[0].out0 ); break; default: retCode = TA_BAD_PARAM; } /* Verify that the inputs 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; errNb = checkDataSame( gBuffer[2].in, history->close, history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; CHECK_EXPECTED_VALUE( gBuffer[0].out0, 0 ); outBegIdx = outNbElement = 0; /* Make another call where the input and the output are the * same buffer. */ switch( test->id ) { case TST_MINUS_DM: retCode = TA_MINUS_DM( test->startIdx, test->endIdx, gBuffer[3].in, gBuffer[1].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[3].in ); break; case TST_MINUS_DI: retCode = TA_MINUS_DI( test->startIdx, test->endIdx, gBuffer[3].in, gBuffer[1].in, gBuffer[2].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[3].in ); break; case TST_DX: retCode = TA_DX( test->startIdx, test->endIdx, gBuffer[3].in, gBuffer[1].in, gBuffer[2].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[3].in ); break; case TST_ADX: retCode = TA_ADX( test->startIdx, test->endIdx, gBuffer[3].in, gBuffer[1].in, gBuffer[2].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[3].in ); break; case TST_PLUS_DM: retCode = TA_PLUS_DM( test->startIdx, test->endIdx, gBuffer[3].in, gBuffer[1].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[3].in ); break; case TST_PLUS_DI: retCode = TA_PLUS_DI( test->startIdx, test->endIdx, gBuffer[3].in, gBuffer[1].in, gBuffer[2].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[3].in ); break; case TST_ADXR: retCode = TA_ADXR( test->startIdx, test->endIdx, gBuffer[3].in, gBuffer[1].in, gBuffer[2].in, test->optInTimePeriod, &outBegIdx, &outNbElement, gBuffer[3].in ); break; default: retCode = TA_BAD_PARAM; } /* Verify that the inputs were preserved. */ errNb = checkDataSame( gBuffer[1].in, history->low, history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; errNb = checkDataSame( gBuffer[2].in, history->close, 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[3].in ); if( errNb != TA_TEST_PASS ) return errNb; CHECK_EXPECTED_VALUE( gBuffer[3].in, 0 ); 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; testParam.close = history->close; if( test->doRangeTestFlag ) { switch( test->id ) { case TST_MINUS_DM: errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_MINUS_DM, (void *)&testParam, 1, 0 ); break; case TST_MINUS_DI: errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_MINUS_DI, (void *)&testParam, 1, 2 ); break; case TST_DX: errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_DX, (void *)&testParam, 1, 2 ); break; case TST_ADX: errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_ADX, (void *)&testParam, 1, 2 ); break; case TST_PLUS_DM: errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_PLUS_DM, (void *)&testParam, 1, 0 ); break; case TST_PLUS_DI: errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_PLUS_DI, (void *)&testParam, 1, 2 ); break; case TST_ADXR: errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_ADX, (void *)&testParam, 1, 2 ); break; } if( errNb != TA_TEST_PASS ) return errNb; } return TA_TEST_PASS; }
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 ); setInputBuffer( 2, history->close, history->nbBars ); /* Set the unstable period requested for that test. */ switch( test->optInSlowK_MAType_2 ) { case TA_MAType_EMA: retCode = TA_SetUnstablePeriod( TA_FUNC_UNST_EMA, test->unstablePeriod ); if( retCode != TA_SUCCESS ) return TA_TEST_TFRR_SETUNSTABLE_PERIOD_FAIL; break; default: /* No unstable period for other methods. */ break; } /* Make a simple first call. */ retCode = TA_STOCH( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, test->optInFastK_Period_0, test->optInSlowK_Period_1, test->optInSlowK_MAType_2, test->optInSlowD_Period_3, test->optInSlowD_MAType_4, &outBegIdx, &outNbElement, gBuffer[0].out0, gBuffer[0].out1 ); 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; errNb = checkDataSame( gBuffer[2].in, history->close,history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; CHECK_EXPECTED_VALUE( gBuffer[0].out0, 0 ); CHECK_EXPECTED_VALUE( gBuffer[0].out1, 1 ); outBegIdx = outNbElement = 0; /* Compare to the non-optimized version */ retCode = referenceStoch( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, test->optInFastK_Period_0, test->optInSlowK_Period_1, test->optInSlowK_MAType_2, test->optInSlowD_Period_3, test->optInSlowD_MAType_4, &outBegIdx, &outNbElement, gBuffer[1].out0, gBuffer[1].out1 ); 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; errNb = checkDataSame( gBuffer[2].in, history->close,history->nbBars ); if( errNb != TA_TEST_PASS ) return errNb; CHECK_EXPECTED_VALUE( gBuffer[1].out0, 0 ); CHECK_EXPECTED_VALUE( gBuffer[1].out1, 1 ); /* The non-optimized reference shall be identical to the optimzied TA-Lib * implementation. * * checkSameContent verify that all value different than NAN in * the first parameter is identical in the second parameter. */ errNb = checkSameContent( gBuffer[1].out0, gBuffer[0].out0 ); if( errNb != TA_TEST_PASS ) return errNb; errNb = checkSameContent( gBuffer[1].out1, gBuffer[0].out1 ); if( errNb != TA_TEST_PASS ) return errNb; /* Make another call where the input and the output are the * same buffer. */ retCode = TA_STOCH( test->startIdx, test->endIdx, gBuffer[0].in, gBuffer[1].in, gBuffer[2].in, test->optInFastK_Period_0, test->optInSlowK_Period_1, test->optInSlowK_MAType_2, test->optInSlowD_Period_3, test->optInSlowD_MAType_4, &outBegIdx, &outNbElement, gBuffer[0].in, gBuffer[1].in ); /* 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[0].out1, gBuffer[1].in ); if( errNb != TA_TEST_PASS ) return errNb; CHECK_EXPECTED_VALUE( gBuffer[0].in, 0 ); CHECK_EXPECTED_VALUE( gBuffer[1].in, 1 ); 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; testParam.close = history->close; if( test->doRangeTestFlag ) { errNb = doRangeTest( rangeTestFunction, TA_FUNC_UNST_EMA, (void *)&testParam, 2, 0 ); if( errNb != TA_TEST_PASS ) return errNb; } /* Call a local non-optimized version of the function. * This way, we make sure that the currently speed optimized * version in TA-Lib is not broken. */ return TA_TEST_PASS; }