TA_RetCode TA_FuncTableFree( TA_StringTable *table ) { TA_StringTablePriv *stringTablePriv; if( table ) { stringTablePriv = (TA_StringTablePriv *)table->hiddenData; if( !stringTablePriv ) { return TA_INTERNAL_ERROR(3); } if( stringTablePriv->magicNumber != TA_STRING_TABLE_FUNC_MAGIC_NB ) { return TA_BAD_OBJECT; } if( table->string ) TA_Free( (void *)table->string ); TA_Free( table ); } return TA_SUCCESS; }
/**** Local functions definitions. ****/ static TA_RetCode rangeTestFunction( TA_Libc *libHandle, TA_Integer startIdx, TA_Integer endIdx, TA_Real *outputBuffer, TA_Integer *outBegIdx, TA_Integer *outNbElement, TA_Integer *lookback, void *opaqueData, unsigned int outputNb ) { TA_RetCode retCode; TA_RangeTestParam *testParam; (void)outputNb; testParam = (TA_RangeTestParam *)opaqueData; switch( testParam->test->theFunction ) { case TA_TRIX_TEST: retCode = TA_TRIX( libHandle, startIdx, endIdx, testParam->close, testParam->test->optInTimePeriod_0, outBegIdx, outNbElement, outputBuffer ); *lookback = TA_TRIX_Lookback( testParam->test->optInTimePeriod_0 ); default: retCode = TA_INTERNAL_ERROR(131); } return retCode; }
TA_RetCode TA_SIMULATOR_GetFirstCategoryHandle( TA_DataSourceHandle *handle, TA_CategoryHandle *categoryHandle ) { TA_PROLOG TA_PrivateHandle *privData; TA_TRACE_BEGIN( TA_SIMULATOR_GetFirstCategoryHandle ); if( (handle == NULL) || (categoryHandle == NULL) ) { TA_TRACE_RETURN( TA_BAD_PARAM ); } privData = (TA_PrivateHandle *)(handle->opaqueData); if( !privData ) { TA_TRACE_RETURN( TA_INTERNAL_ERROR(92) ); } categoryHandle->nbSymbol = 2; categoryHandle->string = privData->ta_sim_ref_cat; categoryHandle->opaqueData = 0; privData->categoryIter = 1; TA_TRACE_RETURN( TA_SUCCESS ); }
TA_RetCode TA_WebPageFree( TA_WebPage *webPage ) { TA_WebPageHiddenData *hiddenData; if( webPage ) { hiddenData = webPage->hiddenData; if( !hiddenData ) return TA_INTERNAL_ERROR(32); if( hiddenData->magicNb != TA_WEBPAGE_MAGIC_NB ) return TA_BAD_OBJECT; /* The object is validated, can start to free ressources * from this point. */ /* Free private data */ TA_Free( hiddenData ); /* Free public data. */ if( webPage->content ) TA_StreamFree( webPage->content ); TA_Free( webPage ); } return TA_SUCCESS; }
TA_RetCode TA_FuncTableFree( TA_StringTable *table ) { TA_StringTableFuncHidden *stringTableHidden; TA_Libc *libHandle; if( table ) { stringTableHidden = (TA_StringTableFuncHidden *)table->hiddenData; if( !stringTableHidden ) return TA_INTERNAL_ERROR(3); if( stringTableHidden->magicNb != TA_STRING_TABLE_FUNC_MAGIC_NB ) return TA_BAD_OBJECT; libHandle = stringTableHidden->libHandle; TA_Free( libHandle, stringTableHidden ); if( table->string ) TA_Free( libHandle, (void *)table->string ); TA_Free( libHandle, table ); } return TA_SUCCESS; }
TA_RetCode TA_SemaDestroy( TA_Sema *sema ) { #if defined( USE_WIN32_API ) BOOL retValue; #endif if( sema == NULL ) return TA_BAD_PARAM; if( !(sema->flags & TA_SEMA_INITIALIZED) ) return TA_SUCCESS; /* Do nothing if not initialized. */ #if defined( USE_WIN32_API ) retValue = CloseHandle( sema->theSema ); if( !retValue ) return TA_INTERNAL_ERROR(23); else return TA_SUCCESS; #endif #if defined( USE_OSLAYER ) sem_destroy( &sema->theSema ); return TA_SUCCESS; #endif }
TA_RetCode TA_FuncTableFree( TA_StringTable *table ) { TA_PROLOG TA_StringTablePriv *stringTablePriv; TA_TRACE_BEGIN( TA_FuncTableFree ); if( table ) { stringTablePriv = (TA_StringTablePriv *)table->hiddenData; if( !stringTablePriv ) { TA_TRACE_RETURN( TA_INTERNAL_ERROR(3) ); } if( stringTablePriv->magicNumber != TA_STRING_TABLE_FUNC_MAGIC_NB ) { TA_TRACE_RETURN( TA_BAD_OBJECT ); } if( table->string ) TA_Free( (void *)table->string ); TA_Free( table ); } TA_TRACE_RETURN( TA_SUCCESS ); }
/* rangeTestFunction is a different way to call any of * the TA function. * * This is called by doRangeTest found in test_util.c * * The doRangeTest verifies behavior that should be common * for ALL TA functions. It detects bugs like: * - outBegIdx, outNbElement and lookback inconsistency. * - off-by-one writes to output. * - output inconsistency for different start/end index. * - ... many other limit cases... * * In the case of candlestick, the output is integer and * should be put in outputBufferInt, and outputBuffer is * ignored. */ 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_RangeTestParam *testParam1; const TA_Test *testParam2; ErrorNumber errNb; TA_RetCode retCode; (void)outputBuffer; (void)outputNb; testParam1 = (TA_RangeTestParam *)opaqueData; testParam2 = (const TA_Test *)testParam1->test; *isOutputInteger = 1; /* Must be != 0 */ retCode = TA_INTERNAL_ERROR(166); /* Call the TA function by name */ errNb = callCandlestick( &testParam1->paramHolder, testParam2->name, startIdx, endIdx, testParam1->open, testParam1->high, testParam1->low, testParam1->close, testParam2->params, outBegIdx, outNbElement, outputBufferInt, lookback, &retCode ); if( errNb != TA_TEST_PASS ) retCode = TA_INTERNAL_ERROR(168); return retCode; }
/**** Local functions definitions. ****/ static TA_RetCode initCategoryHandle( TA_DataSourceHandle *handle, TA_CategoryHandle *categoryHandle, unsigned int index ) { TA_PROLOG TA_PrivateYahooHandle *privData; TA_YahooIdx *yahooIndex; TA_String *string; TA_TRACE_BEGIN( TA_YAHOO_GetFirstCategoryHandle ); if( (handle == NULL) || (categoryHandle == NULL) ) { TA_TRACE_RETURN( TA_BAD_PARAM ); } privData = (TA_PrivateYahooHandle *)(handle->opaqueData); if( !privData ) { TA_TRACE_RETURN( TA_INTERNAL_ERROR(99) ); } yahooIndex = privData->index; if( !yahooIndex ) { TA_TRACE_RETURN( TA_INTERNAL_ERROR(100) ); } if( index >= yahooIndex->nbCategory ) return TA_END_OF_INDEX; string = yahooIndex->categories[index]->name; if( !string ) { TA_TRACE_RETURN( TA_INTERNAL_ERROR(101) ); /* At least one category must exist. */ } /* Set the categoryHandle. */ categoryHandle->string = string; categoryHandle->nbSymbol = yahooIndex->categories[index]->nbSymbol; categoryHandle->opaqueData = yahooIndex->categories[index]; TA_TRACE_RETURN( TA_SUCCESS ); }
/**** Local functions definitions. ****/ static TA_RetCode rangeTestFunction( TA_Integer startIdx, TA_Integer endIdx, TA_Real *outputBuffer, TA_Integer *outBegIdx, TA_Integer *outNbElement, TA_Integer *lookback, void *opaqueData, unsigned int outputNb ) { TA_RetCode retCode; TA_RangeTestParam *testParam; TA_Real *out1; TA_Real *out2; TA_Real *dummyOutput; (void)outputNb; testParam = (TA_RangeTestParam *)opaqueData; dummyOutput = TA_Malloc( (endIdx-startIdx+1) * sizeof(TA_Real) ); if( outputNb == 0 ) { out1 = outputBuffer; out2 = dummyOutput; } else { out1 = dummyOutput; out2 = outputBuffer; } switch( testParam->test->theFunction ) { case TA_HT_PHASOR_TEST: retCode = TA_HT_PHASOR( startIdx, endIdx, testParam->price, outBegIdx, outNbElement, out1, out2 ); *lookback = TA_HT_PHASOR_Lookback(); break; case TA_HT_SINE_TEST: retCode = TA_HT_SINE( startIdx, endIdx, testParam->price, outBegIdx, outNbElement, out1, out2 ); *lookback = TA_HT_SINE_Lookback(); break; default: retCode = TA_INTERNAL_ERROR(132); } TA_Free(dummyOutput); return retCode; }
TA_RetCode TA_ThreadExec( TA_ThreadFunction newThreadEntryPoint, void *args ) { #if defined(WIN32) unsigned long thread_id; thread_id = _beginthread(newThreadEntryPoint,8192*4,(void *)args); if( thread_id == (unsigned long)-1 ) return TA_INTERNAL_ERROR(13); #else pthread_t thread_id; if( pthread_create(&thread_id, NULL,newThreadEntryPoint, args) != 0 ) return TA_INTERNAL_ERROR(14); #endif return TA_SUCCESS; }
TA_RetCode TA_SIMULATOR_GetNextSymbolHandle( TA_DataSourceHandle *handle, TA_CategoryHandle *categoryHandle, TA_SymbolHandle *symbolHandle, unsigned int index ) { TA_PROLOG TA_PrivateHandle *privData; TA_TRACE_BEGIN( TA_SIMULATOR_GetNextSymbolHandle ); (void)index; /* Get ride of compiler warnings. */ if( (handle == NULL) || (categoryHandle == NULL) || (symbolHandle == NULL) ) { TA_TRACE_RETURN( TA_BAD_PARAM ); } privData = (TA_PrivateHandle *)(handle->opaqueData); if( !privData ) { TA_TRACE_RETURN( TA_INTERNAL_ERROR(96) ); } /* Get the first symbol in this category. */ switch( (unsigned int)categoryHandle->opaqueData ) { case 0: /* This is TA_SIM_REF */ if( privData->catRefIter == 1 ) { symbolHandle->string = privData->intra_ref_0; symbolHandle->opaqueData = (void *)1; privData->catRefIter = 2; } else { TA_TRACE_RETURN( TA_END_OF_INDEX ); } break; case 1: /* This is TA_SIM_MRG */ TA_TRACE_RETURN( TA_END_OF_INDEX ); default: TA_TRACE_RETURN( TA_INTERNAL_ERROR(97) ); } TA_TRACE_RETURN( TA_SUCCESS ); }
TA_RetCode TA_GetOptInputParameterInfo( const TA_FuncHandle *handle, unsigned int paramIndex, const TA_OptInputParameterInfo **info ) { const TA_FuncDef *funcDef; const TA_FuncInfo *funcInfo; const TA_OptInputParameterInfo **inputTable; if( (handle == NULL) || (info == NULL) ) { return TA_BAD_PARAM; } *info = NULL; /* Validate that this is a valid funcHandle. */ funcDef = (const TA_FuncDef *)handle; if( funcDef->magicNumber != TA_FUNC_DEF_MAGIC_NB ) { return TA_INVALID_HANDLE; } funcInfo = funcDef->funcInfo; if( !funcInfo ) return TA_INVALID_HANDLE; if( paramIndex >= funcInfo->nbOptInput ) { return TA_BAD_PARAM; } inputTable = (const TA_OptInputParameterInfo **)funcDef->optInput; if( !inputTable ) return TA_INTERNAL_ERROR(3); *info = inputTable[paramIndex]; if( !(*info) ) return TA_INTERNAL_ERROR(4); return TA_SUCCESS; }
/**** 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; (void)outputNb; (void)outputBufferInt; *isOutputInteger = 0; testParam = (TA_RangeTestParam *)opaqueData; switch( testParam->test->theFunction ) { case TA_BOP_TEST: retCode = TA_BOP( startIdx, endIdx, testParam->open, testParam->high, testParam->low, testParam->close, outBegIdx, outNbElement, outputBuffer ); *lookback = TA_BOP_Lookback(); break; case TA_AVGPRICE_TEST: retCode = TA_AVGPRICE( startIdx, endIdx, testParam->open, testParam->high, testParam->low, testParam->close, outBegIdx, outNbElement, outputBuffer ); *lookback = TA_AVGPRICE_Lookback(); break; default: retCode = TA_INTERNAL_ERROR(171); } return retCode; }
TA_RetCode TA_SIMULATOR_GetFirstSymbolHandle( TA_DataSourceHandle *handle, TA_CategoryHandle *categoryHandle, TA_SymbolHandle *symbolHandle ) { TA_PROLOG TA_PrivateHandle *privData; TA_TRACE_BEGIN( TA_SIMULATOR_GetFirstSymbolHandle ); if( (handle == NULL) || (categoryHandle == NULL) || (symbolHandle == NULL) ) { TA_TRACE_RETURN( TA_BAD_PARAM ); } privData = (TA_PrivateHandle *)(handle->opaqueData); if( !privData || !categoryHandle->string ) { TA_TRACE_RETURN( TA_INTERNAL_ERROR(94) ); } /* Get the first symbol in this category. */ switch( (unsigned int)categoryHandle->opaqueData ) { case 0: /* This is TA_SIM_REF */ privData->catRefIter = 1; symbolHandle->string = privData->daily_ref_0; symbolHandle->opaqueData = (void *)0; break; case 1: /* This is TA_SIM_MRG */ privData->catMrgIter = 1; symbolHandle->string = privData->mrg_0; symbolHandle->opaqueData = (void *)0; break; default: TA_TRACE_RETURN( TA_INTERNAL_ERROR(95) ); } TA_TRACE_RETURN( TA_SUCCESS ); }
static TA_RetCode getGroupSize( TA_GroupId groupId, unsigned int *groupSize ) { #ifdef TA_GEN_CODE /* Code used only when compiled with gen_code. */ unsigned int i, j; const TA_FuncDef **funcDefTable; const TA_FuncDef *funcDef; unsigned int tableSize; unsigned int nbFuncFound; if( groupId >= TA_NB_GROUP_ID ) return TA_INTERNAL_ERROR(2); if( !groupSize ) return TA_INTERNAL_ERROR(2); nbFuncFound = 0; for( i=0; i < 26; i++ ) { funcDefTable = TA_DEF_Tables[i]; tableSize = *(TA_DEF_TablesSize[i]); for( j=0; j < tableSize; j++ ) { funcDef = funcDefTable[j]; if( funcDef && (funcDef->groupId == groupId) ) nbFuncFound++; } } *groupSize = nbFuncFound; return TA_SUCCESS; #else /* Optimized code in the final library. */ *groupSize = TA_PerGroupSize[groupId]; return TA_SUCCESS; #endif }
/**** Local functions definitions. ****/ static TA_RetCode rangeTestFunction( TA_Integer startIdx, TA_Integer endIdx, TA_Real *outputBuffer, TA_Integer *outBegIdx, TA_Integer *outNbElement, TA_Integer *lookback, void *opaqueData, unsigned int outputNb ) { TA_RetCode retCode; TA_RangeTestParam *testParam; (void)outputNb; testParam = (TA_RangeTestParam *)opaqueData; switch( testParam->test->theFunction ) { case TA_CCI_TEST: retCode = TA_CCI( startIdx, endIdx, testParam->high, testParam->low, testParam->close, testParam->test->optInTimePeriod, outBegIdx, outNbElement, outputBuffer ); *lookback = TA_CCI_Lookback( testParam->test->optInTimePeriod ); break; case TA_WILLR_TEST: retCode = TA_WILLR( startIdx, endIdx, testParam->high, testParam->low, testParam->close, testParam->test->optInTimePeriod, outBegIdx, outNbElement, outputBuffer ); *lookback = TA_WILLR_Lookback( testParam->test->optInTimePeriod ); break; default: retCode = TA_INTERNAL_ERROR(132); } return retCode; }
/**** Local functions definitions. ****/ static TA_RetCode rangeTestFunction( TA_Libc *libHandle, TA_Integer startIdx, TA_Integer endIdx, TA_Real *outputBuffer, TA_Integer *outBegIdx, TA_Integer *outNbElement, TA_Integer *lookback, void *opaqueData, unsigned int outputNb ) { TA_RetCode retCode; TA_RangeTestParam *testParam; (void)outputNb; testParam = (TA_RangeTestParam *)opaqueData; if( testParam->test->theFunction == TA_MIN_TEST ) { retCode = TA_MIN( libHandle, startIdx, endIdx, testParam->close, testParam->test->optInTimePeriod_0, outBegIdx, outNbElement, outputBuffer ); *lookback = TA_MIN_Lookback( testParam->test->optInTimePeriod_0 ); } else if( testParam->test->theFunction == TA_MAX_TEST ) { retCode = TA_MAX( libHandle, startIdx, endIdx, testParam->close, testParam->test->optInTimePeriod_0, outBegIdx, outNbElement, outputBuffer ); *lookback = TA_MAX_Lookback( testParam->test->optInTimePeriod_0 ); } else retCode = TA_INTERNAL_ERROR(129); return retCode; }
TA_RetCode TA_SetInputParamIntegerPtr( TA_ParamHolder *param, unsigned int paramIndex, const TA_Integer *value ) { TA_ParamHolderPriv *paramHolderPriv; const TA_InputParameterInfo *paramInfo; const TA_FuncInfo *funcInfo; if( (param == NULL) || (value == NULL) ) { return TA_BAD_PARAM; } paramHolderPriv = (TA_ParamHolderPriv *)(param->hiddenData); if( paramHolderPriv->magicNumber != TA_PARAM_HOLDER_PRIV_MAGIC_NB ) { return TA_INVALID_PARAM_HOLDER; } /* Make sure this index really exist. */ funcInfo = paramHolderPriv->funcInfo; if( !funcInfo ) return TA_INVALID_HANDLE; if( paramIndex >= funcInfo->nbInput ) { return TA_BAD_PARAM; } /* Verify the type of the parameter. */ paramInfo = paramHolderPriv->in[paramIndex].inputInfo; if( !paramInfo ) return TA_INTERNAL_ERROR(2); if( paramInfo->type != TA_Input_Integer ) { return TA_INVALID_PARAM_HOLDER_TYPE; } /* keep a copy of the provided parameter. */ paramHolderPriv->in[paramIndex].data.inInteger = value; /* This parameter is now initialized, clear the corresponding bit. */ paramHolderPriv->inBitmap &= ~(1<<paramIndex); return TA_SUCCESS; }
TA_RetCode TA_SetOptInputParamReal( TA_ParamHolder *param, unsigned int paramIndex, TA_Real value ) { TA_ParamHolderPriv *paramHolderPriv; const TA_OptInputParameterInfo *paramInfo; const TA_FuncInfo *funcInfo; if( param == NULL ) { return TA_BAD_PARAM; } paramHolderPriv = (TA_ParamHolderPriv *)(param->hiddenData); if( paramHolderPriv->magicNumber != TA_PARAM_HOLDER_PRIV_MAGIC_NB ) { return TA_INVALID_PARAM_HOLDER; } /* Make sure this index really exist. */ funcInfo = paramHolderPriv->funcInfo; if( !funcInfo ) return TA_INVALID_HANDLE; if( paramIndex >= funcInfo->nbOptInput ) { return TA_BAD_PARAM; } /* Verify the type of the parameter. */ paramInfo = paramHolderPriv->optIn[paramIndex].optInputInfo; if( !paramInfo ) return TA_INTERNAL_ERROR(2); if( (paramInfo->type != TA_OptInput_RealRange) && (paramInfo->type != TA_OptInput_RealList) ) { return TA_INVALID_PARAM_HOLDER_TYPE; } /* keep a copy of the provided parameter. */ paramHolderPriv->optIn[paramIndex].data.optInReal = value; return TA_SUCCESS; }
TA_RetCode TA_GroupTableFree( TA_StringTable *table ) { TA_StringTablePriv *stringTablePriv; if( table ) { stringTablePriv = (TA_StringTablePriv *)table->hiddenData; if( !stringTablePriv ) { return TA_INTERNAL_ERROR(1); } if( stringTablePriv->magicNumber != TA_STRING_TABLE_GROUP_MAGIC_NB ) { return TA_BAD_OBJECT; } TA_Free( table ); } return TA_SUCCESS; }
TA_RetCode TA_GroupTableFree( TA_StringTable *table ) { TA_StringTableGroupHidden *stringTableHidden; TA_Libc *libHandle; if( table ) { stringTableHidden = (TA_StringTableGroupHidden *)table->hiddenData; if( !stringTableHidden ) return TA_INTERNAL_ERROR(1); if( stringTableHidden->magicNb != TA_STRING_TABLE_GROUP_MAGIC_NB ) return TA_BAD_OBJECT; libHandle = stringTableHidden->libHandle; TA_Free( libHandle, stringTableHidden ); TA_Free( libHandle, table ); } return TA_SUCCESS; }
TA_RetCode TA_SIMULATOR_GetNextCategoryHandle( TA_DataSourceHandle *handle, TA_CategoryHandle *categoryHandle, unsigned int index ) { TA_PROLOG TA_PrivateHandle *privData; TA_TRACE_BEGIN( TA_SIMULATOR_GetNextCategoryHandle ); (void)index; /* Get ride of compiler warnings. */ if( (handle == NULL) || (categoryHandle == NULL) ) { TA_TRACE_RETURN( TA_BAD_PARAM ); } privData = (TA_PrivateHandle *)(handle->opaqueData); if( !privData ) { TA_TRACE_RETURN( TA_INTERNAL_ERROR(93) ); } /* No category left. */ if( privData->categoryIter >= 2 ) { TA_TRACE_RETURN( TA_END_OF_INDEX ); } /* Set the categoryHandle. */ categoryHandle->string = privData->ta_sim_mrg_cat; categoryHandle->nbSymbol = 1; categoryHandle->opaqueData = (void *)1; privData->categoryIter++; TA_TRACE_RETURN( TA_SUCCESS ); }
TA_RetCode TA_SetInputParamPricePtr( TA_ParamHolder *param, unsigned int paramIndex, const TA_Real *open, const TA_Real *high, const TA_Real *low, const TA_Real *close, const TA_Real *volume, const TA_Real *openInterest ) { TA_ParamHolderPriv *paramHolderPriv; const TA_InputParameterInfo *paramInfo; const TA_FuncInfo *funcInfo; if( param == NULL ) { return TA_BAD_PARAM; } paramHolderPriv = (TA_ParamHolderPriv *)(param->hiddenData); if( paramHolderPriv->magicNumber != TA_PARAM_HOLDER_PRIV_MAGIC_NB ) { return TA_INVALID_PARAM_HOLDER; } /* Make sure this index really exist. */ funcInfo = paramHolderPriv->funcInfo; if( !funcInfo ) return TA_INVALID_HANDLE; if( paramIndex >= funcInfo->nbInput ) { return TA_BAD_PARAM; } /* Verify the type of the parameter. */ paramInfo = paramHolderPriv->in[paramIndex].inputInfo; if( !paramInfo ) return TA_INTERNAL_ERROR(2); if( paramInfo->type != TA_Input_Price ) { return TA_INVALID_PARAM_HOLDER_TYPE; } /* keep a copy of the provided parameter. */ #define SET_PARAM_INFO(lowerParam,upperParam) \ { \ if( paramInfo->flags & TA_IN_PRICE_##upperParam ) \ { \ if( lowerParam == NULL ) \ { \ return TA_BAD_PARAM; \ } \ paramHolderPriv->in[paramIndex].data.inPrice.lowerParam = lowerParam; \ } \ } SET_PARAM_INFO(open, OPEN ); SET_PARAM_INFO(high, HIGH ); SET_PARAM_INFO(low, LOW ); SET_PARAM_INFO(close, CLOSE ); SET_PARAM_INFO(volume, VOLUME ); SET_PARAM_INFO(openInterest, OPENINTEREST ); #undef SET_PARAM_INFO /* This parameter is now initialized, clear the corresponding bit. */ paramHolderPriv->inBitmap &= ~(1<<paramIndex); return TA_SUCCESS; }
TA_RetCode TA_ParamHolderAlloc( const TA_FuncHandle *handle, TA_ParamHolder **allocatedParams ) { TA_FuncDef *funcDef; unsigned int allocSize, i; TA_ParamHolderInput *input; TA_ParamHolderOptInput *optInput; TA_ParamHolderOutput *output; const TA_FuncInfo *funcInfo; TA_ParamHolder *newParams; TA_ParamHolderPriv *newParamsPriv; const TA_InputParameterInfo **inputInfo; const TA_OptInputParameterInfo **optInputInfo; const TA_OutputParameterInfo **outputInfo; /* Validate the parameters. */ if( !handle || !allocatedParams) { return TA_BAD_PARAM; } /* Validate that this is a valid funcHandle. */ funcDef = (TA_FuncDef *)handle; if( funcDef->magicNumber != TA_FUNC_DEF_MAGIC_NB ) { *allocatedParams = NULL; return TA_INVALID_HANDLE; } /* Get the TA_FuncInfo. */ funcInfo = funcDef->funcInfo; if( !funcInfo ) return TA_INVALID_HANDLE; /* Allocate the TA_ParamHolder. */ newParams = (TA_ParamHolder *)TA_Malloc( sizeof(TA_ParamHolder) + sizeof(TA_ParamHolderPriv)); if( !newParams ) { *allocatedParams = NULL; return TA_ALLOC_ERR; } memset( newParams, 0, sizeof(TA_ParamHolder) + sizeof(TA_ParamHolderPriv) ); newParamsPriv = (TA_ParamHolderPriv *)(((char *)newParams)+sizeof(TA_ParamHolder)); newParamsPriv->magicNumber = TA_PARAM_HOLDER_PRIV_MAGIC_NB; newParams->hiddenData = newParamsPriv; /* From this point, TA_ParamHolderFree can be safely called. */ /* Allocate the array of structure holding the info * for each parameter. */ if( funcInfo->nbInput == 0 ) return TA_INTERNAL_ERROR(2); allocSize = (funcInfo->nbInput) * sizeof(TA_ParamHolderInput); input = (TA_ParamHolderInput *)TA_Malloc( allocSize ); if( !input ) { TA_ParamHolderFree( newParams ); *allocatedParams = NULL; return TA_ALLOC_ERR; } memset( input, 0, allocSize ); newParamsPriv->in = input; if( funcInfo->nbOptInput == 0 ) optInput = NULL; else { allocSize = (funcInfo->nbOptInput) * sizeof(TA_ParamHolderOptInput); optInput = (TA_ParamHolderOptInput *)TA_Malloc( allocSize ); if( !optInput ) { TA_ParamHolderFree( newParams ); *allocatedParams = NULL; return TA_ALLOC_ERR; } memset( optInput, 0, allocSize ); } newParamsPriv->optIn = optInput; allocSize = (funcInfo->nbOutput) * sizeof(TA_ParamHolderOutput); output = (TA_ParamHolderOutput *)TA_Malloc( allocSize ); if( !output ) { TA_ParamHolderFree( newParams ); *allocatedParams = NULL; return TA_ALLOC_ERR; } memset( output, 0, allocSize ); newParamsPriv->out = output; newParamsPriv->funcInfo = funcInfo; inputInfo = (const TA_InputParameterInfo **)funcDef->input; optInputInfo = (const TA_OptInputParameterInfo **)funcDef->optInput; outputInfo = (const TA_OutputParameterInfo **)funcDef->output; for( i=0; i < funcInfo->nbInput; i++ ) { input[i].inputInfo = inputInfo[i]; newParamsPriv->inBitmap <<= 1; newParamsPriv->inBitmap |= 1; } for( i=0; i < funcInfo->nbOptInput; i++ ) { optInput[i].optInputInfo = optInputInfo[i]; if( optInput[i].optInputInfo->type == TA_OptInput_RealRange ) optInput[i].data.optInReal = optInputInfo[i]->defaultValue; else optInput[i].data.optInInteger = (TA_Integer)optInputInfo[i]->defaultValue; } for( i=0; i < funcInfo->nbOutput; i++ ) { output[i].outputInfo = outputInfo[i]; newParamsPriv->outBitmap <<= 1; newParamsPriv->outBitmap |= 1; } /* Succcess, return the result to the caller. */ *allocatedParams = newParams; return TA_SUCCESS; }
TA_RetCode TA_GetFuncHandle( const char *name, const TA_FuncHandle **handle ) { char firstChar, tmp; const TA_FuncDef **funcDefTable; const TA_FuncDef *funcDef; const TA_FuncInfo *funcInfo; unsigned int i, funcDefTableSize; /* A TA_FuncHandle is internally a TA_FuncDef. Let's find it * by using the alphabetical tables. */ if( (name == NULL) || (handle == NULL) ) { return TA_BAD_PARAM; } *handle = NULL; firstChar = name[0]; if( firstChar == '\0' ) { return TA_BAD_PARAM; } tmp = (char)tolower( firstChar ); if( (tmp < 'a') || (tmp > 'z') ) { return TA_FUNC_NOT_FOUND; } /* Identify the table. */ tmp -= (char)'a'; funcDefTable = TA_DEF_Tables[(int)tmp]; /* Identify the table size. */ funcDefTableSize = *TA_DEF_TablesSize[(int)tmp]; if( funcDefTableSize < 1 ) { return TA_FUNC_NOT_FOUND; } /* Iterate all entries of the table and return as soon as found. */ for( i=0; i < funcDefTableSize; i++ ) { funcDef = funcDefTable[i]; if( !funcDef || !funcDef->funcInfo ) return TA_INTERNAL_ERROR(3); funcInfo = funcDef->funcInfo; if( !funcInfo ) return TA_INTERNAL_ERROR(4); if( strcmp( funcInfo->name, name ) == 0 ) { *handle = (TA_FuncHandle *)funcDef; return TA_SUCCESS; } } return TA_FUNC_NOT_FOUND; }
/* Generated */ TA_RetCode TA_PREFIX(INT_MACD)( int startIdx, /* Generated */ int endIdx, /* Generated */ const INPUT_TYPE inReal[], /* Generated */ int optInFastPeriod, /* Generated */ int optInSlowPeriod, /* Generated */ int optInSignalPeriod_2, /* Generated */ int *outBegIdx, /* Generated */ int *outNbElement, /* Generated */ double outMACD[], /* Generated */ double outMACDSignal[], /* Generated */ double outMACDHist[] ) /* Generated */ #endif /* Generated */ { /* Generated */ ARRAY_REF(slowEMABuffer); /* Generated */ ARRAY_REF(fastEMABuffer); /* Generated */ double k1, k2; /* Generated */ TA_RetCode retCode; /* Generated */ int tempInteger, outBegIdx1, outNbElement1; /* Generated */ int outBegIdx2, outNbElement2; /* Generated */ int lookbackTotal, lookbackSignal; /* Generated */ int i; /* Generated */ if( optInSlowPeriod < optInFastPeriod ) /* Generated */ { /* Generated */ tempInteger = optInSlowPeriod; /* Generated */ optInSlowPeriod = optInFastPeriod; /* Generated */ optInFastPeriod = tempInteger; /* Generated */ } /* Generated */ if( optInSlowPeriod != 0 ) /* Generated */ k1 = PER_TO_K(optInSlowPeriod); /* Generated */ else /* Generated */ { /* Generated */ optInSlowPeriod = 26; /* Generated */ k1 = (double)0.075; /* Generated */ } /* Generated */ if( optInFastPeriod != 0 ) /* Generated */ k2 = PER_TO_K(optInFastPeriod); /* Generated */ else /* Generated */ { /* Generated */ optInFastPeriod = 12; /* Generated */ k2 = (double)0.15; /* Generated */ } /* Generated */ lookbackSignal = TA_EMA_Lookback( optInSignalPeriod_2 ); /* Generated */ lookbackTotal = lookbackSignal; /* Generated */ lookbackTotal += TA_EMA_Lookback( optInSlowPeriod ); /* Generated */ if( startIdx < lookbackTotal ) /* Generated */ startIdx = lookbackTotal; /* Generated */ if( startIdx > endIdx ) /* Generated */ { /* Generated */ *outBegIdx = 0; /* Generated */ *outNbElement = 0; /* Generated */ return TA_SUCCESS; /* Generated */ } /* Generated */ tempInteger = (endIdx-startIdx)+1+lookbackSignal; /* Generated */ ARRAY_ALLOC( fastEMABuffer, tempInteger ); /* Generated */ if( !fastEMABuffer ) /* Generated */ { /* Generated */ *outBegIdx = 0; /* Generated */ *outNbElement = 0; /* Generated */ return TA_ALLOC_ERR; /* Generated */ } /* Generated */ ARRAY_ALLOC( slowEMABuffer, tempInteger ); /* Generated */ if( !slowEMABuffer ) /* Generated */ { /* Generated */ *outBegIdx = 0; /* Generated */ *outNbElement = 0; /* Generated */ ARRAY_FREE( fastEMABuffer ); /* Generated */ return TA_ALLOC_ERR; /* Generated */ } /* Generated */ tempInteger = startIdx-lookbackSignal; /* Generated */ retCode = TA_PREFIX(INT_EMA)( tempInteger, endIdx, /* Generated */ inReal, optInSlowPeriod, k1, /* Generated */ &outBegIdx1, &outNbElement1, slowEMABuffer ); /* Generated */ if( retCode != TA_SUCCESS ) /* Generated */ { /* Generated */ *outBegIdx = 0; /* Generated */ *outNbElement = 0; /* Generated */ ARRAY_FREE( fastEMABuffer ); /* Generated */ ARRAY_FREE( slowEMABuffer ); /* Generated */ return retCode; /* Generated */ } /* Generated */ retCode = TA_PREFIX(INT_EMA)( tempInteger, endIdx, /* Generated */ inReal, optInFastPeriod, k2, /* Generated */ &outBegIdx2, &outNbElement2, fastEMABuffer ); /* Generated */ if( retCode != TA_SUCCESS ) /* Generated */ { /* Generated */ *outBegIdx = 0; /* Generated */ *outNbElement = 0; /* Generated */ ARRAY_FREE( fastEMABuffer ); /* Generated */ ARRAY_FREE( slowEMABuffer ); /* Generated */ return retCode; /* Generated */ } /* Generated */ if( (outBegIdx1 != tempInteger) || /* Generated */ (outBegIdx2 != tempInteger) || /* Generated */ (outNbElement1 != outNbElement2) || /* Generated */ (outNbElement1 != (endIdx-startIdx)+1+lookbackSignal) ) /* Generated */ { /* Generated */ *outBegIdx = 0; /* Generated */ *outNbElement = 0; /* Generated */ ARRAY_FREE( fastEMABuffer ); /* Generated */ ARRAY_FREE( slowEMABuffer ); /* Generated */ return TA_INTERNAL_ERROR(119); /* Generated */ } /* Generated */ for( i=0; i < outNbElement1; i++ ) /* Generated */ fastEMABuffer[i] = fastEMABuffer[i] - slowEMABuffer[i]; /* Generated */ ARRAY_MEMMOVE( outMACD, 0, fastEMABuffer, lookbackSignal, (endIdx-startIdx)+1 ); /* Generated */ retCode = TA_INT_EMA( 0, outNbElement1-1, /* Generated */ fastEMABuffer, optInSignalPeriod_2, PER_TO_K(optInSignalPeriod_2), /* Generated */ &outBegIdx2, &outNbElement2, outMACDSignal ); /* Generated */ ARRAY_FREE( fastEMABuffer ); /* Generated */ ARRAY_FREE( slowEMABuffer ); /* Generated */ if( retCode != TA_SUCCESS ) /* Generated */ { /* Generated */ *outBegIdx = 0; /* Generated */ *outNbElement = 0; /* Generated */ return retCode; /* Generated */ } /* Generated */ for( i=0; i < outNbElement2; i++ ) /* Generated */ outMACDHist[i] = outMACD[i]-outMACDSignal[i]; /* Generated */ *outBegIdx = startIdx; /* Generated */ *outNbElement = outNbElement2; /* Generated */ return TA_SUCCESS; /* Generated */ }
/**** 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; (void)outputNb; (void)outputBufferInt; *isOutputInteger = 0; testParam = (TA_RangeTestParam *)opaqueData; switch( testParam->test->theFunction ) { case TA_MFI_TEST: retCode = TA_MFI( startIdx, endIdx, testParam->high, testParam->low, testParam->close, testParam->volume, testParam->test->optInTimePeriod, outBegIdx, outNbElement, outputBuffer ); *lookback = TA_MFI_Lookback( testParam->test->optInTimePeriod ); break; case TA_AD_TEST: retCode = TA_AD( startIdx, endIdx, testParam->high, testParam->low, testParam->close, testParam->volume, outBegIdx, outNbElement, outputBuffer ); *lookback = TA_AD_Lookback(); break; case TA_ADOSC_3_10_TEST: retCode = TA_ADOSC( startIdx, endIdx, testParam->high, testParam->low, testParam->close, testParam->volume, 3, 10, outBegIdx, outNbElement, outputBuffer ); *lookback = TA_ADOSC_Lookback(3,10); break; case TA_ADOSC_5_2_TEST: retCode = TA_ADOSC( startIdx, endIdx, testParam->high, testParam->low, testParam->close, testParam->volume, 5, 2, outBegIdx, outNbElement, outputBuffer ); *lookback = TA_ADOSC_Lookback(5,2); break; default: retCode = TA_INTERNAL_ERROR(132); } 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->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->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; }