📄 test_minmax.c
字号:
testParam->close, testParam->test->optInTimePeriod, outBegIdx, outNbElement, out1Int ); *lookback = TA_MAXINDEX_Lookback( testParam->test->optInTimePeriod ); *isOutputInteger = 1; break; default: retCode = TA_INTERNAL_ERROR(129); break; } TA_Free( dummyBufferReal ); TA_Free( dummyBufferInt ); return retCode;}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;}/* These reference functions were the original non-optimized * version of TA_MIN and TA_MAX. * * TA-Lib might implement a faster algorithm, at the cost * of complexity. Consequently, it is important to verify the * equivalence between the optimize and non-optimized version. */static TA_RetCode referenceMin( TA_Integer startIdx, TA_Integer endIdx, const TA_Real inReal[], TA_Integer optInTimePeriod, TA_Integer *outBegIdx, TA_Integer *outNbElement, TA_Real outReal[] ){ TA_Real lowest, tmp; TA_Integer outIdx, nbInitialElementNeeded; TA_Integer trailingIdx, today, i; /* Identify the minimum number of price bar needed * to identify at least one output over the specified * period. */ nbInitialElementNeeded = (optInTimePeriod-1); /* Move up the start index if there is not * enough initial data. */ if( startIdx < nbInitialElementNeeded ) startIdx = nbInitialElementNeeded; /* Make sure there is still something to evaluate. */ if( startIdx > endIdx ) { *outBegIdx = 0; *outNbElement = 0; return TA_SUCCESS; } /* Proceed with the calculation for the requested range. * Note that this algorithm allows the input and * output to be the same buffer. */ outIdx = 0; today = startIdx; trailingIdx = startIdx-nbInitialElementNeeded; while( today <= endIdx ) { lowest = inReal[trailingIdx++]; for( i=trailingIdx; i <= today; i++ ) { tmp = inReal[i]; if( tmp < lowest) lowest= tmp; } outReal[outIdx++] = lowest; today++; } /* Keep the outBegIdx relative to the * caller input before returning. */ *outBegIdx = startIdx; *outNbElement = outIdx; return TA_SUCCESS;}static TA_RetCode referenceMax( TA_Integer startIdx, TA_Integer endIdx, const TA_Real inReal[], TA_Integer optInTimePeriod, TA_Integer *outBegIdx, TA_Integer *outNbElement, TA_Real outReal[] ){ /* Insert local variables here. */ TA_Real highest, tmp; TA_Integer outIdx, nbInitialElementNeeded; TA_Integer trailingIdx, today, i;#ifndef TA_FUNC_NO_RANGE_CHECK /* Validate the requested output range. */ if( startIdx < 0 ) return TA_OUT_OF_RANGE_START_INDEX; if( (endIdx < 0) || (endIdx < startIdx)) return TA_OUT_OF_RANGE_END_INDEX; /* Validate the parameters. */ if( !inReal ) return TA_BAD_PARAM; /* min/max are checked for optInTimePeriod. */ if( optInTimePeriod == TA_INTEGER_DEFAULT ) optInTimePeriod = 30; if( outReal == NULL ) return TA_BAD_PARAM;#endif /* TA_FUNC_NO_RANGE_CHECK */ /* Insert TA function code here. */ /* Identify the minimum number of price bar needed * to identify at least one output over the specified * period. */ nbInitialElementNeeded = (optInTimePeriod-1); /* Move up the start index if there is not * enough initial data. */ if( startIdx < nbInitialElementNeeded ) startIdx = nbInitialElementNeeded; /* Make sure there is still something to evaluate. */ if( startIdx > endIdx ) { *outBegIdx = 0; *outNbElement = 0; return TA_SUCCESS; } /* Proceed with the calculation for the requested range. * Note that this algorithm allows the input and * output to be the same buffer. */ outIdx = 0; today = startIdx; trailingIdx = startIdx-nbInitialElementNeeded; while( today <= endIdx ) { highest = inReal[trailingIdx++]; for( i=trailingIdx; i <= today; i++ ) { tmp = inReal[i]; if( tmp > highest ) highest = tmp; } outReal[outIdx++] = highest; today++; } /* Keep the outBegIdx relative to the * caller input before returning. */ *outBegIdx = startIdx; *outNbElement = outIdx; return TA_SUCCESS;}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; outBegIdxRef = outNbElementRef = -1; /* 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_TEST_PASS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -