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