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