Ejemplo n.º 1
0
/* This function is suppose to fill the buffer
 * with values going from 0 to 'size'.
 * The filling is done using the CIRCBUF macros.
 */
static TA_RetCode circBufferFillFrom0ToSize( int size, int *buffer )
{
   CIRCBUF_PROLOG(MyBuf,int,4);
   int i, value;
   int outIdx;

   CIRCBUF_CONSTRUCT(MyBuf,int,size);

   outIdx = 0;

   // 1st Loop: Fill MyBuf with initial values
   //           (must be done).
   value = 0;
   for( i=0; i < size; i++ )
   {
      MyBuf[MyBuf_Idx] = value++;
      CIRCBUF_NEXT(MyBuf);
   }

   // 2nd Loop: Get and Add subsequent values
   //           in MyBuf (optional)
   for( i=0; i < 3; i++ )
   {
      buffer[outIdx++] = MyBuf[MyBuf_Idx];
      MyBuf[MyBuf_Idx] = value++;
      CIRCBUF_NEXT(MyBuf);
   }

   // 3rd Loop: Empty MyBuf (optional)
   for( i=0; i < size; i++ )
   {
      buffer[outIdx++] = MyBuf[MyBuf_Idx];
      CIRCBUF_NEXT(MyBuf);
   }

   CIRCBUF_DESTROY(MyBuf);

   return TA_SUCCESS;
}
Ejemplo n.º 2
0
TA_RetCode TA_MFI( TA_Integer    startIdx,
                   TA_Integer    endIdx,
                   const TA_Real inHigh_0[],
                   const TA_Real inLow_0[],
                   const TA_Real inClose_0[],
                   const TA_Integer inVolume_0[],
                   TA_Integer    optInTimePeriod_0, /* From 2 to TA_INTEGER_MAX */
                   TA_Integer   *outBegIdx,
                   TA_Integer   *outNbElement,
                   TA_Real       outReal_0[] )
/**** END GENCODE SECTION 2 - DO NOT DELETE THIS LINE ****/
{
	/* insert local variable here */
   TA_Real posSumMF, negSumMF, prevValue;
   TA_Real tempValue1, tempValue2;
   int lookbackTotal, outIdx, i, today;

   CIRCBUF_PROLOG( mflow, MoneyFlow, 50 ); /* Id, Type, Static Size */
   
/**** START GENCODE SECTION 3 - DO NOT DELETE THIS LINE ****/

#ifndef TA_FUNC_NO_RANGE_CHECK

   /* Validate the requested output range. */
   if( startIdx < 0 )
      return TA_OUT_OF_RANGE_START_INDEX;
   if( (endIdx < 0) || (endIdx < startIdx))
      return TA_OUT_OF_RANGE_END_INDEX;

   /* Validate the parameters. */
   /* Verify required price component. */
   if(!inHigh_0||!inLow_0||!inClose_0||!inVolume_0)
      return TA_BAD_PARAM;

   /* min/max are checked for optInTimePeriod_0. */
   if( (TA_Integer)optInTimePeriod_0 == TA_INTEGER_DEFAULT )
      optInTimePeriod_0 = 14;
   else if( ((TA_Integer)optInTimePeriod_0 < 2) || ((TA_Integer)optInTimePeriod_0 > 2147483647) )
      return TA_BAD_PARAM;

   if( outReal_0 == NULL )
      return TA_BAD_PARAM;

#endif /* TA_FUNC_NO_RANGE_CHECK */

/**** END GENCODE SECTION 3 - DO NOT DELETE THIS LINE ****/

   /* Insert TA function code here. */

   CIRCBUF_CONSTRUCT( mflow, MoneyFlow, optInTimePeriod_0 );

   *outBegIdx    = 0;
   *outNbElement = 0;
   
   /* Adjust startIdx to account for the lookback period. */
   lookbackTotal = optInTimePeriod_0 + TA_Globals.unstablePeriod[TA_FUNC_UNST_MFI];

   if( startIdx < lookbackTotal )
      startIdx = lookbackTotal;

   /* Make sure there is still something to evaluate. */
   if( startIdx > endIdx )
   {
      CIRCBUF_DESTROY(mflow);
      return TA_SUCCESS;
   }

   outIdx = 0; /* Index into the output. */

   /* Accumulate the positive and negative money flow
    * among the initial period.
    */
   today = startIdx-lookbackTotal;
   prevValue = (inHigh_0[today]+inLow_0[today]+inClose_0[today])/3.0;

   posSumMF = 0.0;
   negSumMF = 0.0;
   today++;
   for( i=optInTimePeriod_0; i > 0; i-- )
   {
      tempValue1 = (inHigh_0[today]+inLow_0[today]+inClose_0[today])/3.0;
      tempValue2 = tempValue1 - prevValue;
      prevValue  = tempValue1;
      tempValue1 *= inVolume_0[today++];
      if( tempValue2 < 0 )
      {
         mflow[mflow_Idx].negative = tempValue1;
         negSumMF += tempValue1;
         mflow[mflow_Idx].positive = 0.0;
      }
      else
      {
         mflow[mflow_Idx].positive = tempValue1;
         posSumMF += tempValue1;
         mflow[mflow_Idx].negative = 0.0;
      }

      CIRCBUF_NEXT(mflow);
   }
   
   /* The following two equations are equivalent:
    *    MFI = 100 - (100 / 1 + (posSumMF/negSumMF))
    *    MFI = 100 * (posSumMF/(posSumMF+negSumMF))
    * The second equation is used here for speed optimization.
    */
   if( today > startIdx )
      outReal_0[outIdx++] = 100.0*(posSumMF/(posSumMF+negSumMF));
   else
   {
      /* Skip the unstable period. Do the processing 
       * but do not write it in the output.
       */   
      while( today < startIdx )
      {
         posSumMF -= mflow[mflow_Idx].positive;
         negSumMF -= mflow[mflow_Idx].negative;

         tempValue1 = (inHigh_0[today]+inLow_0[today]+inClose_0[today])/3.0;
         tempValue2 = tempValue1 - prevValue;
         prevValue  = tempValue1;
         tempValue1 *= inVolume_0[today++];
         if( tempValue2 < 0 )
         {
            mflow[mflow_Idx].negative = tempValue1;
            negSumMF += tempValue1;
            mflow[mflow_Idx].positive = 0.0;
         }
         else
         {
            mflow[mflow_Idx].positive = tempValue1;
            posSumMF += tempValue1;
            mflow[mflow_Idx].negative = 0.0;
         }

         CIRCBUF_NEXT(mflow);
      }
   }

   /* Unstable period skipped... now continue
    * processing if needed.
    */
   while( today <= endIdx )
   {
      posSumMF -= mflow[mflow_Idx].positive;
      negSumMF -= mflow[mflow_Idx].negative;

      tempValue1 = (inHigh_0[today]+inLow_0[today]+inClose_0[today])/3.0;
      tempValue2 = tempValue1 - prevValue;
      prevValue  = tempValue1;
      tempValue1 *= inVolume_0[today++];
      if( tempValue2 < 0 )
      {
         mflow[mflow_Idx].negative = tempValue1;
         negSumMF += tempValue1;
         mflow[mflow_Idx].positive = 0.0;
      }
      else
      {
         mflow[mflow_Idx].positive = tempValue1;
         posSumMF += tempValue1;
         mflow[mflow_Idx].negative = 0.0;
      }

      outReal_0[outIdx++] = 100.0*(posSumMF/(posSumMF+negSumMF));

      CIRCBUF_NEXT(mflow);
   }

   CIRCBUF_DESTROY(mflow);

   *outBegIdx = startIdx;
   *outNbElement = outIdx;

   return TA_SUCCESS;
}