示例#1
0
/* Allocate dyamically a copy of string.
 * Eliminate also all whitespace in the copy.
 */
TA_String *TA_StringAllocTrim( TA_StringCache *stringCache,
                               const char *string )
{
   char *str;
   char *ptrCharTmp1;
   const char *ptrCharTmp2;
   unsigned int trimmedSize;
   unsigned int nonTrimmedSize;
   TA_StringCachePriv *stringCachePriv;

   if( stringCache == NULL )
      return NULL;

   stringCachePriv = (TA_StringCachePriv *)stringCache;

   if( !string )
      return NULL;

   /* Evaluate the size and see if any trimming is needed. */
   trimmedSize = 0;
   nonTrimmedSize = 0;
   ptrCharTmp2 = string;
   while( *ptrCharTmp2++ != '\0' )
   {
      if( !isspace(*ptrCharTmp2) )
         trimmedSize++;
      nonTrimmedSize++;
   }

   if( trimmedSize == nonTrimmedSize )
      return TA_StringAlloc( stringCache, string );

   trimmedSize = (trimmedSize + 1)*sizeof( unsigned char );

   str = (char *)TA_Malloc( trimmedSize );

   if( str != NULL )
   {
      /* Eliminate all whitespaces (not speed optimize...) */
      ptrCharTmp1 = &str[0];
      ptrCharTmp2 = string;
      while( *ptrCharTmp2 != '\0' )
      {
         if( !isspace(*ptrCharTmp2) )
         {
            *ptrCharTmp1 = *ptrCharTmp2;
            ptrCharTmp1++;
         }
         ptrCharTmp2++;
      }

      *ptrCharTmp1 = '\0';

      return TA_StringAlloc( stringCache, str );
   }

   /* Allocation error. */
   return (TA_String *)NULL;
}
示例#2
0
/* Allows to dynamically add a mini-driver. */
TA_RetCode TA_SQL_AddMinidriver( const char scheme[], const TA_SQL_Minidriver *minidriver )
{
   TA_PROLOG
   TA_String *schemeStr;
   TA_StringCache *cache;

   TA_RetCode retCode;

   TA_TRACE_BEGIN( TA_SQL_AddMinidriver );

   if( !minidriverDict )
   {
      minidriverDict = TA_DictAlloc( TA_DICT_KEY_ONE_STRING, NULL );
      if( !minidriverDict )
      {
         TA_TRACE_RETURN( TA_ALLOC_ERR );
      }
   }

   cache = TA_GetGlobalStringCache();
   TA_ASSERT( cache != NULL );
   schemeStr = TA_StringAlloc( cache, scheme );
   if( !schemeStr )
   {
      TA_DictFree(minidriverDict);
      TA_TRACE_RETURN( TA_ALLOC_ERR );
   }

   retCode = TA_DictAddPair_S( minidriverDict, schemeStr, (void *)minidriver );
   TA_StringFree( cache, schemeStr );

   TA_TRACE_RETURN( retCode );
}
示例#3
0
/**** Global functions definitions.   ****/
TA_RetCode TA_AllocStringFromLibName( TA_Libc *libHandle,
                                      const TA_String *category,
                                      const TA_String *symbol,
                                      TA_String **allocatedYahooName )
{
   TA_PROLOG;

   TA_RetCode retCode;
   TA_StringCache *stringCache;
   char buffer[200];

   TA_TRACE_BEGIN( libHandle, TA_AllocStringFromLibName );
   buffer[199] = '\0'; /* Just to be safe. */

   /* Translate the category/symbol into the yahoo! name. */
   retCode = translateToYahooName( libHandle, category, symbol, &buffer[0], 199 );
   if( retCode != TA_SUCCESS )
   {
      TA_TRACE_RETURN( retCode );
   }

   stringCache = TA_GetGlobalStringCache( libHandle );
   *allocatedYahooName = TA_StringAlloc( stringCache, buffer );
   if( !*allocatedYahooName )
   {
      TA_TRACE_RETURN( TA_ALLOC_ERR );
   }
   
   TA_TRACE_RETURN( TA_SUCCESS );
}
示例#4
0
TA_RetCode TA_FileIndexAddTreeValue( TA_FileIndexPriv *data,
                                     TA_String *string,
                                     TA_ValueTreeNode **added )
{
   TA_PROLOG;
   TA_ValueTreeNode *node;
   unsigned int allocateEmptyString;
   TA_Libc *libHandle;
   TA_StringCache *stringCache;

   libHandle = data->libHandle;
   TA_TRACE_BEGIN( libHandle, TA_FileIndexAddTreeValue );

   stringCache = TA_GetGlobalStringCache( libHandle );

   allocateEmptyString = 0;
   TA_ASSERT( libHandle, data != NULL );

   if( added )
      *added = NULL;

   if( !string )
   {
      string = TA_StringAlloc( stringCache, "" );
      if( !string )
      {
         TA_TRACE_RETURN( TA_ALLOC_ERR );
      }
      allocateEmptyString = 1;
   }

   /* Alloc the TA_ValueTreeNode */
   node = allocTreeNode( libHandle, data->currentNode, string );

   if( allocateEmptyString )
      TA_StringFree( stringCache, string );

   if( !node )
   {
      TA_TRACE_RETURN( TA_ALLOC_ERR );
   }

   data->currentNode = node;

   if( added )
      *added = node;

   TA_TRACE_RETURN( TA_SUCCESS );
}
示例#5
0
TA_RetCode TA_DirectoryAlloc( const char *path,
                              TA_Directory **directory )
{
   #if defined( USE_WIN32_API )
   HANDLE handle;
   WIN32_FIND_DATA data;
   DWORD win32Error;
   #endif

   #if defined( USE_OSLAYER )
   DIRST dirHandle;
   const char *filePattern;
   char *basePath;
   #endif

   unsigned pathLength;

   int findNextRetCode;

   TA_Directory *dir;
   TA_String *string;
   TA_RetCode retCode;
   TA_SystemGlobal *global;

   const char   *entryName;
   unsigned int  entryIsDirectory;

   *directory = NULL;

   if( (path == NULL) || (directory == NULL) )
      return TA_BAD_PARAM;

   retCode = TA_GetGlobal(  &TA_SystemGlobalControl, (void **)&global );
   if( retCode != TA_SUCCESS )
      return retCode;

   dir = (TA_Directory *)TA_Malloc( sizeof( TA_Directory ) );

   if( dir == NULL )
      return TA_ALLOC_ERR;

   dir->nbFile = 0;
   dir->nbDirectory = 0;

   dir->listOfFile = TA_ListAlloc();
   dir->listOfDirectory = TA_ListAlloc();

   if( (dir->listOfFile == NULL) || (dir->listOfDirectory == NULL) )
   {
      TA_DirectoryFree( dir );
      return TA_ALLOC_ERR;
   }

   /* Verify that the path is valid. */
   pathLength = strlen( path );

   if( (pathLength == 0) || (pathLength >= MAX_PATH) )
   {
      TA_DirectoryFree( dir );
      return TA_BAD_PARAM;
   }

   /* Now get the directory from the operating system. */
   #if defined( USE_WIN32_API )

   handle = FindFirstFile( path, &data );
   if( handle == INVALID_HANDLE_VALUE )
   {
      win32Error = GetLastError();
      global->lastError = win32Error;

      if( (win32Error != ERROR_FILE_NOT_FOUND) &&
          (win32Error != ERROR_PATH_NOT_FOUND) )
      {
         TA_DirectoryFree( dir );
         return TA_ACCESS_FAILED;
      }

      /* No files or directory... but still have to pass the result
       * to the caller.
       */
      *directory = dir;

      return TA_SUCCESS;
   }

   entryName = data.cFileName;
   entryIsDirectory = data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
   #endif

   #if defined( USE_OSLAYER )
   /* Split the path into the basePath and the filePattern. */
   basePath = TA_Malloc( pathLength+1 ); 
   memcpy( basePath, path, pathLength+1 );
   filePattern = split_path_and_file( basePath );

   if( !filePattern )
   {
      /* With no filePattern, no file can be found...
       * so return an empty directory to the caller.
       */
      *directory = dir;
      TA_Free(  basePath );
      return TA_SUCCESS;
   }

   /* Look for last separetor. */
   if( !open_dir(&dirHandle, basePath ) )
   {
      /* Errors, or no files or no directory... but
       * still have to pass the result to the caller.
       */      
      TA_Free(  basePath );
      *directory = dir;
      return TA_SUCCESS;
   }

   entryName = dirHandle.file_name;
   entryIsDirectory = dirHandle.file_attrs & ATTR_SUBDIR;
   #endif

   do
   {
      #if defined( USE_OSLAYER )
      if( file_matches( entryName, filePattern ) )
      {
      #endif
         if( entryIsDirectory )
         {
            if( entryName[0] != '.' )
            {
               string = TA_StringAlloc( global->dirnameCache, entryName );

               if( string == NULL )
               {
                  #if defined( USE_OSLAYER )
                     close_dir(&dirHandle);
                     TA_Free(  basePath );
                  #endif
                  TA_DirectoryFree( dir );
                  return TA_ALLOC_ERR;
               }

               retCode = TA_ListAddTail( dir->listOfDirectory, (void *)string );

               if( retCode != TA_SUCCESS )
               {
                  #if defined( USE_OSLAYER )
                     close_dir(&dirHandle);
                     TA_Free(  basePath );
                  #endif
                  TA_DirectoryFree( dir );
                  return retCode;
               }
               dir->nbDirectory++;
            }
         }
         else
         {
            string = TA_StringAlloc( global->filenameCache, entryName );

            if( string == NULL )
            {
               #if defined( USE_OSLAYER )
                  close_dir(&dirHandle);
                  TA_Free(  basePath );
               #endif
               TA_DirectoryFree( dir );
               return TA_ALLOC_ERR;
            }

            retCode = TA_ListAddTail( dir->listOfFile, (void *)string );

            if( retCode != TA_SUCCESS )
            {
               #if defined( USE_OSLAYER )
                  close_dir(&dirHandle);
                  TA_Free(  basePath );
               #endif
               TA_DirectoryFree( dir );
               return retCode;
            }
            dir->nbFile++;
         }
      #if defined( USE_OSLAYER )
      }
      #endif
      
      #if defined( USE_WIN32_API )
      findNextRetCode = FindNextFile( handle, &data );
      entryName = data.cFileName;
      entryIsDirectory = data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
      #endif

      #if defined( USE_OSLAYER )
      findNextRetCode = read_dir( &dirHandle );
      entryName = dirHandle.file_name;
      entryIsDirectory = dirHandle.file_attrs & ATTR_SUBDIR;
      #endif
   }
   while( findNextRetCode == TRUE );


   #if defined( USE_OSLAYER )
   TA_Free(  basePath );
   if( !close_dir(&dirHandle) )
   {
      TA_DirectoryFree( dir );
      return TA_INTERNAL_ERROR(11);
   }
   #endif

   #if defined( USE_WIN32_API )   
   if( FindClose( handle ) != TRUE )
   {
      global->lastError = GetLastError();
      TA_DirectoryFree( dir );
      return TA_INTERNAL_ERROR(12);
   }
   #endif

   /* Pass the result to the caller. */
   *directory = dir;

   return TA_SUCCESS;
}
示例#6
0
TA_RetCode TA_SIMULATOR_OpenSource( const TA_AddDataSourceParamPriv *param,
                                    TA_DataSourceHandle **handle )
{
   TA_PROLOG
   TA_DataSourceHandle *tmpHandle;
   TA_PrivateHandle *privData;
   TA_StringCache *stringCache;

   *handle = NULL;

   TA_TRACE_BEGIN(  TA_SIMULATOR_OpenSource );

   stringCache = TA_GetGlobalStringCache();

   if( !stringCache )
   {
      TA_TRACE_RETURN( TA_INTERNAL_ERROR(91) );
   }

   /* Verify that the requested functionality is supported or not. */
   if( param->flags & TA_REPLACE_ZERO_PRICE_BAR )
   {
      TA_TRACE_RETURN( TA_NOT_SUPPORTED );
   }

   /* Allocate and initialize the handle. This function will also allocate the
    * private handle (opaque data).
    */
   tmpHandle = (TA_DataSourceHandle *)TA_Malloc( sizeof( TA_DataSourceHandle ) );

   if( tmpHandle == NULL )
   {
      TA_TRACE_RETURN( TA_ALLOC_ERR );
   }
   memset( tmpHandle, 0, sizeof( TA_DataSourceHandle ) );

   privData = (TA_PrivateHandle *)TA_Malloc( sizeof( TA_PrivateHandle ) );
   if( !privData )
   {
      TA_Free(  tmpHandle );
      TA_TRACE_RETURN( TA_ALLOC_ERR );
   }
   memset( privData, 0, sizeof( TA_PrivateHandle ) );

   tmpHandle->opaqueData = privData;

   /* Copy some parameters in the private handle. */
   privData->categoryIter = 0;   
   privData->catRefIter   = 0;
   privData->catMrgIter   = 0;

   if( param->info == NULL )
   {
      privData->mrgInstance = 0;
      tmpHandle->nbCategory = 1;
   }
   else
   {
      privData->mrgInstance = atoi( TA_StringToChar( param->info ) );

      if( (privData->mrgInstance < 1) || (privData->mrgInstance > 4) )
      {
         TA_Free(  tmpHandle );
         TA_Free(  privData );
         TA_TRACE_RETURN( TA_BAD_PARAM );
      }

      tmpHandle->nbCategory = 2;

      /* Allocate the data. */
      
   }

   /* Pre-allocate all the string used in this data source. */
   privData->ta_sim_ref_cat = TA_StringAlloc(stringCache, "TA_SIM_REF");
   privData->ta_sim_mrg_cat = TA_StringAlloc(stringCache, "TA_SIM_MRG");
   privData->daily_ref_0    = TA_StringAlloc(stringCache, "DAILY_REF_0");
   privData->intra_ref_0    = TA_StringAlloc(stringCache, "INTRA_REF_0");
   privData->mrg_0          = TA_StringAlloc(stringCache, "MRG_0");

   if( !privData->ta_sim_ref_cat ||
       !privData->ta_sim_mrg_cat ||
       !privData->daily_ref_0 ||
       !privData->intra_ref_0 ||
       !privData->mrg_0 )
   {
      freePrivateHandle( privData );
      TA_TRACE_RETURN( TA_ALLOC_ERR );
   }

   /* Everything is fine, return the handle to the caller. */
   *handle = tmpHandle;

   TA_TRACE_RETURN( TA_SUCCESS );
}
示例#7
0
TA_RetCode TA_TradeLogAdd( TA_TradeLog    *tradeLog,
                           const TA_Transaction *newTransaction )
{
    TA_TradeLogPriv *tradeLogPriv;
    TA_Instrument *id;
    TA_Dict *theDict;
    TA_DataLog *dataLog;
    TA_TradeDictEntry *dictEntry;
    TA_StringCache *stringCache;
    TA_String *catString;
    TA_String *symString;
    const char *catCharPtr;
    const char *symCharPtr;
    TA_RetCode retCode;
    int quantity, entryTradeQuantity;
    TA_List *entryListToUse;
    TA_DataLog *entryTradeLog;

    TA_Real highestLow, highestHigh, lowestLow, lowestHigh;
    TA_Real entryPrice, tempReal;
    int i;

    retCode = TA_INTERNAL_ERROR(120);

    /* This function will transform the TA_Transaction into
     * an "entry" or multiple "trades" (because an exit can
     * be translated into multiple trade if there was multiple
     * entry point).
     */
    if( !tradeLog || !newTransaction )
        return TA_BAD_PARAM;

    /* Check that the TA_Transaction makes sense. */
    if( (newTransaction->price <= 0.0)  ||
            (newTransaction->quantity <= 0) ||
            (TA_TimestampValidate(&newTransaction->timestamp) != TA_SUCCESS) ||
            (newTransaction->type >= TA_NB_TRADE_TYPE))
        return TA_BAD_PARAM;

    /* Get access to the hidden data of the TA_TradeLog. */
    tradeLogPriv = (TA_TradeLogPriv *)tradeLog->hiddenData;

    /* Make sure this is a valid object. */
    if( !tradeLogPriv || (tradeLogPriv->magicNb != TA_TRADELOGPRIV_MAGIC_NB) )
        return TA_BAD_OBJECT;

    /* Find the TA_TradeDictEntry corresponding to
     * the TA_Instrument.
     *
     * Use the dictionary corresponding to the type of
     * key of the TA_Instrument.
     *
     * If TA_Instrument is NULL, use the pre-allocated
     * default TA_TradeDictEntry.
     */
    id = newTransaction->id;
    if( !id )
    {
        dictEntry = &tradeLogPriv->defaultDictEntry;
        catCharPtr = NULL;
        symCharPtr = NULL;
        theDict    = NULL;
    }
    else
    {
        catCharPtr = id->catString;
        symCharPtr = id->symString;
        if( catCharPtr )
        {
            if( symCharPtr )
            {
                theDict = tradeLogPriv->tradeDictCATSYM;
                dictEntry = TA_DictGetValue_S2( theDict, catCharPtr, symCharPtr );
            }
            else
            {
                theDict = tradeLogPriv->tradeDictCAT;
                dictEntry = TA_DictGetValue_S( theDict, catCharPtr );
            }
        }
        else if( symCharPtr )
        {
            theDict = tradeLogPriv->tradeDictCAT;
            dictEntry = TA_DictGetValue_S( theDict, symCharPtr );
        }
        else
        {
            theDict = tradeLogPriv->tradeDictUserKey;
            dictEntry = TA_DictGetValue_I( theDict, id->userKey );
        }
    }

    if( !dictEntry )
    {
        if( !theDict )
            return TA_INTERNAL_ERROR(146);

        /* The TA_TradeDictEntry was not found, create it! */
        dictEntry = TA_Malloc( sizeof( TA_TradeDictEntry ) );
        if( !dictEntry )
            return TA_ALLOC_ERR;

        memset( &dictEntry->id, 0, sizeof(TA_Instrument) );
        TA_ListInit( &dictEntry->shortEntryPrivList );
        TA_ListInit( &dictEntry->longEntryPrivList );

        /* Add the dictEntry to the corresponding dictionary. */
        stringCache = TA_GetGlobalStringCache();

        if( catCharPtr )
        {
            catString = TA_StringAlloc( stringCache, catCharPtr );
            if( !catString )
            {
                TA_Free( dictEntry );
                return TA_ALLOC_ERR;
            }

            if( symCharPtr )
            {
                symString = TA_StringAlloc( stringCache, symCharPtr );
                if( !symString )
                {
                    TA_Free( dictEntry );
                    TA_StringFree( stringCache, catString );
                    return TA_ALLOC_ERR;
                }
                retCode = TA_DictAddPair_S2( theDict, catString, symString, dictEntry );
                dictEntry->id.symString = TA_StringToChar(symString);
            }
            else
                retCode = TA_DictAddPair_S( theDict, catString, dictEntry );

            dictEntry->id.catString = TA_StringToChar(catString);
        }
        else if( symCharPtr )
        {
            symString = TA_StringAlloc( stringCache, symCharPtr );
            if( !symString )
            {
                TA_Free( dictEntry );
                return TA_ALLOC_ERR;
            }

            retCode = TA_DictAddPair_S( theDict, symString, dictEntry );
            dictEntry->id.symString = TA_StringToChar(symString);
        }
        else
        {
            retCode = TA_DictAddPair_I( theDict, id->userKey, dictEntry );
            dictEntry->id.userKey = id->userKey;
        }

        /* Check the retCode of the TA_DictAddXXXXX function. */
        if( retCode != TA_SUCCESS )
        {
            TA_Free( dictEntry );
            return TA_ALLOC_ERR;
        }
    }

    /* Identify the approriate list of entry. */
    switch( newTransaction->type )
    {
    case TA_LONG_ENTRY:
    case TA_LONG_EXIT:
        entryListToUse = &dictEntry->longEntryPrivList;
        break;
    case TA_SHORT_ENTRY:
    case TA_SHORT_EXIT:
        entryListToUse = &dictEntry->shortEntryPrivList;
        break;
    default:
        return TA_BAD_PARAM;
    }

    /* The sign of the quantity indicates if the
     * data log is a completed trade (+) or an
     * entry (-).
     */
    switch( newTransaction->type )
    {
    case TA_LONG_ENTRY:
    case TA_SHORT_ENTRY:
        /* Allocate a data log and add it to the list. */
        dataLog = TA_AllocatorForDataLog_Alloc( &tradeLogPriv->allocator );
        if( !dataLog )
            return TA_ALLOC_ERR;
        dataLog->u.entry.quantity  = -(newTransaction->quantity);
        dataLog->u.entry.entryPrice = newTransaction->price;
        TA_TimestampCopy( &dataLog->u.entry.entryTimestamp,
                          &newTransaction->timestamp );
        TA_ListNodeAddTail( entryListToUse, &dataLog->u.entry.node, dataLog );
        break;

    case TA_LONG_EXIT:
    case TA_SHORT_EXIT:
        /* Invalidate cached calculation of this trade log. */
        tradeLogPriv->flags &= ~TA_PMVALUECACHE_CALCULATED;

        /* Transform this transaction into one or
         * multiple trade(s).
         */
        entryTradeLog = TA_ListRemoveHead( entryListToUse );
        if( !entryTradeLog )
            return TA_ENTRY_TRANSACTION_MISSING;

        quantity = newTransaction->quantity;
        while( quantity )
        {
            entryTradeQuantity = -entryTradeLog->u.trade.quantity;
            if( entryTradeQuantity == quantity )
            {
                /* This entry have exactly the right amount of
                 * position for what needs to be closed.
                 * Just transform the entry into a trade.
                 */
                entryTradeLog->u.trade.quantity = quantity;
                entryTradeLog->u.trade.id = id;
                TA_TimestampCopy( &entryTradeLog->u.trade.exitTimestamp,
                                  &newTransaction->timestamp );
                /* Calculate the profit and make the entryPrice
                 * negative if this is a short trade.
                 * Both are multiplied by the quantity being
                 * traded.
                 */
                entryPrice = entryTradeLog->u.entry.entryPrice;
                if( newTransaction->type == TA_LONG_EXIT )
                {
                    entryTradeLog->u.trade.profit = (newTransaction->price-entryPrice)*quantity;
                    CALC_EXCURSION_LONG;
                }
                else
                {
                    entryTradeLog->u.trade.profit = (entryPrice-newTransaction->price)*quantity;
                    entryPrice = -entryPrice;
                    CALC_EXCURSION_SHORT;
                }
                entryTradeLog->u.entry.entryPrice = entryPrice * quantity;

                return TA_SUCCESS; /* Done! */
            }
            else if( entryTradeQuantity < quantity )
            {
                /* This entry have less than the amount of
                 * position that needs to be closed.
                 * Just transform the entry into a trade
                 * and move to the next entry.
                 */
                entryTradeLog->u.trade.quantity = entryTradeQuantity;
                quantity -= entryTradeQuantity;
                entryTradeLog->u.trade.id = id;
                TA_TimestampCopy( &entryTradeLog->u.trade.exitTimestamp,
                                  &newTransaction->timestamp );
                /* Calculate the profit and make the entryPrice
                 * negative if this is a short trade.
                 * Both are multiplied by the quantity being
                 * traded.
                 */
                entryPrice = entryTradeLog->u.trade.entryPrice;
                if( newTransaction->type == TA_LONG_EXIT )
                {
                    entryTradeLog->u.trade.profit = (newTransaction->price-entryPrice)*entryTradeQuantity;
                    CALC_EXCURSION_LONG;
                }
                else
                {
                    entryTradeLog->u.trade.profit = (entryPrice-newTransaction->price)*entryTradeQuantity;
                    entryPrice = -entryPrice;
                    CALC_EXCURSION_SHORT;
                }
                entryTradeLog->u.trade.entryPrice = entryPrice * entryTradeQuantity;

                /* Move to the next entry. If none available, that means there
                 * was more "exit" than "entry" and this is considered an
                 * error.
                 */
                entryTradeLog = TA_ListRemoveHead( entryListToUse );
                if( !entryTradeLog )
                    return TA_ENTRY_TRANSACTION_MISSING;
            }
            else
            {
                /* This entry have more position than what the
                 * exit requires, so the entry must be preserved.
                 * Consequently, a new tradeLog must be allocated.
                 */
                dataLog = TA_AllocatorForDataLog_Alloc( &tradeLogPriv->allocator );
                if( !dataLog )
                    return TA_ALLOC_ERR;

                TA_TimestampCopy( &dataLog->u.trade.entryTimestamp,
                                  &entryTradeLog->u.trade.entryTimestamp );
                TA_TimestampCopy( &dataLog->u.trade.exitTimestamp,
                                  &newTransaction->timestamp );
                dataLog->u.trade.quantity = quantity;
                entryPrice = entryTradeLog->u.trade.entryPrice;
                if( newTransaction->type == TA_LONG_EXIT )
                {
                    dataLog->u.trade.profit = (newTransaction->price-entryPrice)*quantity;
                    CALC_EXCURSION_LONG;
                }
                else
                {
                    dataLog->u.trade.profit = (entryPrice-newTransaction->price)*quantity;
                    entryPrice = -entryPrice;
                    CALC_EXCURSION_SHORT;
                }
                dataLog->u.trade.entryPrice = entryPrice*quantity;
                dataLog->u.trade.id = id;

                /* Adjust the entry and put it back for being process
                 * again later.
                 */
                entryTradeLog->u.trade.quantity += quantity;
                TA_ListNodeAddHead( entryListToUse, &entryTradeLog->u.entry.node, entryTradeLog );
                return TA_SUCCESS; /* Done! */
            }
        }
        break;
    default:
        return TA_INTERNAL_ERROR(121);
    }

    return TA_SUCCESS;
}
示例#8
0
/**** Global functions definitions.   ****/
TA_FileIndexPriv *TA_FileIndexPrivAlloc( TA_Libc *libHandle,
                                         TA_String *initialCategory,
                                         TA_String *initialCategoryCountry,
                                         TA_String *initialCategoryExchange,
                                         TA_String *initialCategoryType )
{
   TA_FileIndexPriv *fileIndexPrivData;
   TA_StringCache *stringCache;

   stringCache = TA_GetGlobalStringCache( libHandle );

   /* Initialize the TA_FileIndexPriv element. */
   fileIndexPrivData = (TA_FileIndexPriv *)TA_Malloc( libHandle, sizeof( TA_FileIndexPriv ) );

   if( !fileIndexPrivData )
      return NULL;

   /* initialize all fields to NULL. */
   memset( fileIndexPrivData, 0, sizeof( TA_FileIndexPriv ) );

   /* Now attempt to allocate all sub-elements. */
   fileIndexPrivData->libHandle = libHandle;

   stringCache = TA_GetGlobalStringCache( libHandle );
   fileIndexPrivData->initialCategoryString         = TA_StringDup( stringCache, initialCategory );
   fileIndexPrivData->initialCategoryCountryString  = TA_StringDup( stringCache, initialCategoryCountry);
   fileIndexPrivData->initialCategoryExchangeString = TA_StringDup( stringCache, initialCategoryExchange );
   fileIndexPrivData->initialCategoryTypeString     = TA_StringDup( stringCache, initialCategoryType );

   if( (fileIndexPrivData->initialCategoryString         == NULL) ||
       (fileIndexPrivData->initialCategoryCountryString  == NULL) ||
       (fileIndexPrivData->initialCategoryExchangeString == NULL) ||
       (fileIndexPrivData->initialCategoryTypeString     == NULL) )
   {
      freeFileIndexPriv( (void *)fileIndexPrivData );
      return NULL;
   }

   fileIndexPrivData->scratchPad = (char *)TA_Malloc( libHandle, TA_SOURCELOCATION_MAX_LENGTH+2 );
   if( !fileIndexPrivData->scratchPad )
   {
      freeFileIndexPriv( (void *)fileIndexPrivData );
      return NULL;
   }

   fileIndexPrivData->listLocationToken = TA_ListAlloc( libHandle );
   if( !fileIndexPrivData->listLocationToken )
   {
      freeFileIndexPriv( (void *)fileIndexPrivData );
      return NULL;
   }

   fileIndexPrivData->listCategory = TA_ListAlloc( libHandle );
   if( !fileIndexPrivData->listCategory )
   {
      freeFileIndexPriv( (void *)fileIndexPrivData );
      return NULL;
   }

   fileIndexPrivData->root = allocTreeNode( libHandle, NULL, NULL );
   if( !fileIndexPrivData->root )
   {
      freeFileIndexPriv( (void *)fileIndexPrivData );
      return NULL;
   }

   fileIndexPrivData->currentNode = fileIndexPrivData->root;

   fileIndexPrivData->wildOneChar = TA_StringAlloc( stringCache, "?" );
   fileIndexPrivData->wildZeroOrMoreChar = TA_StringAlloc( stringCache, "*" );
   fileIndexPrivData->wildOneOrMoreChar = TA_StringAlloc( stringCache, "?*" );

   if( (!fileIndexPrivData->wildOneChar) ||
       (!fileIndexPrivData->wildZeroOrMoreChar) ||
       (!fileIndexPrivData->wildOneOrMoreChar) )
   {
      freeFileIndexPriv( (void *)fileIndexPrivData );
      return NULL;
   }

   return fileIndexPrivData;
}