1 /* TA-LIB Copyright (c) 1999-2007, Mario Fortier
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or
5  * without modification, are permitted provided that the following
6  * conditions are met:
7  *
8  * - Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  *
11  * - Redistributions in binary form must reproduce the above copyright
12  *   notice, this list of conditions and the following disclaimer in
13  *   the documentation and/or other materials provided with the
14  *   distribution.
15  *
16  * - Neither name of author nor the names of its contributors
17  *   may be used to endorse or promote products derived from this
18  *   software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
30  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
31  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /* List of contributors:
35  *
36  *  Initial  Name/description
37  *  -------------------------------------------------------------------
38  *  MF       Mario Fortier
39  *
40  *
41  * Change history:
42  *
43  *  MMDDYY BY   Description
44  *  -------------------------------------------------------------------
45  *  112400 MF   Template creation.
46  *  052603 MF   Adapt code to compile with .NET Managed C++
47  *
48  */
49 
50 /**** START GENCODE SECTION 1 - DO NOT DELETE THIS LINE ****/
51 /* All code within this section is automatically
52  * generated by gen_code. Any modification will be lost
53  * next time gen_code is run.
54  */
55 /* Generated */
56 /* Generated */ #if defined( _MANAGED )
57 /* Generated */    #include "TA-Lib-Core.h"
58 /* Generated */    #define TA_INTERNAL_ERROR(Id) (RetCode::InternalError)
59 /* Generated */    namespace TicTacTec { namespace TA { namespace Library {
60 /* Generated */ #elif defined( _JAVA )
61 /* Generated */    #include "ta_defs.h"
62 /* Generated */    #include "ta_java_defs.h"
63 /* Generated */    #define TA_INTERNAL_ERROR(Id) (RetCode.InternalError)
64 /* Generated */ #else
65 /* Generated */    #include <string.h>
66 /* Generated */    #include <math.h>
67 /* Generated */    #include "ta_func.h"
68 /* Generated */ #endif
69 /* Generated */
70 /* Generated */ #ifndef TA_UTILITY_H
71 /* Generated */    #include "ta_utility.h"
72 /* Generated */ #endif
73 /* Generated */
74 /* Generated */ #ifndef TA_MEMORY_H
75 /* Generated */    #include "ta_memory.h"
76 /* Generated */ #endif
77 /* Generated */
78 /* Generated */ #define TA_PREFIX(x) TA_##x
79 /* Generated */ #define INPUT_TYPE   double
80 /* Generated */
81 /* Generated */ #if defined( _MANAGED )
StochLookback(int optInFastK_Period,int optInSlowK_Period,MAType optInSlowK_MAType,int optInSlowD_Period,MAType optInSlowD_MAType)82 /* Generated */ int Core::StochLookback( int           optInFastK_Period, /* From 1 to 100000 */
83 /* Generated */                        int           optInSlowK_Period, /* From 1 to 100000 */
84 /* Generated */                        MAType        optInSlowK_MAType,
85 /* Generated */                        int           optInSlowD_Period, /* From 1 to 100000 */
86 /* Generated */                        MAType        optInSlowD_MAType ) /* Generated */
87 /* Generated */ #elif defined( _JAVA )
88 /* Generated */ public int stochLookback( int           optInFastK_Period, /* From 1 to 100000 */
89 /* Generated */                         int           optInSlowK_Period, /* From 1 to 100000 */
90 /* Generated */                         MAType        optInSlowK_MAType,
91 /* Generated */                         int           optInSlowD_Period, /* From 1 to 100000 */
92 /* Generated */                         MAType        optInSlowD_MAType ) /* Generated */
93 /* Generated */ #else
94 /* Generated */ int TA_STOCH_Lookback( int           optInFastK_Period, /* From 1 to 100000 */
95 /* Generated */                      int           optInSlowK_Period, /* From 1 to 100000 */
96 /* Generated */                      TA_MAType     optInSlowK_MAType,
97 /* Generated */                      int           optInSlowD_Period, /* From 1 to 100000 */
98 /* Generated */                      TA_MAType     optInSlowD_MAType ) /* Generated */
99 /* Generated */ #endif
100 /**** END GENCODE SECTION 1 - DO NOT DELETE THIS LINE ****/
101 {
102    /* insert local variable here */
103    int retValue;
104 
105 /**** START GENCODE SECTION 2 - DO NOT DELETE THIS LINE ****/
106 /* Generated */ #ifndef TA_FUNC_NO_RANGE_CHECK
107 /* Generated */    /* min/max are checked for optInFastK_Period. */
108 /* Generated */    if( (int)optInFastK_Period == TA_INTEGER_DEFAULT )
109 /* Generated */       optInFastK_Period = 5;
110 /* Generated */    else if( ((int)optInFastK_Period < 1) || ((int)optInFastK_Period > 100000) )
111 /* Generated */       return -1;
112 /* Generated */
113 /* Generated */    /* min/max are checked for optInSlowK_Period. */
114 /* Generated */    if( (int)optInSlowK_Period == TA_INTEGER_DEFAULT )
115 /* Generated */       optInSlowK_Period = 3;
116 /* Generated */    else if( ((int)optInSlowK_Period < 1) || ((int)optInSlowK_Period > 100000) )
117 /* Generated */       return -1;
118 /* Generated */
119 /* Generated */    #if !defined(_MANAGED) && !defined(_JAVA)
120 /* Generated */    if( (int)optInSlowK_MAType == TA_INTEGER_DEFAULT )
121 /* Generated */       optInSlowK_MAType = (TA_MAType)0;
122 /* Generated */    else if( ((int)optInSlowK_MAType < 0) || ((int)optInSlowK_MAType > 8) )
123 /* Generated */       return -1;
124 /* Generated */
125 /* Generated */    #endif /* !defined(_MANAGED) && !defined(_JAVA)*/
126 /* Generated */    /* min/max are checked for optInSlowD_Period. */
127 /* Generated */    if( (int)optInSlowD_Period == TA_INTEGER_DEFAULT )
128 /* Generated */       optInSlowD_Period = 3;
129 /* Generated */    else if( ((int)optInSlowD_Period < 1) || ((int)optInSlowD_Period > 100000) )
130 /* Generated */       return -1;
131 /* Generated */
132 /* Generated */    #if !defined(_MANAGED) && !defined(_JAVA)
133 /* Generated */    if( (int)optInSlowD_MAType == TA_INTEGER_DEFAULT )
134 /* Generated */       optInSlowD_MAType = (TA_MAType)0;
135 /* Generated */    else if( ((int)optInSlowD_MAType < 0) || ((int)optInSlowD_MAType > 8) )
136 /* Generated */       return -1;
137 /* Generated */
138 /* Generated */    #endif /* !defined(_MANAGED) && !defined(_JAVA)*/
139 /* Generated */ #endif /* TA_FUNC_NO_RANGE_CHECK */
140 /**** END GENCODE SECTION 2 - DO NOT DELETE THIS LINE ****/
141 
142    /* insert lookback code here. */
143 
144    /* Account for the initial data needed for Fast-K. */
145    retValue = (optInFastK_Period - 1);
146 
147    /* Add the smoothing being done for %K slow */
148    retValue += LOOKBACK_CALL(MA)( optInSlowK_Period, optInSlowK_MAType );
149 
150    /* Add the smoothing being done for %D slow. */
151    retValue += LOOKBACK_CALL(MA)( optInSlowD_Period, optInSlowD_MAType );
152 
153    return retValue;
154 }
155 
156 /**** START GENCODE SECTION 3 - DO NOT DELETE THIS LINE ****/
157 /*
158  * TA_STOCH - Stochastic
159  *
160  * Input  = High, Low, Close
161  * Output = double, double
162  *
163  * Optional Parameters
164  * -------------------
165  * optInFastK_Period:(From 1 to 100000)
166  *    Time period for building the Fast-K line
167  *
168  * optInSlowK_Period:(From 1 to 100000)
169  *    Smoothing for making the Slow-K line. Usually set to 3
170  *
171  * optInSlowK_MAType:
172  *    Type of Moving Average for Slow-K
173  *
174  * optInSlowD_Period:(From 1 to 100000)
175  *    Smoothing for making the Slow-D line
176  *
177  * optInSlowD_MAType:
178  *    Type of Moving Average for Slow-D
179  *
180  *
181  */
182 /* Generated */
183 /* Generated */ #if defined( _MANAGED ) && defined( USE_SUBARRAY )
184 /* Generated */ enum class Core::RetCode Core::Stoch( int    startIdx,
185 /* Generated */                                       int    endIdx,
186 /* Generated */                                       SubArray^    inHigh,
187 /* Generated */                                       SubArray^    inLow,
188 /* Generated */                                       SubArray^    inClose,
189 /* Generated */                                       int           optInFastK_Period, /* From 1 to 100000 */
190 /* Generated */                                       int           optInSlowK_Period, /* From 1 to 100000 */
191 /* Generated */                                       MAType        optInSlowK_MAType,
192 /* Generated */                                       int           optInSlowD_Period, /* From 1 to 100000 */
193 /* Generated */                                       MAType        optInSlowD_MAType,
194 /* Generated */                                       [Out]int%    outBegIdx,
195 /* Generated */                                       [Out]int%    outNBElement,
196 /* Generated */                                       cli::array<double>^  outSlowK,
197 /* Generated */                                       cli::array<double>^  outSlowD )
198 /* Generated */ #elif defined( _MANAGED )
199 /* Generated */ enum class Core::RetCode Core::Stoch( int    startIdx,
200 /* Generated */                                       int    endIdx,
201 /* Generated */                                       cli::array<double>^ inHigh,
202 /* Generated */                                       cli::array<double>^ inLow,
203 /* Generated */                                       cli::array<double>^ inClose,
204 /* Generated */                                       int           optInFastK_Period, /* From 1 to 100000 */
205 /* Generated */                                       int           optInSlowK_Period, /* From 1 to 100000 */
206 /* Generated */                                       MAType        optInSlowK_MAType,
207 /* Generated */                                       int           optInSlowD_Period, /* From 1 to 100000 */
208 /* Generated */                                       MAType        optInSlowD_MAType,
209 /* Generated */                                       [Out]int%    outBegIdx,
210 /* Generated */                                       [Out]int%    outNBElement,
211 /* Generated */                                       cli::array<double>^  outSlowK,
212 /* Generated */                                       cli::array<double>^  outSlowD )
213 /* Generated */ #elif defined( _JAVA )
214 /* Generated */ public RetCode stoch( int    startIdx,
215 /* Generated */                       int    endIdx,
216 /* Generated */                       double       inHigh[],
217 /* Generated */                       double       inLow[],
218 /* Generated */                       double       inClose[],
219 /* Generated */                       int           optInFastK_Period, /* From 1 to 100000 */
220 /* Generated */                       int           optInSlowK_Period, /* From 1 to 100000 */
221 /* Generated */                       MAType        optInSlowK_MAType,
222 /* Generated */                       int           optInSlowD_Period, /* From 1 to 100000 */
223 /* Generated */                       MAType        optInSlowD_MAType,
224 /* Generated */                       MInteger     outBegIdx,
225 /* Generated */                       MInteger     outNBElement,
226 /* Generated */                       double        outSlowK[],
227 /* Generated */                       double        outSlowD[] )
228 /* Generated */ #else
229 /* Generated */ TA_RetCode TA_STOCH( int    startIdx,
230 /* Generated */                      int    endIdx,
231 /* Generated */                      const double inHigh[],
232 /* Generated */                      const double inLow[],
233 /* Generated */                      const double inClose[],
234 /* Generated */                      int           optInFastK_Period, /* From 1 to 100000 */
235 /* Generated */                      int           optInSlowK_Period, /* From 1 to 100000 */
236 /* Generated */                      TA_MAType     optInSlowK_MAType,
237 /* Generated */                      int           optInSlowD_Period, /* From 1 to 100000 */
238 /* Generated */                      TA_MAType     optInSlowD_MAType,
239 /* Generated */                      int          *outBegIdx,
240 /* Generated */                      int          *outNBElement,
241 /* Generated */                      double        outSlowK[],
242 /* Generated */                      double        outSlowD[] )
243 /* Generated */ #endif
244 /**** END GENCODE SECTION 3 - DO NOT DELETE THIS LINE ****/
245 {
246    /* Insert local variables here. */
247    ENUM_DECLARATION(RetCode) retCode;
248    double lowest, highest, tmp, diff;
249    ARRAY_REF( tempBuffer );
250    int outIdx, lowestIdx, highestIdx;
251    int lookbackTotal, lookbackK, lookbackKSlow, lookbackDSlow;
252    int trailingIdx, today, i;
253    #if !defined( _MANAGED ) && !defined(USE_SINGLE_PRECISION_INPUT) &&!defined(_JAVA)
254    int bufferIsAllocated;
255    #endif
256 
257 /**** START GENCODE SECTION 4 - DO NOT DELETE THIS LINE ****/
258 /* Generated */
259 /* Generated */ #ifndef TA_FUNC_NO_RANGE_CHECK
260 /* Generated */
261 /* Generated */    /* Validate the requested output range. */
262 /* Generated */    if( startIdx < 0 )
263 /* Generated */       return ENUM_VALUE(RetCode,TA_OUT_OF_RANGE_START_INDEX,OutOfRangeStartIndex);
264 /* Generated */    if( (endIdx < 0) || (endIdx < startIdx))
265 /* Generated */       return ENUM_VALUE(RetCode,TA_OUT_OF_RANGE_END_INDEX,OutOfRangeEndIndex);
266 /* Generated */
267 /* Generated */    #if !defined(_JAVA)
268 /* Generated */    /* Verify required price component. */
269 /* Generated */    if(!inHigh||!inLow||!inClose)
270 /* Generated */       return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
271 /* Generated */
272 /* Generated */    #endif /* !defined(_JAVA)*/
273 /* Generated */    /* min/max are checked for optInFastK_Period. */
274 /* Generated */    if( (int)optInFastK_Period == TA_INTEGER_DEFAULT )
275 /* Generated */       optInFastK_Period = 5;
276 /* Generated */    else if( ((int)optInFastK_Period < 1) || ((int)optInFastK_Period > 100000) )
277 /* Generated */       return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
278 /* Generated */
279 /* Generated */    /* min/max are checked for optInSlowK_Period. */
280 /* Generated */    if( (int)optInSlowK_Period == TA_INTEGER_DEFAULT )
281 /* Generated */       optInSlowK_Period = 3;
282 /* Generated */    else if( ((int)optInSlowK_Period < 1) || ((int)optInSlowK_Period > 100000) )
283 /* Generated */       return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
284 /* Generated */
285 /* Generated */    #if !defined(_MANAGED) && !defined(_JAVA)
286 /* Generated */    if( (int)optInSlowK_MAType == TA_INTEGER_DEFAULT )
287 /* Generated */       optInSlowK_MAType = (TA_MAType)0;
288 /* Generated */    else if( ((int)optInSlowK_MAType < 0) || ((int)optInSlowK_MAType > 8) )
289 /* Generated */       return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
290 /* Generated */
291 /* Generated */    #endif /* !defined(_MANAGED) && !defined(_JAVA)*/
292 /* Generated */    /* min/max are checked for optInSlowD_Period. */
293 /* Generated */    if( (int)optInSlowD_Period == TA_INTEGER_DEFAULT )
294 /* Generated */       optInSlowD_Period = 3;
295 /* Generated */    else if( ((int)optInSlowD_Period < 1) || ((int)optInSlowD_Period > 100000) )
296 /* Generated */       return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
297 /* Generated */
298 /* Generated */    #if !defined(_MANAGED) && !defined(_JAVA)
299 /* Generated */    if( (int)optInSlowD_MAType == TA_INTEGER_DEFAULT )
300 /* Generated */       optInSlowD_MAType = (TA_MAType)0;
301 /* Generated */    else if( ((int)optInSlowD_MAType < 0) || ((int)optInSlowD_MAType > 8) )
302 /* Generated */       return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
303 /* Generated */
304 /* Generated */    #endif /* !defined(_MANAGED) && !defined(_JAVA)*/
305 /* Generated */    #if !defined(_JAVA)
306 /* Generated */    if( !outSlowK )
307 /* Generated */       return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
308 /* Generated */
309 /* Generated */    if( !outSlowD )
310 /* Generated */       return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
311 /* Generated */
312 /* Generated */    #endif /* !defined(_JAVA) */
313 /* Generated */ #endif /* TA_FUNC_NO_RANGE_CHECK */
314 /* Generated */
315 /**** END GENCODE SECTION 4 - DO NOT DELETE THIS LINE ****/
316 
317    /* Insert TA function code here. */
318 
319    /* With stochastic, there is a total of 4 different lines that
320     * are defined: FASTK, FASTD, SLOWK and SLOWD.
321     *
322     * The D is the signal line usually drawn over its
323     * corresponding K function.
324     *
325     *                    (Today's Close - LowestLow)
326     *  FASTK(Kperiod) =  --------------------------- * 100
327     *                     (HighestHigh - LowestLow)
328     *
329     *  FASTD(FastDperiod, MA type) = MA Smoothed FASTK over FastDperiod
330     *
331     *  SLOWK(SlowKperiod, MA type) = MA Smoothed FASTK over SlowKperiod
332     *
333     *  SLOWD(SlowDperiod, MA Type) = MA Smoothed SLOWK over SlowDperiod
334     *
335     * The HighestHigh and LowestLow are the extreme values among the
336     * last 'Kperiod'.
337     *
338     * SLOWK and FASTD are equivalent when using the same period.
339     *
340     * The following shows how these four lines are made available in TA-LIB:
341     *
342     *  TA_STOCH  : Returns the SLOWK and SLOWD
343     *  TA_STOCHF : Returns the FASTK and FASTD
344     *
345     * The TA_STOCH function correspond to the more widely implemented version
346     * found in many software/charting package. The TA_STOCHF is more rarely
347     * used because its higher volatility cause often whipsaws.
348     */
349 
350    /* Identify the lookback needed. */
351    lookbackK      = optInFastK_Period-1;
352    lookbackKSlow  = LOOKBACK_CALL(MA)( optInSlowK_Period, optInSlowK_MAType );
353    lookbackDSlow  = LOOKBACK_CALL(MA)( optInSlowD_Period, optInSlowD_MAType );
354    lookbackTotal  = lookbackK + lookbackDSlow + lookbackKSlow;
355 
356    /* Move up the start index if there is not
357     * enough initial data.
358     */
359    if( startIdx < lookbackTotal )
360       startIdx = lookbackTotal;
361 
362    /* Make sure there is still something to evaluate. */
363    if( startIdx > endIdx )
364    {
365       /* Succeed... but no data in the output. */
366       VALUE_HANDLE_DEREF_TO_ZERO(outBegIdx);
367       VALUE_HANDLE_DEREF_TO_ZERO(outNBElement);
368       return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
369    }
370 
371    /* Do the K calculation:
372     *
373     *    Kt = 100 x ((Ct-Lt)/(Ht-Lt))
374     *
375     * Kt is today stochastic
376     * Ct is today closing price.
377     * Lt is the lowest price of the last K Period (including today)
378     * Ht is the highest price of the last K Period (including today)
379     */
380 
381    /* Proceed with the calculation for the requested range.
382     * Note that this algorithm allows the input and
383     * output to be the same buffer.
384     */
385    outIdx = 0;
386 
387    /* Calculate just enough K for ending up with the caller
388     * requested range. (The range of k must consider all
389     * the lookback involve with the smoothing).
390     */
391    trailingIdx = startIdx-lookbackTotal;
392    today       = trailingIdx+lookbackK;
393    lowestIdx   = highestIdx = -1;
394    diff = highest = lowest  = 0.0;
395 
396    /* Allocate a temporary buffer large enough to
397     * store the K.
398     *
399     * If the output is the same as the input, great
400     * we just save ourself one memory allocation.
401     */
402    #if !defined( _MANAGED ) && !defined(USE_SINGLE_PRECISION_INPUT) && !defined( _JAVA )
403       bufferIsAllocated = 0;
404    #endif
405 
406    #if defined(USE_SINGLE_PRECISION_INPUT) || defined( USE_SUBARRAY )
407       /* Always alloc, since output is of different type and
408        * its allocated size is not guarantee to be as large as
409        * the input.
410        */
411       ARRAY_ALLOC( tempBuffer, endIdx-today+1 );
412    #else
413       if( (outSlowK == inHigh) ||
414           (outSlowK == inLow)  ||
415           (outSlowK == inClose) )
416       {
417          tempBuffer = outSlowK;
418       }
419       else if( (outSlowD == inHigh) ||
420                (outSlowD == inLow)  ||
421                (outSlowD == inClose) )
422       {
423          tempBuffer = outSlowD;
424       }
425       else
426       {
427          #if !defined( _MANAGED ) && !defined(_JAVA)
428             bufferIsAllocated = 1;
429          #endif
430          ARRAY_ALLOC( tempBuffer, endIdx-today+1 );
431       }
432    #endif
433 
434    /* Do the K calculation */
435    while( today <= endIdx )
436    {
437       /* Set the lowest low */
438       tmp = inLow[today];
439       if( lowestIdx < trailingIdx )
440       {
441          lowestIdx = trailingIdx;
442          lowest = inLow[lowestIdx];
443          i = lowestIdx;
444          while( ++i<=today )
445          {
446             tmp = inLow[i];
447             if( tmp < lowest )
448             {
449                lowestIdx = i;
450                lowest = tmp;
451             }
452          }
453          diff = (highest - lowest)/100.0;
454       }
455       else if( tmp <= lowest )
456       {
457          lowestIdx = today;
458          lowest = tmp;
459          diff = (highest - lowest)/100.0;
460       }
461 
462       /* Set the highest high */
463       tmp = inHigh[today];
464       if( highestIdx < trailingIdx )
465       {
466          highestIdx = trailingIdx;
467          highest = inHigh[highestIdx];
468          i = highestIdx;
469          while( ++i<=today )
470          {
471             tmp = inHigh[i];
472             if( tmp > highest )
473             {
474                highestIdx = i;
475                highest = tmp;
476             }
477          }
478          diff = (highest - lowest)/100.0;
479       }
480       else if( tmp >= highest )
481       {
482          highestIdx = today;
483          highest = tmp;
484          diff = (highest - lowest)/100.0;
485       }
486 
487       /* Calculate stochastic. */
488       if( diff != 0.0 )
489         tempBuffer[outIdx++] = (inClose[today]-lowest)/diff;
490       else
491         tempBuffer[outIdx++] = 0.0;
492 
493       trailingIdx++;
494       today++;
495    }
496 
497    /* Un-smoothed K calculation completed. This K calculation is not returned
498     * to the caller. It is always smoothed and then return.
499     * Some documentation will refer to the smoothed version as being
500     * "K-Slow", but often this end up to be shorten to "K".
501     */
502    retCode = FUNCTION_CALL_DOUBLE(MA)( 0, outIdx-1,
503                                        tempBuffer, optInSlowK_Period,
504                                        optInSlowK_MAType,
505                                        outBegIdx, outNBElement, tempBuffer );
506 
507 
508    if( (retCode != ENUM_VALUE(RetCode,TA_SUCCESS,Success) ) || ((int)VALUE_HANDLE_DEREF(outNBElement) == 0) )
509    {
510       #if defined(USE_SINGLE_PRECISION_INPUT)
511          ARRAY_FREE( tempBuffer );
512       #else
513          ARRAY_FREE_COND( bufferIsAllocated, tempBuffer );
514       #endif
515       /* Something wrong happen? No further data? */
516       VALUE_HANDLE_DEREF_TO_ZERO(outBegIdx);
517       VALUE_HANDLE_DEREF_TO_ZERO(outNBElement);
518       return retCode;
519    }
520 
521    /* Calculate the %D which is simply a moving average of
522     * the already smoothed %K.
523     */
524    retCode = FUNCTION_CALL_DOUBLE(MA)( 0, (int)VALUE_HANDLE_DEREF(outNBElement)-1,
525                                        tempBuffer, optInSlowD_Period,
526                                        optInSlowD_MAType,
527                                        outBegIdx, outNBElement, outSlowD );
528 
529    /* Copy tempBuffer into the caller buffer.
530     * (Calculation could not be done directly in the
531     *  caller buffer because more input data then the
532     *  requested range was needed for doing %D).
533     */
534    ARRAY_MEMMOVE( outSlowK, 0, tempBuffer,lookbackDSlow,(int)VALUE_HANDLE_DEREF(outNBElement));
535 
536    /* Don't need K anymore, free it if it was allocated here. */
537    #if defined(USE_SINGLE_PRECISION_INPUT)
538       ARRAY_FREE( tempBuffer );
539    #else
540       ARRAY_FREE_COND( bufferIsAllocated, tempBuffer );
541    #endif
542 
543    if( retCode != ENUM_VALUE(RetCode,TA_SUCCESS,Success) )
544    {
545       /* Something wrong happen while processing %D? */
546       VALUE_HANDLE_DEREF_TO_ZERO(outBegIdx);
547       VALUE_HANDLE_DEREF_TO_ZERO(outNBElement);
548       return retCode;
549    }
550 
551    /* Note: Keep the outBegIdx relative to the
552     *       caller input before returning.
553     */
554    VALUE_HANDLE_DEREF(outBegIdx) = startIdx;
555 
556    return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
557 }
558 
559 
560 /**** START GENCODE SECTION 5 - DO NOT DELETE THIS LINE ****/
561 /* Generated */
562 /* Generated */ #define  USE_SINGLE_PRECISION_INPUT
563 /* Generated */ #if !defined( _MANAGED ) && !defined( _JAVA )
564 /* Generated */    #undef   TA_PREFIX
565 /* Generated */    #define  TA_PREFIX(x) TA_S_##x
566 /* Generated */ #endif
567 /* Generated */ #undef   INPUT_TYPE
568 /* Generated */ #define  INPUT_TYPE float
569 /* Generated */ #if defined( _MANAGED )
570 /* Generated */ enum class Core::RetCode Core::Stoch( int    startIdx,
571 /* Generated */                                       int    endIdx,
572 /* Generated */                                       cli::array<float>^ inHigh,
573 /* Generated */                                       cli::array<float>^ inLow,
574 /* Generated */                                       cli::array<float>^ inClose,
575 /* Generated */                                       int           optInFastK_Period, /* From 1 to 100000 */
576 /* Generated */                                       int           optInSlowK_Period, /* From 1 to 100000 */
577 /* Generated */                                       MAType        optInSlowK_MAType,
578 /* Generated */                                       int           optInSlowD_Period, /* From 1 to 100000 */
579 /* Generated */                                       MAType        optInSlowD_MAType,
580 /* Generated */                                       [Out]int%    outBegIdx,
581 /* Generated */                                       [Out]int%    outNBElement,
582 /* Generated */                                       cli::array<double>^  outSlowK,
583 /* Generated */                                       cli::array<double>^  outSlowD )
584 /* Generated */ #elif defined( _JAVA )
585 /* Generated */ public RetCode stoch( int    startIdx,
586 /* Generated */                       int    endIdx,
587 /* Generated */                       float        inHigh[],
588 /* Generated */                       float        inLow[],
589 /* Generated */                       float        inClose[],
590 /* Generated */                       int           optInFastK_Period, /* From 1 to 100000 */
591 /* Generated */                       int           optInSlowK_Period, /* From 1 to 100000 */
592 /* Generated */                       MAType        optInSlowK_MAType,
593 /* Generated */                       int           optInSlowD_Period, /* From 1 to 100000 */
594 /* Generated */                       MAType        optInSlowD_MAType,
595 /* Generated */                       MInteger     outBegIdx,
596 /* Generated */                       MInteger     outNBElement,
597 /* Generated */                       double        outSlowK[],
598 /* Generated */                       double        outSlowD[] )
599 /* Generated */ #else
600 /* Generated */ TA_RetCode TA_S_STOCH( int    startIdx,
601 /* Generated */                        int    endIdx,
602 /* Generated */                        const float  inHigh[],
603 /* Generated */                        const float  inLow[],
604 /* Generated */                        const float  inClose[],
605 /* Generated */                        int           optInFastK_Period, /* From 1 to 100000 */
606 /* Generated */                        int           optInSlowK_Period, /* From 1 to 100000 */
607 /* Generated */                        TA_MAType     optInSlowK_MAType,
608 /* Generated */                        int           optInSlowD_Period, /* From 1 to 100000 */
609 /* Generated */                        TA_MAType     optInSlowD_MAType,
610 /* Generated */                        int          *outBegIdx,
611 /* Generated */                        int          *outNBElement,
612 /* Generated */                        double        outSlowK[],
613 /* Generated */                        double        outSlowD[] )
614 /* Generated */ #endif
615 /* Generated */ {
616 /* Generated */    ENUM_DECLARATION(RetCode) retCode;
617 /* Generated */    double lowest, highest, tmp, diff;
618 /* Generated */    ARRAY_REF( tempBuffer );
619 /* Generated */    int outIdx, lowestIdx, highestIdx;
620 /* Generated */    int lookbackTotal, lookbackK, lookbackKSlow, lookbackDSlow;
621 /* Generated */    int trailingIdx, today, i;
622 /* Generated */    #if !defined( _MANAGED ) && !defined(USE_SINGLE_PRECISION_INPUT) &&!defined(_JAVA)
623 /* Generated */    int bufferIsAllocated;
624 /* Generated */    #endif
625 /* Generated */  #ifndef TA_FUNC_NO_RANGE_CHECK
626 /* Generated */     if( startIdx < 0 )
627 /* Generated */        return ENUM_VALUE(RetCode,TA_OUT_OF_RANGE_START_INDEX,OutOfRangeStartIndex);
628 /* Generated */     if( (endIdx < 0) || (endIdx < startIdx))
629 /* Generated */        return ENUM_VALUE(RetCode,TA_OUT_OF_RANGE_END_INDEX,OutOfRangeEndIndex);
630 /* Generated */     #if !defined(_JAVA)
631 /* Generated */     if(!inHigh||!inLow||!inClose)
632 /* Generated */        return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
633 /* Generated */     #endif
634 /* Generated */     if( (int)optInFastK_Period == TA_INTEGER_DEFAULT )
635 /* Generated */        optInFastK_Period = 5;
636 /* Generated */     else if( ((int)optInFastK_Period < 1) || ((int)optInFastK_Period > 100000) )
637 /* Generated */        return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
638 /* Generated */     if( (int)optInSlowK_Period == TA_INTEGER_DEFAULT )
639 /* Generated */        optInSlowK_Period = 3;
640 /* Generated */     else if( ((int)optInSlowK_Period < 1) || ((int)optInSlowK_Period > 100000) )
641 /* Generated */        return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
642 /* Generated */     #if !defined(_MANAGED) && !defined(_JAVA)
643 /* Generated */     if( (int)optInSlowK_MAType == TA_INTEGER_DEFAULT )
644 /* Generated */        optInSlowK_MAType = (TA_MAType)0;
645 /* Generated */     else if( ((int)optInSlowK_MAType < 0) || ((int)optInSlowK_MAType > 8) )
646 /* Generated */        return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
647 /* Generated */     #endif
648 /* Generated */     if( (int)optInSlowD_Period == TA_INTEGER_DEFAULT )
649 /* Generated */        optInSlowD_Period = 3;
650 /* Generated */     else if( ((int)optInSlowD_Period < 1) || ((int)optInSlowD_Period > 100000) )
651 /* Generated */        return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
652 /* Generated */     #if !defined(_MANAGED) && !defined(_JAVA)
653 /* Generated */     if( (int)optInSlowD_MAType == TA_INTEGER_DEFAULT )
654 /* Generated */        optInSlowD_MAType = (TA_MAType)0;
655 /* Generated */     else if( ((int)optInSlowD_MAType < 0) || ((int)optInSlowD_MAType > 8) )
656 /* Generated */        return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
657 /* Generated */     #endif
658 /* Generated */     #if !defined(_JAVA)
659 /* Generated */     if( !outSlowK )
660 /* Generated */        return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
661 /* Generated */     if( !outSlowD )
662 /* Generated */        return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
663 /* Generated */     #endif
664 /* Generated */  #endif
665 /* Generated */    lookbackK      = optInFastK_Period-1;
666 /* Generated */    lookbackKSlow  = LOOKBACK_CALL(MA)( optInSlowK_Period, optInSlowK_MAType );
667 /* Generated */    lookbackDSlow  = LOOKBACK_CALL(MA)( optInSlowD_Period, optInSlowD_MAType );
668 /* Generated */    lookbackTotal  = lookbackK + lookbackDSlow + lookbackKSlow;
669 /* Generated */    if( startIdx < lookbackTotal )
670 /* Generated */       startIdx = lookbackTotal;
671 /* Generated */    if( startIdx > endIdx )
672 /* Generated */    {
673 /* Generated */       VALUE_HANDLE_DEREF_TO_ZERO(outBegIdx);
674 /* Generated */       VALUE_HANDLE_DEREF_TO_ZERO(outNBElement);
675 /* Generated */       return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
676 /* Generated */    }
677 /* Generated */    outIdx = 0;
678 /* Generated */    trailingIdx = startIdx-lookbackTotal;
679 /* Generated */    today       = trailingIdx+lookbackK;
680 /* Generated */    lowestIdx   = highestIdx = -1;
681 /* Generated */    diff = highest = lowest  = 0.0;
682 /* Generated */    #if !defined( _MANAGED ) && !defined(USE_SINGLE_PRECISION_INPUT) && !defined( _JAVA )
683 /* Generated */       bufferIsAllocated = 0;
684 /* Generated */    #endif
685 /* Generated */    #if defined(USE_SINGLE_PRECISION_INPUT) || defined( USE_SUBARRAY )
686 /* Generated */       ARRAY_ALLOC( tempBuffer, endIdx-today+1 );
687 /* Generated */    #else
688 /* Generated */       if( (outSlowK == inHigh) ||
689 /* Generated */           (outSlowK == inLow)  ||
690 /* Generated */           (outSlowK == inClose) )
691 /* Generated */       {
692 /* Generated */          tempBuffer = outSlowK;
693 /* Generated */       }
694 /* Generated */       else if( (outSlowD == inHigh) ||
695 /* Generated */                (outSlowD == inLow)  ||
696 /* Generated */                (outSlowD == inClose) )
697 /* Generated */       {
698 /* Generated */          tempBuffer = outSlowD;
699 /* Generated */       }
700 /* Generated */       else
701 /* Generated */       {
702 /* Generated */          #if !defined( _MANAGED ) && !defined(_JAVA)
703 /* Generated */             bufferIsAllocated = 1;
704 /* Generated */          #endif
705 /* Generated */          ARRAY_ALLOC( tempBuffer, endIdx-today+1 );
706 /* Generated */       }
707 /* Generated */    #endif
708 /* Generated */    while( today <= endIdx )
709 /* Generated */    {
710 /* Generated */       tmp = inLow[today];
711 /* Generated */       if( lowestIdx < trailingIdx )
712 /* Generated */       {
713 /* Generated */          lowestIdx = trailingIdx;
714 /* Generated */          lowest = inLow[lowestIdx];
715 /* Generated */          i = lowestIdx;
716 /* Generated */          while( ++i<=today )
717 /* Generated */          {
718 /* Generated */             tmp = inLow[i];
719 /* Generated */             if( tmp < lowest )
720 /* Generated */             {
721 /* Generated */                lowestIdx = i;
722 /* Generated */                lowest = tmp;
723 /* Generated */             }
724 /* Generated */          }
725 /* Generated */          diff = (highest - lowest)/100.0;
726 /* Generated */       }
727 /* Generated */       else if( tmp <= lowest )
728 /* Generated */       {
729 /* Generated */          lowestIdx = today;
730 /* Generated */          lowest = tmp;
731 /* Generated */          diff = (highest - lowest)/100.0;
732 /* Generated */       }
733 /* Generated */       tmp = inHigh[today];
734 /* Generated */       if( highestIdx < trailingIdx )
735 /* Generated */       {
736 /* Generated */          highestIdx = trailingIdx;
737 /* Generated */          highest = inHigh[highestIdx];
738 /* Generated */          i = highestIdx;
739 /* Generated */          while( ++i<=today )
740 /* Generated */          {
741 /* Generated */             tmp = inHigh[i];
742 /* Generated */             if( tmp > highest )
743 /* Generated */             {
744 /* Generated */                highestIdx = i;
745 /* Generated */                highest = tmp;
746 /* Generated */             }
747 /* Generated */          }
748 /* Generated */          diff = (highest - lowest)/100.0;
749 /* Generated */       }
750 /* Generated */       else if( tmp >= highest )
751 /* Generated */       {
752 /* Generated */          highestIdx = today;
753 /* Generated */          highest = tmp;
754 /* Generated */          diff = (highest - lowest)/100.0;
755 /* Generated */       }
756 /* Generated */       if( diff != 0.0 )
757 /* Generated */         tempBuffer[outIdx++] = (inClose[today]-lowest)/diff;
758 /* Generated */       else
759 /* Generated */         tempBuffer[outIdx++] = 0.0;
760 /* Generated */       trailingIdx++;
761 /* Generated */       today++;
762 /* Generated */    }
763 /* Generated */    retCode = FUNCTION_CALL_DOUBLE(MA)( 0, outIdx-1,
764 /* Generated */                                        tempBuffer, optInSlowK_Period,
765 /* Generated */                                        optInSlowK_MAType,
766 /* Generated */                                        outBegIdx, outNBElement, tempBuffer );
767 /* Generated */    if( (retCode != ENUM_VALUE(RetCode,TA_SUCCESS,Success) ) || ((int)VALUE_HANDLE_DEREF(outNBElement) == 0) )
768 /* Generated */    {
769 /* Generated */       #if defined(USE_SINGLE_PRECISION_INPUT)
770 /* Generated */          ARRAY_FREE( tempBuffer );
771 /* Generated */       #else
772 /* Generated */          ARRAY_FREE_COND( bufferIsAllocated, tempBuffer );
773 /* Generated */       #endif
774 /* Generated */       VALUE_HANDLE_DEREF_TO_ZERO(outBegIdx);
775 /* Generated */       VALUE_HANDLE_DEREF_TO_ZERO(outNBElement);
776 /* Generated */       return retCode;
777 /* Generated */    }
778 /* Generated */    retCode = FUNCTION_CALL_DOUBLE(MA)( 0, (int)VALUE_HANDLE_DEREF(outNBElement)-1,
779 /* Generated */                                        tempBuffer, optInSlowD_Period,
780 /* Generated */                                        optInSlowD_MAType,
781 /* Generated */                                        outBegIdx, outNBElement, outSlowD );
782 /* Generated */    ARRAY_MEMMOVE( outSlowK, 0, tempBuffer,lookbackDSlow,(int)VALUE_HANDLE_DEREF(outNBElement));
783 /* Generated */    #if defined(USE_SINGLE_PRECISION_INPUT)
784 /* Generated */       ARRAY_FREE( tempBuffer );
785 /* Generated */    #else
786 /* Generated */       ARRAY_FREE_COND( bufferIsAllocated, tempBuffer );
787 /* Generated */    #endif
788 /* Generated */    if( retCode != ENUM_VALUE(RetCode,TA_SUCCESS,Success) )
789 /* Generated */    {
790 /* Generated */       VALUE_HANDLE_DEREF_TO_ZERO(outBegIdx);
791 /* Generated */       VALUE_HANDLE_DEREF_TO_ZERO(outNBElement);
792 /* Generated */       return retCode;
793 /* Generated */    }
794 /* Generated */    VALUE_HANDLE_DEREF(outBegIdx) = startIdx;
795 /* Generated */    return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
796 /* Generated */ }
797 /* Generated */
798 /* Generated */ #if defined( _MANAGED )
799 /* Generated */ }}} // Close namespace TicTacTec.TA.Lib
800 /* Generated */ #endif
801 /**** END GENCODE SECTION 5 - DO NOT DELETE THIS LINE ****/
802 
803