Пример #1
0
TA_RetCode TA_PMAlloc( const TA_Timestamp  *startDate,
                       const TA_Timestamp  *endDate,
                       TA_Real              initialCapital,
                       TA_PM              **allocatedPM )
{
    TA_PM     *pm;
    TA_PMPriv *pmPriv;
    unsigned int delta;
    TA_RetCode retCode;

    /* Check all the parameters. */
    if( !allocatedPM )
        return TA_BAD_PARAM;
    *allocatedPM = NULL;

    if( !startDate || !endDate )
        return TA_BAD_PARAM;

    if( TA_TimestampValidate( startDate ) )
        return TA_BAD_START_DATE;

    if( TA_TimestampValidate( endDate ) || TA_TimestampGreater( startDate, endDate ) )
        return TA_BAD_END_DATE;

    /* To keep things simple, it is assumed that
     * the requested date range contains at least
     * one weekday.
     */
    retCode = TA_TimestampDeltaWeekday( startDate, endDate, &delta );
    if( retCode != TA_SUCCESS )
        return retCode;
    if( delta <= 0 )
        return TA_NO_WEEKDAY_IN_DATE_RANGE;

    /* Allocate the public and private structure. */
    pm = TA_Malloc( sizeof( TA_PM ) + sizeof( TA_PMPriv ) );
    if( !pm )
        return TA_ALLOC_ERR;

    memset( pm, 0, sizeof( TA_PM ) + sizeof( TA_PMPriv ) );
    pmPriv = (TA_PMPriv *)(((char *)pm)+sizeof(TA_PM));
    pmPriv->magicNb        = TA_PMPRIV_MAGIC_NB;
    pmPriv->initialCapital = initialCapital;
    pm->hiddenData         = pmPriv;

    TA_ListInit(  &pmPriv->tradeLogList );

    /* TA_PMFree can be safely called from this point. */

    TA_TimestampCopy( &pmPriv->endDate, endDate );
    TA_TimestampCopy( &pmPriv->startDate, startDate );

    /* Success, return the allocated data to the caller. */
    *allocatedPM = pm;

    return TA_SUCCESS;
}
Пример #2
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. */
}
Пример #3
0
/* Period transformation is highly dependable on
 * the function evaluating the 'delta' between
 * two timestamp, so this is verified here.
 */
static ErrorNumber testTimestampDelta( void )
{
   TA_RetCode retCode;
   unsigned int i, delta; 

   /* !!! A lot more of testing could be added !!! */

   /* Test weekday delta. */
   TA_SetDate( 2002, 12, 29, &sundayTS );
   TA_SetDate( 2002, 12, 30, &mondayTS );
   TA_SetDate( 2002, 12, 31, &tuesdayTS );
   TA_SetDate( 2003,  1,  1, &wednesdayTS );
   TA_SetDate( 2003,  1,  2, &thursdayTS );
   TA_SetDate( 2003,  1,  3, &fridayTS );
   TA_SetDate( 2003,  1,  4, &saturdayTS );

   TA_SetDate( 2003,  1,  5, &sunday2TS );
   TA_SetDate( 2003,  1,  6, &monday2TS );
   TA_SetDate( 2003,  1,  7, &tuesday2TS );
   TA_SetDate( 2003,  1,  8, &wednesday2TS );
   TA_SetDate( 2003,  1,  9, &thursday2TS );
   TA_SetDate( 2003,  1, 10, &friday2TS );
   TA_SetDate( 2003,  1, 11, &saturday2TS );

   for( i=0; i < NB_WEEKDAY_CHECK_TO_DO; i++ )
   {
      retCode = TA_TimestampDeltaWeekday( toCheck[i].start,
                                          toCheck[i].end,                                          
                                          &delta );
      if( retCode != TA_SUCCESS )
      {
         printf( "Failed: Weekday delta test #%d\n", i );
         return TA_PERIOD_DELTA_WEEKDAY_FAILED;
      }

      if( delta != toCheck[i].expectedDelta )
      {
         printf( "Failed: Expected delta != delta (%d!=%d) for test #%d\n", toCheck[i].expectedDelta, delta, i );
         return TA_PERIOD_DELTA_WEEKDAY_FAILED_1;
      }
   }

   return TA_TEST_PASS; /* Success. */
}
Пример #4
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;
}
Пример #5
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;
}