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  *  AM       Adrian Michel
40  *  MIF      Mirek Fontan (mira@fontan.cz)
41  *  CF       Christo Fogelberg
42  *
43  * Change history:
44  *
45  *  MMDDYY BY    Description
46  *  -------------------------------------------------------------------
47  *  010802 MF    Template creation.
48  *  052603 MF    Adapt code to compile with .NET Managed C++
49  *  082303 MF    Fix #792298. Remove rounding. Bug reported by AM.
50  *  062704 MF    Fix #965557. Div by zero bug reported by MIF.
51  *  122204 MF,CF Fix #1090231. Issues when period is 1.
52  */
53 
54 /**** START GENCODE SECTION 1 - DO NOT DELETE THIS LINE ****/
55 /* All code within this section is automatically
56  * generated by gen_code. Any modification will be lost
57  * next time gen_code is run.
58  */
59 /* Generated */
60 /* Generated */ #if defined( _MANAGED )
61 /* Generated */    #include "TA-Lib-Core.h"
62 /* Generated */    #define TA_INTERNAL_ERROR(Id) (RetCode::InternalError)
63 /* Generated */    namespace TicTacTec { namespace TA { namespace Library {
64 /* Generated */ #elif defined( _JAVA )
65 /* Generated */    #include "ta_defs.h"
66 /* Generated */    #include "ta_java_defs.h"
67 /* Generated */    #define TA_INTERNAL_ERROR(Id) (RetCode.InternalError)
68 /* Generated */ #else
69 /* Generated */    #include <string.h>
70 /* Generated */    #include <math.h>
71 /* Generated */    #include "ta_func.h"
72 /* Generated */ #endif
73 /* Generated */
74 /* Generated */ #ifndef TA_UTILITY_H
75 /* Generated */    #include "ta_utility.h"
76 /* Generated */ #endif
77 /* Generated */
78 /* Generated */ #ifndef TA_MEMORY_H
79 /* Generated */    #include "ta_memory.h"
80 /* Generated */ #endif
81 /* Generated */
82 /* Generated */ #define TA_PREFIX(x) TA_##x
83 /* Generated */ #define INPUT_TYPE   double
84 /* Generated */
85 /* Generated */ #if defined( _MANAGED )
PlusDILookback(int optInTimePeriod)86 /* Generated */ int Core::PlusDILookback( int           optInTimePeriod )  /* From 1 to 100000 */
87 /* Generated */
88 /* Generated */ #elif defined( _JAVA )
89 /* Generated */ public int plusDILookback( int           optInTimePeriod )  /* From 1 to 100000 */
90 /* Generated */
91 /* Generated */ #else
92 /* Generated */ int TA_PLUS_DI_Lookback( int           optInTimePeriod )  /* From 1 to 100000 */
93 /* Generated */
94 /* Generated */ #endif
95 /**** END GENCODE SECTION 1 - DO NOT DELETE THIS LINE ****/
96 {
97    /* insert local variable here */
98 
99 /**** START GENCODE SECTION 2 - DO NOT DELETE THIS LINE ****/
100 /* Generated */ #ifndef TA_FUNC_NO_RANGE_CHECK
101 /* Generated */    /* min/max are checked for optInTimePeriod. */
102 /* Generated */    if( (int)optInTimePeriod == TA_INTEGER_DEFAULT )
103 /* Generated */       optInTimePeriod = 14;
104 /* Generated */    else if( ((int)optInTimePeriod < 1) || ((int)optInTimePeriod > 100000) )
105 /* Generated */       return -1;
106 /* Generated */
107 /* Generated */ #endif /* TA_FUNC_NO_RANGE_CHECK */
108 /**** END GENCODE SECTION 2 - DO NOT DELETE THIS LINE ****/
109 
110    /* insert lookback code here. */
111 
112    if( optInTimePeriod > 1 )
113       return optInTimePeriod + TA_GLOBALS_UNSTABLE_PERIOD(TA_FUNC_UNST_PLUS_DI,PlusDI);
114    else
115       return 1;
116 }
117 
118 /**** START GENCODE SECTION 3 - DO NOT DELETE THIS LINE ****/
119 /*
120  * TA_PLUS_DI - Plus Directional Indicator
121  *
122  * Input  = High, Low, Close
123  * Output = double
124  *
125  * Optional Parameters
126  * -------------------
127  * optInTimePeriod:(From 1 to 100000)
128  *    Number of period
129  *
130  *
131  */
132 /* Generated */
133 /* Generated */ #if defined( _MANAGED ) && defined( USE_SUBARRAY )
134 /* Generated */ enum class Core::RetCode Core::PlusDI( int    startIdx,
135 /* Generated */                                        int    endIdx,
136 /* Generated */                                        SubArray^    inHigh,
137 /* Generated */                                        SubArray^    inLow,
138 /* Generated */                                        SubArray^    inClose,
139 /* Generated */                                        int           optInTimePeriod, /* From 1 to 100000 */
140 /* Generated */                                        [Out]int%    outBegIdx,
141 /* Generated */                                        [Out]int%    outNBElement,
142 /* Generated */                                        cli::array<double>^  outReal )
143 /* Generated */ #elif defined( _MANAGED )
144 /* Generated */ enum class Core::RetCode Core::PlusDI( int    startIdx,
145 /* Generated */                                        int    endIdx,
146 /* Generated */                                        cli::array<double>^ inHigh,
147 /* Generated */                                        cli::array<double>^ inLow,
148 /* Generated */                                        cli::array<double>^ inClose,
149 /* Generated */                                        int           optInTimePeriod, /* From 1 to 100000 */
150 /* Generated */                                        [Out]int%    outBegIdx,
151 /* Generated */                                        [Out]int%    outNBElement,
152 /* Generated */                                        cli::array<double>^  outReal )
153 /* Generated */ #elif defined( _JAVA )
154 /* Generated */ public RetCode plusDI( int    startIdx,
155 /* Generated */                        int    endIdx,
156 /* Generated */                        double       inHigh[],
157 /* Generated */                        double       inLow[],
158 /* Generated */                        double       inClose[],
159 /* Generated */                        int           optInTimePeriod, /* From 1 to 100000 */
160 /* Generated */                        MInteger     outBegIdx,
161 /* Generated */                        MInteger     outNBElement,
162 /* Generated */                        double        outReal[] )
163 /* Generated */ #else
164 /* Generated */ TA_RetCode TA_PLUS_DI( int    startIdx,
165 /* Generated */                        int    endIdx,
166 /* Generated */                        const double inHigh[],
167 /* Generated */                        const double inLow[],
168 /* Generated */                        const double inClose[],
169 /* Generated */                        int           optInTimePeriod, /* From 1 to 100000 */
170 /* Generated */                        int          *outBegIdx,
171 /* Generated */                        int          *outNBElement,
172 /* Generated */                        double        outReal[] )
173 /* Generated */ #endif
174 /**** END GENCODE SECTION 3 - DO NOT DELETE THIS LINE ****/
175 {
176 	/* insert local variable here */
177 
178    int today, lookbackTotal, outIdx;
179    double prevHigh, prevLow, prevClose;
180    double prevPlusDM, prevTR;
181    double tempReal, tempReal2, diffP, diffM;
182 
183    int i;
184 
185    #define TRUE_RANGE(TH,TL,YC,OUT) {\
186       OUT = TH-TL; \
187       tempReal2 = std_fabs(TH-YC); \
188       if( tempReal2 > OUT ) \
189          OUT = tempReal2; \
190       tempReal2 = std_fabs(TL-YC); \
191       if( tempReal2 > OUT ) \
192          OUT = tempReal2; \
193    }
194 
195 /**** START GENCODE SECTION 4 - DO NOT DELETE THIS LINE ****/
196 /* Generated */
197 /* Generated */ #ifndef TA_FUNC_NO_RANGE_CHECK
198 /* Generated */
199 /* Generated */    /* Validate the requested output range. */
200 /* Generated */    if( startIdx < 0 )
201 /* Generated */       return ENUM_VALUE(RetCode,TA_OUT_OF_RANGE_START_INDEX,OutOfRangeStartIndex);
202 /* Generated */    if( (endIdx < 0) || (endIdx < startIdx))
203 /* Generated */       return ENUM_VALUE(RetCode,TA_OUT_OF_RANGE_END_INDEX,OutOfRangeEndIndex);
204 /* Generated */
205 /* Generated */    #if !defined(_JAVA)
206 /* Generated */    /* Verify required price component. */
207 /* Generated */    if(!inHigh||!inLow||!inClose)
208 /* Generated */       return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
209 /* Generated */
210 /* Generated */    #endif /* !defined(_JAVA)*/
211 /* Generated */    /* min/max are checked for optInTimePeriod. */
212 /* Generated */    if( (int)optInTimePeriod == TA_INTEGER_DEFAULT )
213 /* Generated */       optInTimePeriod = 14;
214 /* Generated */    else if( ((int)optInTimePeriod < 1) || ((int)optInTimePeriod > 100000) )
215 /* Generated */       return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
216 /* Generated */
217 /* Generated */    #if !defined(_JAVA)
218 /* Generated */    if( !outReal )
219 /* Generated */       return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
220 /* Generated */
221 /* Generated */    #endif /* !defined(_JAVA) */
222 /* Generated */ #endif /* TA_FUNC_NO_RANGE_CHECK */
223 /* Generated */
224 /**** END GENCODE SECTION 4 - DO NOT DELETE THIS LINE ****/
225 
226    /* Insert TA function code here. */
227    /*
228     * The DM1 (one period) is base on the largest part of
229     * today's range that is outside of yesterdays range.
230     *
231     * The following 7 cases explain how the +DM and -DM are
232     * calculated on one period:
233     *
234     * Case 1:                       Case 2:
235     *    C|                        A|
236     *     |                         | C|
237     *     | +DM1 = (C-A)           B|  | +DM1 = 0
238     *     | -DM1 = 0                   | -DM1 = (B-D)
239     * A|  |                           D|
240     *  | D|
241     * B|
242     *
243     * Case 3:                       Case 4:
244     *    C|                           C|
245     *     |                        A|  |
246     *     | +DM1 = (C-A)            |  | +DM1 = 0
247     *     | -DM1 = 0               B|  | -DM1 = (B-D)
248     * A|  |                            |
249     *  |  |                           D|
250     * B|  |
251     *    D|
252     *
253     * Case 5:                      Case 6:
254     * A|                           A| C|
255     *  | C| +DM1 = 0                |  |  +DM1 = 0
256     *  |  | -DM1 = 0                |  |  -DM1 = 0
257     *  | D|                         |  |
258     * B|                           B| D|
259     *
260     *
261     * Case 7:
262     *
263     *    C|
264     * A|  |
265     *  |  | +DM1=0
266     * B|  | -DM1=0
267     *    D|
268     *
269     * In case 3 and 4, the rule is that the smallest delta between
270     * (C-A) and (B-D) determine which of +DM or -DM is zero.
271     *
272     * In case 7, (C-A) and (B-D) are equal, so both +DM and -DM are
273     * zero.
274     *
275     * The rules remain the same when A=B and C=D (when the highs
276     * equal the lows).
277     *
278     * When calculating the DM over a period > 1, the one-period DM
279     * for the desired period are initialy sum. In other word,
280     * for a -DM14, sum the -DM1 for the first 14 days (that's
281     * 13 values because there is no DM for the first day!)
282     * Subsequent DM are calculated using the Wilder's
283     * smoothing approach:
284     *
285     *                                    Previous +DM14
286     *  Today's +DM14 = Previous +DM14 -  -------------- + Today's +DM1
287     *                                         14
288     *
289     * Calculation of a +DI14 is as follow:
290     *
291     *               +DM14
292     *     +DI14 =  --------
293     *                TR14
294     *
295     * Calculation of the TR14 is:
296     *
297     *                                   Previous TR14
298     *    Today's TR14 = Previous TR14 - -------------- + Today's TR1
299     *                                         14
300     *
301     *    The first TR14 is the summation of the first 14 TR1. See the
302     *    TA_TRANGE function on how to calculate the true range.
303     *
304     * Reference:
305     *    New Concepts In Technical Trading Systems, J. Welles Wilder Jr
306     */
307 
308    /* Original implementation from Wilder's book was doing some integer
309     * rounding in its calculations.
310     *
311     * This was understandable in the context that at the time the book
312     * was written, most user were doing the calculation by hand.
313     *
314     * For a computer, rounding is unnecessary (and even problematic when inputs
315     * are close to 1).
316     *
317     * TA-Lib does not do the rounding. Still, if you want to reproduce Wilder's examples,
318     * you can comment out the following #undef/#define and rebuild the library.
319     */
320    #undef  round_pos
321    #define round_pos(x) (x)
322 
323    if( optInTimePeriod > 1 )
324       lookbackTotal = optInTimePeriod + TA_GLOBALS_UNSTABLE_PERIOD(TA_FUNC_UNST_PLUS_DI,PlusDI);
325    else
326       lookbackTotal = 1;
327 
328    /* Adjust startIdx to account for the lookback period. */
329    if( startIdx < lookbackTotal )
330       startIdx = lookbackTotal;
331 
332    /* Make sure there is still something to evaluate. */
333    if( startIdx > endIdx )
334    {
335       VALUE_HANDLE_DEREF_TO_ZERO(outBegIdx);
336       VALUE_HANDLE_DEREF_TO_ZERO(outNBElement);
337       return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
338    }
339 
340    /* Indicate where the next output should be put
341     * in the outReal.
342     */
343    outIdx = 0;
344 
345    /* Trap the case where no smoothing is needed. */
346    if( optInTimePeriod <= 1 )
347    {
348       /* No smoothing needed. Just do the following:
349        * for each price bar.
350        *          +DM1
351        *   +DI1 = ----
352        *           TR1
353        */
354       VALUE_HANDLE_DEREF(outBegIdx) = startIdx;
355       today = startIdx-1;
356       prevHigh  = inHigh[today];
357       prevLow   = inLow[today];
358       prevClose = inClose[today];
359       while( today < endIdx )
360       {
361          today++;
362          tempReal = inHigh[today];
363          diffP    = tempReal-prevHigh; /* Plus Delta */
364          prevHigh = tempReal;
365          tempReal = inLow[today];
366          diffM    = prevLow-tempReal;   /* Minus Delta */
367          prevLow  = tempReal;
368          if( (diffP > 0) && (diffP > diffM) )
369          {
370             /* Case 1 and 3: +DM=diffP,-DM=0 */
371             TRUE_RANGE(prevHigh,prevLow,prevClose,tempReal);
372             if( TA_IS_ZERO(tempReal) )
373                outReal[outIdx++] = (double)0.0;
374             else
375                outReal[outIdx++] = diffP/tempReal;
376          }
377          else
378             outReal[outIdx++] = (double)0.0;
379          prevClose = inClose[today];
380       }
381 
382       VALUE_HANDLE_DEREF(outNBElement) = outIdx;
383       return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
384    }
385 
386    /* Process the initial DM and TR */
387    VALUE_HANDLE_DEREF(outBegIdx) = today = startIdx;
388 
389    prevPlusDM  = 0.0;
390    prevTR      = 0.0;
391    today       = startIdx - lookbackTotal;
392    prevHigh    = inHigh[today];
393    prevLow     = inLow[today];
394    prevClose   = inClose[today];
395    i           = optInTimePeriod-1;
396    while( i-- > 0 )
397    {
398       today++;
399       tempReal = inHigh[today];
400       diffP    = tempReal-prevHigh; /* Plus Delta */
401       prevHigh = tempReal;
402 
403       tempReal = inLow[today];
404       diffM    = prevLow-tempReal;   /* Minus Delta */
405       prevLow  = tempReal;
406       if( (diffP > 0) && (diffP > diffM) )
407       {
408          /* Case 1 and 3: +DM=diffP,-DM=0 */
409          prevPlusDM += diffP;
410       }
411 
412       TRUE_RANGE(prevHigh,prevLow,prevClose,tempReal);
413       prevTR += tempReal;
414       prevClose = inClose[today];
415    }
416 
417    /* Process subsequent DI */
418 
419    /* Skip the unstable period. Note that this loop must be executed
420     * at least ONCE to calculate the first DI.
421     */
422    i = TA_GLOBALS_UNSTABLE_PERIOD(TA_FUNC_UNST_PLUS_DI,PlusDI) + 1;
423    while( i-- != 0 )
424    {
425       /* Calculate the prevPlusDM */
426       today++;
427       tempReal = inHigh[today];
428       diffP    = tempReal-prevHigh; /* Plus Delta */
429       prevHigh = tempReal;
430       tempReal = inLow[today];
431       diffM    = prevLow-tempReal;   /* Minus Delta */
432       prevLow  = tempReal;
433       if( (diffP > 0) && (diffP > diffM) )
434       {
435          /* Case 1 and 3: +DM=diffP,-DM=0 */
436          prevPlusDM = prevPlusDM - (prevPlusDM/optInTimePeriod) + diffP;
437       }
438       else
439       {
440          /* Case 2,4,5 and 7 */
441          prevPlusDM = prevPlusDM - (prevPlusDM/optInTimePeriod);
442       }
443 
444       /* Calculate the prevTR */
445       TRUE_RANGE(prevHigh,prevLow,prevClose,tempReal);
446       prevTR = prevTR - (prevTR/optInTimePeriod) + tempReal;
447       prevClose = inClose[today];
448    }
449 
450    /* Now start to write the output in
451     * the caller provided outReal.
452     */
453 
454    if( !TA_IS_ZERO(prevTR) )
455       outReal[0] = round_pos(100.0*(prevPlusDM/prevTR));
456    else
457       outReal[0] = 0.0;
458    outIdx = 1;
459 
460    while( today < endIdx )
461    {
462       /* Calculate the prevPlusDM */
463       today++;
464       tempReal = inHigh[today];
465       diffP    = tempReal-prevHigh; /* Plus Delta */
466       prevHigh = tempReal;
467       tempReal = inLow[today];
468       diffM    = prevLow-tempReal;   /* Minus Delta */
469       prevLow  = tempReal;
470       if( (diffP > 0) && (diffP > diffM) )
471       {
472          /* Case 1 and 3: +DM=diffP,-DM=0 */
473          prevPlusDM = prevPlusDM - (prevPlusDM/optInTimePeriod) + diffP;
474       }
475       else
476       {
477          /* Case 2,4,5 and 7 */
478          prevPlusDM = prevPlusDM - (prevPlusDM/optInTimePeriod);
479       }
480 
481       /* Calculate the prevTR */
482       TRUE_RANGE(prevHigh,prevLow,prevClose,tempReal);
483       prevTR = prevTR - (prevTR/optInTimePeriod) + tempReal;
484       prevClose = inClose[today];
485 
486       /* Calculate the DI. The value is rounded (see Wilder book). */
487       if( !TA_IS_ZERO(prevTR) )
488          outReal[outIdx++] = round_pos(100.0*(prevPlusDM/prevTR));
489       else
490          outReal[outIdx++] = 0.0;
491 
492    }
493 
494    VALUE_HANDLE_DEREF(outNBElement) = outIdx;
495 
496    return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
497 }
498 
499 /**** START GENCODE SECTION 5 - DO NOT DELETE THIS LINE ****/
500 /* Generated */
501 /* Generated */ #define  USE_SINGLE_PRECISION_INPUT
502 /* Generated */ #if !defined( _MANAGED ) && !defined( _JAVA )
503 /* Generated */    #undef   TA_PREFIX
504 /* Generated */    #define  TA_PREFIX(x) TA_S_##x
505 /* Generated */ #endif
506 /* Generated */ #undef   INPUT_TYPE
507 /* Generated */ #define  INPUT_TYPE float
508 /* Generated */ #if defined( _MANAGED )
509 /* Generated */ enum class Core::RetCode Core::PlusDI( int    startIdx,
510 /* Generated */                                        int    endIdx,
511 /* Generated */                                        cli::array<float>^ inHigh,
512 /* Generated */                                        cli::array<float>^ inLow,
513 /* Generated */                                        cli::array<float>^ inClose,
514 /* Generated */                                        int           optInTimePeriod, /* From 1 to 100000 */
515 /* Generated */                                        [Out]int%    outBegIdx,
516 /* Generated */                                        [Out]int%    outNBElement,
517 /* Generated */                                        cli::array<double>^  outReal )
518 /* Generated */ #elif defined( _JAVA )
519 /* Generated */ public RetCode plusDI( int    startIdx,
520 /* Generated */                        int    endIdx,
521 /* Generated */                        float        inHigh[],
522 /* Generated */                        float        inLow[],
523 /* Generated */                        float        inClose[],
524 /* Generated */                        int           optInTimePeriod, /* From 1 to 100000 */
525 /* Generated */                        MInteger     outBegIdx,
526 /* Generated */                        MInteger     outNBElement,
527 /* Generated */                        double        outReal[] )
528 /* Generated */ #else
529 /* Generated */ TA_RetCode TA_S_PLUS_DI( int    startIdx,
530 /* Generated */                          int    endIdx,
531 /* Generated */                          const float  inHigh[],
532 /* Generated */                          const float  inLow[],
533 /* Generated */                          const float  inClose[],
534 /* Generated */                          int           optInTimePeriod, /* From 1 to 100000 */
535 /* Generated */                          int          *outBegIdx,
536 /* Generated */                          int          *outNBElement,
537 /* Generated */                          double        outReal[] )
538 /* Generated */ #endif
539 /* Generated */ {
540 /* Generated */    int today, lookbackTotal, outIdx;
541 /* Generated */    double prevHigh, prevLow, prevClose;
542 /* Generated */    double prevPlusDM, prevTR;
543 /* Generated */    double tempReal, tempReal2, diffP, diffM;
544 /* Generated */    int i;
545 /* Generated */    #define TRUE_RANGE(TH,TL,YC,OUT) {\
546 /* Generated */       OUT = TH-TL; \
547 /* Generated */       tempReal2 = std_fabs(TH-YC); \
548 /* Generated */       if( tempReal2 > OUT ) \
549 /* Generated */          OUT = tempReal2; \
550 /* Generated */       tempReal2 = std_fabs(TL-YC); \
551 /* Generated */       if( tempReal2 > OUT ) \
552 /* Generated */          OUT = tempReal2; \
553 /* Generated */    }
554 /* Generated */  #ifndef TA_FUNC_NO_RANGE_CHECK
555 /* Generated */     if( startIdx < 0 )
556 /* Generated */        return ENUM_VALUE(RetCode,TA_OUT_OF_RANGE_START_INDEX,OutOfRangeStartIndex);
557 /* Generated */     if( (endIdx < 0) || (endIdx < startIdx))
558 /* Generated */        return ENUM_VALUE(RetCode,TA_OUT_OF_RANGE_END_INDEX,OutOfRangeEndIndex);
559 /* Generated */     #if !defined(_JAVA)
560 /* Generated */     if(!inHigh||!inLow||!inClose)
561 /* Generated */        return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
562 /* Generated */     #endif
563 /* Generated */     if( (int)optInTimePeriod == TA_INTEGER_DEFAULT )
564 /* Generated */        optInTimePeriod = 14;
565 /* Generated */     else if( ((int)optInTimePeriod < 1) || ((int)optInTimePeriod > 100000) )
566 /* Generated */        return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
567 /* Generated */     #if !defined(_JAVA)
568 /* Generated */     if( !outReal )
569 /* Generated */        return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
570 /* Generated */     #endif
571 /* Generated */  #endif
572 /* Generated */    #undef  round_pos
573 /* Generated */    #define round_pos(x) (x)
574 /* Generated */    if( optInTimePeriod > 1 )
575 /* Generated */       lookbackTotal = optInTimePeriod + TA_GLOBALS_UNSTABLE_PERIOD(TA_FUNC_UNST_PLUS_DI,PlusDI);
576 /* Generated */    else
577 /* Generated */       lookbackTotal = 1;
578 /* Generated */    if( startIdx < lookbackTotal )
579 /* Generated */       startIdx = lookbackTotal;
580 /* Generated */    if( startIdx > endIdx )
581 /* Generated */    {
582 /* Generated */       VALUE_HANDLE_DEREF_TO_ZERO(outBegIdx);
583 /* Generated */       VALUE_HANDLE_DEREF_TO_ZERO(outNBElement);
584 /* Generated */       return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
585 /* Generated */    }
586 /* Generated */    outIdx = 0;
587 /* Generated */    if( optInTimePeriod <= 1 )
588 /* Generated */    {
589 /* Generated */       VALUE_HANDLE_DEREF(outBegIdx) = startIdx;
590 /* Generated */       today = startIdx-1;
591 /* Generated */       prevHigh  = inHigh[today];
592 /* Generated */       prevLow   = inLow[today];
593 /* Generated */       prevClose = inClose[today];
594 /* Generated */       while( today < endIdx )
595 /* Generated */       {
596 /* Generated */          today++;
597 /* Generated */          tempReal = inHigh[today];
598 /* Generated */          diffP    = tempReal-prevHigh;
599 /* Generated */          prevHigh = tempReal;
600 /* Generated */          tempReal = inLow[today];
601 /* Generated */          diffM    = prevLow-tempReal;
602 /* Generated */          prevLow  = tempReal;
603 /* Generated */          if( (diffP > 0) && (diffP > diffM) )
604 /* Generated */          {
605 /* Generated */             TRUE_RANGE(prevHigh,prevLow,prevClose,tempReal);
606 /* Generated */             if( TA_IS_ZERO(tempReal) )
607 /* Generated */                outReal[outIdx++] = (double)0.0;
608 /* Generated */             else
609 /* Generated */                outReal[outIdx++] = diffP/tempReal;
610 /* Generated */          }
611 /* Generated */          else
612 /* Generated */             outReal[outIdx++] = (double)0.0;
613 /* Generated */          prevClose = inClose[today];
614 /* Generated */       }
615 /* Generated */       VALUE_HANDLE_DEREF(outNBElement) = outIdx;
616 /* Generated */       return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
617 /* Generated */    }
618 /* Generated */    VALUE_HANDLE_DEREF(outBegIdx) = today = startIdx;
619 /* Generated */    prevPlusDM  = 0.0;
620 /* Generated */    prevTR      = 0.0;
621 /* Generated */    today       = startIdx - lookbackTotal;
622 /* Generated */    prevHigh    = inHigh[today];
623 /* Generated */    prevLow     = inLow[today];
624 /* Generated */    prevClose   = inClose[today];
625 /* Generated */    i           = optInTimePeriod-1;
626 /* Generated */    while( i-- > 0 )
627 /* Generated */    {
628 /* Generated */       today++;
629 /* Generated */       tempReal = inHigh[today];
630 /* Generated */       diffP    = tempReal-prevHigh;
631 /* Generated */       prevHigh = tempReal;
632 /* Generated */       tempReal = inLow[today];
633 /* Generated */       diffM    = prevLow-tempReal;
634 /* Generated */       prevLow  = tempReal;
635 /* Generated */       if( (diffP > 0) && (diffP > diffM) )
636 /* Generated */       {
637 /* Generated */          prevPlusDM += diffP;
638 /* Generated */       }
639 /* Generated */       TRUE_RANGE(prevHigh,prevLow,prevClose,tempReal);
640 /* Generated */       prevTR += tempReal;
641 /* Generated */       prevClose = inClose[today];
642 /* Generated */    }
643 /* Generated */    i = TA_GLOBALS_UNSTABLE_PERIOD(TA_FUNC_UNST_PLUS_DI,PlusDI) + 1;
644 /* Generated */    while( i-- != 0 )
645 /* Generated */    {
646 /* Generated */       today++;
647 /* Generated */       tempReal = inHigh[today];
648 /* Generated */       diffP    = tempReal-prevHigh;
649 /* Generated */       prevHigh = tempReal;
650 /* Generated */       tempReal = inLow[today];
651 /* Generated */       diffM    = prevLow-tempReal;
652 /* Generated */       prevLow  = tempReal;
653 /* Generated */       if( (diffP > 0) && (diffP > diffM) )
654 /* Generated */       {
655 /* Generated */          prevPlusDM = prevPlusDM - (prevPlusDM/optInTimePeriod) + diffP;
656 /* Generated */       }
657 /* Generated */       else
658 /* Generated */       {
659 /* Generated */          prevPlusDM = prevPlusDM - (prevPlusDM/optInTimePeriod);
660 /* Generated */       }
661 /* Generated */       TRUE_RANGE(prevHigh,prevLow,prevClose,tempReal);
662 /* Generated */       prevTR = prevTR - (prevTR/optInTimePeriod) + tempReal;
663 /* Generated */       prevClose = inClose[today];
664 /* Generated */    }
665 /* Generated */    if( !TA_IS_ZERO(prevTR) )
666 /* Generated */       outReal[0] = round_pos(100.0*(prevPlusDM/prevTR));
667 /* Generated */    else
668 /* Generated */       outReal[0] = 0.0;
669 /* Generated */    outIdx = 1;
670 /* Generated */    while( today < endIdx )
671 /* Generated */    {
672 /* Generated */       today++;
673 /* Generated */       tempReal = inHigh[today];
674 /* Generated */       diffP    = tempReal-prevHigh;
675 /* Generated */       prevHigh = tempReal;
676 /* Generated */       tempReal = inLow[today];
677 /* Generated */       diffM    = prevLow-tempReal;
678 /* Generated */       prevLow  = tempReal;
679 /* Generated */       if( (diffP > 0) && (diffP > diffM) )
680 /* Generated */       {
681 /* Generated */          prevPlusDM = prevPlusDM - (prevPlusDM/optInTimePeriod) + diffP;
682 /* Generated */       }
683 /* Generated */       else
684 /* Generated */       {
685 /* Generated */          prevPlusDM = prevPlusDM - (prevPlusDM/optInTimePeriod);
686 /* Generated */       }
687 /* Generated */       TRUE_RANGE(prevHigh,prevLow,prevClose,tempReal);
688 /* Generated */       prevTR = prevTR - (prevTR/optInTimePeriod) + tempReal;
689 /* Generated */       prevClose = inClose[today];
690 /* Generated */       if( !TA_IS_ZERO(prevTR) )
691 /* Generated */          outReal[outIdx++] = round_pos(100.0*(prevPlusDM/prevTR));
692 /* Generated */       else
693 /* Generated */          outReal[outIdx++] = 0.0;
694 /* Generated */    }
695 /* Generated */    VALUE_HANDLE_DEREF(outNBElement) = outIdx;
696 /* Generated */    return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
697 /* Generated */ }
698 /* Generated */
699 /* Generated */ #if defined( _MANAGED )
700 /* Generated */ }}} // Close namespace TicTacTec.TA.Lib
701 /* Generated */ #endif
702 /**** END GENCODE SECTION 5 - DO NOT DELETE THIS LINE ****/
703 
704