Пример #1
0
static int isGapAcceptable( TA_Timestamp *lastBarTimestampAdded,
                            TA_Timestamp *lastBarTimestamp )
{
   TA_RetCode retCode;
   unsigned int deltaDay, i;

   /* Verify if that gap in the data is acceptable. This is not
    * a "perfect" algorithm, but the idea is to avoid obvious
    * failure. Small failure might get through, but the consequence
    * won't be worst than a long week-end gap.
    */

   retCode = TA_TimestampDeltaDay( lastBarTimestampAdded, lastBarTimestamp, &deltaDay );
   if( (retCode != TA_SUCCESS) || (deltaDay >= 7) )
   {
      /* A gap of more than 7 days is an error for sure. Or may be the symbol
       * is not being traded anymore? Don't take a chance and return an error.
       */
      return 0;
   }

   /* The gap should not be more than 3 weekdays (after removing special case) */
   retCode = TA_TimestampDeltaWeekday( lastBarTimestampAdded, lastBarTimestamp, &deltaDay );
   if(  retCode != TA_SUCCESS ) 
   {
      return 0;
   }

   /* Handle special cases */

   /* Trading were suspended on many exchange on september 11 2001 to september 14 2001  */
   for( i=11; i <= 14; i++ )
   {
      if( TA_DateWithinRange( 2001,9,i, lastBarTimestampAdded, lastBarTimestamp ) )
         --deltaDay;
   }
      
   
   /* Handling holidays would be better here, any volunteer to implement this? */
   if( deltaDay > 3 )
      return 0;

   return 1; /* The gap is acceptable. */
}
Пример #2
0
/**** Global functions definitions.   ****/
TA_RetCode TA_PMValue( TA_PM *pm,
                       TA_PMValueId valueId,
                       TA_PMGroup grp,
                       TA_Real *value )
{
    TA_PMPriv         *pmPriv;
    TA_RetCode         retCode;
    TA_List           *tradeLogList;
    TA_TradeLogPriv   *tradeLogPriv;
    unsigned int tempInt, tempInt2;
    TA_Real tempReal, tempReal2, tempReal3;

    /* Validate parameters. */
    if( !pm || !value )
        return TA_BAD_PARAM;

    if( (valueId >= TA_PM_NB_VALUEID ) ||
            (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 || (pmPriv->magicNb != TA_PMPRIV_MAGIC_NB) )
        return TA_BAD_OBJECT;

    /* Process ALL the basic calculation if not already done. */
    tradeLogList = &pmPriv->tradeLogList;
    tradeLogPriv = TA_ListAccessHead( tradeLogList );

    if( !(pmPriv->flags & TA_PMVALUECACHE_CALCULATED) )
    {
        initValueCache( &pmPriv->longValueCache  );
        initValueCache( &pmPriv->shortValueCache );
        if( !tradeLogPriv )
            return TA_NO_TRADE_LOG;
        else
        {
            do
            {
                if( !(tradeLogPriv->flags & TA_PMVALUECACHE_CALCULATED) )
                {
                    retCode = processTradeLog_BasicCalculation( &pmPriv->startDate,
                              &pmPriv->endDate,
                              tradeLogPriv );
                }

                mergeValueCache( &pmPriv->longValueCache, &tradeLogPriv->longValueCache );
                mergeValueCache( &pmPriv->shortValueCache, &tradeLogPriv->shortValueCache );
                tradeLogPriv = TA_ListAccessNext( tradeLogList );
            } while( tradeLogPriv );
        }
        pmPriv->flags |= TA_PMVALUECACHE_CALCULATED;
    }

    switch( valueId )
    {
    case TA_PM_TOTAL_NB_OF_TRADE:
        switch( grp )
        {
        case TA_PM_ALL_TRADES:
            tempInt  = pmPriv->shortValueCache.nbWinningTrade;
            tempInt += pmPriv->shortValueCache.nbLosingTrade;
            tempInt += pmPriv->longValueCache.nbWinningTrade;
            tempInt += pmPriv->longValueCache.nbLosingTrade;
            break;
        case TA_PM_LONG_TRADES:
            tempInt  = pmPriv->longValueCache.nbWinningTrade;
            tempInt += pmPriv->longValueCache.nbLosingTrade;
            break;
        case TA_PM_SHORT_TRADES:
            tempInt  = pmPriv->shortValueCache.nbWinningTrade;
            tempInt += pmPriv->shortValueCache.nbLosingTrade;
            break;
        default:
            return TA_BAD_PARAM;
        }
        *value = (TA_Real)tempInt;
        break;

    case TA_PM_NB_WINNING_TRADE:
        switch( grp )
        {
        case TA_PM_ALL_TRADES:
            tempInt  = pmPriv->shortValueCache.nbWinningTrade;
            tempInt += pmPriv->longValueCache.nbWinningTrade;
            break;
        case TA_PM_LONG_TRADES:
            tempInt  = pmPriv->longValueCache.nbWinningTrade;
            break;
        case TA_PM_SHORT_TRADES:
            tempInt  = pmPriv->shortValueCache.nbWinningTrade;
            break;
        default:
            return TA_BAD_PARAM;
        }
        *value = (TA_Real)tempInt;
        break;

    case TA_PM_NB_LOSING_TRADE:
        switch( grp )
        {
        case TA_PM_ALL_TRADES:
            tempInt  = pmPriv->shortValueCache.nbLosingTrade;
            tempInt += pmPriv->longValueCache.nbLosingTrade;
            break;
        case TA_PM_LONG_TRADES:
            tempInt  = pmPriv->longValueCache.nbLosingTrade;
            break;
        case TA_PM_SHORT_TRADES:
            tempInt  = pmPriv->shortValueCache.nbLosingTrade;
            break;
        default:
            return TA_BAD_PARAM;
        }
        *value = (TA_Real)tempInt;
        break;

    case TA_PM_TOTAL_NET_PROFIT:
        switch( grp )
        {
        case TA_PM_ALL_TRADES:
            tempInt  = pmPriv->shortValueCache.nbWinningTrade;
            tempInt += pmPriv->shortValueCache.nbLosingTrade;
            tempInt += pmPriv->longValueCache.nbWinningTrade;
            tempInt += pmPriv->longValueCache.nbLosingTrade;
            tempReal  = pmPriv->shortValueCache.sumProfit;
            tempReal += pmPriv->shortValueCache.sumLoss; /* loss are negative */
            tempReal += pmPriv->longValueCache.sumProfit;
            tempReal += pmPriv->longValueCache.sumLoss;
            break;
        case TA_PM_LONG_TRADES:
            tempInt  = pmPriv->longValueCache.nbWinningTrade;
            tempInt += pmPriv->longValueCache.nbLosingTrade;
            tempReal  = pmPriv->longValueCache.sumProfit;
            tempReal += pmPriv->longValueCache.sumLoss;
            break;
        case TA_PM_SHORT_TRADES:
            tempInt  = pmPriv->shortValueCache.nbWinningTrade;
            tempInt += pmPriv->shortValueCache.nbLosingTrade;
            tempReal  = pmPriv->shortValueCache.sumProfit;
            tempReal += pmPriv->shortValueCache.sumLoss;
            break;
        default:
            return TA_BAD_PARAM;
        }
        if( tempInt == 0 )
        {
            *value = 0.0;
            return TA_VALUE_NOT_APPLICABLE;
        }
        else
            *value = tempReal;
        break;

    case TA_PM_STARTING_CAPITAL:
        *value = pmPriv->initialCapital;
        switch( grp )
        {
        case TA_PM_ALL_TRADES:
            break;
        case TA_PM_LONG_TRADES:
        case TA_PM_SHORT_TRADES:
            return TA_VALUE_NOT_APPLICABLE;
        default:
            return TA_BAD_PARAM;
        }
        break;

    case TA_PM_ENDING_CAPITAL:
        tempReal  = pmPriv->shortValueCache.sumProfit;
        tempReal += pmPriv->shortValueCache.sumLoss; /* loss are negative */
        tempReal += pmPriv->longValueCache.sumProfit;
        tempReal += pmPriv->longValueCache.sumLoss;
        *value = pmPriv->initialCapital + tempReal;
        switch( grp )
        {
        case TA_PM_ALL_TRADES:
            break;
        case TA_PM_LONG_TRADES:
        case TA_PM_SHORT_TRADES:
            return TA_VALUE_NOT_APPLICABLE;
        default:
            return TA_BAD_PARAM;
        }
        break;

    case TA_PM_GROSS_PROFIT:
        switch( grp )
        {
        case TA_PM_ALL_TRADES:
            tempInt   = pmPriv->shortValueCache.nbWinningTrade;
            tempInt  += pmPriv->longValueCache.nbWinningTrade;
            tempReal  = pmPriv->shortValueCache.sumProfit;
            tempReal += pmPriv->longValueCache.sumProfit;
            break;
        case TA_PM_LONG_TRADES:
            tempInt  = pmPriv->longValueCache.nbWinningTrade;
            tempReal = pmPriv->longValueCache.sumProfit;
            break;
        case TA_PM_SHORT_TRADES:
            tempInt  = pmPriv->shortValueCache.nbWinningTrade;
            tempReal = pmPriv->shortValueCache.sumProfit;
            break;
        default:
            return TA_BAD_PARAM;
        }

        if( tempInt == 0 )
        {
            *value = 0.0;
            return TA_VALUE_NOT_APPLICABLE;
        }
        else
            *value = tempReal;
        break;

    case TA_PM_GROSS_LOSS:
        /* loss are negative */
        switch( grp )
        {
        case TA_PM_ALL_TRADES:
            tempInt   = pmPriv->shortValueCache.nbLosingTrade;
            tempInt  += pmPriv->longValueCache.nbLosingTrade;
            tempReal  = pmPriv->shortValueCache.sumLoss;
            tempReal += pmPriv->longValueCache.sumLoss;
            break;
        case TA_PM_LONG_TRADES:
            tempInt  = pmPriv->longValueCache.nbLosingTrade;
            tempReal = pmPriv->longValueCache.sumLoss;
            break;
        case TA_PM_SHORT_TRADES:
            tempInt  = pmPriv->shortValueCache.nbLosingTrade;
            tempReal = pmPriv->shortValueCache.sumLoss;
            break;
        default:
            return TA_BAD_PARAM;
        }
        if( tempInt == 0 )
        {
            *value = 0.0;
            return TA_VALUE_NOT_APPLICABLE;
        }
        else
            *value = tempReal;
        break;

    case TA_PM_PROFIT_FACTOR:
        switch( grp )
        {
        case TA_PM_ALL_TRADES:
            tempInt  = pmPriv->shortValueCache.nbWinningTrade;
            tempInt += pmPriv->shortValueCache.nbLosingTrade;
            tempInt += pmPriv->longValueCache.nbWinningTrade;
            tempInt += pmPriv->longValueCache.nbLosingTrade;
            tempReal   = pmPriv->shortValueCache.sumProfit;
            tempReal  += pmPriv->longValueCache.sumProfit;
            tempReal2  = pmPriv->shortValueCache.sumLoss;
            tempReal2 += pmPriv->longValueCache.sumLoss;
            break;
        case TA_PM_LONG_TRADES:
            tempInt  = pmPriv->longValueCache.nbWinningTrade;
            tempInt += pmPriv->longValueCache.nbLosingTrade;
            tempReal   = pmPriv->longValueCache.sumProfit;
            tempReal2  = pmPriv->longValueCache.sumLoss;
            break;
        case TA_PM_SHORT_TRADES:
            tempInt  = pmPriv->shortValueCache.nbWinningTrade;
            tempInt += pmPriv->shortValueCache.nbLosingTrade;
            tempReal   = pmPriv->shortValueCache.sumProfit;
            tempReal2  = pmPriv->shortValueCache.sumLoss;
            break;
        default:
            return TA_BAD_PARAM;
        }
        if( (tempReal2 >= 0.0) || (tempReal <= 0.0) )
        {
            *value = 0.0;
            return TA_VALUE_NOT_APPLICABLE;
        }
        else
            *value = tempReal/(-tempReal2);
        break;

    case TA_PM_AVG_PROFIT:
        switch( grp )
        {
        case TA_PM_ALL_TRADES:
            tempInt   = pmPriv->shortValueCache.nbWinningTrade;
            tempInt  += pmPriv->longValueCache.nbWinningTrade;
            tempReal  = pmPriv->shortValueCache.sumProfit;
            tempReal += pmPriv->longValueCache.sumProfit;
            break;
        case TA_PM_LONG_TRADES:
            tempInt   = pmPriv->longValueCache.nbWinningTrade;
            tempReal  = pmPriv->longValueCache.sumProfit;
            break;
        case TA_PM_SHORT_TRADES:
            tempInt   = pmPriv->shortValueCache.nbWinningTrade;
            tempReal  = pmPriv->shortValueCache.sumProfit;
            break;
        default:
            return TA_BAD_PARAM;
        }
        if( tempInt <= 0 )
        {
            *value = 0.0;
            return TA_VALUE_NOT_APPLICABLE;
        }
        else
            *value = tempReal/((TA_Real)tempInt);
        break;

    case TA_PM_PERCENT_PROFITABLE:

        switch( grp )
        {
        case TA_PM_ALL_TRADES:
            tempInt2  = pmPriv->shortValueCache.nbWinningTrade;
            tempInt2 += pmPriv->longValueCache.nbWinningTrade;
            tempInt   = pmPriv->shortValueCache.nbLosingTrade;
            tempInt  += pmPriv->longValueCache.nbLosingTrade;
            break;
        case TA_PM_LONG_TRADES:
            tempInt2 = pmPriv->longValueCache.nbWinningTrade;
            tempInt  = pmPriv->longValueCache.nbLosingTrade;
            break;
        case TA_PM_SHORT_TRADES:
            tempInt2 = pmPriv->shortValueCache.nbWinningTrade;
            tempInt  = pmPriv->shortValueCache.nbLosingTrade;
            break;
        default:
            return TA_BAD_PARAM;
        }
        if( tempInt == 0 )
        {
            /* No losing trades. */
            if( tempInt2 == 0 )
            {
                /* No trades at all */
                *value = (TA_Real)0.0;
                return TA_VALUE_NOT_APPLICABLE;
            }
            /* All trades are winning trades. */
            *value = (TA_Real)100.0;
        }
        else
        {
            tempInt += tempInt2;
            *value = ((TA_Real)tempInt2)/((TA_Real)tempInt)*100.0;
        }
        break;

    case TA_PM_AVG_PROFIT_PERCENT:
        switch( grp )
        {
        case TA_PM_ALL_TRADES:
            tempInt   = pmPriv->shortValueCache.nbWinningTrade;
            tempInt  += pmPriv->longValueCache.nbWinningTrade;
            tempReal  = pmPriv->shortValueCache.sumProfitPercent;
            tempReal += pmPriv->longValueCache.sumProfitPercent;
            break;
        case TA_PM_LONG_TRADES:
            tempInt   = pmPriv->longValueCache.nbWinningTrade;
            tempReal  = pmPriv->longValueCache.sumProfitPercent;
            break;
        case TA_PM_SHORT_TRADES:
            tempInt   = pmPriv->shortValueCache.nbWinningTrade;
            tempReal  = pmPriv->shortValueCache.sumProfitPercent;
            break;
        default:
            return TA_BAD_PARAM;
        }
        if( tempInt <= 0 )
        {
            *value = 0.0;
            return TA_VALUE_NOT_APPLICABLE;
        }
        else
            *value = (tempReal*100.0)/((TA_Real)tempInt);
        break;

    case TA_PM_AVG_LOSS:
        switch( grp )
        {
        case TA_PM_ALL_TRADES:
            tempInt   = pmPriv->shortValueCache.nbLosingTrade;
            tempInt  += pmPriv->longValueCache.nbLosingTrade;
            tempReal  = pmPriv->shortValueCache.sumLoss;
            tempReal += pmPriv->longValueCache.sumLoss;
            break;
        case TA_PM_LONG_TRADES:
            tempInt   = pmPriv->longValueCache.nbLosingTrade;
            tempReal  = pmPriv->longValueCache.sumLoss;
            break;
        case TA_PM_SHORT_TRADES:
            tempInt   = pmPriv->shortValueCache.nbLosingTrade;
            tempReal  = pmPriv->shortValueCache.sumLoss;
            break;
        default:
            return TA_BAD_PARAM;
        }
        if( tempInt <= 0 )
        {
            *value = 0.0;
            return TA_VALUE_NOT_APPLICABLE;
        }
        else
            *value = tempReal/((TA_Real)tempInt);
        break;

    case TA_PM_AVG_LOSS_PERCENT:
        switch( grp )
        {
        case TA_PM_ALL_TRADES:
            tempInt   = pmPriv->shortValueCache.nbLosingTrade;
            tempInt  += pmPriv->longValueCache.nbLosingTrade;
            tempReal  = pmPriv->shortValueCache.sumLossPercent;
            tempReal += pmPriv->longValueCache.sumLossPercent;
            break;
        case TA_PM_LONG_TRADES:
            tempInt   = pmPriv->longValueCache.nbLosingTrade;
            tempReal  = pmPriv->longValueCache.sumLossPercent;
            break;
        case TA_PM_SHORT_TRADES:
            tempInt   = pmPriv->shortValueCache.nbLosingTrade;
            tempReal  = pmPriv->shortValueCache.sumLossPercent;
            break;
        default:
            return TA_BAD_PARAM;
        }
        if( tempInt <= 0 )
        {
            *value = 0.0;
            return TA_VALUE_NOT_APPLICABLE;
        }
        else
            *value = (tempReal*100.0)/((TA_Real)tempInt);
        break;

    case TA_PM_LARGEST_PROFIT:
        switch( grp )
        {
        case TA_PM_ALL_TRADES:
            tempReal = MAX( pmPriv->shortValueCache.largestProfit,
                            pmPriv->longValueCache.largestProfit );
            break;
        case TA_PM_LONG_TRADES:
            tempReal = pmPriv->longValueCache.largestProfit;
            break;
        case TA_PM_SHORT_TRADES:
            tempReal = pmPriv->shortValueCache.largestProfit;
            break;
        default:
            return TA_BAD_PARAM;
        }
        if( tempReal == TA_REAL_MIN )
        {
            *value = 0.0;
            return TA_VALUE_NOT_APPLICABLE;
        }
        else
            *value = tempReal;
        break;

    case TA_PM_LARGEST_LOSS:
        switch( grp )
        {
        case TA_PM_ALL_TRADES:
            tempReal = MIN( pmPriv->shortValueCache.largestLoss,
                            pmPriv->longValueCache.largestLoss );
            break;
        case TA_PM_LONG_TRADES:
            tempReal = pmPriv->longValueCache.largestLoss;
            break;
        case TA_PM_SHORT_TRADES:
            tempReal = pmPriv->shortValueCache.largestLoss;
            break;
        default:
            return TA_BAD_PARAM;
        }

        if( tempReal == TA_REAL_MAX )
        {
            *value = 0.0;
            return TA_VALUE_NOT_APPLICABLE;
        }
        else
            *value = tempReal;
        break;

    case TA_PM_LARGEST_PROFIT_PERCENT:
        switch( grp )
        {
        case TA_PM_ALL_TRADES:
            tempReal = MAX( pmPriv->shortValueCache.largestProfitPercent,
                            pmPriv->longValueCache.largestProfitPercent );
            break;
        case TA_PM_LONG_TRADES:
            tempReal = pmPriv->longValueCache.largestProfitPercent;
            break;
        case TA_PM_SHORT_TRADES:
            tempReal = pmPriv->shortValueCache.largestProfitPercent;
            break;
        default:
            return TA_BAD_PARAM;
        }
        if( tempReal == TA_REAL_MIN )
        {
            *value = 0.0;
            return TA_VALUE_NOT_APPLICABLE;
        }
        else
            *value = tempReal*100.0;
        break;

    case TA_PM_LARGEST_LOSS_PERCENT:
        switch( grp )
        {
        case TA_PM_ALL_TRADES:
            tempReal = MIN( pmPriv->shortValueCache.largestLossPercent,
                            pmPriv->longValueCache.largestLossPercent );
            break;
        case TA_PM_LONG_TRADES:
            tempReal = pmPriv->longValueCache.largestLossPercent;
            break;
        case TA_PM_SHORT_TRADES:
            tempReal = pmPriv->shortValueCache.largestLossPercent;
            break;
        default:
            return TA_BAD_PARAM;
        }

        if( tempReal == TA_REAL_MAX )
        {
            *value = 0.0;
            return TA_VALUE_NOT_APPLICABLE;
        }
        else
            *value = tempReal*100.0;
        break;

    case TA_PM_RATE_OF_RETURN:
        /* One-period rate of return: (profit / initialCapital) */
        tempReal3 = pmPriv->initialCapital;
        if( tempReal3 <= 0.0 )
        {
            *value = 0.0;
            return TA_BAD_STARTING_CAPITAL;
        }

        switch( grp )
        {
        case TA_PM_ALL_TRADES:
            tempReal   = pmPriv->shortValueCache.sumProfit;
            tempReal  += pmPriv->longValueCache.sumProfit;
            tempReal2  = pmPriv->shortValueCache.sumLoss; /* loss are negative */
            tempReal2 += pmPriv->longValueCache.sumLoss;
            break;
        case TA_PM_LONG_TRADES:
            tempReal  = pmPriv->longValueCache.sumProfit;
            tempReal2 = pmPriv->longValueCache.sumLoss;
            break;
        case TA_PM_SHORT_TRADES:
            tempReal  = pmPriv->shortValueCache.sumProfit;
            tempReal2 = pmPriv->shortValueCache.sumLoss;
            break;
        default:
            return TA_BAD_PARAM;
        }
        if( (tempReal <= 0.0) && (tempReal2 >= 0.0) )
        {
            *value = 0.0;
            return TA_VALUE_NOT_APPLICABLE;
        }
        else
            *value = ((tempReal+tempReal2)/tempReal3)*100.0;
        break;

    case TA_PM_ANNUALIZED_RETURN:
        /* Annualized rate of return on a simple-interest basis:
         *
         *   (Ending Value - Starting Value)     365
         *   -------------------------------  *  ---
         *           Starting Value               n
         *
         * Where 'n' is the number of day between the end and
         * start date when the TA_PM was created.
         */
        tempReal3 = pmPriv->initialCapital;
        if( tempReal3 <= 0.0 )
        {
            *value = 0.0;
            return TA_BAD_STARTING_CAPITAL;
        }

        switch( grp )
        {
        case TA_PM_ALL_TRADES:
            tempReal   = pmPriv->shortValueCache.sumProfit;
            tempReal  += pmPriv->longValueCache.sumProfit;
            tempReal2  = pmPriv->shortValueCache.sumLoss; /* loss are negative */
            tempReal2 += pmPriv->longValueCache.sumLoss;
            break;
        case TA_PM_LONG_TRADES:
            tempReal  = pmPriv->longValueCache.sumProfit;
            tempReal2 = pmPriv->longValueCache.sumLoss;
            break;
        case TA_PM_SHORT_TRADES:
            tempReal  = pmPriv->shortValueCache.sumProfit;
            tempReal2 = pmPriv->shortValueCache.sumLoss;
            break;
        default:
            return TA_BAD_PARAM;
        }

        retCode = TA_TimestampDeltaDay( &pmPriv->startDate,
                                        &pmPriv->endDate,
                                        &tempInt );
        if( retCode != TA_SUCCESS )
            return retCode;

        if( ((tempReal <= 0.0) && (tempReal2 >= 0.0)) || (tempInt == 0) )
        {
            *value = 0.0;
            return TA_VALUE_NOT_APPLICABLE;
        }
        else
        {
            tempReal += tempReal2;
            *value = (tempReal/tempReal3)*(36500.0/tempInt);
        }
        break;

    case TA_PM_ANNUALIZED_COMPOUNDED_RETURN:
        /* Annualized compounded rate of return:
         *
         * ((Ending Value / Starting Value)^(1/y)) - 1
         *
         * Where 'y' is the number of year between the end
         * and start date when the TA_PM was created.
         */
        tempReal3 = pmPriv->initialCapital;
        if( tempReal3 <= 0.0 )
        {
            *value = 0.0;
            return TA_BAD_STARTING_CAPITAL;
        }

        switch( grp )
        {
        case TA_PM_ALL_TRADES:
            tempReal   = pmPriv->shortValueCache.sumProfit;
            tempReal  += pmPriv->longValueCache.sumProfit;
            tempReal2  = pmPriv->shortValueCache.sumLoss; /* loss are negative */
            tempReal2 += pmPriv->longValueCache.sumLoss;
            break;
        case TA_PM_LONG_TRADES:
            tempReal  = pmPriv->longValueCache.sumProfit;
            tempReal2 = pmPriv->longValueCache.sumLoss;
            break;
        case TA_PM_SHORT_TRADES:
            tempReal  = pmPriv->shortValueCache.sumProfit;
            tempReal2 = pmPriv->shortValueCache.sumLoss;
            break;
        default:
            return TA_BAD_PARAM;
        }

        retCode = TA_TimestampDeltaDay( &pmPriv->startDate,
                                        &pmPriv->endDate,
                                        &tempInt );
        if( retCode != TA_SUCCESS )
            return retCode;

        if( ((tempReal <= 0.0) && (tempReal2 >= 0.0)) || (tempInt == 0) )
        {
            *value = 0.0;
            return TA_VALUE_NOT_APPLICABLE;
        }
        else
        {
            tempReal += (tempReal2+tempReal3);
            *value = (pow(tempReal/tempReal3,1.0/(tempInt/365.0)) - 1.0)*100.0;
        }
        break;

    default:
        return TA_INVALID_VALUE_ID;
    }

    return TA_SUCCESS;
}
Пример #3
0
TA_RetCode TA_EstimateAllocInit( const TA_Timestamp *start,
                                 const TA_Timestamp *end,
                                 TA_Period period,
                                 unsigned int minimumSize,
                                 unsigned int maximumSize,
                                 TA_EstimateInfo *estimationInfo,
                                 unsigned int *nbElementToAllocate )
{
   unsigned int nbElement;

   #if 0
      /* Force extrems value for testing. */
      *nbElementToAllocate = 1;
      return TA_SUCCESS;
   #endif

   nbElement = minimumSize; /* Default */

   if( start && end )
   {
      switch( period )
      {
      case TA_DAILY:
         TA_TimestampDeltaDay( start, end, &nbElement );
         break;
      case TA_WEEKLY:
         TA_TimestampDeltaWeek( start, end, &nbElement );
         break;
      case TA_MONTHLY:
         TA_TimestampDeltaMonth( start, end, &nbElement );
         break;
      case TA_QUARTERLY:
         TA_TimestampDeltaQuarter( start, end, &nbElement );
         break;
      case TA_YEARLY:
         TA_TimestampDeltaYear( start, end, &nbElement );
         break;
      default:
         if( (period >= TA_1SEC) && (period <= TA_1HOUR) )
         {
            /* Estimate the number of day */
            if( (TA_GetDay  (start) != TA_GetDay  (end)) ||
                (TA_GetMonth(start) != TA_GetMonth(end)) ||
                (TA_GetYear (start) != TA_GetYear (end)) )
            {
               /* Estimate assuming market is open for 8 hours per day 
                * (it does not hurt to slightly under or over estimate)
                */
               TA_TimestampDeltaDay( start, end, &nbElement );
               nbElement *= (8*60*60);
               nbElement /= period;
            }
            else
            {
               nbElement = (8*60*60);
               nbElement /= period;
            }
         }
         break;
      }
      nbElement += 2;
   }

   /* Make the estimation fits within the max/min provided. */
   estimationInfo->maximumSize = maximumSize;
   estimationInfo->minimumSize = minimumSize;
   if( nbElement > maximumSize )
      nbElement = maximumSize;

   if( nbElement < minimumSize )
      nbElement = minimumSize;

   *nbElementToAllocate = nbElement;

   return TA_SUCCESS;
}