1 /* TA-LIB Copyright (c) 1999-2007, Mario Fortier
2 * All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or
5 * without modification, are permitted provided that the following
6 * conditions are met:
7 *
8 * - Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * - Neither name of author nor the names of its contributors
17 * may be used to endorse or promote products derived from this
18 * software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
30 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
31 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 /* List of contributors:
35 *
36 * Initial Name/description
37 * -------------------------------------------------------------------
38 * MF Mario Fortier
39 *
40 *
41 * Change history:
42 *
43 * MMDDYY BY Description
44 * -------------------------------------------------------------------
45 * 120802 MF Template creation.
46 * 052603 MF Adapt code to compile with .NET Managed C++
47 *
48 */
49
50 /**** START GENCODE SECTION 1 - DO NOT DELETE THIS LINE ****/
51 /* All code within this section is automatically
52 * generated by gen_code. Any modification will be lost
53 * next time gen_code is run.
54 */
55 /* Generated */
56 /* Generated */ #if defined( _MANAGED )
57 /* Generated */ #include "TA-Lib-Core.h"
58 /* Generated */ #define TA_INTERNAL_ERROR(Id) (RetCode::InternalError)
59 /* Generated */ namespace TicTacTec { namespace TA { namespace Library {
60 /* Generated */ #elif defined( _JAVA )
61 /* Generated */ #include "ta_defs.h"
62 /* Generated */ #include "ta_java_defs.h"
63 /* Generated */ #define TA_INTERNAL_ERROR(Id) (RetCode.InternalError)
64 /* Generated */ #else
65 /* Generated */ #include <string.h>
66 /* Generated */ #include <math.h>
67 /* Generated */ #include "ta_func.h"
68 /* Generated */ #endif
69 /* Generated */
70 /* Generated */ #ifndef TA_UTILITY_H
71 /* Generated */ #include "ta_utility.h"
72 /* Generated */ #endif
73 /* Generated */
74 /* Generated */ #ifndef TA_MEMORY_H
75 /* Generated */ #include "ta_memory.h"
76 /* Generated */ #endif
77 /* Generated */
78 /* Generated */ #define TA_PREFIX(x) TA_##x
79 /* Generated */ #define INPUT_TYPE double
80 /* Generated */
81 /* Generated */ #if defined( _MANAGED )
HtDcPhaseLookback(void)82 /* Generated */ int Core::HtDcPhaseLookback( void )
83 /* Generated */
84 /* Generated */ #elif defined( _JAVA )
85 /* Generated */ public int htDcPhaseLookback( )
86 /* Generated */
87 /* Generated */ #else
88 /* Generated */ int TA_HT_DCPHASE_Lookback( void )
89 /* Generated */
90 /* Generated */ #endif
91 /**** END GENCODE SECTION 1 - DO NOT DELETE THIS LINE ****/
92 {
93 /* insert local variable here */
94
95 /**** START GENCODE SECTION 2 - DO NOT DELETE THIS LINE ****/
96 /* Generated */ /* No parameters to validate. */
97 /**** END GENCODE SECTION 2 - DO NOT DELETE THIS LINE ****/
98
99 /* insert lookback code here. */
100
101 /* 31 input are skip
102 * +32 output are skip to account for misc lookback
103 * ---
104 * 63 Total Lookback
105 *
106 * 31 is for being compatible with Tradestation.
107 * See TA_MAMA_Lookback for an explanation of the "32".
108 */
109 return 63 + TA_GLOBALS_UNSTABLE_PERIOD(TA_FUNC_UNST_HT_DCPHASE,HtDcPhase);
110 }
111
112 /**** START GENCODE SECTION 3 - DO NOT DELETE THIS LINE ****/
113 /*
114 * TA_HT_DCPHASE - Hilbert Transform - Dominant Cycle Phase
115 *
116 * Input = double
117 * Output = double
118 *
119 */
120 /* Generated */
121 /* Generated */ #if defined( _MANAGED ) && defined( USE_SUBARRAY )
122 /* Generated */ enum class Core::RetCode Core::HtDcPhase( int startIdx,
123 /* Generated */ int endIdx,
124 /* Generated */ SubArray^ inReal,
125 /* Generated */ [Out]int% outBegIdx,
126 /* Generated */ [Out]int% outNBElement,
127 /* Generated */ cli::array<double>^ outReal )
128 /* Generated */ #elif defined( _MANAGED )
129 /* Generated */ enum class Core::RetCode Core::HtDcPhase( int startIdx,
130 /* Generated */ int endIdx,
131 /* Generated */ cli::array<double>^ inReal,
132 /* Generated */ [Out]int% outBegIdx,
133 /* Generated */ [Out]int% outNBElement,
134 /* Generated */ cli::array<double>^ outReal )
135 /* Generated */ #elif defined( _JAVA )
136 /* Generated */ public RetCode htDcPhase( int startIdx,
137 /* Generated */ int endIdx,
138 /* Generated */ double inReal[],
139 /* Generated */ MInteger outBegIdx,
140 /* Generated */ MInteger outNBElement,
141 /* Generated */ double outReal[] )
142 /* Generated */ #else
143 /* Generated */ TA_RetCode TA_HT_DCPHASE( int startIdx,
144 /* Generated */ int endIdx,
145 /* Generated */ const double inReal[],
146 /* Generated */ int *outBegIdx,
147 /* Generated */ int *outNBElement,
148 /* Generated */ double outReal[] )
149 /* Generated */ #endif
150 /**** END GENCODE SECTION 3 - DO NOT DELETE THIS LINE ****/
151 {
152 /* insert local variable here */
153 int outIdx, i;
154 int lookbackTotal, today;
155 double tempReal, tempReal2;
156
157 double adjustedPrevPeriod, period;
158
159 /* Variable used for the price smoother (a weighted moving average). */
160 int trailingWMAIdx;
161 double periodWMASum, periodWMASub, trailingWMAValue;
162 double smoothedValue;
163
164 /* Variables used for the Hilbert Transormation */
165 CONSTANT_DOUBLE(a) = 0.0962;
166 CONSTANT_DOUBLE(b) = 0.5769;
167 double hilbertTempReal;
168 int hilbertIdx;
169
170 HILBERT_VARIABLES( detrender );
171 HILBERT_VARIABLES( Q1 );
172 HILBERT_VARIABLES( jI );
173 HILBERT_VARIABLES( jQ );
174
175 double Q2, I2, prevQ2, prevI2, Re, Im;
176
177 double I1ForOddPrev2, I1ForOddPrev3;
178 double I1ForEvenPrev2, I1ForEvenPrev3;
179
180 double rad2Deg, constDeg2RadBy360;
181
182 double todayValue, smoothPeriod;
183
184 /* Varaible used to keep track of the previous
185 * smooth price. In the case of this algorithm,
186 * we will never need more than 50 values.
187 */
188 #define SMOOTH_PRICE_SIZE 50
189 CIRCBUF_PROLOG(smoothPrice,double,SMOOTH_PRICE_SIZE);
190 int idx;
191
192 /* Variable used to calculate the dominant cycle phase */
193 int DCPeriodInt;
194 double DCPhase, DCPeriod, imagPart, realPart;
195
196 /**** START GENCODE SECTION 4 - DO NOT DELETE THIS LINE ****/
197 /* Generated */
198 /* Generated */ #ifndef TA_FUNC_NO_RANGE_CHECK
199 /* Generated */
200 /* Generated */ /* Validate the requested output range. */
201 /* Generated */ if( startIdx < 0 )
202 /* Generated */ return ENUM_VALUE(RetCode,TA_OUT_OF_RANGE_START_INDEX,OutOfRangeStartIndex);
203 /* Generated */ if( (endIdx < 0) || (endIdx < startIdx))
204 /* Generated */ return ENUM_VALUE(RetCode,TA_OUT_OF_RANGE_END_INDEX,OutOfRangeEndIndex);
205 /* Generated */
206 /* Generated */ #if !defined(_JAVA)
207 /* Generated */ if( !inReal ) return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
208 /* Generated */ #endif /* !defined(_JAVA)*/
209 /* Generated */ #if !defined(_JAVA)
210 /* Generated */ if( !outReal )
211 /* Generated */ return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
212 /* Generated */
213 /* Generated */ #endif /* !defined(_JAVA) */
214 /* Generated */ #endif /* TA_FUNC_NO_RANGE_CHECK */
215 /* Generated */
216 /**** END GENCODE SECTION 4 - DO NOT DELETE THIS LINE ****/
217
218 /* Insert TA function code here. */
219
220 CIRCBUF_INIT_LOCAL_ONLY(smoothPrice,double);
221
222 /* Constant */
223 tempReal = std_atan(1);
224 rad2Deg = 45.0/tempReal;
225 constDeg2RadBy360 = tempReal*8.0;
226
227 /* Identify the minimum number of price bar needed
228 * to calculate at least one output.
229 */
230 lookbackTotal = 63 + TA_GLOBALS_UNSTABLE_PERIOD(TA_FUNC_UNST_HT_DCPHASE,HtDcPhase);
231
232 /* Move up the start index if there is not
233 * enough initial data.
234 */
235 if( startIdx < lookbackTotal )
236 startIdx = lookbackTotal;
237
238 /* Make sure there is still something to evaluate. */
239 if( startIdx > endIdx )
240 {
241 VALUE_HANDLE_DEREF_TO_ZERO(outBegIdx);
242 VALUE_HANDLE_DEREF_TO_ZERO(outNBElement);
243 return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
244 }
245
246 VALUE_HANDLE_DEREF(outBegIdx) = startIdx;
247
248 /* Initialize the price smoother, which is simply a weighted
249 * moving average of the price.
250 * To understand this algorithm, I strongly suggest to understand
251 * first how TA_WMA is done.
252 */
253 trailingWMAIdx = startIdx - lookbackTotal;
254 today = trailingWMAIdx;
255
256 /* Initialization is same as WMA, except loop is unrolled
257 * for speed optimization.
258 */
259 tempReal = inReal[today++];
260 periodWMASub = tempReal;
261 periodWMASum = tempReal;
262 tempReal = inReal[today++];
263 periodWMASub += tempReal;
264 periodWMASum += tempReal*2.0;
265 tempReal = inReal[today++];
266 periodWMASub += tempReal;
267 periodWMASum += tempReal*3.0;
268
269 trailingWMAValue = 0.0;
270
271 /* Subsequent WMA value are evaluated by using
272 * the DO_PRICE_WMA macro.
273 */
274 #define DO_PRICE_WMA(varNewPrice,varToStoreSmoothedValue) { \
275 periodWMASub += varNewPrice; \
276 periodWMASub -= trailingWMAValue; \
277 periodWMASum += varNewPrice*4.0; \
278 trailingWMAValue = inReal[trailingWMAIdx++]; \
279 varToStoreSmoothedValue = periodWMASum*0.1; \
280 periodWMASum -= periodWMASub; \
281 }
282
283 i = 34;
284 do
285 {
286 tempReal = inReal[today++];
287 DO_PRICE_WMA(tempReal,smoothedValue);
288 } while( --i != 0);
289
290 /* Initialize the circular buffers used by the hilbert
291 * transform logic.
292 * A buffer is used for odd day and another for even days.
293 * This minimize the number of memory access and floating point
294 * operations needed (note also that by using static circular buffer,
295 * no large dynamic memory allocation is needed for storing
296 * intermediate calculation!).
297 */
298 hilbertIdx = 0;
299
300 INIT_HILBERT_VARIABLES(detrender);
301 INIT_HILBERT_VARIABLES(Q1);
302 INIT_HILBERT_VARIABLES(jI);
303 INIT_HILBERT_VARIABLES(jQ);
304
305 period = 0.0;
306 outIdx = 0;
307
308 prevI2 = prevQ2 = 0.0;
309 Re = Im = 0.0;
310 I1ForOddPrev3 = I1ForEvenPrev3 = 0.0;
311 I1ForOddPrev2 = I1ForEvenPrev2 = 0.0;
312 smoothPeriod = 0.0;
313
314 for( i=0; i < SMOOTH_PRICE_SIZE; i++ )
315 smoothPrice[i] = 0.0;
316
317 /* The code is speed optimized and is most likely very
318 * hard to follow if you do not already know well the
319 * original algorithm.
320 * To understadn better, it is strongly suggested to look
321 * first at the Excel implementation in "test_MAMA.xls" included
322 * in this package.
323 */
324 DCPhase = 0.0;
325 while( today <= endIdx )
326 {
327 adjustedPrevPeriod = (0.075*period)+0.54;
328
329 todayValue = inReal[today];
330 DO_PRICE_WMA(todayValue,smoothedValue);
331
332 /* Remember the smoothedValue into the smoothPrice
333 * circular buffer.
334 */
335 smoothPrice[smoothPrice_Idx] = smoothedValue;
336
337 if( (today%2) == 0 )
338 {
339 /* Do the Hilbert Transforms for even price bar */
340 DO_HILBERT_EVEN(detrender,smoothedValue);
341 DO_HILBERT_EVEN(Q1,detrender);
342 DO_HILBERT_EVEN(jI,I1ForEvenPrev3);
343 DO_HILBERT_EVEN(jQ,Q1);
344 if( ++hilbertIdx == 3 )
345 hilbertIdx = 0;
346
347 Q2 = (0.2*(Q1 + jI)) + (0.8*prevQ2);
348 I2 = (0.2*(I1ForEvenPrev3 - jQ)) + (0.8*prevI2);
349
350 /* The variable I1 is the detrender delayed for
351 * 3 price bars.
352 *
353 * Save the current detrender value for being
354 * used by the "odd" logic later.
355 */
356 I1ForOddPrev3 = I1ForOddPrev2;
357 I1ForOddPrev2 = detrender;
358 }
359 else
360 {
361 /* Do the Hilbert Transforms for odd price bar */
362 DO_HILBERT_ODD(detrender,smoothedValue);
363 DO_HILBERT_ODD(Q1,detrender);
364 DO_HILBERT_ODD(jI,I1ForOddPrev3);
365 DO_HILBERT_ODD(jQ,Q1);
366
367 Q2 = (0.2*(Q1 + jI)) + (0.8*prevQ2);
368 I2 = (0.2*(I1ForOddPrev3 - jQ)) + (0.8*prevI2);
369
370 /* The varaiable I1 is the detrender delayed for
371 * 3 price bars.
372 *
373 * Save the current detrender value for being
374 * used by the "even" logic later.
375 */
376 I1ForEvenPrev3 = I1ForEvenPrev2;
377 I1ForEvenPrev2 = detrender;
378 }
379
380 /* Adjust the period for next price bar */
381 Re = (0.2*((I2*prevI2)+(Q2*prevQ2)))+(0.8*Re);
382 Im = (0.2*((I2*prevQ2)-(Q2*prevI2)))+(0.8*Im);
383 prevQ2 = Q2;
384 prevI2 = I2;
385 tempReal = period;
386 if( (Im != 0.0) && (Re != 0.0) )
387 period = 360.0 / (std_atan(Im/Re)*rad2Deg);
388 tempReal2 = 1.5*tempReal;
389 if( period > tempReal2)
390 period = tempReal2;
391 tempReal2 = 0.67*tempReal;
392 if( period < tempReal2 )
393 period = tempReal2;
394 if( period < 6 )
395 period = 6;
396 else if( period > 50 )
397 period = 50;
398 period = (0.2*period) + (0.8 * tempReal);
399
400 smoothPeriod = (0.33*period)+(0.67*smoothPeriod);
401
402 /* Compute Dominant Cycle Phase */
403 DCPeriod = smoothPeriod+0.5;
404 DCPeriodInt = (int)DCPeriod;
405 realPart = 0.0;
406 imagPart = 0.0;
407
408 /* idx is used to iterate for up to 50 of the last
409 * value of smoothPrice.
410 */
411 idx = smoothPrice_Idx;
412 for( i=0; i < DCPeriodInt; i++ )
413 {
414 tempReal = ((double)i*constDeg2RadBy360)/(double)DCPeriodInt;
415 tempReal2 = smoothPrice[idx];
416 realPart += std_sin(tempReal)*tempReal2;
417 imagPart += std_cos(tempReal)*tempReal2;
418 if( idx == 0 )
419 idx = SMOOTH_PRICE_SIZE-1;
420 else
421 idx--;
422 }
423
424 tempReal = std_fabs(imagPart);
425 if( tempReal > 0.0 )
426 DCPhase = std_atan(realPart/imagPart)*rad2Deg;
427 else if( tempReal <= 0.01 )
428 {
429 if( realPart < 0.0 )
430 DCPhase -= 90.0;
431 else if( realPart > 0.0 )
432 DCPhase += 90.0;
433 }
434 DCPhase += 90.0;
435
436 /* Compensate for one bar lag of the weighted moving average */
437 DCPhase += 360.0 / smoothPeriod;
438 if( imagPart < 0.0 )
439 DCPhase += 180.0;
440 if( DCPhase > 315.0 )
441 DCPhase -= 360.0;
442
443 if( today >= startIdx )
444 {
445 outReal[outIdx++] = DCPhase;
446 }
447
448 /* Ooof... let's do the next price bar now! */
449 CIRCBUF_NEXT(smoothPrice);
450 today++;
451 }
452
453 VALUE_HANDLE_DEREF(outNBElement) = outIdx;
454
455 return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
456 }
457
458 /**** START GENCODE SECTION 5 - DO NOT DELETE THIS LINE ****/
459 /* Generated */
460 /* Generated */ #define USE_SINGLE_PRECISION_INPUT
461 /* Generated */ #if !defined( _MANAGED ) && !defined( _JAVA )
462 /* Generated */ #undef TA_PREFIX
463 /* Generated */ #define TA_PREFIX(x) TA_S_##x
464 /* Generated */ #endif
465 /* Generated */ #undef INPUT_TYPE
466 /* Generated */ #define INPUT_TYPE float
467 /* Generated */ #if defined( _MANAGED )
468 /* Generated */ enum class Core::RetCode Core::HtDcPhase( int startIdx,
469 /* Generated */ int endIdx,
470 /* Generated */ cli::array<float>^ inReal,
471 /* Generated */ [Out]int% outBegIdx,
472 /* Generated */ [Out]int% outNBElement,
473 /* Generated */ cli::array<double>^ outReal )
474 /* Generated */ #elif defined( _JAVA )
475 /* Generated */ public RetCode htDcPhase( int startIdx,
476 /* Generated */ int endIdx,
477 /* Generated */ float inReal[],
478 /* Generated */ MInteger outBegIdx,
479 /* Generated */ MInteger outNBElement,
480 /* Generated */ double outReal[] )
481 /* Generated */ #else
482 /* Generated */ TA_RetCode TA_S_HT_DCPHASE( int startIdx,
483 /* Generated */ int endIdx,
484 /* Generated */ const float inReal[],
485 /* Generated */ int *outBegIdx,
486 /* Generated */ int *outNBElement,
487 /* Generated */ double outReal[] )
488 /* Generated */ #endif
489 /* Generated */ {
490 /* Generated */ int outIdx, i;
491 /* Generated */ int lookbackTotal, today;
492 /* Generated */ double tempReal, tempReal2;
493 /* Generated */ double adjustedPrevPeriod, period;
494 /* Generated */ int trailingWMAIdx;
495 /* Generated */ double periodWMASum, periodWMASub, trailingWMAValue;
496 /* Generated */ double smoothedValue;
497 /* Generated */ CONSTANT_DOUBLE(a) = 0.0962;
498 /* Generated */ CONSTANT_DOUBLE(b) = 0.5769;
499 /* Generated */ double hilbertTempReal;
500 /* Generated */ int hilbertIdx;
501 /* Generated */ HILBERT_VARIABLES( detrender );
502 /* Generated */ HILBERT_VARIABLES( Q1 );
503 /* Generated */ HILBERT_VARIABLES( jI );
504 /* Generated */ HILBERT_VARIABLES( jQ );
505 /* Generated */ double Q2, I2, prevQ2, prevI2, Re, Im;
506 /* Generated */ double I1ForOddPrev2, I1ForOddPrev3;
507 /* Generated */ double I1ForEvenPrev2, I1ForEvenPrev3;
508 /* Generated */ double rad2Deg, constDeg2RadBy360;
509 /* Generated */ double todayValue, smoothPeriod;
510 /* Generated */ #define SMOOTH_PRICE_SIZE 50
511 /* Generated */ CIRCBUF_PROLOG(smoothPrice,double,SMOOTH_PRICE_SIZE);
512 /* Generated */ int idx;
513 /* Generated */ int DCPeriodInt;
514 /* Generated */ double DCPhase, DCPeriod, imagPart, realPart;
515 /* Generated */ #ifndef TA_FUNC_NO_RANGE_CHECK
516 /* Generated */ if( startIdx < 0 )
517 /* Generated */ return ENUM_VALUE(RetCode,TA_OUT_OF_RANGE_START_INDEX,OutOfRangeStartIndex);
518 /* Generated */ if( (endIdx < 0) || (endIdx < startIdx))
519 /* Generated */ return ENUM_VALUE(RetCode,TA_OUT_OF_RANGE_END_INDEX,OutOfRangeEndIndex);
520 /* Generated */ #if !defined(_JAVA)
521 /* Generated */ if( !inReal ) return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
522 /* Generated */ #endif
523 /* Generated */ #if !defined(_JAVA)
524 /* Generated */ if( !outReal )
525 /* Generated */ return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
526 /* Generated */ #endif
527 /* Generated */ #endif
528 /* Generated */ CIRCBUF_INIT_LOCAL_ONLY(smoothPrice,double);
529 /* Generated */ tempReal = std_atan(1);
530 /* Generated */ rad2Deg = 45.0/tempReal;
531 /* Generated */ constDeg2RadBy360 = tempReal*8.0;
532 /* Generated */ lookbackTotal = 63 + TA_GLOBALS_UNSTABLE_PERIOD(TA_FUNC_UNST_HT_DCPHASE,HtDcPhase);
533 /* Generated */ if( startIdx < lookbackTotal )
534 /* Generated */ startIdx = lookbackTotal;
535 /* Generated */ if( startIdx > endIdx )
536 /* Generated */ {
537 /* Generated */ VALUE_HANDLE_DEREF_TO_ZERO(outBegIdx);
538 /* Generated */ VALUE_HANDLE_DEREF_TO_ZERO(outNBElement);
539 /* Generated */ return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
540 /* Generated */ }
541 /* Generated */ VALUE_HANDLE_DEREF(outBegIdx) = startIdx;
542 /* Generated */ trailingWMAIdx = startIdx - lookbackTotal;
543 /* Generated */ today = trailingWMAIdx;
544 /* Generated */ tempReal = inReal[today++];
545 /* Generated */ periodWMASub = tempReal;
546 /* Generated */ periodWMASum = tempReal;
547 /* Generated */ tempReal = inReal[today++];
548 /* Generated */ periodWMASub += tempReal;
549 /* Generated */ periodWMASum += tempReal*2.0;
550 /* Generated */ tempReal = inReal[today++];
551 /* Generated */ periodWMASub += tempReal;
552 /* Generated */ periodWMASum += tempReal*3.0;
553 /* Generated */ trailingWMAValue = 0.0;
554 /* Generated */ #define DO_PRICE_WMA(varNewPrice,varToStoreSmoothedValue) { \
555 /* Generated */ periodWMASub += varNewPrice; \
556 /* Generated */ periodWMASub -= trailingWMAValue; \
557 /* Generated */ periodWMASum += varNewPrice*4.0; \
558 /* Generated */ trailingWMAValue = inReal[trailingWMAIdx++]; \
559 /* Generated */ varToStoreSmoothedValue = periodWMASum*0.1; \
560 /* Generated */ periodWMASum -= periodWMASub; \
561 /* Generated */ }
562 /* Generated */ i = 34;
563 /* Generated */ do
564 /* Generated */ {
565 /* Generated */ tempReal = inReal[today++];
566 /* Generated */ DO_PRICE_WMA(tempReal,smoothedValue);
567 /* Generated */ } while( --i != 0);
568 /* Generated */ hilbertIdx = 0;
569 /* Generated */ INIT_HILBERT_VARIABLES(detrender);
570 /* Generated */ INIT_HILBERT_VARIABLES(Q1);
571 /* Generated */ INIT_HILBERT_VARIABLES(jI);
572 /* Generated */ INIT_HILBERT_VARIABLES(jQ);
573 /* Generated */ period = 0.0;
574 /* Generated */ outIdx = 0;
575 /* Generated */ prevI2 = prevQ2 = 0.0;
576 /* Generated */ Re = Im = 0.0;
577 /* Generated */ I1ForOddPrev3 = I1ForEvenPrev3 = 0.0;
578 /* Generated */ I1ForOddPrev2 = I1ForEvenPrev2 = 0.0;
579 /* Generated */ smoothPeriod = 0.0;
580 /* Generated */ for( i=0; i < SMOOTH_PRICE_SIZE; i++ )
581 /* Generated */ smoothPrice[i] = 0.0;
582 /* Generated */ DCPhase = 0.0;
583 /* Generated */ while( today <= endIdx )
584 /* Generated */ {
585 /* Generated */ adjustedPrevPeriod = (0.075*period)+0.54;
586 /* Generated */ todayValue = inReal[today];
587 /* Generated */ DO_PRICE_WMA(todayValue,smoothedValue);
588 /* Generated */ smoothPrice[smoothPrice_Idx] = smoothedValue;
589 /* Generated */ if( (today%2) == 0 )
590 /* Generated */ {
591 /* Generated */ DO_HILBERT_EVEN(detrender,smoothedValue);
592 /* Generated */ DO_HILBERT_EVEN(Q1,detrender);
593 /* Generated */ DO_HILBERT_EVEN(jI,I1ForEvenPrev3);
594 /* Generated */ DO_HILBERT_EVEN(jQ,Q1);
595 /* Generated */ if( ++hilbertIdx == 3 )
596 /* Generated */ hilbertIdx = 0;
597 /* Generated */ Q2 = (0.2*(Q1 + jI)) + (0.8*prevQ2);
598 /* Generated */ I2 = (0.2*(I1ForEvenPrev3 - jQ)) + (0.8*prevI2);
599 /* Generated */ I1ForOddPrev3 = I1ForOddPrev2;
600 /* Generated */ I1ForOddPrev2 = detrender;
601 /* Generated */ }
602 /* Generated */ else
603 /* Generated */ {
604 /* Generated */ DO_HILBERT_ODD(detrender,smoothedValue);
605 /* Generated */ DO_HILBERT_ODD(Q1,detrender);
606 /* Generated */ DO_HILBERT_ODD(jI,I1ForOddPrev3);
607 /* Generated */ DO_HILBERT_ODD(jQ,Q1);
608 /* Generated */ Q2 = (0.2*(Q1 + jI)) + (0.8*prevQ2);
609 /* Generated */ I2 = (0.2*(I1ForOddPrev3 - jQ)) + (0.8*prevI2);
610 /* Generated */ I1ForEvenPrev3 = I1ForEvenPrev2;
611 /* Generated */ I1ForEvenPrev2 = detrender;
612 /* Generated */ }
613 /* Generated */ Re = (0.2*((I2*prevI2)+(Q2*prevQ2)))+(0.8*Re);
614 /* Generated */ Im = (0.2*((I2*prevQ2)-(Q2*prevI2)))+(0.8*Im);
615 /* Generated */ prevQ2 = Q2;
616 /* Generated */ prevI2 = I2;
617 /* Generated */ tempReal = period;
618 /* Generated */ if( (Im != 0.0) && (Re != 0.0) )
619 /* Generated */ period = 360.0 / (std_atan(Im/Re)*rad2Deg);
620 /* Generated */ tempReal2 = 1.5*tempReal;
621 /* Generated */ if( period > tempReal2)
622 /* Generated */ period = tempReal2;
623 /* Generated */ tempReal2 = 0.67*tempReal;
624 /* Generated */ if( period < tempReal2 )
625 /* Generated */ period = tempReal2;
626 /* Generated */ if( period < 6 )
627 /* Generated */ period = 6;
628 /* Generated */ else if( period > 50 )
629 /* Generated */ period = 50;
630 /* Generated */ period = (0.2*period) + (0.8 * tempReal);
631 /* Generated */ smoothPeriod = (0.33*period)+(0.67*smoothPeriod);
632 /* Generated */ DCPeriod = smoothPeriod+0.5;
633 /* Generated */ DCPeriodInt = (int)DCPeriod;
634 /* Generated */ realPart = 0.0;
635 /* Generated */ imagPart = 0.0;
636 /* Generated */ idx = smoothPrice_Idx;
637 /* Generated */ for( i=0; i < DCPeriodInt; i++ )
638 /* Generated */ {
639 /* Generated */ tempReal = ((double)i*constDeg2RadBy360)/(double)DCPeriodInt;
640 /* Generated */ tempReal2 = smoothPrice[idx];
641 /* Generated */ realPart += std_sin(tempReal)*tempReal2;
642 /* Generated */ imagPart += std_cos(tempReal)*tempReal2;
643 /* Generated */ if( idx == 0 )
644 /* Generated */ idx = SMOOTH_PRICE_SIZE-1;
645 /* Generated */ else
646 /* Generated */ idx--;
647 /* Generated */ }
648 /* Generated */ tempReal = std_fabs(imagPart);
649 /* Generated */ if( tempReal > 0.0 )
650 /* Generated */ DCPhase = std_atan(realPart/imagPart)*rad2Deg;
651 /* Generated */ else if( tempReal <= 0.01 )
652 /* Generated */ {
653 /* Generated */ if( realPart < 0.0 )
654 /* Generated */ DCPhase -= 90.0;
655 /* Generated */ else if( realPart > 0.0 )
656 /* Generated */ DCPhase += 90.0;
657 /* Generated */ }
658 /* Generated */ DCPhase += 90.0;
659 /* Generated */ DCPhase += 360.0 / smoothPeriod;
660 /* Generated */ if( imagPart < 0.0 )
661 /* Generated */ DCPhase += 180.0;
662 /* Generated */ if( DCPhase > 315.0 )
663 /* Generated */ DCPhase -= 360.0;
664 /* Generated */ if( today >= startIdx )
665 /* Generated */ {
666 /* Generated */ outReal[outIdx++] = DCPhase;
667 /* Generated */ }
668 /* Generated */ CIRCBUF_NEXT(smoothPrice);
669 /* Generated */ today++;
670 /* Generated */ }
671 /* Generated */ VALUE_HANDLE_DEREF(outNBElement) = outIdx;
672 /* Generated */ return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
673 /* Generated */ }
674 /* Generated */
675 /* Generated */ #if defined( _MANAGED )
676 /* Generated */ }}} // Close namespace TicTacTec.TA.Lib
677 /* Generated */ #endif
678 /**** END GENCODE SECTION 5 - DO NOT DELETE THIS LINE ****/
679
680