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  *  GC       guycom@users.sourceforge.net
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  *  082206 MF   Fix #1544555. Div by zero bug reported by GC.
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 )
AdxLookback(int optInTimePeriod)86 /* Generated */ int Core::AdxLookback( int           optInTimePeriod )  /* From 2 to 100000 */
87 /* Generated */
88 /* Generated */ #elif defined( _JAVA )
89 /* Generated */ public int adxLookback( int           optInTimePeriod )  /* From 2 to 100000 */
90 /* Generated */
91 /* Generated */ #else
92 /* Generated */ int TA_ADX_Lookback( int           optInTimePeriod )  /* From 2 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 < 2) || ((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    return (2 * optInTimePeriod) + TA_GLOBALS_UNSTABLE_PERIOD(TA_FUNC_UNST_ADX,Adx) - 1;
112 }
113 
114 /**** START GENCODE SECTION 3 - DO NOT DELETE THIS LINE ****/
115 /*
116  * TA_ADX - Average Directional Movement Index
117  *
118  * Input  = High, Low, Close
119  * Output = double
120  *
121  * Optional Parameters
122  * -------------------
123  * optInTimePeriod:(From 2 to 100000)
124  *    Number of period
125  *
126  *
127  */
128 /* Generated */
129 /* Generated */ #if defined( _MANAGED ) && defined( USE_SUBARRAY )
130 /* Generated */ enum class Core::RetCode Core::Adx( int    startIdx,
131 /* Generated */                                     int    endIdx,
132 /* Generated */                                     SubArray^    inHigh,
133 /* Generated */                                     SubArray^    inLow,
134 /* Generated */                                     SubArray^    inClose,
135 /* Generated */                                     int           optInTimePeriod, /* From 2 to 100000 */
136 /* Generated */                                     [Out]int%    outBegIdx,
137 /* Generated */                                     [Out]int%    outNBElement,
138 /* Generated */                                     cli::array<double>^  outReal )
139 /* Generated */ #elif defined( _MANAGED )
140 /* Generated */ enum class Core::RetCode Core::Adx( int    startIdx,
141 /* Generated */                                     int    endIdx,
142 /* Generated */                                     cli::array<double>^ inHigh,
143 /* Generated */                                     cli::array<double>^ inLow,
144 /* Generated */                                     cli::array<double>^ inClose,
145 /* Generated */                                     int           optInTimePeriod, /* From 2 to 100000 */
146 /* Generated */                                     [Out]int%    outBegIdx,
147 /* Generated */                                     [Out]int%    outNBElement,
148 /* Generated */                                     cli::array<double>^  outReal )
149 /* Generated */ #elif defined( _JAVA )
150 /* Generated */ public RetCode adx( int    startIdx,
151 /* Generated */                     int    endIdx,
152 /* Generated */                     double       inHigh[],
153 /* Generated */                     double       inLow[],
154 /* Generated */                     double       inClose[],
155 /* Generated */                     int           optInTimePeriod, /* From 2 to 100000 */
156 /* Generated */                     MInteger     outBegIdx,
157 /* Generated */                     MInteger     outNBElement,
158 /* Generated */                     double        outReal[] )
159 /* Generated */ #else
160 /* Generated */ TA_RetCode TA_ADX( int    startIdx,
161 /* Generated */                    int    endIdx,
162 /* Generated */                    const double inHigh[],
163 /* Generated */                    const double inLow[],
164 /* Generated */                    const double inClose[],
165 /* Generated */                    int           optInTimePeriod, /* From 2 to 100000 */
166 /* Generated */                    int          *outBegIdx,
167 /* Generated */                    int          *outNBElement,
168 /* Generated */                    double        outReal[] )
169 /* Generated */ #endif
170 /**** END GENCODE SECTION 3 - DO NOT DELETE THIS LINE ****/
171 {
172 	/* insert local variable here */
173    int today, lookbackTotal, outIdx;
174    double prevHigh, prevLow, prevClose;
175    double prevMinusDM, prevPlusDM, prevTR;
176    double tempReal, tempReal2, diffP, diffM;
177    double minusDI, plusDI, sumDX, prevADX;
178 
179    int i;
180 
181    #define TRUE_RANGE(TH,TL,YC,OUT) {\
182       OUT = TH-TL; \
183       tempReal2 = std_fabs(TH-YC); \
184       if( tempReal2 > OUT ) \
185          OUT = tempReal2; \
186       tempReal2 = std_fabs(TL-YC); \
187       if( tempReal2 > OUT ) \
188          OUT = tempReal2; \
189    }
190 
191 /**** START GENCODE SECTION 4 - DO NOT DELETE THIS LINE ****/
192 /* Generated */
193 /* Generated */ #ifndef TA_FUNC_NO_RANGE_CHECK
194 /* Generated */
195 /* Generated */    /* Validate the requested output range. */
196 /* Generated */    if( startIdx < 0 )
197 /* Generated */       return ENUM_VALUE(RetCode,TA_OUT_OF_RANGE_START_INDEX,OutOfRangeStartIndex);
198 /* Generated */    if( (endIdx < 0) || (endIdx < startIdx))
199 /* Generated */       return ENUM_VALUE(RetCode,TA_OUT_OF_RANGE_END_INDEX,OutOfRangeEndIndex);
200 /* Generated */
201 /* Generated */    #if !defined(_JAVA)
202 /* Generated */    /* Verify required price component. */
203 /* Generated */    if(!inHigh||!inLow||!inClose)
204 /* Generated */       return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
205 /* Generated */
206 /* Generated */    #endif /* !defined(_JAVA)*/
207 /* Generated */    /* min/max are checked for optInTimePeriod. */
208 /* Generated */    if( (int)optInTimePeriod == TA_INTEGER_DEFAULT )
209 /* Generated */       optInTimePeriod = 14;
210 /* Generated */    else if( ((int)optInTimePeriod < 2) || ((int)optInTimePeriod > 100000) )
211 /* Generated */       return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
212 /* Generated */
213 /* Generated */    #if !defined(_JAVA)
214 /* Generated */    if( !outReal )
215 /* Generated */       return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
216 /* Generated */
217 /* Generated */    #endif /* !defined(_JAVA) */
218 /* Generated */ #endif /* TA_FUNC_NO_RANGE_CHECK */
219 /* Generated */
220 /**** END GENCODE SECTION 4 - DO NOT DELETE THIS LINE ****/
221 
222    /* Insert TA function code here. */
223 
224    /*
225     * The DM1 (one period) is base on the largest part of
226     * today's range that is outside of yesterdays range.
227     *
228     * The following 7 cases explain how the +DM and -DM are
229     * calculated on one period:
230     *
231     * Case 1:                       Case 2:
232     *    C|                        A|
233     *     |                         | C|
234     *     | +DM1 = (C-A)           B|  | +DM1 = 0
235     *     | -DM1 = 0                   | -DM1 = (B-D)
236     * A|  |                           D|
237     *  | D|
238     * B|
239     *
240     * Case 3:                       Case 4:
241     *    C|                           C|
242     *     |                        A|  |
243     *     | +DM1 = (C-A)            |  | +DM1 = 0
244     *     | -DM1 = 0               B|  | -DM1 = (B-D)
245     * A|  |                            |
246     *  |  |                           D|
247     * B|  |
248     *    D|
249     *
250     * Case 5:                      Case 6:
251     * A|                           A| C|
252     *  | C| +DM1 = 0                |  |  +DM1 = 0
253     *  |  | -DM1 = 0                |  |  -DM1 = 0
254     *  | D|                         |  |
255     * B|                           B| D|
256     *
257     *
258     * Case 7:
259     *
260     *    C|
261     * A|  |
262     *  |  | +DM=0
263     * B|  | -DM=0
264     *    D|
265     *
266     * In case 3 and 4, the rule is that the smallest delta between
267     * (C-A) and (B-D) determine which of +DM or -DM is zero.
268     *
269     * In case 7, (C-A) and (B-D) are equal, so both +DM and -DM are
270     * zero.
271     *
272     * The rules remain the same when A=B and C=D (when the highs
273     * equal the lows).
274     *
275     * When calculating the DM over a period > 1, the one-period DM
276     * for the desired period are initialy sum. In other word,
277     * for a -DM14, sum the -DM1 for the first 14 days (that's
278     * 13 values because there is no DM for the first day!)
279     * Subsequent DM are calculated using the Wilder's
280     * smoothing approach:
281     *
282     *                                    Previous -DM14
283     *  Today's -DM14 = Previous -DM14 -  -------------- + Today's -DM1
284     *                                         14
285     *
286     * (Same thing for +DM14)
287     *
288     * Calculation of a -DI14 is as follow:
289     *
290     *               -DM14
291     *     -DI14 =  --------
292     *                TR14
293     *
294     * (Same thing for +DI14)
295     *
296     * Calculation of the TR14 is:
297     *
298     *                                   Previous TR14
299     *    Today's TR14 = Previous TR14 - -------------- + Today's TR1
300     *                                         14
301     *
302     *    The first TR14 is the summation of the first 14 TR1. See the
303     *    TA_TRANGE function on how to calculate the true range.
304     *
305     * Calculation of the DX14 is:
306     *
307     *    diffDI = ABS( (-DI14) - (+DI14) )
308     *    sumDI  = (-DI14) + (+DI14)
309     *
310     *    DX14 = 100 * (diffDI / sumDI)
311     *
312     * Calculation of the first ADX:
313     *
314     *    ADX14 = SUM of the first 14 DX
315     *
316     * Calculation of subsequent ADX:
317     *
318     *            ((Previous ADX14)*(14-1))+ Today's DX
319     *    ADX14 = -------------------------------------
320     *                             14
321     *
322     * Reference:
323     *    New Concepts In Technical Trading Systems, J. Welles Wilder Jr
324     */
325 
326    /* Original implementation from Wilder's book was doing some integer
327     * rounding in its calculations.
328     *
329     * This was understandable in the context that at the time the book
330     * was written, most user were doing the calculation by hand.
331     *
332     * For a computer, rounding is unnecessary (and even problematic when inputs
333     * are close to 1).
334     *
335     * TA-Lib does not do the rounding. Still, if you want to reproduce Wilder's examples,
336     * you can comment out the following #undef/#define and rebuild the library.
337     */
338    #undef  round_pos
339    #define round_pos(x) (x)
340 
341    lookbackTotal = (2*optInTimePeriod) + TA_GLOBALS_UNSTABLE_PERIOD(TA_FUNC_UNST_ADX,Adx) - 1;
342 
343    /* Adjust startIdx to account for the lookback period. */
344    if( startIdx < lookbackTotal )
345       startIdx = lookbackTotal;
346 
347    /* Make sure there is still something to evaluate. */
348    if( startIdx > endIdx )
349    {
350       VALUE_HANDLE_DEREF_TO_ZERO(outBegIdx);
351       VALUE_HANDLE_DEREF_TO_ZERO(outNBElement);
352       return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
353    }
354 
355    /* Indicate where the next output should be put
356     * in the outReal.
357     */
358    outIdx = 0;
359 
360    /* Process the initial DM and TR */
361    VALUE_HANDLE_DEREF(outBegIdx) = today = startIdx;
362 
363    prevMinusDM = 0.0;
364    prevPlusDM  = 0.0;
365    prevTR      = 0.0;
366    today       = startIdx - lookbackTotal;
367    prevHigh    = inHigh[today];
368    prevLow     = inLow[today];
369    prevClose   = inClose[today];
370    i           = optInTimePeriod-1;
371    while( i-- > 0 )
372    {
373       /* Calculate the prevMinusDM and prevPlusDM */
374       today++;
375       tempReal = inHigh[today];
376       diffP    = tempReal-prevHigh; /* Plus Delta */
377       prevHigh = tempReal;
378 
379       tempReal = inLow[today];
380       diffM    = prevLow-tempReal;   /* Minus Delta */
381       prevLow  = tempReal;
382 
383       if( (diffM > 0) && (diffP < diffM) )
384       {
385           /* Case 2 and 4: +DM=0,-DM=diffM */
386           prevMinusDM += diffM;
387       }
388       else if( (diffP > 0) && (diffP > diffM) )
389       {
390           /* Case 1 and 3: +DM=diffP,-DM=0 */
391           prevPlusDM += diffP;
392       }
393 
394       TRUE_RANGE(prevHigh,prevLow,prevClose,tempReal);
395       prevTR += tempReal;
396       prevClose = inClose[today];
397    }
398 
399    /* Add up all the initial DX. */
400    sumDX = 0.0;
401    i = optInTimePeriod;
402    while( i-- > 0 )
403    {
404       /* Calculate the prevMinusDM and prevPlusDM */
405       today++;
406       tempReal = inHigh[today];
407       diffP    = tempReal-prevHigh; /* Plus Delta */
408       prevHigh = tempReal;
409 
410       tempReal = inLow[today];
411       diffM    = prevLow-tempReal;   /* Minus Delta */
412       prevLow  = tempReal;
413 
414       prevMinusDM -= prevMinusDM/optInTimePeriod;
415       prevPlusDM  -= prevPlusDM/optInTimePeriod;
416 
417       if( (diffM > 0) && (diffP < diffM) )
418       {
419          /* Case 2 and 4: +DM=0,-DM=diffM */
420          prevMinusDM += diffM;
421       }
422       else if( (diffP > 0) && (diffP > diffM) )
423       {
424          /* Case 1 and 3: +DM=diffP,-DM=0 */
425          prevPlusDM += diffP;
426       }
427 
428       /* Calculate the prevTR */
429       TRUE_RANGE(prevHigh,prevLow,prevClose,tempReal);
430       prevTR = prevTR - (prevTR/optInTimePeriod) + tempReal;
431       prevClose = inClose[today];
432 
433       /* Calculate the DX. The value is rounded (see Wilder book). */
434       if( !TA_IS_ZERO(prevTR) )
435       {
436          minusDI = round_pos(100.0*(prevMinusDM/prevTR));
437          plusDI  = round_pos(100.0*(prevPlusDM/prevTR));
438          /* This loop is just to accumulate the initial DX */
439          tempReal = minusDI+plusDI;
440          if( !TA_IS_ZERO(tempReal) )
441             sumDX  += round_pos( 100.0 * (std_fabs(minusDI-plusDI)/tempReal) );
442       }
443    }
444 
445    /* Calculate the first ADX */
446    prevADX = round_pos( sumDX / optInTimePeriod );
447 
448    /* Skip the unstable period */
449    i = TA_GLOBALS_UNSTABLE_PERIOD(TA_FUNC_UNST_ADX,Adx);
450    while( i-- > 0 )
451    {
452       /* Calculate the prevMinusDM and prevPlusDM */
453       today++;
454       tempReal = inHigh[today];
455       diffP    = tempReal-prevHigh; /* Plus Delta */
456       prevHigh = tempReal;
457 
458       tempReal = inLow[today];
459       diffM    = prevLow-tempReal;   /* Minus Delta */
460       prevLow  = tempReal;
461 
462       prevMinusDM -= prevMinusDM/optInTimePeriod;
463       prevPlusDM  -= prevPlusDM/optInTimePeriod;
464 
465       if( (diffM > 0) && (diffP < diffM) )
466       {
467          /* Case 2 and 4: +DM=0,-DM=diffM */
468          prevMinusDM += diffM;
469       }
470       else if( (diffP > 0) && (diffP > diffM) )
471       {
472          /* Case 1 and 3: +DM=diffP,-DM=0 */
473          prevPlusDM += diffP;
474       }
475 
476       /* Calculate the prevTR */
477       TRUE_RANGE(prevHigh,prevLow,prevClose,tempReal);
478       prevTR = prevTR - (prevTR/optInTimePeriod) + tempReal;
479       prevClose = inClose[today];
480 
481       if( !TA_IS_ZERO(prevTR) )
482       {
483          /* Calculate the DX. The value is rounded (see Wilder book). */
484          minusDI  = round_pos(100.0*(prevMinusDM/prevTR));
485          plusDI   = round_pos(100.0*(prevPlusDM/prevTR));
486          tempReal = minusDI+plusDI;
487          if( !TA_IS_ZERO(tempReal) )
488          {
489             tempReal = round_pos(100.0*(std_fabs(minusDI-plusDI)/tempReal));
490             /* Calculate the ADX */
491             prevADX = round_pos(((prevADX*(optInTimePeriod-1))+tempReal)/optInTimePeriod);
492          }
493       }
494    }
495 
496    /* Output the first ADX */
497    outReal[0] = prevADX;
498    outIdx = 1;
499 
500    /* Calculate and output subsequent ADX */
501    while( today < endIdx )
502    {
503       /* Calculate the prevMinusDM and prevPlusDM */
504       today++;
505       tempReal = inHigh[today];
506       diffP    = tempReal-prevHigh; /* Plus Delta */
507       prevHigh = tempReal;
508 
509       tempReal = inLow[today];
510       diffM    = prevLow-tempReal;   /* Minus Delta */
511       prevLow  = tempReal;
512 
513       prevMinusDM -= prevMinusDM/optInTimePeriod;
514       prevPlusDM  -= prevPlusDM/optInTimePeriod;
515 
516       if( (diffM > 0) && (diffP < diffM) )
517       {
518          /* Case 2 and 4: +DM=0,-DM=diffM */
519          prevMinusDM += diffM;
520       }
521       else if( (diffP > 0) && (diffP > diffM) )
522       {
523          /* Case 1 and 3: +DM=diffP,-DM=0 */
524          prevPlusDM += diffP;
525       }
526 
527       /* Calculate the prevTR */
528       TRUE_RANGE(prevHigh,prevLow,prevClose,tempReal);
529       prevTR = prevTR - (prevTR/optInTimePeriod) + tempReal;
530       prevClose = inClose[today];
531 
532       if( !TA_IS_ZERO(prevTR) )
533       {
534          /* Calculate the DX. The value is rounded (see Wilder book). */
535          minusDI  = round_pos(100.0*(prevMinusDM/prevTR));
536          plusDI   = round_pos(100.0*(prevPlusDM/prevTR));
537          tempReal = minusDI+plusDI;
538          if( !TA_IS_ZERO(tempReal) )
539          {
540             tempReal = round_pos(100.0*(std_fabs(minusDI-plusDI)/tempReal));
541             /* Calculate the ADX */
542             prevADX = round_pos(((prevADX*(optInTimePeriod-1))+tempReal)/optInTimePeriod);
543          }
544       }
545 
546       /* Output the ADX */
547       outReal[outIdx++] = prevADX;
548    }
549 
550    VALUE_HANDLE_DEREF(outNBElement) = outIdx;
551 
552    return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
553 }
554 
555 /**** START GENCODE SECTION 5 - DO NOT DELETE THIS LINE ****/
556 /* Generated */
557 /* Generated */ #define  USE_SINGLE_PRECISION_INPUT
558 /* Generated */ #if !defined( _MANAGED ) && !defined( _JAVA )
559 /* Generated */    #undef   TA_PREFIX
560 /* Generated */    #define  TA_PREFIX(x) TA_S_##x
561 /* Generated */ #endif
562 /* Generated */ #undef   INPUT_TYPE
563 /* Generated */ #define  INPUT_TYPE float
564 /* Generated */ #if defined( _MANAGED )
565 /* Generated */ enum class Core::RetCode Core::Adx( int    startIdx,
566 /* Generated */                                     int    endIdx,
567 /* Generated */                                     cli::array<float>^ inHigh,
568 /* Generated */                                     cli::array<float>^ inLow,
569 /* Generated */                                     cli::array<float>^ inClose,
570 /* Generated */                                     int           optInTimePeriod, /* From 2 to 100000 */
571 /* Generated */                                     [Out]int%    outBegIdx,
572 /* Generated */                                     [Out]int%    outNBElement,
573 /* Generated */                                     cli::array<double>^  outReal )
574 /* Generated */ #elif defined( _JAVA )
575 /* Generated */ public RetCode adx( int    startIdx,
576 /* Generated */                     int    endIdx,
577 /* Generated */                     float        inHigh[],
578 /* Generated */                     float        inLow[],
579 /* Generated */                     float        inClose[],
580 /* Generated */                     int           optInTimePeriod, /* From 2 to 100000 */
581 /* Generated */                     MInteger     outBegIdx,
582 /* Generated */                     MInteger     outNBElement,
583 /* Generated */                     double        outReal[] )
584 /* Generated */ #else
585 /* Generated */ TA_RetCode TA_S_ADX( int    startIdx,
586 /* Generated */                      int    endIdx,
587 /* Generated */                      const float  inHigh[],
588 /* Generated */                      const float  inLow[],
589 /* Generated */                      const float  inClose[],
590 /* Generated */                      int           optInTimePeriod, /* From 2 to 100000 */
591 /* Generated */                      int          *outBegIdx,
592 /* Generated */                      int          *outNBElement,
593 /* Generated */                      double        outReal[] )
594 /* Generated */ #endif
595 /* Generated */ {
596 /* Generated */    int today, lookbackTotal, outIdx;
597 /* Generated */    double prevHigh, prevLow, prevClose;
598 /* Generated */    double prevMinusDM, prevPlusDM, prevTR;
599 /* Generated */    double tempReal, tempReal2, diffP, diffM;
600 /* Generated */    double minusDI, plusDI, sumDX, prevADX;
601 /* Generated */    int i;
602 /* Generated */    #define TRUE_RANGE(TH,TL,YC,OUT) {\
603 /* Generated */       OUT = TH-TL; \
604 /* Generated */       tempReal2 = std_fabs(TH-YC); \
605 /* Generated */       if( tempReal2 > OUT ) \
606 /* Generated */          OUT = tempReal2; \
607 /* Generated */       tempReal2 = std_fabs(TL-YC); \
608 /* Generated */       if( tempReal2 > OUT ) \
609 /* Generated */          OUT = tempReal2; \
610 /* Generated */    }
611 /* Generated */  #ifndef TA_FUNC_NO_RANGE_CHECK
612 /* Generated */     if( startIdx < 0 )
613 /* Generated */        return ENUM_VALUE(RetCode,TA_OUT_OF_RANGE_START_INDEX,OutOfRangeStartIndex);
614 /* Generated */     if( (endIdx < 0) || (endIdx < startIdx))
615 /* Generated */        return ENUM_VALUE(RetCode,TA_OUT_OF_RANGE_END_INDEX,OutOfRangeEndIndex);
616 /* Generated */     #if !defined(_JAVA)
617 /* Generated */     if(!inHigh||!inLow||!inClose)
618 /* Generated */        return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
619 /* Generated */     #endif
620 /* Generated */     if( (int)optInTimePeriod == TA_INTEGER_DEFAULT )
621 /* Generated */        optInTimePeriod = 14;
622 /* Generated */     else if( ((int)optInTimePeriod < 2) || ((int)optInTimePeriod > 100000) )
623 /* Generated */        return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
624 /* Generated */     #if !defined(_JAVA)
625 /* Generated */     if( !outReal )
626 /* Generated */        return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
627 /* Generated */     #endif
628 /* Generated */  #endif
629 /* Generated */    #undef  round_pos
630 /* Generated */    #define round_pos(x) (x)
631 /* Generated */    lookbackTotal = (2*optInTimePeriod) + TA_GLOBALS_UNSTABLE_PERIOD(TA_FUNC_UNST_ADX,Adx) - 1;
632 /* Generated */    if( startIdx < lookbackTotal )
633 /* Generated */       startIdx = lookbackTotal;
634 /* Generated */    if( startIdx > endIdx )
635 /* Generated */    {
636 /* Generated */       VALUE_HANDLE_DEREF_TO_ZERO(outBegIdx);
637 /* Generated */       VALUE_HANDLE_DEREF_TO_ZERO(outNBElement);
638 /* Generated */       return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
639 /* Generated */    }
640 /* Generated */    outIdx = 0;
641 /* Generated */    VALUE_HANDLE_DEREF(outBegIdx) = today = startIdx;
642 /* Generated */    prevMinusDM = 0.0;
643 /* Generated */    prevPlusDM  = 0.0;
644 /* Generated */    prevTR      = 0.0;
645 /* Generated */    today       = startIdx - lookbackTotal;
646 /* Generated */    prevHigh    = inHigh[today];
647 /* Generated */    prevLow     = inLow[today];
648 /* Generated */    prevClose   = inClose[today];
649 /* Generated */    i           = optInTimePeriod-1;
650 /* Generated */    while( i-- > 0 )
651 /* Generated */    {
652 /* Generated */       today++;
653 /* Generated */       tempReal = inHigh[today];
654 /* Generated */       diffP    = tempReal-prevHigh;
655 /* Generated */       prevHigh = tempReal;
656 /* Generated */       tempReal = inLow[today];
657 /* Generated */       diffM    = prevLow-tempReal;
658 /* Generated */       prevLow  = tempReal;
659 /* Generated */       if( (diffM > 0) && (diffP < diffM) )
660 /* Generated */       {
661 /* Generated */           prevMinusDM += diffM;
662 /* Generated */       }
663 /* Generated */       else if( (diffP > 0) && (diffP > diffM) )
664 /* Generated */       {
665 /* Generated */           prevPlusDM += diffP;
666 /* Generated */       }
667 /* Generated */       TRUE_RANGE(prevHigh,prevLow,prevClose,tempReal);
668 /* Generated */       prevTR += tempReal;
669 /* Generated */       prevClose = inClose[today];
670 /* Generated */    }
671 /* Generated */    sumDX = 0.0;
672 /* Generated */    i = optInTimePeriod;
673 /* Generated */    while( i-- > 0 )
674 /* Generated */    {
675 /* Generated */       today++;
676 /* Generated */       tempReal = inHigh[today];
677 /* Generated */       diffP    = tempReal-prevHigh;
678 /* Generated */       prevHigh = tempReal;
679 /* Generated */       tempReal = inLow[today];
680 /* Generated */       diffM    = prevLow-tempReal;
681 /* Generated */       prevLow  = tempReal;
682 /* Generated */       prevMinusDM -= prevMinusDM/optInTimePeriod;
683 /* Generated */       prevPlusDM  -= prevPlusDM/optInTimePeriod;
684 /* Generated */       if( (diffM > 0) && (diffP < diffM) )
685 /* Generated */       {
686 /* Generated */          prevMinusDM += diffM;
687 /* Generated */       }
688 /* Generated */       else if( (diffP > 0) && (diffP > diffM) )
689 /* Generated */       {
690 /* Generated */          prevPlusDM += diffP;
691 /* Generated */       }
692 /* Generated */       TRUE_RANGE(prevHigh,prevLow,prevClose,tempReal);
693 /* Generated */       prevTR = prevTR - (prevTR/optInTimePeriod) + tempReal;
694 /* Generated */       prevClose = inClose[today];
695 /* Generated */       if( !TA_IS_ZERO(prevTR) )
696 /* Generated */       {
697 /* Generated */          minusDI = round_pos(100.0*(prevMinusDM/prevTR));
698 /* Generated */          plusDI  = round_pos(100.0*(prevPlusDM/prevTR));
699 /* Generated */          tempReal = minusDI+plusDI;
700 /* Generated */          if( !TA_IS_ZERO(tempReal) )
701 /* Generated */             sumDX  += round_pos( 100.0 * (std_fabs(minusDI-plusDI)/tempReal) );
702 /* Generated */       }
703 /* Generated */    }
704 /* Generated */    prevADX = round_pos( sumDX / optInTimePeriod );
705 /* Generated */    i = TA_GLOBALS_UNSTABLE_PERIOD(TA_FUNC_UNST_ADX,Adx);
706 /* Generated */    while( i-- > 0 )
707 /* Generated */    {
708 /* Generated */       today++;
709 /* Generated */       tempReal = inHigh[today];
710 /* Generated */       diffP    = tempReal-prevHigh;
711 /* Generated */       prevHigh = tempReal;
712 /* Generated */       tempReal = inLow[today];
713 /* Generated */       diffM    = prevLow-tempReal;
714 /* Generated */       prevLow  = tempReal;
715 /* Generated */       prevMinusDM -= prevMinusDM/optInTimePeriod;
716 /* Generated */       prevPlusDM  -= prevPlusDM/optInTimePeriod;
717 /* Generated */       if( (diffM > 0) && (diffP < diffM) )
718 /* Generated */       {
719 /* Generated */          prevMinusDM += diffM;
720 /* Generated */       }
721 /* Generated */       else if( (diffP > 0) && (diffP > diffM) )
722 /* Generated */       {
723 /* Generated */          prevPlusDM += diffP;
724 /* Generated */       }
725 /* Generated */       TRUE_RANGE(prevHigh,prevLow,prevClose,tempReal);
726 /* Generated */       prevTR = prevTR - (prevTR/optInTimePeriod) + tempReal;
727 /* Generated */       prevClose = inClose[today];
728 /* Generated */       if( !TA_IS_ZERO(prevTR) )
729 /* Generated */       {
730 /* Generated */          minusDI  = round_pos(100.0*(prevMinusDM/prevTR));
731 /* Generated */          plusDI   = round_pos(100.0*(prevPlusDM/prevTR));
732 /* Generated */          tempReal = minusDI+plusDI;
733 /* Generated */          if( !TA_IS_ZERO(tempReal) )
734 /* Generated */          {
735 /* Generated */             tempReal = round_pos(100.0*(std_fabs(minusDI-plusDI)/tempReal));
736 /* Generated */             prevADX = round_pos(((prevADX*(optInTimePeriod-1))+tempReal)/optInTimePeriod);
737 /* Generated */          }
738 /* Generated */       }
739 /* Generated */    }
740 /* Generated */    outReal[0] = prevADX;
741 /* Generated */    outIdx = 1;
742 /* Generated */    while( today < endIdx )
743 /* Generated */    {
744 /* Generated */       today++;
745 /* Generated */       tempReal = inHigh[today];
746 /* Generated */       diffP    = tempReal-prevHigh;
747 /* Generated */       prevHigh = tempReal;
748 /* Generated */       tempReal = inLow[today];
749 /* Generated */       diffM    = prevLow-tempReal;
750 /* Generated */       prevLow  = tempReal;
751 /* Generated */       prevMinusDM -= prevMinusDM/optInTimePeriod;
752 /* Generated */       prevPlusDM  -= prevPlusDM/optInTimePeriod;
753 /* Generated */       if( (diffM > 0) && (diffP < diffM) )
754 /* Generated */       {
755 /* Generated */          prevMinusDM += diffM;
756 /* Generated */       }
757 /* Generated */       else if( (diffP > 0) && (diffP > diffM) )
758 /* Generated */       {
759 /* Generated */          prevPlusDM += diffP;
760 /* Generated */       }
761 /* Generated */       TRUE_RANGE(prevHigh,prevLow,prevClose,tempReal);
762 /* Generated */       prevTR = prevTR - (prevTR/optInTimePeriod) + tempReal;
763 /* Generated */       prevClose = inClose[today];
764 /* Generated */       if( !TA_IS_ZERO(prevTR) )
765 /* Generated */       {
766 /* Generated */          minusDI  = round_pos(100.0*(prevMinusDM/prevTR));
767 /* Generated */          plusDI   = round_pos(100.0*(prevPlusDM/prevTR));
768 /* Generated */          tempReal = minusDI+plusDI;
769 /* Generated */          if( !TA_IS_ZERO(tempReal) )
770 /* Generated */          {
771 /* Generated */             tempReal = round_pos(100.0*(std_fabs(minusDI-plusDI)/tempReal));
772 /* Generated */             prevADX = round_pos(((prevADX*(optInTimePeriod-1))+tempReal)/optInTimePeriod);
773 /* Generated */          }
774 /* Generated */       }
775 /* Generated */       outReal[outIdx++] = prevADX;
776 /* Generated */    }
777 /* Generated */    VALUE_HANDLE_DEREF(outNBElement) = outIdx;
778 /* Generated */    return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
779 /* Generated */ }
780 /* Generated */
781 /* Generated */ #if defined( _MANAGED )
782 /* Generated */ }}} // Close namespace TicTacTec.TA.Lib
783 /* Generated */ #endif
784 /**** END GENCODE SECTION 5 - DO NOT DELETE THIS LINE ****/
785 
786