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 * 023003 MF Initial Coding of MAMA.
47 * 052603 MF Adapt code to compile with .NET Managed C++
48 *
49 */
50
51 /**** START GENCODE SECTION 1 - DO NOT DELETE THIS LINE ****/
52 /* All code within this section is automatically
53 * generated by gen_code. Any modification will be lost
54 * next time gen_code is run.
55 */
56 /* Generated */
57 /* Generated */ #if defined( _MANAGED )
58 /* Generated */ #include "TA-Lib-Core.h"
59 /* Generated */ #define TA_INTERNAL_ERROR(Id) (RetCode::InternalError)
60 /* Generated */ namespace TicTacTec { namespace TA { namespace Library {
61 /* Generated */ #elif defined( _JAVA )
62 /* Generated */ #include "ta_defs.h"
63 /* Generated */ #include "ta_java_defs.h"
64 /* Generated */ #define TA_INTERNAL_ERROR(Id) (RetCode.InternalError)
65 /* Generated */ #else
66 /* Generated */ #include <string.h>
67 /* Generated */ #include <math.h>
68 /* Generated */ #include "ta_func.h"
69 /* Generated */ #endif
70 /* Generated */
71 /* Generated */ #ifndef TA_UTILITY_H
72 /* Generated */ #include "ta_utility.h"
73 /* Generated */ #endif
74 /* Generated */
75 /* Generated */ #ifndef TA_MEMORY_H
76 /* Generated */ #include "ta_memory.h"
77 /* Generated */ #endif
78 /* Generated */
79 /* Generated */ #define TA_PREFIX(x) TA_##x
80 /* Generated */ #define INPUT_TYPE double
81 /* Generated */
82 /* Generated */ #if defined( _MANAGED )
MamaLookback(double optInFastLimit,double optInSlowLimit)83 /* Generated */ int Core::MamaLookback( double optInFastLimit, /* From 0.01 to 0.99 */
84 /* Generated */ double optInSlowLimit ) /* From 0.01 to 0.99 */
85 /* Generated */
86 /* Generated */ #elif defined( _JAVA )
87 /* Generated */ public int mamaLookback( double optInFastLimit, /* From 0.01 to 0.99 */
88 /* Generated */ double optInSlowLimit ) /* From 0.01 to 0.99 */
89 /* Generated */
90 /* Generated */ #else
91 /* Generated */ int TA_MAMA_Lookback( double optInFastLimit, /* From 0.01 to 0.99 */
92 /* Generated */ double optInSlowLimit ) /* From 0.01 to 0.99 */
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 */ if( optInFastLimit == TA_REAL_DEFAULT )
102 /* Generated */ optInFastLimit = 5.000000e-1;
103 /* Generated */ else if( (optInFastLimit < 1.000000e-2) ||/* Generated */ (optInFastLimit > 9.900000e-1) )
104 /* Generated */ return -1;
105 /* Generated */
106 /* Generated */ if( optInSlowLimit == TA_REAL_DEFAULT )
107 /* Generated */ optInSlowLimit = 5.000000e-2;
108 /* Generated */ else if( (optInSlowLimit < 1.000000e-2) ||/* Generated */ (optInSlowLimit > 9.900000e-1) )
109 /* Generated */ return -1;
110 /* Generated */
111 /* Generated */ #endif /* TA_FUNC_NO_RANGE_CHECK */
112 /**** END GENCODE SECTION 2 - DO NOT DELETE THIS LINE ****/
113
114 /* insert lookback code here. */
115
116 /* The two parameters are not a factor to determine
117 * the lookback, but are still requested for
118 * consistency with all other Lookback functions.
119 */
120 UNUSED_VARIABLE(optInFastLimit);
121 UNUSED_VARIABLE(optInSlowLimit);
122
123 /* Lookback is a fix amount + the unstable period.
124 *
125 *
126 * The fix lookback is 32 and is establish as follow:
127 *
128 * 12 price bar to be compatible with the implementation
129 * of TradeStation found in John Ehlers book.
130 * 6 price bars for the Detrender
131 * 6 price bars for Q1
132 * 3 price bars for jI
133 * 3 price bars for jQ
134 * 1 price bar for Re/Im
135 * 1 price bar for the Delta Phase
136 * -------
137 * 32 Total
138 */
139
140 return 32 + TA_GLOBALS_UNSTABLE_PERIOD(TA_FUNC_UNST_MAMA,Mama);
141 }
142
143 /**** START GENCODE SECTION 3 - DO NOT DELETE THIS LINE ****/
144 /*
145 * TA_MAMA - MESA Adaptive Moving Average
146 *
147 * Input = double
148 * Output = double, double
149 *
150 * Optional Parameters
151 * -------------------
152 * optInFastLimit:(From 0.01 to 0.99)
153 * Upper limit use in the adaptive algorithm
154 *
155 * optInSlowLimit:(From 0.01 to 0.99)
156 * Lower limit use in the adaptive algorithm
157 *
158 *
159 */
160 /* Generated */
161 /* Generated */ #if defined( _MANAGED ) && defined( USE_SUBARRAY )
162 /* Generated */ enum class Core::RetCode Core::Mama( int startIdx,
163 /* Generated */ int endIdx,
164 /* Generated */ SubArray^ inReal,
165 /* Generated */ double optInFastLimit, /* From 0.01 to 0.99 */
166 /* Generated */ double optInSlowLimit, /* From 0.01 to 0.99 */
167 /* Generated */ [Out]int% outBegIdx,
168 /* Generated */ [Out]int% outNBElement,
169 /* Generated */ cli::array<double>^ outMAMA,
170 /* Generated */ cli::array<double>^ outFAMA )
171 /* Generated */ #elif defined( _MANAGED )
172 /* Generated */ enum class Core::RetCode Core::Mama( int startIdx,
173 /* Generated */ int endIdx,
174 /* Generated */ cli::array<double>^ inReal,
175 /* Generated */ double optInFastLimit, /* From 0.01 to 0.99 */
176 /* Generated */ double optInSlowLimit, /* From 0.01 to 0.99 */
177 /* Generated */ [Out]int% outBegIdx,
178 /* Generated */ [Out]int% outNBElement,
179 /* Generated */ cli::array<double>^ outMAMA,
180 /* Generated */ cli::array<double>^ outFAMA )
181 /* Generated */ #elif defined( _JAVA )
182 /* Generated */ public RetCode mama( int startIdx,
183 /* Generated */ int endIdx,
184 /* Generated */ double inReal[],
185 /* Generated */ double optInFastLimit, /* From 0.01 to 0.99 */
186 /* Generated */ double optInSlowLimit, /* From 0.01 to 0.99 */
187 /* Generated */ MInteger outBegIdx,
188 /* Generated */ MInteger outNBElement,
189 /* Generated */ double outMAMA[],
190 /* Generated */ double outFAMA[] )
191 /* Generated */ #else
192 /* Generated */ TA_RetCode TA_MAMA( int startIdx,
193 /* Generated */ int endIdx,
194 /* Generated */ const double inReal[],
195 /* Generated */ double optInFastLimit, /* From 0.01 to 0.99 */
196 /* Generated */ double optInSlowLimit, /* From 0.01 to 0.99 */
197 /* Generated */ int *outBegIdx,
198 /* Generated */ int *outNBElement,
199 /* Generated */ double outMAMA[],
200 /* Generated */ double outFAMA[] )
201 /* Generated */ #endif
202 /**** END GENCODE SECTION 3 - DO NOT DELETE THIS LINE ****/
203 {
204 /* insert local variable here */
205
206 int outIdx, i;
207 int lookbackTotal, today;
208 double tempReal, tempReal2;
209
210 double adjustedPrevPeriod, period;
211
212 /* Variable used for the price smoother (a weighted moving average). */
213 int trailingWMAIdx;
214 double periodWMASum, periodWMASub, trailingWMAValue;
215 double smoothedValue;
216
217 /* Variables used for the Hilbert Transormation */
218 CONSTANT_DOUBLE(a) = 0.0962;
219 CONSTANT_DOUBLE(b) = 0.5769;
220 double hilbertTempReal;
221 int hilbertIdx;
222
223 HILBERT_VARIABLES( detrender );
224 HILBERT_VARIABLES( Q1 );
225 HILBERT_VARIABLES( jI );
226 HILBERT_VARIABLES( jQ );
227
228 double Q2, I2, prevQ2, prevI2, Re, Im;
229
230 double I1ForOddPrev2, I1ForOddPrev3;
231 double I1ForEvenPrev2, I1ForEvenPrev3;
232
233 double rad2Deg;
234
235 double mama,fama,todayValue,prevPhase;
236
237 /**** START GENCODE SECTION 4 - DO NOT DELETE THIS LINE ****/
238 /* Generated */
239 /* Generated */ #ifndef TA_FUNC_NO_RANGE_CHECK
240 /* Generated */
241 /* Generated */ /* Validate the requested output range. */
242 /* Generated */ if( startIdx < 0 )
243 /* Generated */ return ENUM_VALUE(RetCode,TA_OUT_OF_RANGE_START_INDEX,OutOfRangeStartIndex);
244 /* Generated */ if( (endIdx < 0) || (endIdx < startIdx))
245 /* Generated */ return ENUM_VALUE(RetCode,TA_OUT_OF_RANGE_END_INDEX,OutOfRangeEndIndex);
246 /* Generated */
247 /* Generated */ #if !defined(_JAVA)
248 /* Generated */ if( !inReal ) return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
249 /* Generated */ #endif /* !defined(_JAVA)*/
250 /* Generated */ if( optInFastLimit == TA_REAL_DEFAULT )
251 /* Generated */ optInFastLimit = 5.000000e-1;
252 /* Generated */ else if( (optInFastLimit < 1.000000e-2) ||/* Generated */ (optInFastLimit > 9.900000e-1) )
253 /* Generated */ return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
254 /* Generated */
255 /* Generated */ if( optInSlowLimit == TA_REAL_DEFAULT )
256 /* Generated */ optInSlowLimit = 5.000000e-2;
257 /* Generated */ else if( (optInSlowLimit < 1.000000e-2) ||/* Generated */ (optInSlowLimit > 9.900000e-1) )
258 /* Generated */ return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
259 /* Generated */
260 /* Generated */ #if !defined(_JAVA)
261 /* Generated */ if( !outMAMA )
262 /* Generated */ return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
263 /* Generated */
264 /* Generated */ if( !outFAMA )
265 /* Generated */ return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
266 /* Generated */
267 /* Generated */ #endif /* !defined(_JAVA) */
268 /* Generated */ #endif /* TA_FUNC_NO_RANGE_CHECK */
269 /* Generated */
270 /**** END GENCODE SECTION 4 - DO NOT DELETE THIS LINE ****/
271
272 /* Insert TA function code here. */
273
274 /* Constant */
275 rad2Deg = 180.0 / (4.0 * std_atan(1));
276
277 /* Identify the minimum number of price bar needed
278 * to calculate at least one output.
279 */
280 lookbackTotal = 32 + TA_GLOBALS_UNSTABLE_PERIOD(TA_FUNC_UNST_MAMA,Mama);
281
282 /* Move up the start index if there is not
283 * enough initial data.
284 */
285 if( startIdx < lookbackTotal )
286 startIdx = lookbackTotal;
287
288 /* Make sure there is still something to evaluate. */
289 if( startIdx > endIdx )
290 {
291 VALUE_HANDLE_DEREF_TO_ZERO(outBegIdx);
292 VALUE_HANDLE_DEREF_TO_ZERO(outNBElement);
293 return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
294 }
295
296 VALUE_HANDLE_DEREF(outBegIdx) = startIdx;
297
298 /* Initialize the price smoother, which is simply a weighted
299 * moving average of the price.
300 * To understand this algorithm, I strongly suggest to understand
301 * first how TA_WMA is done.
302 */
303 trailingWMAIdx = startIdx - lookbackTotal;
304 today = trailingWMAIdx;
305
306 /* Initialization is same as WMA, except loop is unrolled
307 * for speed optimization.
308 */
309 tempReal = inReal[today++];
310 periodWMASub = tempReal;
311 periodWMASum = tempReal;
312 tempReal = inReal[today++];
313 periodWMASub += tempReal;
314 periodWMASum += tempReal*2.0;
315 tempReal = inReal[today++];
316 periodWMASub += tempReal;
317 periodWMASum += tempReal*3.0;
318
319 trailingWMAValue = 0.0;
320
321 /* Subsequent WMA value are evaluated by using
322 * the DO_PRICE_WMA macro.
323 */
324 #define DO_PRICE_WMA(varNewPrice,varToStoreSmoothedValue) { \
325 periodWMASub += varNewPrice; \
326 periodWMASub -= trailingWMAValue; \
327 periodWMASum += varNewPrice*4.0; \
328 trailingWMAValue = inReal[trailingWMAIdx++]; \
329 varToStoreSmoothedValue = periodWMASum*0.1; \
330 periodWMASum -= periodWMASub; \
331 }
332
333 i = 9;
334 do
335 {
336 tempReal = inReal[today++];
337 DO_PRICE_WMA(tempReal,smoothedValue);
338 } while( --i != 0);
339
340 /* Initialize the circular buffers used by the hilbert
341 * transform logic.
342 * A buffer is used for odd day and another for even days.
343 * This minimize the number of memory access and floating point
344 * operations needed (note also that by using static circular buffer,
345 * no large dynamic memory allocation is needed for storing
346 * intermediate calculation!).
347 */
348 hilbertIdx = 0;
349
350 INIT_HILBERT_VARIABLES(detrender);
351 INIT_HILBERT_VARIABLES(Q1);
352 INIT_HILBERT_VARIABLES(jI);
353 INIT_HILBERT_VARIABLES(jQ);
354
355 period = 0.0;
356 outIdx = 0;
357
358 prevI2 = prevQ2 = 0.0;
359 Re = Im = 0.0;
360 mama = fama = 0.0;
361 I1ForOddPrev3 = I1ForEvenPrev3 = 0.0;
362 I1ForOddPrev2 = I1ForEvenPrev2 = 0.0;
363
364 prevPhase = 0.0;
365
366 /* The code is speed optimized and is most likely very
367 * hard to follow if you do not already know well the
368 * original algorithm.
369 * To understadn better, it is strongly suggested to look
370 * first at the Excel implementation in "test_MAMA.xls" included
371 * in this package.
372 */
373 while( today <= endIdx )
374 {
375 adjustedPrevPeriod = (0.075*period)+0.54;
376
377 todayValue = inReal[today];
378 DO_PRICE_WMA(todayValue,smoothedValue);
379
380 if( (today%2) == 0 )
381 {
382 /* Do the Hilbert Transforms for even price bar */
383 DO_HILBERT_EVEN(detrender,smoothedValue);
384 DO_HILBERT_EVEN(Q1,detrender);
385 DO_HILBERT_EVEN(jI,I1ForEvenPrev3);
386 DO_HILBERT_EVEN(jQ,Q1);
387 if( ++hilbertIdx == 3 )
388 hilbertIdx = 0;
389
390 Q2 = (0.2*(Q1 + jI)) + (0.8*prevQ2);
391 I2 = (0.2*(I1ForEvenPrev3 - jQ)) + (0.8*prevI2);
392
393 /* The variable I1 is the detrender delayed for
394 * 3 price bars.
395 *
396 * Save the current detrender value for being
397 * used by the "odd" logic later.
398 */
399 I1ForOddPrev3 = I1ForOddPrev2;
400 I1ForOddPrev2 = detrender;
401
402 /* Put Alpha in tempReal2 */
403 if( I1ForEvenPrev3 != 0.0 )
404 tempReal2 = (std_atan(Q1/I1ForEvenPrev3)*rad2Deg);
405 else
406 tempReal2 = 0.0;
407 }
408 else
409 {
410 /* Do the Hilbert Transforms for odd price bar */
411 DO_HILBERT_ODD(detrender,smoothedValue);
412 DO_HILBERT_ODD(Q1,detrender);
413 DO_HILBERT_ODD(jI,I1ForOddPrev3);
414 DO_HILBERT_ODD(jQ,Q1);
415
416 Q2 = (0.2*(Q1 + jI)) + (0.8*prevQ2);
417 I2 = (0.2*(I1ForOddPrev3 - jQ)) + (0.8*prevI2);
418
419 /* The varaiable I1 is the detrender delayed for
420 * 3 price bars.
421 *
422 * Save the current detrender value for being
423 * used by the "odd" logic later.
424 */
425 I1ForEvenPrev3 = I1ForEvenPrev2;
426 I1ForEvenPrev2 = detrender;
427
428 /* Put Alpha in tempReal2 */
429 if( I1ForOddPrev3 != 0.0 )
430 tempReal2 = (std_atan(Q1/I1ForOddPrev3)*rad2Deg);
431 else
432 tempReal2 = 0.0;
433 }
434
435 /* Put Delta Phase into tempReal */
436 tempReal = prevPhase - tempReal2;
437 prevPhase = tempReal2;
438 if( tempReal < 1.0 )
439 tempReal = 1.0;
440
441 /* Put Alpha into tempReal */
442 if( tempReal > 1.0 )
443 {
444 tempReal = optInFastLimit/tempReal;
445 if( tempReal < optInSlowLimit )
446 tempReal = optInSlowLimit;
447 }
448 else
449 {
450 tempReal = optInFastLimit;
451 }
452
453 /* Calculate MAMA, FAMA */
454 mama = (tempReal*todayValue)+((1-tempReal)*mama);
455 tempReal *= 0.5;
456 fama = (tempReal*mama)+((1-tempReal)*fama);
457 if( today >= startIdx )
458 {
459 outMAMA[outIdx] = mama;
460 outFAMA[outIdx++] = fama;
461 }
462
463 /* Adjust the period for next price bar */
464 Re = (0.2*((I2*prevI2)+(Q2*prevQ2)))+(0.8*Re);
465 Im = (0.2*((I2*prevQ2)-(Q2*prevI2)))+(0.8*Im);
466 prevQ2 = Q2;
467 prevI2 = I2;
468 tempReal = period;
469 if( (Im != 0.0) && (Re != 0.0) )
470 period = 360.0 / (std_atan(Im/Re)*rad2Deg);
471 tempReal2 = 1.5*tempReal;
472 if( period > tempReal2)
473 period = tempReal2;
474 tempReal2 = 0.67*tempReal;
475 if( period < tempReal2 )
476 period = tempReal2;
477 if( period < 6 )
478 period = 6;
479 else if( period > 50 )
480 period = 50;
481 period = (0.2*period) + (0.8 * tempReal);
482
483 /* Ooof... let's do the next price bar now! */
484 today++;
485 }
486
487 /* Default return values */
488 VALUE_HANDLE_DEREF(outNBElement) = outIdx;
489
490 return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
491 }
492
493 /**** START GENCODE SECTION 5 - DO NOT DELETE THIS LINE ****/
494 /* Generated */
495 /* Generated */ #define USE_SINGLE_PRECISION_INPUT
496 /* Generated */ #if !defined( _MANAGED ) && !defined( _JAVA )
497 /* Generated */ #undef TA_PREFIX
498 /* Generated */ #define TA_PREFIX(x) TA_S_##x
499 /* Generated */ #endif
500 /* Generated */ #undef INPUT_TYPE
501 /* Generated */ #define INPUT_TYPE float
502 /* Generated */ #if defined( _MANAGED )
503 /* Generated */ enum class Core::RetCode Core::Mama( int startIdx,
504 /* Generated */ int endIdx,
505 /* Generated */ cli::array<float>^ inReal,
506 /* Generated */ double optInFastLimit, /* From 0.01 to 0.99 */
507 /* Generated */ double optInSlowLimit, /* From 0.01 to 0.99 */
508 /* Generated */ [Out]int% outBegIdx,
509 /* Generated */ [Out]int% outNBElement,
510 /* Generated */ cli::array<double>^ outMAMA,
511 /* Generated */ cli::array<double>^ outFAMA )
512 /* Generated */ #elif defined( _JAVA )
513 /* Generated */ public RetCode mama( int startIdx,
514 /* Generated */ int endIdx,
515 /* Generated */ float inReal[],
516 /* Generated */ double optInFastLimit, /* From 0.01 to 0.99 */
517 /* Generated */ double optInSlowLimit, /* From 0.01 to 0.99 */
518 /* Generated */ MInteger outBegIdx,
519 /* Generated */ MInteger outNBElement,
520 /* Generated */ double outMAMA[],
521 /* Generated */ double outFAMA[] )
522 /* Generated */ #else
523 /* Generated */ TA_RetCode TA_S_MAMA( int startIdx,
524 /* Generated */ int endIdx,
525 /* Generated */ const float inReal[],
526 /* Generated */ double optInFastLimit, /* From 0.01 to 0.99 */
527 /* Generated */ double optInSlowLimit, /* From 0.01 to 0.99 */
528 /* Generated */ int *outBegIdx,
529 /* Generated */ int *outNBElement,
530 /* Generated */ double outMAMA[],
531 /* Generated */ double outFAMA[] )
532 /* Generated */ #endif
533 /* Generated */ {
534 /* Generated */ int outIdx, i;
535 /* Generated */ int lookbackTotal, today;
536 /* Generated */ double tempReal, tempReal2;
537 /* Generated */ double adjustedPrevPeriod, period;
538 /* Generated */ int trailingWMAIdx;
539 /* Generated */ double periodWMASum, periodWMASub, trailingWMAValue;
540 /* Generated */ double smoothedValue;
541 /* Generated */ CONSTANT_DOUBLE(a) = 0.0962;
542 /* Generated */ CONSTANT_DOUBLE(b) = 0.5769;
543 /* Generated */ double hilbertTempReal;
544 /* Generated */ int hilbertIdx;
545 /* Generated */ HILBERT_VARIABLES( detrender );
546 /* Generated */ HILBERT_VARIABLES( Q1 );
547 /* Generated */ HILBERT_VARIABLES( jI );
548 /* Generated */ HILBERT_VARIABLES( jQ );
549 /* Generated */ double Q2, I2, prevQ2, prevI2, Re, Im;
550 /* Generated */ double I1ForOddPrev2, I1ForOddPrev3;
551 /* Generated */ double I1ForEvenPrev2, I1ForEvenPrev3;
552 /* Generated */ double rad2Deg;
553 /* Generated */ double mama,fama,todayValue,prevPhase;
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( !inReal ) return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
561 /* Generated */ #endif
562 /* Generated */ if( optInFastLimit == TA_REAL_DEFAULT )
563 /* Generated */ optInFastLimit = 5.000000e-1;
564 /* Generated */ else if( (optInFastLimit < 1.000000e-2) || (optInFastLimit > 9.900000e-1) )
565 /* Generated */ return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
566 /* Generated */ if( optInSlowLimit == TA_REAL_DEFAULT )
567 /* Generated */ optInSlowLimit = 5.000000e-2;
568 /* Generated */ else if( (optInSlowLimit < 1.000000e-2) || (optInSlowLimit > 9.900000e-1) )
569 /* Generated */ return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
570 /* Generated */ #if !defined(_JAVA)
571 /* Generated */ if( !outMAMA )
572 /* Generated */ return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
573 /* Generated */ if( !outFAMA )
574 /* Generated */ return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);
575 /* Generated */ #endif
576 /* Generated */ #endif
577 /* Generated */ rad2Deg = 180.0 / (4.0 * std_atan(1));
578 /* Generated */ lookbackTotal = 32 + TA_GLOBALS_UNSTABLE_PERIOD(TA_FUNC_UNST_MAMA,Mama);
579 /* Generated */ if( startIdx < lookbackTotal )
580 /* Generated */ startIdx = lookbackTotal;
581 /* Generated */ if( startIdx > endIdx )
582 /* Generated */ {
583 /* Generated */ VALUE_HANDLE_DEREF_TO_ZERO(outBegIdx);
584 /* Generated */ VALUE_HANDLE_DEREF_TO_ZERO(outNBElement);
585 /* Generated */ return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
586 /* Generated */ }
587 /* Generated */ VALUE_HANDLE_DEREF(outBegIdx) = startIdx;
588 /* Generated */ trailingWMAIdx = startIdx - lookbackTotal;
589 /* Generated */ today = trailingWMAIdx;
590 /* Generated */ tempReal = inReal[today++];
591 /* Generated */ periodWMASub = tempReal;
592 /* Generated */ periodWMASum = tempReal;
593 /* Generated */ tempReal = inReal[today++];
594 /* Generated */ periodWMASub += tempReal;
595 /* Generated */ periodWMASum += tempReal*2.0;
596 /* Generated */ tempReal = inReal[today++];
597 /* Generated */ periodWMASub += tempReal;
598 /* Generated */ periodWMASum += tempReal*3.0;
599 /* Generated */ trailingWMAValue = 0.0;
600 /* Generated */ #define DO_PRICE_WMA(varNewPrice,varToStoreSmoothedValue) { \
601 /* Generated */ periodWMASub += varNewPrice; \
602 /* Generated */ periodWMASub -= trailingWMAValue; \
603 /* Generated */ periodWMASum += varNewPrice*4.0; \
604 /* Generated */ trailingWMAValue = inReal[trailingWMAIdx++]; \
605 /* Generated */ varToStoreSmoothedValue = periodWMASum*0.1; \
606 /* Generated */ periodWMASum -= periodWMASub; \
607 /* Generated */ }
608 /* Generated */ i = 9;
609 /* Generated */ do
610 /* Generated */ {
611 /* Generated */ tempReal = inReal[today++];
612 /* Generated */ DO_PRICE_WMA(tempReal,smoothedValue);
613 /* Generated */ } while( --i != 0);
614 /* Generated */ hilbertIdx = 0;
615 /* Generated */ INIT_HILBERT_VARIABLES(detrender);
616 /* Generated */ INIT_HILBERT_VARIABLES(Q1);
617 /* Generated */ INIT_HILBERT_VARIABLES(jI);
618 /* Generated */ INIT_HILBERT_VARIABLES(jQ);
619 /* Generated */ period = 0.0;
620 /* Generated */ outIdx = 0;
621 /* Generated */ prevI2 = prevQ2 = 0.0;
622 /* Generated */ Re = Im = 0.0;
623 /* Generated */ mama = fama = 0.0;
624 /* Generated */ I1ForOddPrev3 = I1ForEvenPrev3 = 0.0;
625 /* Generated */ I1ForOddPrev2 = I1ForEvenPrev2 = 0.0;
626 /* Generated */ prevPhase = 0.0;
627 /* Generated */ while( today <= endIdx )
628 /* Generated */ {
629 /* Generated */ adjustedPrevPeriod = (0.075*period)+0.54;
630 /* Generated */ todayValue = inReal[today];
631 /* Generated */ DO_PRICE_WMA(todayValue,smoothedValue);
632 /* Generated */ if( (today%2) == 0 )
633 /* Generated */ {
634 /* Generated */ DO_HILBERT_EVEN(detrender,smoothedValue);
635 /* Generated */ DO_HILBERT_EVEN(Q1,detrender);
636 /* Generated */ DO_HILBERT_EVEN(jI,I1ForEvenPrev3);
637 /* Generated */ DO_HILBERT_EVEN(jQ,Q1);
638 /* Generated */ if( ++hilbertIdx == 3 )
639 /* Generated */ hilbertIdx = 0;
640 /* Generated */ Q2 = (0.2*(Q1 + jI)) + (0.8*prevQ2);
641 /* Generated */ I2 = (0.2*(I1ForEvenPrev3 - jQ)) + (0.8*prevI2);
642 /* Generated */ I1ForOddPrev3 = I1ForOddPrev2;
643 /* Generated */ I1ForOddPrev2 = detrender;
644 /* Generated */ if( I1ForEvenPrev3 != 0.0 )
645 /* Generated */ tempReal2 = (std_atan(Q1/I1ForEvenPrev3)*rad2Deg);
646 /* Generated */ else
647 /* Generated */ tempReal2 = 0.0;
648 /* Generated */ }
649 /* Generated */ else
650 /* Generated */ {
651 /* Generated */ DO_HILBERT_ODD(detrender,smoothedValue);
652 /* Generated */ DO_HILBERT_ODD(Q1,detrender);
653 /* Generated */ DO_HILBERT_ODD(jI,I1ForOddPrev3);
654 /* Generated */ DO_HILBERT_ODD(jQ,Q1);
655 /* Generated */ Q2 = (0.2*(Q1 + jI)) + (0.8*prevQ2);
656 /* Generated */ I2 = (0.2*(I1ForOddPrev3 - jQ)) + (0.8*prevI2);
657 /* Generated */ I1ForEvenPrev3 = I1ForEvenPrev2;
658 /* Generated */ I1ForEvenPrev2 = detrender;
659 /* Generated */ if( I1ForOddPrev3 != 0.0 )
660 /* Generated */ tempReal2 = (std_atan(Q1/I1ForOddPrev3)*rad2Deg);
661 /* Generated */ else
662 /* Generated */ tempReal2 = 0.0;
663 /* Generated */ }
664 /* Generated */ tempReal = prevPhase - tempReal2;
665 /* Generated */ prevPhase = tempReal2;
666 /* Generated */ if( tempReal < 1.0 )
667 /* Generated */ tempReal = 1.0;
668 /* Generated */ if( tempReal > 1.0 )
669 /* Generated */ {
670 /* Generated */ tempReal = optInFastLimit/tempReal;
671 /* Generated */ if( tempReal < optInSlowLimit )
672 /* Generated */ tempReal = optInSlowLimit;
673 /* Generated */ }
674 /* Generated */ else
675 /* Generated */ {
676 /* Generated */ tempReal = optInFastLimit;
677 /* Generated */ }
678 /* Generated */ mama = (tempReal*todayValue)+((1-tempReal)*mama);
679 /* Generated */ tempReal *= 0.5;
680 /* Generated */ fama = (tempReal*mama)+((1-tempReal)*fama);
681 /* Generated */ if( today >= startIdx )
682 /* Generated */ {
683 /* Generated */ outMAMA[outIdx] = mama;
684 /* Generated */ outFAMA[outIdx++] = fama;
685 /* Generated */ }
686 /* Generated */ Re = (0.2*((I2*prevI2)+(Q2*prevQ2)))+(0.8*Re);
687 /* Generated */ Im = (0.2*((I2*prevQ2)-(Q2*prevI2)))+(0.8*Im);
688 /* Generated */ prevQ2 = Q2;
689 /* Generated */ prevI2 = I2;
690 /* Generated */ tempReal = period;
691 /* Generated */ if( (Im != 0.0) && (Re != 0.0) )
692 /* Generated */ period = 360.0 / (std_atan(Im/Re)*rad2Deg);
693 /* Generated */ tempReal2 = 1.5*tempReal;
694 /* Generated */ if( period > tempReal2)
695 /* Generated */ period = tempReal2;
696 /* Generated */ tempReal2 = 0.67*tempReal;
697 /* Generated */ if( period < tempReal2 )
698 /* Generated */ period = tempReal2;
699 /* Generated */ if( period < 6 )
700 /* Generated */ period = 6;
701 /* Generated */ else if( period > 50 )
702 /* Generated */ period = 50;
703 /* Generated */ period = (0.2*period) + (0.8 * tempReal);
704 /* Generated */ today++;
705 /* Generated */ }
706 /* Generated */ VALUE_HANDLE_DEREF(outNBElement) = outIdx;
707 /* Generated */ return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
708 /* Generated */ }
709 /* Generated */
710 /* Generated */ #if defined( _MANAGED )
711 /* Generated */ }}} // Close namespace TicTacTec.TA.Lib
712 /* Generated */ #endif
713 /**** END GENCODE SECTION 5 - DO NOT DELETE THIS LINE ****/
714
715