⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test_stoch.c

📁 股票主要技术指标源码
💻 C
📖 第 1 页 / 共 2 页
字号:
   /* Set the unstable period requested for that test. */   switch( test->optInMAType_1 )   {   case TA_MAType_EMA:      retCode = TA_SetUnstablePeriod( TA_FUNC_UNST_EMA, test->unstablePeriod );      if( retCode != TA_SUCCESS )         return TA_TEST_TFRR_SETUNSTABLE_PERIOD_FAIL;      break;   default:      /* No unstable period for other methods. */      break;   }   /* Make a simple first call. */   switch( test->testId )   {   case TEST_STOCH:      retCode = TA_STOCH( test->startIdx,                          test->endIdx,                          gBuffer[0].in,                          gBuffer[1].in,                          gBuffer[2].in,                          test->optInPeriod_0,                          test->optInPeriod_1,                          (TA_MAType)test->optInMAType_1,                          test->optInPeriod_2,                          (TA_MAType)test->optInMAType_2,                          &outBegIdx, &outNbElement,                          gBuffer[0].out0,                           gBuffer[0].out1 );      break;   case TEST_STOCHF:      retCode = TA_STOCHF( test->startIdx,                           test->endIdx,                           gBuffer[0].in,                           gBuffer[1].in,                           gBuffer[2].in,                           test->optInPeriod_0,                           test->optInPeriod_1,                           (TA_MAType)test->optInMAType_1,                           &outBegIdx, &outNbElement,                           gBuffer[0].out0,                            gBuffer[0].out1 );      break;   case TEST_STOCHRSI:      retCode = TA_STOCHRSI( test->startIdx,                             test->endIdx,                             gBuffer[2].in,                             test->optInPeriod_0,                             test->optInPeriod_1,                             test->optInPeriod_2,                             (TA_MAType)test->optInMAType_2,                             &outBegIdx, &outNbElement,                             gBuffer[0].out0,                              gBuffer[0].out1 );      break;   }                          errNb = checkDataSame( gBuffer[0].in, history->high,history->nbBars );   if( errNb != TA_TEST_PASS )      return errNb;   errNb = checkDataSame( gBuffer[1].in, history->low, history->nbBars );   if( errNb != TA_TEST_PASS )      return errNb;   errNb = checkDataSame( gBuffer[2].in, history->close,history->nbBars );   if( errNb != TA_TEST_PASS )      return errNb;   CHECK_EXPECTED_VALUE( gBuffer[0].out0, 0 );   CHECK_EXPECTED_VALUE( gBuffer[0].out1, 1 );   outBegIdx = outNbElement = 0;   if( test->testId == TEST_STOCH )   {      /* Call a local non-optimized version of the function.       * This way, we make sure that the currently speed optimized       * version in TA-Lib is not broken.       */      retCode = referenceStoch(                          test->startIdx,                          test->endIdx,                          gBuffer[0].in,                          gBuffer[1].in,                          gBuffer[2].in,                          test->optInPeriod_0,                          test->optInPeriod_1,                          test->optInMAType_1,                             test->optInPeriod_2,                          test->optInMAType_2,                          &outBegIdx, &outNbElement,                          gBuffer[1].out0,                           gBuffer[1].out1 );      errNb = checkDataSame( gBuffer[0].in, history->high,history->nbBars );      if( errNb != TA_TEST_PASS )         return errNb;      errNb = checkDataSame( gBuffer[1].in, history->low, history->nbBars );      if( errNb != TA_TEST_PASS )         return errNb;      errNb = checkDataSame( gBuffer[2].in, history->close,history->nbBars );      if( errNb != TA_TEST_PASS )         return errNb;      CHECK_EXPECTED_VALUE( gBuffer[1].out0, 0 );      CHECK_EXPECTED_VALUE( gBuffer[1].out1, 1 );      /* The non-optimized reference shall be identical to the optimized        * TA-Lib implementation.       *       * checkSameContent verify that all value different than NAN in       * the first parameter is identical in the second parameter.       */      errNb = checkSameContent( gBuffer[1].out0, gBuffer[0].out0 );      if( errNb != TA_TEST_PASS )         return errNb;      errNb = checkSameContent( gBuffer[1].out1, gBuffer[0].out1 );      if( errNb != TA_TEST_PASS )         return errNb;   }   /* Make another call where the input and the output are the    * same buffer.    */   switch( test->testId )   {   case TEST_STOCH:      retCode = TA_STOCH( test->startIdx,                          test->endIdx,                          gBuffer[0].in,                          gBuffer[1].in,                          gBuffer[2].in,                          test->optInPeriod_0,                          test->optInPeriod_1,                          (TA_MAType)test->optInMAType_1,                          test->optInPeriod_2,                          (TA_MAType)test->optInMAType_2,                          &outBegIdx, &outNbElement,                          gBuffer[0].in,                           gBuffer[1].in );      break;   case TEST_STOCHF:      retCode = TA_STOCHF( test->startIdx,                           test->endIdx,                           gBuffer[0].in,                           gBuffer[1].in,                           gBuffer[2].in,                           test->optInPeriod_0,                           test->optInPeriod_1,                           (TA_MAType)test->optInMAType_1,                           &outBegIdx, &outNbElement,                           gBuffer[0].in,                            gBuffer[1].in );      break;   case TEST_STOCHRSI:      retCode = TA_STOCHRSI( test->startIdx,                             test->endIdx,                             gBuffer[2].in,                             test->optInPeriod_0,                             test->optInPeriod_1,                             test->optInPeriod_2,                             (TA_MAType)test->optInMAType_2,                             &outBegIdx, &outNbElement,                             gBuffer[0].in,                              gBuffer[1].in );      break;      }   /* The previous call should have the same output as this call.    *    * checkSameContent verify that all value different than NAN in    * the first parameter is identical in the second parameter.    */   errNb = checkSameContent( gBuffer[0].out0, gBuffer[0].in );   if( errNb != TA_TEST_PASS )      return errNb;   errNb = checkSameContent( gBuffer[0].out1, gBuffer[1].in );   if( errNb != TA_TEST_PASS )      return errNb;   CHECK_EXPECTED_VALUE( gBuffer[0].in, 0 );   CHECK_EXPECTED_VALUE( gBuffer[1].in, 1 );   if( errNb != TA_TEST_PASS )      return errNb;   /* Do a systematic test of most of the    * possible startIdx/endIdx range.    */   testParam.test  = test;   testParam.high  = history->high;   testParam.low   = history->low;   testParam.close = history->close;   if( test->doRangeTestFlag )   {      switch( test->testId )      {      case TEST_STOCH:      case TEST_STOCHF:         errNb = doRangeTest( rangeTestFunction,                               TA_FUNC_UNST_NONE,                              (void *)&testParam, 2, 0 );         break;      case TEST_STOCHRSI:         errNb = doRangeTest( rangeTestFunction,                               TA_FUNC_UNST_RSI,                              (void *)&testParam, 2, 0 );         break;      }      if( errNb != TA_TEST_PASS )         return errNb;   }   return TA_TEST_PASS;}/* This is an un-optimized version of the STOCH function */static TA_RetCode referenceStoch( TA_Integer    startIdx,                     TA_Integer    endIdx,                     const TA_Real inHigh[],                     const TA_Real inLow[],                     const TA_Real inClose[],                     TA_Integer    optInPeriod_0, /* From 1 to TA_INTEGER_MAX */                     TA_Integer    optInPeriod_1, /* From 1 to TA_INTEGER_MAX */                     TA_Integer    optInMAType_1,                     TA_Integer    optInPeriod_2, /* From 1 to TA_INTEGER_MAX */                     TA_Integer    optInMAType_2,                     TA_Integer   *outBegIdx,                     TA_Integer   *outNbElement,                     TA_Real       outSlowK_0[],                     TA_Real       outSlowD_1[] ){   TA_RetCode retCode;   double Lt, Ht, tmp, *tempBuffer;   int outIdx;   int lookbackTotal, lookbackK, lookbackKSlow, lookbackDSlow;   int trailingIdx, today, i, bufferIsAllocated;   /* Identify the lookback needed. */   lookbackK      = optInPeriod_0-1;   lookbackKSlow  = TA_MA_Lookback( optInPeriod_1, (TA_MAType)optInMAType_1 );   lookbackDSlow  = TA_MA_Lookback( optInPeriod_2, (TA_MAType)optInMAType_2 );   lookbackTotal  = lookbackK + lookbackDSlow + lookbackKSlow;   /* Move up the start index if there is not    * enough initial data.    */   if( startIdx < lookbackTotal )      startIdx = lookbackTotal;   /* Make sure there is still something to evaluate. */   if( startIdx > endIdx )   {      /* Succeed... but no data in the output. */      *outBegIdx    = 0;      *outNbElement = 0;      return TA_SUCCESS;   }   /* Do the K calculation:    *    *    Kt = 100 x ((Ct-Lt)/(Ht-Lt))    *    * Kt is today stochastic    * Ct is today closing price.    * Lt is the lowest price of the last K Period (including today)    * Ht is the highest price of the last K Period (including today)    */   /* Proceed with the calculation for the requested range.    * Note that this algorithm allows the input and    * output to be the same buffer.    */   outIdx = 0;   /* Calculate just enough K for ending up with the caller     * requested range. (The range of k must consider all    * the lookback involve with the smoothing).    */   trailingIdx = startIdx-lookbackTotal;   today       = trailingIdx+lookbackK;   /* Allocate a temporary buffer large enough to    * store the K.    *    * If the output is the same as the input, great    * we just save ourself one memory allocation.    */   bufferIsAllocated = 0;   if( (outSlowK_0 == inHigh) ||        (outSlowK_0 == inLow)  ||        (outSlowK_0 == inClose) )   {      tempBuffer = outSlowK_0;   }   else if( (outSlowD_1 == inHigh) ||            (outSlowD_1 == inLow)  ||            (outSlowD_1 == inClose) )   {      tempBuffer = outSlowD_1;   }   else   {      bufferIsAllocated = 1;      tempBuffer = TA_Malloc( (endIdx-today+1)*sizeof(TA_Real) );   }   /* Do the K calculation */   while( today <= endIdx )   {      /* Find Lt and Ht for the requested K period. */      Lt = inLow [trailingIdx];      Ht = inHigh[trailingIdx];      trailingIdx++;      for( i=trailingIdx; i <= today; i++ )      {         tmp = inLow[i];         if( tmp < Lt ) Lt = tmp;         tmp = inHigh[i];         if( tmp > Ht ) Ht = tmp;      }      /* Calculate stochastic. */      tmp = Ht-Lt;      if( tmp > 0.0 )        tempBuffer[outIdx++] = 100.0*((inClose[today]-Lt)/tmp);      else        tempBuffer[outIdx++] = 100.0;      today++;   }   /* Un-smoothed K calculation completed. This K calculation is not returned    * to the caller. It is always smoothed and then return.    * Some documentation will refer to the smoothed version as being     * "K-Slow", but often this end up to be shorten to "K".    */   retCode = TA_MA( 0, outIdx-1,                    tempBuffer, optInPeriod_1,                    (TA_MAType)optInMAType_1,                    outBegIdx, outNbElement, tempBuffer );   if( (retCode != TA_SUCCESS) || (*outNbElement == 0) )   {      if( bufferIsAllocated )        TA_Free(  tempBuffer );       /* Something wrong happen? No further data? */      *outBegIdx    = 0;      *outNbElement = 0;      return retCode;    }   /* Calculate the %D which is simply a moving average of    * the already smoothed %K.    */   retCode = TA_MA( 0, (*outNbElement)-1,                    tempBuffer, optInPeriod_2,                    (TA_MAType)optInMAType_2,                    outBegIdx, outNbElement, outSlowD_1 );   /* Copy tempBuffer into the caller buffer.     * (Calculation could not be done directly in the    *  caller buffer because more input data then the    *  requested range was needed for doing %D).    */   memmove( outSlowK_0, &tempBuffer[lookbackDSlow], (*outNbElement) * sizeof(TA_Real) );   /* Don't need K anymore, free it if it was allocated here. */   if( bufferIsAllocated )      TA_Free(  tempBuffer );    if( retCode != TA_SUCCESS )   {      /* Something wrong happen while processing %D? */      *outBegIdx    = 0;      *outNbElement = 0;      return retCode;   }   /* Note: Keep the outBegIdx relative to the    *       caller input before returning.    */   *outBegIdx = startIdx;   return TA_SUCCESS;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -