示例#1
0
unsigned int TA_FileSize( TA_FileHandle *handle )
{
   #if defined( USE_WIN32_API )
   BY_HANDLE_FILE_INFORMATION bhfi;
   #endif

   TA_FileHandlePriv *fileHandlePriv;
   unsigned int fileSize;

   TA_ASSERT_RET( handle != NULL, 0 );

   fileHandlePriv = (TA_FileHandlePriv *)handle;

   if( fileHandlePriv->streamAccess )
   {
      /* Use the stream instead of the file. */
      fileSize = TA_StreamSizeInByte( fileHandlePriv->stream );
   }
   else
   {
      #if defined( USE_WIN32_API )
         TA_ASSERT_RET( fileHandlePriv->handle != INVALID_HANDLE_VALUE, 0 );
         GetFileInformationByHandle( fileHandlePriv->handle, &bhfi );
         fileSize = bhfi.nFileSizeLow;
      #endif

      #if defined( USE_OSLAYER )
         TA_ASSERT_RET( fileHandlePriv->handle != NULL, 0 );
         fileSize = get_file_size( fileHandlePriv->path );
      #endif
   }

   return fileSize;
}
示例#2
0
static int findTimestampIndex( const TA_PMPriv *pmPriv,
                               const TA_Timestamp *exitTimestamp,
                               int *idx )
{
   const TA_Timestamp *startDate;
   const TA_Timestamp *endDate;
   TA_DayOfWeek dayOfTheWeek;

   /* Return 0 when no index can be resolved. */
   startDate = &pmPriv->startDate;
   endDate   = &pmPriv->endDate;

   /* Make sure the exitTimestamp is within the start/end date. */ 
   if( (TA_TimestampGreater(exitTimestamp,startDate)&&TA_TimestampLess(exitTimestamp,endDate)) ||
       TA_TimestampEqual(exitTimestamp, startDate) ||
       TA_TimestampEqual(exitTimestamp, endDate) )
   {
      /* Make sure the exitTimestamp is NOT on week-end. Week-end
       * trades are currently ignored.
       */
      dayOfTheWeek = TA_GetDayOfTheWeek( exitTimestamp );
      if( (dayOfTheWeek != TA_SUNDAY) && (dayOfTheWeek != TA_SATURDAY) )
      {
         TA_TimestampDeltaWeekday( startDate, exitTimestamp, (unsigned int *)idx );
         *idx -= 1;

         #ifdef TA_DEBUG
         TA_ASSERT_RET( *idx >= 0, 0 );
         TA_ASSERT_RET( (unsigned int)*idx < pmPriv->nbDailyBars, 0 );             
         TA_ASSERT_RET( TA_TimestampEqual(&pmPriv->arrayTimestamp[*idx], exitTimestamp ), 0 );
         #endif

         return 1;
      }
   }

   /* No index can be found, initialize to zero, just to
    * be safe.
    */
   *idx = 0; 

   return 0;
}
示例#3
0
TA_ValueTreeNode *TA_FileIndexGoUpTreeValue( TA_FileIndexPriv *data )
{
   TA_ValueTreeNode *retValue;
   TA_Libc *libHandle;

   libHandle = data->libHandle;

   TA_ASSERT_RET( libHandle, data != NULL, (TA_ValueTreeNode *)NULL );

   if( !data->currentNode )
      return (TA_ValueTreeNode *)NULL;

   retValue = data->currentNode->parent;

   /* Change data->currentNode only if we can really go up... */
   if( retValue  )
      data->currentNode = retValue;

   return retValue;
}
示例#4
0
/* Two very limited function to walk up/down in the Tree.
 * These functions are useful only when walking on a known linear portion
 * of the tree (when for each parent there is only one child).
 */
TA_ValueTreeNode *TA_FileIndexGoDownTreeValue( TA_FileIndexPriv *data )
{
   TA_ValueTreeNode *retValue;
   TA_Libc *libHandle;

   libHandle = data->libHandle;

   TA_ASSERT_RET( libHandle, data != NULL, (TA_ValueTreeNode *)NULL );

   /* Go down using the first child only. */
   if( (!data->currentNode) || (!data->currentNode->child) )
      return NULL;

   retValue = TA_ListAccessHead( data->currentNode->child );

   /* Change data->currentNode only if we really can go down... */
   if( retValue )
      data->currentNode = retValue;

   return retValue;
}
示例#5
0
const char *TA_FileSeqRead( TA_FileHandle *handle, unsigned int *nbByteRead )
{
   #if defined( USE_WIN32_API )
   BOOL retValue;
   DWORD nbByteReadLocal;
   #else
   size_t nbByteReadLocal;
   #endif

   TA_FileHandlePriv *fileHandlePriv;
   const char *returnValue;
   TA_RetCode retCode;

   TA_ASSERT_RET( handle != NULL, (char *)NULL );
   TA_ASSERT_RET( nbByteRead != NULL, (char *)NULL );

   fileHandlePriv = (TA_FileHandlePriv *)handle;

   if( fileHandlePriv->streamAccess )
   {
      /* Use the stream instead of the file. 
       * Get the data chunk by chunk.
       */
      retCode = TA_StreamAccessGetBuffer( fileHandlePriv->streamAccess,
                                          &returnValue,
                                          nbByteRead );
      if( retCode != TA_SUCCESS )
         return 0;
   }  
   else
   { 
	   
      TA_ASSERT_RET( fileHandlePriv->allocBuffer != NULL, (char *)NULL );
      TA_ASSERT_RET( fileHandlePriv->allocBufferSize >= 128, (char *)NULL );

      *nbByteRead = 0;

      #if defined( USE_WIN32_API )
         TA_ASSERT_RET( fileHandlePriv->handle != INVALID_HANDLE_VALUE, (char *)NULL );
         retValue = ReadFile( fileHandlePriv->handle,
                              fileHandlePriv->allocBuffer,
                              fileHandlePriv->allocBufferSize,
                              &nbByteReadLocal,
                              NULL );

         if( retValue == 0 )
            return NULL;
      #else
         TA_ASSERT_RET( fileHandlePriv->handle != NULL, (char *)NULL );
         if( feof(fileHandlePriv->handle) || ferror(fileHandlePriv->handle) )
            return NULL;

         nbByteReadLocal = fread( fileHandlePriv->allocBuffer, 1, 
                                  fileHandlePriv->allocBufferSize,
                                  fileHandlePriv->handle );
      #endif

      *nbByteRead = nbByteReadLocal;

      if( *nbByteRead == 0 )
         return NULL;

      returnValue = fileHandlePriv->allocBuffer;
   }

   return returnValue;
}
示例#6
0
TA_String *stringAllocNInternal( TA_StringCache *stringCache,
                                 const char *string,
                                 unsigned int maxNbChar,
                                 TA_CharCase caseType )
{
   TA_String *tmp;
   unsigned int hashIndex;
   char *hashEntry;
   TA_StringCachePriv *stringCachePriv;
   unsigned int newStringLength;
   int sameString;
   unsigned int i;

   #if !defined( TA_SINGLE_THREAD )
   TA_RetCode retCode;
   #endif

   if( stringCache == NULL )
      return NULL;

   stringCachePriv = (TA_StringCachePriv *)stringCache;

   if( !string )
      return NULL;

   hashIndex = calcHash( string, caseType );
   TA_ASSERT_RET( hashIndex < NB_CACHE_ENTRY, (TA_String *)NULL );

   /* Evaluate the final length of the new string. */
   newStringLength = strlen( string );
   if( maxNbChar != 0 )
   {
      if( maxNbChar < newStringLength )
         newStringLength = maxNbChar;
   }

   #if !defined( TA_SINGLE_THREAD )
      /* Get the semaphore for this cache. */
      retCode = TA_SemaWait( &stringCachePriv->sema );

      if( retCode != TA_SUCCESS )
         return NULL;
   #endif

   /* Check if already in the hash table. If yes, re-use it. */
   hashEntry = (char *)stringCachePriv->cache[ hashIndex ];
   if( hashEntry && ((unsigned char)hashEntry[0] < 255) )
   {
      /* Check that this is the same string, same size. */
      if( (caseType == NO_CASE) && 
          (!strncmp( string, &hashEntry[1], newStringLength)) &&
          (hashEntry[newStringLength+1] == '\0') )
         sameString = 1;     
      else if( caseType == PATH )
      {
          sameString = 1;
          for( i=0; i <= newStringLength && (sameString == 1); i++ )
          {
             if( hashEntry[i+1] == '\0' )
                sameString = 0;
             if( (string[i] != hashEntry[i+1]) && !TA_IsSeparatorChar(string[i]) )
                sameString = 0;
          }

          if( sameString && (hashEntry[newStringLength+1] != '\0') )
            sameString = 0;
      }
      else if( caseType == UPPER_CASE )
      {
          sameString = 1;
          for( i=0; i <= newStringLength && (sameString == 1); i++ )
          {
             if( hashEntry[i+1] == '\0' )
                sameString = 0;
             if( (toupper(string[i]) != hashEntry[i+1]) )
                sameString = 0;
          }

          if( sameString && (hashEntry[newStringLength+1] != '\0') )
            sameString = 0;
      }
      else
         sameString = 0;

      if( sameString )
      {
         tmp = stringDupInternal( (TA_String *)hashEntry );
         #if !defined( TA_SINGLE_THREAD )
            TA_SemaPost( &stringCachePriv->sema );         
         #endif
         return tmp;
      }
   }

   tmp = stringAllocInternal( string, newStringLength, caseType );

   if( tmp != NULL )
   {
      /* Store in cache. */

      /* Delete previous entry in the same position in the cache. */
      if( hashEntry )
         stringFreeInternal( (TA_String *)hashEntry );

      /* Keep track of this latest allocation. */
      stringCachePriv->cache[hashIndex] = stringDupInternal( tmp );
   }

   #if !defined( TA_SINGLE_THREAD )
      TA_SemaPost( &stringCachePriv->sema );
   #endif

   return tmp;
}
示例#7
0
/**** Global functions definitions.   ****/
TA_RetCode TA_PMArrayAlloc( TA_PM        *pm,
                            TA_PMArrayId  arrayId,
                            TA_PMGroup    grp,
                            TA_Period     period,
                            TA_PMArray  **allocatedArray )
{
   TA_PMPriv       *pmPriv;
   TA_List         *tradeLogList;
   TA_TradeLogPriv *tradeLogPriv;
   int              timeSerieSize;
   TA_RetCode       retCode;
   TA_PMArray      *newPMArray;
   unsigned int     finalNbBars;
   TA_Real         *finalData;
   TA_Timestamp    *finalTimestamp;

   if( !allocatedArray )
      return TA_BAD_PARAM;

   *allocatedArray = NULL;

   if( !pm || 
       (arrayId >= TA_PM_NB_ARRAYID) ||
       (grp >= TA_PM_NB_GROUP) )
      return TA_BAD_PARAM;

   /* Make sure 'pm' is a ptr on a valid object */
   pmPriv = (TA_PMPriv *)pm->hiddenData; 
   if( pmPriv->magicNb != TA_PMPRIV_MAGIC_NB )
      return TA_BAD_OBJECT;


   #if 0
   /* Get the number of trade that applies to the period.
    * Doing so will also force the update of all
    * "basic calculation" if needed.
    */
   retCode = TA_PMValue( pm, TA_PM_TOTAL_NB_OF_TRADE,
                         TA_PM_ALL_TRADES, &nbTrade );
   if( retCode != TA_SUCCESS )
      return retCode;
   #endif


   /* Because the startDate/endDate are fix in the
    * lifetime of a TA_PM, all the cached time series
    * are allocated once here and freed only when the
    * TA_PM is freed.
    */
   if( !pmPriv->arrayTimestamp )
   {
      /* Allocate the timestamps (excluding week-end)
       * from [startDate..endDate] inclusive.
       * There is only one array of timestamps for all the
       * time series. 
       */
      pmPriv->arrayTimestamp = allocTimestampArray( &pmPriv->startDate,
                                                    &pmPriv->endDate,
                                                    (int *)&pmPriv->nbDailyBars );
      if( !pmPriv->arrayTimestamp )
         return TA_ALLOC_ERR;
   }


   if( !(pmPriv->flags & TA_PMARRAYCACHE_CALCULATED) )
   {
      /* The cached time serie needs to be recalculated
       * from scratch.
       */
      tradeLogList = &pmPriv->tradeLogList;
      tradeLogPriv = TA_ListAccessHead( tradeLogList );
      
      if( !tradeLogPriv )
         return TA_NO_TRADE_LOG;
      else
      {
         /* Make sure all required cached time series are correctly
          * allocated.
          */
         timeSerieSize = sizeof(TA_Real)*pmPriv->nbDailyBars;
         #define TRY_ALLOC_IF_NULL(x) { \
            if( !x ) \
            { \
               x = TA_Malloc( timeSerieSize ); \
               if( !x ) \
                  return TA_ALLOC_ERR; \
            } }

         TRY_ALLOC_IF_NULL( pmPriv->shortArrayCache.investment );
         TRY_ALLOC_IF_NULL( pmPriv->shortArrayCache.profit );
         TRY_ALLOC_IF_NULL( pmPriv->longArrayCache.investment );
         TRY_ALLOC_IF_NULL( pmPriv->longArrayCache.profit );
         #undef TRY_ALLOC_IF_NULL

         /* Reset to zero all the timeseries. */
         memset( pmPriv->shortArrayCache.investment, 0, timeSerieSize );
         memset( pmPriv->shortArrayCache.profit,     0, timeSerieSize );
         memset( pmPriv->longArrayCache.investment,  0, timeSerieSize );
         memset( pmPriv->longArrayCache.profit,      0, timeSerieSize );

         /* Iterate through all the TA_TradeLog */
         do
         {
            if( !(tradeLogPriv->flags & TA_PMARRAYCACHE_CALCULATED) )
               processCache( pmPriv, tradeLogPriv );

            tradeLogPriv = TA_ListAccessNext( tradeLogList );
         } while( tradeLogPriv );
      }

      pmPriv->flags |= TA_PMARRAYCACHE_CALCULATED;
   }
   
   switch( arrayId )
   {
   case TA_PM_ARRAY_EQUITY:
      if( !(pmPriv->flags & TA_EQUITY_CALCULATED) )
      {
         /* Allocate the daily equity. 
          * Keep it cached in "pmPriv->equity".
          */
         retCode = processDailyEquityArray(pmPriv,grp);
         if( retCode != TA_SUCCESS )
            return retCode;
         pmPriv->flags |= TA_EQUITY_CALCULATED;
      }

      /* If requested is not daily, translate to the
       * new period.
       */
      if( period == TA_DAILY )
      {
         finalTimestamp = pmPriv->arrayTimestamp;
         finalData      = pmPriv->equity;
         finalNbBars    = pmPriv->nbDailyBars;
      }
      else
      {
         retCode = equityPeriodTransform( pmPriv, period, &finalNbBars,
                                          &finalTimestamp, &finalData );

         if( retCode != TA_SUCCESS )
            return retCode;
      }
      break;

   /*case TA_PM_ARRAY_RETURNS:
      break;*/

   default:
      return TA_BAD_PARAM;
   }

   TA_ASSERT_RET( pmPriv->arrayTimestamp != NULL, TA_INTERNAL_ERROR(122) );
   TA_ASSERT_RET( pmPriv->equity != NULL, TA_INTERNAL_ERROR(123) );
   TA_ASSERT_RET( finalData != NULL, TA_INTERNAL_ERROR(124) );
   TA_ASSERT_RET( finalTimestamp != NULL, TA_INTERNAL_ERROR(125) );
 
   /* At last, allocate and fill up the TA_PMArray. */
   newPMArray = TA_Malloc( sizeof( TA_PMArray ) );
   if( !newPMArray )
      return TA_ALLOC_ERR;
   newPMArray->arrayId    = arrayId;
   newPMArray->grp        = grp;
   newPMArray->period     = period;
   newPMArray->data       = finalData;
   newPMArray->timestamp  = finalTimestamp;
   newPMArray->nbData     = finalNbBars;
   newPMArray->hiddenData = pm;

   *allocatedArray = newPMArray;
     
   return TA_SUCCESS;
}
示例#8
0
static TA_Timestamp *allocTimestampArray( const TA_Timestamp *start,
                                          const TA_Timestamp *end,
                                          int                *nbDays )
{
   TA_RetCode    retCode;
   TA_Timestamp *array;
   int outIdx;
   TA_Timestamp curDate;
   TA_DayOfWeek dayOfTheWeek;

   TA_ASSERT_RET( TA_TimestampValidate(start) == TA_SUCCESS, (TA_Timestamp *)NULL );
   TA_ASSERT_RET( TA_TimestampValidate(end  ) == TA_SUCCESS, (TA_Timestamp *)NULL );
   TA_ASSERT_RET( nbDays != NULL, (TA_Timestamp *)NULL );

   /* Calculate the exact number of week days
    * between start and end inclusive.
    * Excluding week-ends.
    */
   retCode = TA_TimestampDeltaWeekday( start, end, (unsigned int *)nbDays );
   if( retCode != TA_SUCCESS )
      return (TA_Timestamp *)NULL;

   /* Allocate the array. Add two element just to be on the safe side. */
   array = TA_Malloc( sizeof( TA_Timestamp ) * ((*nbDays)+2) );
   if( !array )
      return (TA_Timestamp *)NULL;

   /* Fill up the array. */
   TA_TimestampCopy( &curDate, start );

   /* Write the start point, if it is a weekday. */
   outIdx = 0;
   dayOfTheWeek = TA_GetDayOfTheWeek( &curDate );
   if( (dayOfTheWeek != TA_SUNDAY) && (dayOfTheWeek != TA_SATURDAY) )
   {
      TA_TimestampCopy( &array[outIdx], &curDate );
      outIdx++;
      TA_NextWeekday( &curDate );
      TA_ASSERT_RET( TA_TimestampValidate(&curDate) == TA_SUCCESS, (TA_Timestamp *)NULL );
   }

   /* Count the number of weekday */
   while( TA_TimestampLess( &curDate, end ) )
   {
      TA_TimestampCopy( &array[outIdx], &curDate );
      outIdx++;
      TA_NextWeekday( &curDate );
      TA_ASSERT_RET( TA_TimestampValidate(&curDate) == TA_SUCCESS, (TA_Timestamp *)NULL );
   } 

   /* Check if the ending point is a weekday. */
   if( TA_TimestampEqual( &curDate, end ) )
   {
      dayOfTheWeek = TA_GetDayOfTheWeek( &curDate );
      if( (dayOfTheWeek != TA_SUNDAY) && (dayOfTheWeek != TA_SATURDAY) )
         TA_TimestampCopy( &array[outIdx++], &curDate );
   }

   TA_ASSERT_RET( outIdx == (*nbDays), (TA_Timestamp *)NULL );

   return array;
}