TA_RetCode TA_EMA( TA_Libc *libHandle, TA_Integer startIdx, TA_Integer endIdx, const TA_Real inReal_0[], TA_Integer optInTimePeriod_0, /* From 1 to TA_INTEGER_MAX */ TA_Integer optInCompatibility_1, TA_Integer *outBegIdx, TA_Integer *outNbElement, TA_Real outReal_0[] ) /**** END GENCODE SECTION 2 - DO NOT DELETE THIS LINE ****/ { /* Insert local variables here. */ /**** START GENCODE SECTION 3 - DO NOT DELETE THIS LINE ****/ (void)libHandle; /* Get ride of warning if unused. */ #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. */ if( !inReal_0 ) return TA_BAD_PARAM; /* min/max are checked for optInTimePeriod_0. */ if( optInTimePeriod_0 == TA_INTEGER_DEFAULT ) optInTimePeriod_0 = 30; else if( (optInTimePeriod_0 < 1) || (optInTimePeriod_0 > 2147483647) ) return TA_BAD_PARAM; if( optInCompatibility_1 == TA_INTEGER_DEFAULT ) optInCompatibility_1 = 0; else if( (optInCompatibility_1 < 0) || (optInCompatibility_1 > 1) ) 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. */ /* Simply call the internal implementation of the EMA. */ return TA_INT_EMA( startIdx, endIdx, inReal_0, optInTimePeriod_0, /* From 1 to 200 */ PER_TO_K( optInTimePeriod_0 ), optInCompatibility_1, outBegIdx, outNbElement, outReal_0 ); }
/* Generated */ TA_RetCode TA_PREFIX(INT_MACD)( int startIdx, /* Generated */ int endIdx, /* Generated */ const INPUT_TYPE inReal[], /* Generated */ int optInFastPeriod, /* Generated */ int optInSlowPeriod, /* Generated */ int optInSignalPeriod_2, /* Generated */ int *outBegIdx, /* Generated */ int *outNbElement, /* Generated */ double outMACD[], /* Generated */ double outMACDSignal[], /* Generated */ double outMACDHist[] ) /* Generated */ #endif /* Generated */ { /* Generated */ ARRAY_REF(slowEMABuffer); /* Generated */ ARRAY_REF(fastEMABuffer); /* Generated */ double k1, k2; /* Generated */ TA_RetCode retCode; /* Generated */ int tempInteger, outBegIdx1, outNbElement1; /* Generated */ int outBegIdx2, outNbElement2; /* Generated */ int lookbackTotal, lookbackSignal; /* Generated */ int i; /* Generated */ if( optInSlowPeriod < optInFastPeriod ) /* Generated */ { /* Generated */ tempInteger = optInSlowPeriod; /* Generated */ optInSlowPeriod = optInFastPeriod; /* Generated */ optInFastPeriod = tempInteger; /* Generated */ } /* Generated */ if( optInSlowPeriod != 0 ) /* Generated */ k1 = PER_TO_K(optInSlowPeriod); /* Generated */ else /* Generated */ { /* Generated */ optInSlowPeriod = 26; /* Generated */ k1 = (double)0.075; /* Generated */ } /* Generated */ if( optInFastPeriod != 0 ) /* Generated */ k2 = PER_TO_K(optInFastPeriod); /* Generated */ else /* Generated */ { /* Generated */ optInFastPeriod = 12; /* Generated */ k2 = (double)0.15; /* Generated */ } /* Generated */ lookbackSignal = TA_EMA_Lookback( optInSignalPeriod_2 ); /* Generated */ lookbackTotal = lookbackSignal; /* Generated */ lookbackTotal += TA_EMA_Lookback( optInSlowPeriod ); /* Generated */ if( startIdx < lookbackTotal ) /* Generated */ startIdx = lookbackTotal; /* Generated */ if( startIdx > endIdx ) /* Generated */ { /* Generated */ *outBegIdx = 0; /* Generated */ *outNbElement = 0; /* Generated */ return TA_SUCCESS; /* Generated */ } /* Generated */ tempInteger = (endIdx-startIdx)+1+lookbackSignal; /* Generated */ ARRAY_ALLOC( fastEMABuffer, tempInteger ); /* Generated */ if( !fastEMABuffer ) /* Generated */ { /* Generated */ *outBegIdx = 0; /* Generated */ *outNbElement = 0; /* Generated */ return TA_ALLOC_ERR; /* Generated */ } /* Generated */ ARRAY_ALLOC( slowEMABuffer, tempInteger ); /* Generated */ if( !slowEMABuffer ) /* Generated */ { /* Generated */ *outBegIdx = 0; /* Generated */ *outNbElement = 0; /* Generated */ ARRAY_FREE( fastEMABuffer ); /* Generated */ return TA_ALLOC_ERR; /* Generated */ } /* Generated */ tempInteger = startIdx-lookbackSignal; /* Generated */ retCode = TA_PREFIX(INT_EMA)( tempInteger, endIdx, /* Generated */ inReal, optInSlowPeriod, k1, /* Generated */ &outBegIdx1, &outNbElement1, slowEMABuffer ); /* Generated */ if( retCode != TA_SUCCESS ) /* Generated */ { /* Generated */ *outBegIdx = 0; /* Generated */ *outNbElement = 0; /* Generated */ ARRAY_FREE( fastEMABuffer ); /* Generated */ ARRAY_FREE( slowEMABuffer ); /* Generated */ return retCode; /* Generated */ } /* Generated */ retCode = TA_PREFIX(INT_EMA)( tempInteger, endIdx, /* Generated */ inReal, optInFastPeriod, k2, /* Generated */ &outBegIdx2, &outNbElement2, fastEMABuffer ); /* Generated */ if( retCode != TA_SUCCESS ) /* Generated */ { /* Generated */ *outBegIdx = 0; /* Generated */ *outNbElement = 0; /* Generated */ ARRAY_FREE( fastEMABuffer ); /* Generated */ ARRAY_FREE( slowEMABuffer ); /* Generated */ return retCode; /* Generated */ } /* Generated */ if( (outBegIdx1 != tempInteger) || /* Generated */ (outBegIdx2 != tempInteger) || /* Generated */ (outNbElement1 != outNbElement2) || /* Generated */ (outNbElement1 != (endIdx-startIdx)+1+lookbackSignal) ) /* Generated */ { /* Generated */ *outBegIdx = 0; /* Generated */ *outNbElement = 0; /* Generated */ ARRAY_FREE( fastEMABuffer ); /* Generated */ ARRAY_FREE( slowEMABuffer ); /* Generated */ return TA_INTERNAL_ERROR(119); /* Generated */ } /* Generated */ for( i=0; i < outNbElement1; i++ ) /* Generated */ fastEMABuffer[i] = fastEMABuffer[i] - slowEMABuffer[i]; /* Generated */ ARRAY_MEMMOVE( outMACD, 0, fastEMABuffer, lookbackSignal, (endIdx-startIdx)+1 ); /* Generated */ retCode = TA_INT_EMA( 0, outNbElement1-1, /* Generated */ fastEMABuffer, optInSignalPeriod_2, PER_TO_K(optInSignalPeriod_2), /* Generated */ &outBegIdx2, &outNbElement2, outMACDSignal ); /* Generated */ ARRAY_FREE( fastEMABuffer ); /* Generated */ ARRAY_FREE( slowEMABuffer ); /* Generated */ if( retCode != TA_SUCCESS ) /* Generated */ { /* Generated */ *outBegIdx = 0; /* Generated */ *outNbElement = 0; /* Generated */ return retCode; /* Generated */ } /* Generated */ for( i=0; i < outNbElement2; i++ ) /* Generated */ outMACDHist[i] = outMACD[i]-outMACDSignal[i]; /* Generated */ *outBegIdx = startIdx; /* Generated */ *outNbElement = outNbElement2; /* Generated */ return TA_SUCCESS; /* Generated */ }
TA_RetCode TA_TEMA( TA_Libc *libHandle, TA_Integer startIdx, TA_Integer endIdx, const TA_Real inReal_0[], TA_Integer optInTimePeriod_0, /* From 1 to TA_INTEGER_MAX */ TA_Integer optInCompatibility_1, TA_Integer *outBegIdx, TA_Integer *outNbElement, TA_Real outReal_0[] ) /**** END GENCODE SECTION 2 - DO NOT DELETE THIS LINE ****/ { /* Insert local variables here. */ TA_Real *firstEMA, *secondEMA; TA_Real k; TA_Integer firstEMABegIdx, firstEMANbElement; TA_Integer secondEMABegIdx, secondEMANbElement; TA_Integer thirdEMABegIdx, thirdEMANbElement; TA_Integer tempInt, outIdx, lookbackTotal, lookbackEMA; TA_Integer firstEMAIdx, secondEMAIdx; TA_RetCode retCode; /**** START GENCODE SECTION 3 - DO NOT DELETE THIS LINE ****/ (void)libHandle; /* Get ride of warning if unused. */ #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. */ if( !inReal_0 ) return TA_BAD_PARAM; /* min/max are checked for optInTimePeriod_0. */ if( optInTimePeriod_0 == TA_INTEGER_DEFAULT ) optInTimePeriod_0 = 30; else if( (optInTimePeriod_0 < 1) || (optInTimePeriod_0 > 2147483647) ) return TA_BAD_PARAM; if( optInCompatibility_1 == TA_INTEGER_DEFAULT ) optInCompatibility_1 = 0; else if( (optInCompatibility_1 < 0) || (optInCompatibility_1 > 1) ) 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. */ /* For an explanation of this function, please read: * * Stocks & Commodities V. 12:1 (11-19): * Smoothing Data With Faster Moving Averages * Stocks & Commodities V. 12:2 (72-80): * Smoothing Data With Less Lag * * Both magazine articles written by Patrick G. Mulloy * * Essentially, a TEMA of time serie 't' is: * EMA1 = EMA(t,period) * EMA2 = EMA(EMA(t,period),period) * EMA3 = EMA(EMA(EMA(t,period),period)) * TEMA = 3*EMA1 - 3*EMA2 + EMA3 * * TEMA offers a moving average with less lags then the * traditional EMA. * * Do not confuse a TEMA with EMA3. Both are called "Triple EMA" * in the litterature. * * DEMA is very similar (and from the same author). */ /* Will change only on success. */ *outNbElement = 0; *outBegIdx = 0; /* Adjust startIdx to account for the lookback period. */ lookbackEMA = TA_EMA_Lookback( optInTimePeriod_0, optInCompatibility_1 ); lookbackTotal = lookbackEMA * 3; if( startIdx < lookbackTotal ) startIdx = lookbackTotal; /* Make sure there is still something to evaluate. */ if( startIdx > endIdx ) return TA_SUCCESS; /* Allocate a temporary buffer for the firstEMA. */ tempInt = lookbackTotal+(endIdx-startIdx)+1; firstEMA = (TA_Real *)TA_Malloc( libHandle, tempInt * sizeof( TA_Real) ); if( !firstEMA ) return TA_ALLOC_ERR; /* Calculate the first EMA */ k = PER_TO_K(optInTimePeriod_0); retCode = TA_INT_EMA( startIdx-(lookbackEMA*2), endIdx, inReal_0, optInTimePeriod_0, k, optInCompatibility_1, &firstEMABegIdx, &firstEMANbElement, firstEMA ); /* Verify for failure or if not enough data after * calculating the first EMA. */ if( (retCode != TA_SUCCESS) || (firstEMANbElement == 0) ) { TA_Free( libHandle, firstEMA ); return retCode; } /* Allocate a temporary buffer for storing the EMA2 */ secondEMA = (TA_Real *)TA_Malloc( libHandle, firstEMANbElement * sizeof( TA_Real) ); if( !secondEMA ) { TA_Free( libHandle, firstEMA ); return TA_ALLOC_ERR; } retCode = TA_INT_EMA( 0, firstEMANbElement-1, firstEMA, optInTimePeriod_0, k, optInCompatibility_1, &secondEMABegIdx, &secondEMANbElement, secondEMA ); /* Return empty output on failure or if not enough data after * calculating the second EMA. */ if( (retCode != TA_SUCCESS) || (secondEMANbElement == 0) ) { TA_Free( libHandle, firstEMA ); TA_Free( libHandle, secondEMA ); return retCode; } /* Calculate the EMA3 into the caller provided output. */ retCode = TA_INT_EMA( 0, secondEMANbElement-1, secondEMA, optInTimePeriod_0, k, optInCompatibility_1, &thirdEMABegIdx, &thirdEMANbElement, outReal_0 ); /* Return empty output on failure or if not enough data after * calculating the third EMA. */ if( (retCode != TA_SUCCESS) || (thirdEMANbElement == 0) ) { TA_Free( libHandle, firstEMA ); TA_Free( libHandle, secondEMA ); return retCode; } /* Indicate where the output starts relative to * the caller input. */ firstEMAIdx = thirdEMABegIdx + secondEMABegIdx; secondEMAIdx = thirdEMABegIdx; *outBegIdx = firstEMAIdx + firstEMABegIdx; /* Do the TEMA: * Iterate through the EMA3 (output buffer) and adjust * the value by using the EMA2 and EMA1. */ outIdx = 0; while( outIdx < thirdEMANbElement ) { outReal_0[outIdx] += (3.0*firstEMA[firstEMAIdx++]) - (3.0*secondEMA[secondEMAIdx++]); outIdx++; } TA_Free( libHandle, firstEMA ); TA_Free( libHandle, secondEMA ); /* Indicates to the caller the number of output * successfully calculated. */ *outNbElement = outIdx; return TA_SUCCESS; }
/* Generated */ TA_RetCode TA_S_TEMA( int startIdx, /* Generated */ int endIdx, /* Generated */ const float inReal_0[], /* Generated */ int optInTimePeriod_0, /* From 2 to 100000 */ /* Generated */ int *outBegIdx, /* Generated */ int *outNbElement, /* Generated */ double outReal_0[] ) /* Generated */ #endif /* Generated */ { /* Generated */ ARRAY_REF(firstEMA); /* Generated */ ARRAY_REF(secondEMA); /* Generated */ double k; /* Generated */ int firstEMABegIdx, firstEMANbElement; /* Generated */ int secondEMABegIdx, secondEMANbElement; /* Generated */ int thirdEMABegIdx, thirdEMANbElement; /* Generated */ int tempInt, outIdx, lookbackTotal, lookbackEMA; /* Generated */ int firstEMAIdx, secondEMAIdx; /* Generated */ TA_RetCode retCode; /* Generated */ #ifndef TA_FUNC_NO_RANGE_CHECK /* Generated */ if( startIdx < 0 ) /* Generated */ return TA_OUT_OF_RANGE_START_INDEX; /* Generated */ if( (endIdx < 0) || (endIdx < startIdx)) /* Generated */ return TA_OUT_OF_RANGE_END_INDEX; /* Generated */ if( !inReal_0 ) return TA_BAD_PARAM; /* Generated */ if( (int)optInTimePeriod_0 == TA_INTEGER_DEFAULT ) /* Generated */ optInTimePeriod_0 = 30; /* Generated */ else if( ((int)optInTimePeriod_0 < 2) || ((int)optInTimePeriod_0 > 100000) ) /* Generated */ return TA_BAD_PARAM; /* Generated */ if( outReal_0 == NULL ) /* Generated */ return TA_BAD_PARAM; /* Generated */ #endif /* Generated */ *outNbElement = 0; /* Generated */ *outBegIdx = 0; /* Generated */ lookbackEMA = TA_EMA_Lookback( optInTimePeriod_0 ); /* Generated */ lookbackTotal = lookbackEMA * 3; /* Generated */ if( startIdx < lookbackTotal ) /* Generated */ startIdx = lookbackTotal; /* Generated */ if( startIdx > endIdx ) /* Generated */ return TA_SUCCESS; /* Generated */ tempInt = lookbackTotal+(endIdx-startIdx)+1; /* Generated */ ARRAY_ALLOC(firstEMA,tempInt); /* Generated */ if( !firstEMA ) /* Generated */ return TA_ALLOC_ERR; /* Generated */ k = PER_TO_K(optInTimePeriod_0); /* Generated */ retCode = TA_PREFIX(INT_EMA)( startIdx-(lookbackEMA*2), endIdx, inReal_0, /* Generated */ optInTimePeriod_0, k, /* Generated */ &firstEMABegIdx, &firstEMANbElement, firstEMA ); /* Generated */ if( (retCode != TA_SUCCESS) || (firstEMANbElement == 0) ) /* Generated */ { /* Generated */ ARRAY_FREE( firstEMA ); /* Generated */ return retCode; /* Generated */ } /* Generated */ ARRAY_ALLOC(secondEMA,firstEMANbElement); /* Generated */ if( !secondEMA ) /* Generated */ { /* Generated */ ARRAY_FREE( firstEMA ); /* Generated */ return TA_ALLOC_ERR; /* Generated */ } /* Generated */ retCode = TA_INT_EMA( 0, firstEMANbElement-1, firstEMA, /* Generated */ optInTimePeriod_0, k, /* Generated */ &secondEMABegIdx, &secondEMANbElement, secondEMA ); /* Generated */ if( (retCode != TA_SUCCESS) || (secondEMANbElement == 0) ) /* Generated */ { /* Generated */ ARRAY_FREE( firstEMA ); /* Generated */ ARRAY_FREE( secondEMA ); /* Generated */ return retCode; /* Generated */ } /* Generated */ retCode = TA_INT_EMA( 0, secondEMANbElement-1, secondEMA, /* Generated */ optInTimePeriod_0, k, /* Generated */ &thirdEMABegIdx, &thirdEMANbElement, /* Generated */ outReal_0 ); /* Generated */ if( (retCode != TA_SUCCESS) || (thirdEMANbElement == 0) ) /* Generated */ { /* Generated */ ARRAY_FREE( firstEMA ); /* Generated */ ARRAY_FREE( secondEMA ); /* Generated */ return retCode; /* Generated */ } /* Generated */ firstEMAIdx = thirdEMABegIdx + secondEMABegIdx; /* Generated */ secondEMAIdx = thirdEMABegIdx; /* Generated */ *outBegIdx = firstEMAIdx + firstEMABegIdx; /* Generated */ outIdx = 0; /* Generated */ while( outIdx < thirdEMANbElement ) /* Generated */ { /* Generated */ outReal_0[outIdx] += (3.0*firstEMA[firstEMAIdx++]) - (3.0*secondEMA[secondEMAIdx++]); /* Generated */ outIdx++; /* Generated */ } /* Generated */ ARRAY_FREE( firstEMA ); /* Generated */ ARRAY_FREE( secondEMA ); /* Generated */ *outNbElement = outIdx; /* Generated */ return TA_SUCCESS; /* Generated */ }
TA_RetCode TA_MA( TA_Integer startIdx, TA_Integer endIdx, const TA_Real inReal_0[], TA_Integer optInTimePeriod_0, /* From 2 to TA_INTEGER_MAX */ TA_MAType optInMAType_1, TA_Integer *outBegIdx, TA_Integer *outNbElement, TA_Real outReal_0[] ) /**** END GENCODE SECTION 2 - DO NOT DELETE THIS LINE ****/ { /* Insert local variables here. */ TA_Real *dummyBuffer; TA_RetCode retCode; /**** 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. */ if( !inReal_0 ) return TA_BAD_PARAM; /* min/max are checked for optInTimePeriod_0. */ if( (TA_Integer)optInTimePeriod_0 == TA_INTEGER_DEFAULT ) optInTimePeriod_0 = 30; else if( ((TA_Integer)optInTimePeriod_0 < 2) || ((TA_Integer)optInTimePeriod_0 > 2147483647) ) return TA_BAD_PARAM; if( (TA_Integer)optInMAType_1 == TA_INTEGER_DEFAULT ) optInMAType_1 = 0; else if( ((TA_Integer)optInMAType_1 < 0) || ((TA_Integer)optInMAType_1 > 8) ) 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 ****/ /* Simply call the internal implementation of the * requested moving average. */ switch( optInMAType_1 ) { case TA_MAType_SMA: return TA_INT_SMA( startIdx, endIdx, inReal_0, optInTimePeriod_0, outBegIdx, outNbElement, outReal_0 ); break; case TA_MAType_EMA: return TA_INT_EMA( startIdx, endIdx, inReal_0, optInTimePeriod_0, PER_TO_K(optInTimePeriod_0), outBegIdx, outNbElement, outReal_0 ); break; case TA_MAType_WMA: return TA_INT_WMA( startIdx, endIdx, inReal_0, optInTimePeriod_0, outBegIdx, outNbElement, outReal_0 ); break; case TA_MAType_DEMA: return TA_DEMA( startIdx, endIdx, inReal_0, optInTimePeriod_0, outBegIdx, outNbElement, outReal_0 ); break; case TA_MAType_TEMA: return TA_TEMA( startIdx, endIdx, inReal_0, optInTimePeriod_0, outBegIdx, outNbElement, outReal_0 ); break; case TA_MAType_TRIMA: return TA_TRIMA( startIdx, endIdx, inReal_0, optInTimePeriod_0, outBegIdx, outNbElement, outReal_0 ); break; case TA_MAType_KAMA: return TA_KAMA( startIdx, endIdx, inReal_0, optInTimePeriod_0, outBegIdx, outNbElement, outReal_0 ); break; case TA_MAType_MAMA: /* The optInTimePeriod_0 is ignored and the FAMA output of the MAMA * is ignored. */ dummyBuffer = TA_Malloc( sizeof(TA_Real)*(endIdx-startIdx+1) ); if( !dummyBuffer ) return TA_ALLOC_ERR; retCode = TA_MAMA( startIdx, endIdx, inReal_0, 0.5, 0.05, outBegIdx, outNbElement, outReal_0, dummyBuffer ); TA_Free( dummyBuffer ); return retCode; break; case TA_MAType_T3: return TA_T3( startIdx, endIdx, inReal_0, optInTimePeriod_0, 0.7, outBegIdx, outNbElement, outReal_0 ); break; } *outBegIdx = 0; *outNbElement = 0; return TA_BAD_PARAM; }