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