/* Finally, call a TA function with the parameters. */ TA_RetCode TA_CallFunc( const TA_ParamHolder *param, TA_Integer startIdx, TA_Integer endIdx, TA_Integer *outBegIdx, TA_Integer *outNbElement ) { TA_PROLOG TA_RetCode retCode; const TA_ParamHolderPriv *paramHolderPriv; const TA_FuncDef *funcDef; const TA_FuncInfo *funcInfo; TA_FrameFunction function; TA_TRACE_BEGIN( TA_CallFunc ); if( (param == NULL) || (outBegIdx == NULL) || (outNbElement == NULL) ) { TA_TRACE_RETURN( TA_BAD_PARAM ); } paramHolderPriv = (TA_ParamHolderPriv *)(param->hiddenData); if( paramHolderPriv->magicNumber != TA_PARAM_HOLDER_PRIV_MAGIC_NB ) { TA_TRACE_RETURN( TA_INVALID_PARAM_HOLDER ); } /* Check that all parameters are initialize (except the optInput). */ if( paramHolderPriv->inBitmap != 0 ) { TA_TRACE_RETURN( TA_INPUT_NOT_ALL_INITIALIZE ); } if( paramHolderPriv->outBitmap != 0 ) { TA_TRACE_RETURN( TA_OUTPUT_NOT_ALL_INITIALIZE ); } /* Get the pointer on the function */ funcInfo = paramHolderPriv->funcInfo; TA_DEBUG_ASSERT( funcInfo != NULL ); funcDef = (const TA_FuncDef *)funcInfo->handle; TA_DEBUG_ASSERT( funcDef != NULL ); function = funcDef->function; TA_DEBUG_ASSERT( function != NULL ); /* Perform the function call. */ retCode = (*function)( paramHolderPriv, startIdx, endIdx, outBegIdx, outNbElement ); TA_TRACE_RETURN( retCode ); }
TA_RetCode TA_GetFuncInfo( const TA_FuncHandle *handle, const TA_FuncInfo **funcInfo ) { TA_PROLOG const TA_FuncDef *funcDef; TA_TRACE_BEGIN( TA_GetFuncInfo ); if( !funcInfo || !handle ) { TA_TRACE_RETURN( TA_BAD_PARAM ); } /* Validate that this is a valid funcHandle. */ funcDef = (const TA_FuncDef *)handle; if( funcDef->magicNumber != TA_FUNC_DEF_MAGIC_NB ) { TA_TRACE_RETURN( TA_INVALID_HANDLE ); } *funcInfo = funcDef->funcInfo; TA_DEBUG_ASSERT( *funcInfo != NULL ); TA_TRACE_RETURN( TA_SUCCESS ); }
TA_RetCode TA_SetInputParamRealPtr( TA_ParamHolder *param, unsigned int paramIndex, const TA_Real *value ) { TA_PROLOG TA_ParamHolderPriv *paramHolderPriv; const TA_InputParameterInfo *paramInfo; const TA_FuncInfo *funcInfo; TA_TRACE_BEGIN( TA_SetInputParamIntegerPtr ); if( (param == NULL) || (value == NULL) ) { TA_TRACE_RETURN( TA_BAD_PARAM ); } paramHolderPriv = (TA_ParamHolderPriv *)(param->hiddenData); if( paramHolderPriv->magicNumber != TA_PARAM_HOLDER_PRIV_MAGIC_NB ) { TA_TRACE_RETURN( TA_INVALID_PARAM_HOLDER ); } /* Make sure this index really exist. */ funcInfo = paramHolderPriv->funcInfo; TA_DEBUG_ASSERT( funcInfo != NULL ); if( paramIndex >= funcInfo->nbInput ) { TA_TRACE_RETURN( TA_BAD_PARAM ); } /* Verify the type of the parameter. */ paramInfo = paramHolderPriv->in[paramIndex].inputInfo; TA_DEBUG_ASSERT( paramInfo != NULL ); if( paramInfo->type != TA_Input_Real ) { TA_TRACE_RETURN( TA_INVALID_PARAM_HOLDER_TYPE ); } /* keep a copy of the provided parameter. */ paramHolderPriv->in[paramIndex].data.inReal = value; /* This parameter is now initialized, clear the corresponding bit. */ paramHolderPriv->inBitmap &= ~(1<<paramIndex); TA_TRACE_RETURN( TA_SUCCESS ); }
TA_RetCode TA_SetOptInputParamInteger( TA_ParamHolder *param, unsigned int paramIndex, TA_Integer value ) { TA_PROLOG TA_ParamHolderPriv *paramHolderPriv; const TA_OptInputParameterInfo *paramInfo; const TA_FuncInfo *funcInfo; TA_TRACE_BEGIN( TA_SetOptInputParamReal ); if( param == NULL ) { TA_TRACE_RETURN( TA_BAD_PARAM ); } paramHolderPriv = (TA_ParamHolderPriv *)(param->hiddenData); if( paramHolderPriv->magicNumber != TA_PARAM_HOLDER_PRIV_MAGIC_NB ) { TA_TRACE_RETURN( TA_INVALID_PARAM_HOLDER ); } /* Make sure this index really exist. */ funcInfo = paramHolderPriv->funcInfo; TA_DEBUG_ASSERT( funcInfo != NULL ); if( paramIndex >= funcInfo->nbOptInput ) { TA_TRACE_RETURN( TA_BAD_PARAM ); } /* Verify the type of the parameter. */ paramInfo = paramHolderPriv->optIn[paramIndex].optInputInfo; TA_DEBUG_ASSERT( paramInfo != NULL ); if( (paramInfo->type != TA_OptInput_IntegerRange) && (paramInfo->type != TA_OptInput_IntegerList) ) { TA_TRACE_RETURN( TA_INVALID_PARAM_HOLDER_TYPE ); } /* keep a copy of the provided parameter. */ paramHolderPriv->optIn[paramIndex].data.optInInteger = value; TA_TRACE_RETURN( TA_SUCCESS ); }
TA_RetCode TA_SetOutputParameterInfoPtr( const TA_FuncHandle *handle, unsigned int paramIndex, const TA_OutputParameterInfo **info ) { TA_PROLOG const TA_FuncDef *funcDef; const TA_FuncInfo *funcInfo; const TA_OutputParameterInfo **outputTable; TA_TRACE_BEGIN( TA_SetOutputParameterInfoPtr ); if( (handle == NULL) || (info == NULL) ) { TA_TRACE_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 ) { TA_TRACE_RETURN( TA_INVALID_HANDLE ); } funcInfo = funcDef->funcInfo; TA_DEBUG_ASSERT( funcInfo != NULL ); if( paramIndex >= funcInfo->nbOutput ) { TA_TRACE_RETURN( TA_BAD_PARAM ); } outputTable = (const TA_OutputParameterInfo **)funcDef->output; TA_DEBUG_ASSERT( outputTable != NULL ); *info = outputTable[paramIndex]; TA_DEBUG_ASSERT( *info != NULL ); TA_TRACE_RETURN( TA_SUCCESS ); }
/* Finally, call a TA function with the parameters. */ TA_RetCode TA_CallFunc( const TA_FuncHandle *handle, TA_Integer startIdx, TA_Integer endIdx, TA_Integer *outBegIdx, TA_Integer *outNbElement, const TA_ParamHolder *inputParams, const TA_ParamHolder *optInputParams, const TA_ParamHolder *outputParams ) { TA_PROLOG; TA_RetCode retCode; TA_ParamHolderPriv *inParamHolderPriv; TA_ParamHolderPriv *optInParamHolderPriv; TA_ParamHolderPriv *outParamHolderPriv; const TA_FuncDef *funcDef; const TA_FuncInfo *funcInfo; TA_FrameFunction function; unsigned int i; TA_Libc *libHandle; if( (handle == NULL) || (inputParams == NULL) || (optInputParams == NULL) || (outputParams == NULL) || (outBegIdx == NULL) || (outNbElement == NULL) ) return TA_BAD_PARAM; /* Validate that this is a valid funcHandle. */ funcDef = (const TA_FuncDef *)handle; if( funcDef->magicNumber != TA_FUNC_DEF_MAGIC_NB ) return TA_INVALID_HANDLE; inParamHolderPriv = (TA_ParamHolderPriv *)inputParams; optInParamHolderPriv = (TA_ParamHolderPriv *)optInputParams; outParamHolderPriv = (TA_ParamHolderPriv *)outputParams; libHandle = inParamHolderPriv->libHandle; TA_TRACE_BEGIN( libHandle, TA_CallFunc ); /* Validate the TA_ParamHolderPriv (only the first of each type will * be sufficient). */ if( (inParamHolderPriv[0].magicNumber != TA_PARAM_HOLDER_PRIV_MAGIC_NB) || (optInParamHolderPriv[0].magicNumber != TA_PARAM_HOLDER_PRIV_MAGIC_NB) || (outParamHolderPriv[0].magicNumber != TA_PARAM_HOLDER_PRIV_MAGIC_NB) ) { TA_TRACE_RETURN( TA_INVALID_PARAM_HOLDER ); } if( (inParamHolderPriv[0].type != TA_PARAM_HOLDER_INPUT ) || (optInParamHolderPriv[0].type != TA_PARAM_HOLDER_OPTINPUT ) || (outParamHolderPriv[0].type != TA_PARAM_HOLDER_OUTPUT ) ) { TA_TRACE_RETURN( TA_INVALID_PARAM_HOLDER_TYPE ); } function = funcDef->function; if( (inParamHolderPriv[0].function != function ) || (optInParamHolderPriv[0].function != function ) || (outParamHolderPriv[0].function != function ) ) { TA_TRACE_RETURN( TA_INVALID_PARAM_FUNCTION ); } TA_DEBUG_ASSERT( libHandle, function != NULL ); /* Check that all parameters are initialize (except the optInput). */ funcInfo = funcDef->funcInfo; for( i=0; i < funcInfo->nbInput; i++ ) { if( !inParamHolderPriv[i].valueInitialize ) { TA_TRACE_RETURN( TA_INPUT_NOT_ALL_INITIALIZE ); } } for( i=0; i < funcInfo->nbOutput; i++ ) { if( !outParamHolderPriv[i].valueInitialize ) { TA_TRACE_RETURN( TA_OUTPUT_NOT_ALL_INITIALIZE ); } } /* Perform the function call. */ retCode = (*function)( libHandle, startIdx, endIdx, outBegIdx, outNbElement, inParamHolderPriv, optInParamHolderPriv, outParamHolderPriv ); TA_TRACE_RETURN( retCode ); }
TA_RetCode TA_ParamHoldersAlloc( TA_Libc *libHandle, const TA_FuncHandle *handle, TA_ParamHolder **newInputParams, TA_ParamHolder **newOptInputParams, TA_ParamHolder **newOutputParams ) { TA_PROLOG; TA_FuncDef *funcDef; unsigned int allocSize, i; TA_ParamHolderPriv *input; TA_ParamHolderPriv *optInput; TA_ParamHolderPriv *output; const TA_InputParameterInfo *inputInfo; const TA_OptInputParameterInfo *optInputInfo; const TA_OutputParameterInfo *outputInfo; const TA_FuncInfo *funcInfo; TA_TRACE_BEGIN( libHandle, TA_ParamHoldersAlloc ); /* Validate the parameters. */ if( !handle || !newInputParams || !newOptInputParams || !newOutputParams) { TA_TRACE_RETURN( TA_BAD_PARAM ); } *newInputParams = NULL; *newOptInputParams = NULL; *newOutputParams = NULL; /* Validate that this is a valid funcHandle. */ funcDef = (TA_FuncDef *)handle; if( funcDef->magicNumber != TA_FUNC_DEF_MAGIC_NB ) { TA_TRACE_RETURN( TA_INVALID_HANDLE ); } /* Get the TA_FuncInfo. */ funcInfo = funcDef->funcInfo; TA_DEBUG_ASSERT( libHandle, funcInfo != NULL ); /* Allocate all the TA_ParamHolderPriv. */ allocSize = (funcInfo->nbInput) * sizeof(TA_ParamHolderPriv); input = (TA_ParamHolderPriv *)TA_Malloc( libHandle, allocSize ); if( input == NULL ) { TA_TRACE_RETURN( TA_ALLOC_ERR ); } if( funcInfo->nbOptInput == 0 ) optInput = NULL; else { allocSize = (funcInfo->nbOptInput) * sizeof(TA_ParamHolderPriv); optInput = (TA_ParamHolderPriv *)TA_Malloc( libHandle, allocSize ); if( optInput == NULL ) { TA_Free( libHandle, optInput ); TA_TRACE_RETURN( TA_ALLOC_ERR ); } } allocSize = (funcInfo->nbOutput) * sizeof(TA_ParamHolderPriv); output = (TA_ParamHolderPriv *)TA_Malloc( libHandle, allocSize ); if( output == NULL ) { TA_Free( libHandle, input ); TA_Free( libHandle, optInput ); TA_TRACE_RETURN( TA_ALLOC_ERR ); } /* Initialize the default values. */ inputInfo = funcDef->input; optInputInfo = funcDef->optInput; outputInfo = funcDef->output; for( i=0; i < funcInfo->nbInput; i++ ) { input[i].libHandle = libHandle; input[i].valueInitialize = 0; input[i].type = TA_PARAM_HOLDER_INPUT; memset( &input[i].p.in.data, 0, sizeof(union TA_ParamHolderInputData) ); input[i].p.in.inputInfo = &inputInfo[i]; input[i].function = 0; } for( i=0; i < funcInfo->nbOptInput; i++ ) { optInput[i].libHandle = libHandle; optInput[i].valueInitialize = 0; optInput[i].type = TA_PARAM_HOLDER_OPTINPUT; memset( &optInput[i].p.optIn.data, 0, sizeof(union TA_ParamHolderOptInData) ); optInput[i].p.optIn.optInputInfo = &optInputInfo[i]; optInput[i].function = 0; } for( i=0; i < funcInfo->nbOutput; i++ ) { output[i].libHandle = libHandle; output[i].valueInitialize = 0; output[i].type = TA_PARAM_HOLDER_OUTPUT; memset( &output[i].p.out.data, 0, sizeof(union TA_ParamHolderOutputData) ); output[i].p.out.outputInfo = &outputInfo[i]; output[i].function = 0; } input[0].function = funcDef->function; optInput[0].function = funcDef->function; output[0].function = funcDef->function; /* Succcess, return the result to the caller. * (Disguise as TA_ParamHolder for end-user). */ *newInputParams = (TA_ParamHolder *)input; *newOptInputParams = (TA_ParamHolder *)optInput; *newOutputParams = (TA_ParamHolder *)output; TA_TRACE_RETURN( TA_SUCCESS ); }
TA_RetCode TA_GetFuncHandle( TA_Libc *libHandle, const char *name, const TA_FuncHandle **handle ) { TA_PROLOG; char firstChar, tmp; const TA_FuncDef **funcDefTable; const TA_FuncDef *funcDef; const TA_FuncInfo *funcInfo; unsigned int i, funcDefTableSize; TA_TRACE_BEGIN( libHandle, TA_GetFuncHandle ); /* A TA_FuncHandle is internally a TA_FuncDef. Let's find it * by using the alphabetical tables. */ if( (name == NULL) || (handle == NULL) ) { TA_TRACE_RETURN( TA_BAD_PARAM ); } *handle = NULL; firstChar = name[0]; if( firstChar == '\0' ) { TA_TRACE_RETURN( TA_BAD_PARAM ); } tmp = (char)tolower( firstChar ); if( (tmp < 'a') || (tmp > 'z') ) { TA_TRACE_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 ) { TA_TRACE_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]; TA_DEBUG_ASSERT( libHandle, funcDef != NULL ); TA_DEBUG_ASSERT( libHandle, funcDef->funcInfo != NULL ); funcInfo = funcDef->funcInfo; TA_DEBUG_ASSERT( libHandle, funcInfo != NULL ); if( strcmp( funcInfo->name, name ) == 0 ) { *handle = (TA_FuncHandle *)funcDef; TA_TRACE_RETURN( TA_SUCCESS ); } } TA_TRACE_RETURN( TA_FUNC_NOT_FOUND ); }
TA_RetCode TA_ForEachFunc( TA_Libc *libHandle, TA_CallForEachFunc functionToCall, void *opaqueData ) { TA_PROLOG; TA_StringTable *tableGroup; TA_StringTable *tableFunc; const TA_FuncDef *funcDef; const TA_FuncHandle *funcHandle; TA_RetCode retCode; unsigned int i, j; const TA_FuncInfo *funcInfo; TA_TRACE_BEGIN( libHandle, TA_ForEachFunc ); if( functionToCall == NULL ) { TA_TRACE_RETURN( TA_BAD_PARAM ); } /* Get all the group to iterate. */ retCode = TA_GroupTableAlloc( libHandle, &tableGroup ); if( retCode == TA_SUCCESS ) { TA_ASSERT( libHandle, tableGroup != NULL ); for( i=0; i < tableGroup->size; i++ ) { TA_DEBUG_ASSERT( libHandle, tableGroup->string[i] != NULL ); /* Get all the symbols to iterate for this category. */ retCode = TA_FuncTableAlloc( libHandle, tableGroup->string[i], &tableFunc ); if( retCode == TA_SUCCESS ) { TA_DEBUG_ASSERT( libHandle, tableFunc != NULL ); for( j=0; j < tableFunc->size; j++ ) { TA_DEBUG_ASSERT( libHandle, tableFunc->string[j] != NULL ); /* Get the function handle, and then the TA_FuncDef, * and then the TA_FuncInfo... */ retCode = TA_GetFuncHandle( libHandle, tableFunc->string[j], &funcHandle ); if( retCode != TA_SUCCESS ) continue; TA_DEBUG_ASSERT( libHandle, funcHandle != NULL ); funcDef = (const TA_FuncDef *)funcHandle; TA_DEBUG_ASSERT( libHandle, funcDef != NULL ); funcInfo = funcDef->funcInfo; TA_DEBUG_ASSERT( libHandle, funcInfo != NULL ); /* Call user provided function. */ (*functionToCall)( libHandle, funcInfo, opaqueData ); } } TA_FuncTableFree( tableFunc ); } TA_GroupTableFree( tableGroup ); } else { TA_TRACE_RETURN( TA_INTERNAL_ERROR(2) ); } TA_TRACE_RETURN( TA_SUCCESS ); }
std::string ILogType::getSimpleMessage ( va_list& args ) const { // Format string is the first arg char* format = ""; try { format = va_arg ( args, char* ); std::string test ( format ); TA_DEBUG_ASSERT ( test.size() != 0, "Empty log message" ); TA_DEBUG_ASSERT ( format != "", "Empty log message" ); TA_DEBUG_ASSERT ( format, "Empty log message" ); TA_DEBUG_ASSERT ( test.c_str() != NULL, "Empty log message" ); } catch ( TA_Base_Core::AssertException& ae ) { // This exception was caught from TA_DEBUG_ASSERT so throw it again, // as these situations should not occur if LOG is used correctly. throw ae; } catch ( ... ) { throw TA_Base_Core::DebugMsgConstructionException ( "A char * was not passed in as the format string" ); } // Construct message from format string and args std::string message(""); char* buff = new char[MAXLOGMESGSIZE + 1]; memset(buff, 0, MAXLOGMESGSIZE + 1); try { int ret = vsnprintf ( buff, MAXLOGMESGSIZE, format, args ); if ( ret > MAXLOGMESGSIZE || ret < 0 ) { std::ostringstream str; str << "ERROR: DebugMsgConstructionException: Message length exceeds " << MAXLOGMESGSIZE << " characters: " << format; message = str.str(); //throw TA_Base_Core::DebugMsgConstructionException(str.str()); } else { message = buff; } } catch ( ... ) { std::ostringstream str; str << "ERROR: DebugMsgConstructionException: Invalid argument types (was a std::string used?): " << format; message = str.str(); //throw TA_Base_Core::DebugMsgConstructionException(str.str()); } if (NULL != buff) { delete[] buff; buff = NULL; } TA_DEBUG_ASSERT ( !message.empty(), "Empty log message" ); message = message.insert ( 0, " "); // Preprend indentation message += "\n"; return message; }
static TA_RetCode equityPeriodTransform( TA_PMPriv *pmPriv, TA_Period newPeriod, /* The new desired period. */ unsigned int *nbBars, /* Return the number of price bar */ TA_Timestamp **timestamp, /* Allocate new timestamp. */ TA_Real **equity ) /* Allocate new equity. */ { TA_PROLOG /* Notice that this function is very similar to the * TA_PeriodTransform function in ta_period.c * * If you find a bug here, may be worth double * checking TA_PeriodTransform as well... */ TA_RetCode retCode; /* Temporaries. */ const TA_Timestamp *tempTimestamp; unsigned int tempInt, tempInt2; /* Variable used to identify period crossing. */ unsigned int currentWeek, currentMonth, currentYear, currentQuarter; /* Pointer on the history being transformed. */ const TA_Timestamp *old_timestamp; const TA_Real *old_equity; TA_Integer old_nbBars; /* Pointer on the transformed data. */ TA_Timestamp *new_timestamp; /* New allocated timestamp. */ TA_Real *new_equity; /* New allocated open. */ TA_Integer new_nbBars; TA_Timestamp cur_timestamp; /* Current new timestamp of new period. */ TA_Real cur_equity; /* Current new equity of new period. */ int oldPriceBar, newPriceBar; /* Array iterators. */ unsigned int again, periodCompleted; /* Boolean */ int firstIteration; TA_TRACE_BEGIN( TA_PeriodTransform ); /* Validate some mandatory parameter. */ TA_ASSERT( newPeriod != 0 ); TA_ASSERT( nbBars != NULL ); /* It is assume that the caller call this function * when there is really a transform to do. */ TA_ASSERT( newPeriod != TA_DAILY ); /* Of course, timestamps from the source are needed. */ TA_ASSERT( pmPriv->arrayTimestamp != NULL ); /* Initialize all callers pointers to NULL. * These will be initialize only on success. * In the meantime, new_XXXX pointers are * going to be used on the new allocated data. */ if( !timestamp || !equity ) return TA_BAD_PARAM; *timestamp = NULL; *equity = NULL; *nbBars = 0; /* Validate the supported transformation. */ /* Eliminate all the transform that * are currently not supported. * Identify also the major steps * needed to perform the transformation. */ switch( newPeriod ) { case TA_WEEKLY: case TA_MONTHLY: case TA_QUARTERLY: case TA_YEARLY: /* These are supported. */ break; default: TA_TRACE_RETURN( TA_PERIOD_NOT_AVAILABLE ); } /* OK.. now proceed with the transformations. * The strategy is simple: * The equity for the whole period will be the * equity at the last daily price bar of * that period. */ old_timestamp = &pmPriv->arrayTimestamp[0]; old_equity = &pmPriv->equity[0]; old_nbBars = pmPriv->nbDailyBars; new_timestamp = NULL; newPriceBar = 0; cur_timestamp.date = 0; /* Current new timestamp of new period. */ cur_timestamp.time = 0; /* Current new timestamp of new period. */ /* Overestimate the number of required new price bar. */ switch( newPeriod ) { case TA_WEEKLY: retCode = TA_TimestampDeltaWeek( &old_timestamp[0], &old_timestamp[old_nbBars-1], (unsigned int *)&new_nbBars ); break; case TA_MONTHLY: retCode = TA_TimestampDeltaMonth( &old_timestamp[0], &old_timestamp[old_nbBars-1], (unsigned int *)&new_nbBars ); break; case TA_QUARTERLY: retCode = TA_TimestampDeltaQuarter( &old_timestamp[0], &old_timestamp[old_nbBars-1], (unsigned int *)&new_nbBars ); break; case TA_YEARLY: retCode = TA_TimestampDeltaYear( &old_timestamp[0], &old_timestamp[old_nbBars-1], (unsigned int *)&new_nbBars ); break; default: TA_TRACE_RETURN( TA_INTERNAL_ERROR(126) ); } if( retCode != TA_SUCCESS ) { TA_TRACE_RETURN( retCode ); } new_nbBars += 2; /* To be on the safe side */ /* Allocate the new data. */ new_timestamp = TA_Malloc( new_nbBars * sizeof( TA_Timestamp ) ); if( !new_timestamp ) { TA_TRACE_RETURN( TA_ALLOC_ERR ); } new_equity = TA_Malloc( new_nbBars * sizeof( TA_Real ) ); if( !new_equity ) { TA_Free( new_timestamp ); TA_TRACE_RETURN( TA_ALLOC_ERR ); } /* Allows to detect crossing of the new period. */ currentYear = TA_GetYear ( &old_timestamp[0] ); currentMonth = TA_GetMonth( &old_timestamp[0] ); currentWeek = TA_GetWeekOfTheYear( &old_timestamp[0] ); currentQuarter = TA_GetQuarterOfTheYear( &old_timestamp[0] ); /* Iterate through the old price bar. */ oldPriceBar = 0; /* Iterate through the new price bar. */ newPriceBar = 0; again = 1; /* Becomes false when all bars are processed. */ while( again ) { /* Initialize cur_XXXXXX variables with the first bar in old timeframe. */ cur_timestamp = old_timestamp[oldPriceBar]; cur_equity = old_equity [oldPriceBar]; /* Go through the bars and accumulate the info * until the end of the requested period is reach. */ periodCompleted = 0; firstIteration = 1; while( (oldPriceBar < old_nbBars) && !periodCompleted ) { tempTimestamp = &old_timestamp[oldPriceBar]; /* Check if we reached an end of period. */ switch( newPeriod ) { case TA_WEEKLY: tempInt = TA_GetWeekOfTheYear( tempTimestamp ); /* Trap weeks on years boundary. */ if( (currentWeek == 52) && (tempInt == 0) ) currentWeek = 0; else if( currentWeek != tempInt ) { periodCompleted = 1; currentWeek = tempInt; } break; case TA_MONTHLY: tempInt = TA_GetMonth( tempTimestamp ); tempInt2 = TA_GetYear(tempTimestamp); if( (currentMonth != tempInt) || (currentYear != tempInt2) ) { periodCompleted = 1; currentMonth = tempInt; currentYear = tempInt2; } break; case TA_QUARTERLY: tempInt = TA_GetQuarterOfTheYear( tempTimestamp ); tempInt2 = TA_GetYear(tempTimestamp); if( (currentQuarter != tempInt) || (currentYear != tempInt2) ) { periodCompleted = 1; currentQuarter = tempInt; currentYear = tempInt2; } break; case TA_YEARLY: tempInt = TA_GetYear( tempTimestamp ); if( currentYear != tempInt ) { periodCompleted = 1; currentYear = tempInt; } break; default: /* Do nothing */ break; } /* If this is not the end of a period (in the new timeframe) * just accumulate the data. If this is the end of the period * that while loop will be exited. * Nothing is done on the first iteration because all the * cur_XXXX variables have been already initialized. */ if( !periodCompleted ) { if( !firstIteration ) { /* Adjust the new price bar. */ cur_timestamp = old_timestamp[oldPriceBar]; cur_equity = old_equity [oldPriceBar]; } else firstIteration = 0; /* Move to next bar. */ oldPriceBar++; } } /* We got all the info needed in the cur_XXXXX variables for * proceeding with the initialization of the new period price bar. */ TA_DEBUG_ASSERT( newPriceBar < new_nbBars ); /* If the timestamp is requested, some adjustment could be * needed to cur_timestamp. */ switch( newPeriod ) { case TA_WEEKLY: /* Now something a little bit tricky, we must * make sure that this new price bar is reported * as being the Friday of that week (even if there * is no price bar for that Friday). */ TA_JumpToDayOfWeek( &cur_timestamp, TA_FRIDAY ); break; case TA_MONTHLY: /* Monthly timestamp always end with the last day of * the month. Even if there was no actual transaction * the last day. */ TA_JumpToEndOfMonth( &cur_timestamp ); break; case TA_QUARTERLY: /* Quarterly timestamp always end with the last day of * the quarter. Even if there was no actual transaction * the last day. * Quarter 1 = 3/31 * Quarter 2 = 6/30 * Quarter 3 = 9/30 * Quarter 4 = 12/31 */ TA_JumpToEndOfQuarter( &cur_timestamp ); break; case TA_YEARLY: /* Yearly data always end on 12/31. */ TA_JumpToEndOfYear( &cur_timestamp ); break; default: /* Do nothing. */ break; } /* The new price bar is initialized here. */ new_timestamp[newPriceBar] = cur_timestamp; new_equity [newPriceBar] = cur_equity; /* This new period bar is completed, move to the next one. */ newPriceBar++; /* Any more data to process? */ if( oldPriceBar >= old_nbBars) again = 0; /* All bars have been processsed. */ } /* All done! Return the final result to the caller. */ *equity = new_equity; *timestamp = new_timestamp; *nbBars = newPriceBar; TA_TRACE_RETURN( TA_SUCCESS ); }
TA_RetCode TA_AllocStringFromYahooName( TA_Libc *libHandle, TA_DecodingParam *marketDecodingParam, const char *yahooSymbol, TA_String **allocatedCategoryName, TA_String **allocatedSymbolName, unsigned int allowOnlineProcessing ) { TA_PROLOG; TA_RetCode retCode; const char *symbol; unsigned int symbolLength; const char *ext; const char *countryAbbrev; const char *exchangeString; const char *typeString; unsigned int i; char *tempBuffer; TA_String *allocCategory; TA_String *allocSymbol; TA_StringCache *stringCache; TA_CountryId countryId; TA_YahooMarketPage *allocatedMarketPage; TA_TRACE_BEGIN( libHandle, TA_AllocStringFromYahooName ); /* Validate parameter */ if( !libHandle || !marketDecodingParam || !yahooSymbol || !allocatedCategoryName || !allocatedSymbolName ) { TA_TRACE_RETURN( TA_BAD_PARAM ); } stringCache = TA_GetGlobalStringCache( libHandle ); /* Set a pointer on where the symbol start. */ symbol = yahooSymbol; /* Size of the symbol. */ symbolLength = getstrfldlen( symbol, 0, 0, "." ); if( symbolLength < 2 ) { TA_TRACE_RETURN( TA_BAD_PARAM ); } else symbolLength--; /* The 3 strings forming the final Category string. */ countryAbbrev = NULL; exchangeString = NULL; typeString = NULL; /* Identify if there is an extension. */ ext = strchr( symbol, '.' ); if( ext ) { ext++; if( *ext == '\0' ) ext = NULL; } /* If ext != NULL, ext points on first char of the extension. */ if( ext ) { /* Identify known USA/CAN extension. */ for( i=0; i < NB_YAHOO_EXCHANGE_EXTENSION; i++ ) { if( lexcmp( TA_YahooExtensionTable[i].extension, ext ) == 0 ) { countryId = TA_YahooExtensionTable[i].countryId; countryAbbrev = TA_CountryIdToAbbrev( countryId ); exchangeString = TA_YahooExtensionTable[i].exchange; typeString = TA_YahooExtensionTable[i].type; break; /* Exit the loop */ } } /* Unknown extension, let's use the whole thing * as the symbol and keep going as if nothing * happened. */ if( !countryAbbrev ) ext = NULL; /* No known extension. */ } if( !exchangeString ) { /* If online access is not allowed, and the * symbol does not have a known extension, it * is not possible to identify the exchange. * * With online access, the exchange can be * found by doing further investigation on the * Yahoo! web sites. */ if( !allowOnlineProcessing ) return TA_INVALID_SECURITY_EXCHANGE; /* OK, we need to proceed by extracting the info * from Yahoo! web sites. */ retCode = internalMarketPageAlloc( libHandle, marketDecodingParam, yahooSymbol, &allocatedMarketPage ); if( retCode != TA_SUCCESS ) return retCode; TA_DEBUG_ASSERT( libHandle, allocatedMarketPage->exchange != NULL ); TA_DEBUG_ASSERT( libHandle, allocatedMarketPage->type != NULL ); /* All these string pointer are globals. So the allocatedMarketPage * can be freed and the member-poitners are still valid. */ countryAbbrev = TA_CountryIdToAbbrev( allocatedMarketPage->countryId ); exchangeString = allocatedMarketPage->exchange; typeString = allocatedMarketPage->type; internalMarketPageFree( allocatedMarketPage ); } TA_DEBUG_ASSERT( libHandle, typeString != NULL ); TA_DEBUG_ASSERT( libHandle, exchangeString != NULL ); TA_DEBUG_ASSERT( libHandle, countryAbbrev != NULL ); /* Build the Category string into a buffer. */ tempBuffer = TA_Malloc( libHandle, strlen( countryAbbrev ) + strlen( exchangeString ) + strlen( typeString ) + 3 ); sprintf( tempBuffer, "%s.%s.%s", countryAbbrev, exchangeString, typeString ); /* Allocate the Category string. */ allocCategory = TA_StringAlloc_UC( stringCache, tempBuffer ); TA_Free( libHandle, tempBuffer ); if( !allocCategory ) { TA_TRACE_RETURN( TA_ALLOC_ERR ); } /* Allocate the symbol string. */ allocSymbol = TA_StringAllocN_UC( stringCache, symbol, symbolLength ); if( !allocSymbol ) { TA_StringFree( stringCache, allocCategory ); TA_TRACE_RETURN( TA_ALLOC_ERR ); } /* Everything went fine, return the info to the caller. */ *allocatedCategoryName = allocCategory; *allocatedSymbolName = allocSymbol; TA_TRACE_RETURN( TA_SUCCESS ); }
TA_RetCode TA_SetInputParamPricePtr( TA_ParamHolder *param, unsigned int paramIndex, const TA_Timestamp *timestamp, const TA_Real *open, const TA_Real *high, const TA_Real *low, const TA_Real *close, const TA_Integer *volume, const TA_Integer *openInterest ) { TA_PROLOG TA_ParamHolderPriv *paramHolderPriv; const TA_InputParameterInfo *paramInfo; const TA_FuncInfo *funcInfo; TA_TRACE_BEGIN( TA_SetInputParamIntegerPtr ); if( param == NULL ) { TA_TRACE_RETURN( TA_BAD_PARAM ); } paramHolderPriv = (TA_ParamHolderPriv *)(param->hiddenData); if( paramHolderPriv->magicNumber != TA_PARAM_HOLDER_PRIV_MAGIC_NB ) { TA_TRACE_RETURN( TA_INVALID_PARAM_HOLDER ); } /* Make sure this index really exist. */ funcInfo = paramHolderPriv->funcInfo; TA_DEBUG_ASSERT( funcInfo != NULL ); if( paramIndex >= funcInfo->nbInput ) { TA_TRACE_RETURN( TA_BAD_PARAM ); } /* Verify the type of the parameter. */ paramInfo = paramHolderPriv->in[paramIndex].inputInfo; TA_DEBUG_ASSERT( paramInfo != NULL ); if( paramInfo->type != TA_Input_Price ) { TA_TRACE_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 ) \ { \ TA_TRACE_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 ); SET_PARAM_INFO(timestamp, TIMESTAMP ); #undef SET_PARAM_INFO /* This parameter is now initialized, clear the corresponding bit. */ paramHolderPriv->inBitmap &= ~(1<<paramIndex); TA_TRACE_RETURN( TA_SUCCESS ); }
TA_RetCode TA_ParamHolderAlloc( const TA_FuncHandle *handle, TA_ParamHolder **allocatedParams ) { TA_PROLOG 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; TA_TRACE_BEGIN( TA_ParamHoldersAlloc ); /* Validate the parameters. */ if( !handle || !allocatedParams) { TA_TRACE_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; TA_TRACE_RETURN( TA_INVALID_HANDLE ); } /* Get the TA_FuncInfo. */ funcInfo = funcDef->funcInfo; TA_DEBUG_ASSERT( funcInfo != NULL ); /* Allocate the TA_ParamHolder. */ newParams = (TA_ParamHolder *)TA_Malloc( sizeof(TA_ParamHolder) + sizeof(TA_ParamHolderPriv)); if( !newParams ) { *allocatedParams = NULL; TA_TRACE_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. */ TA_DEBUG_ASSERT( funcInfo->nbInput != 0 ); allocSize = (funcInfo->nbInput) * sizeof(TA_ParamHolderInput); input = (TA_ParamHolderInput *)TA_Malloc( allocSize ); if( !input ) { TA_ParamHolderFree( newParams ); *allocatedParams = NULL; TA_TRACE_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; TA_TRACE_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; TA_TRACE_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; TA_TRACE_RETURN( TA_SUCCESS ); }