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 * 112400 MF First version.
46 *
47 */
48
49 /* Description:
50 * Test functions that have one output and takes a period and
51 * basically use only an EMA in its algorithm.
52 */
53
54 /**** Headers ****/
55 #include <stdio.h>
56 #include <string.h>
57
58 #include "ta_test_priv.h"
59 #include "ta_test_func.h"
60 #include "ta_utility.h"
61
62 /**** External functions declarations. ****/
63 /* None */
64
65 /**** External variables declarations. ****/
66 /* None */
67
68 /**** Global variables definitions. ****/
69 /* None */
70
71 /**** Local declarations. ****/
72 typedef enum {
73 TA_TRIX_TEST
74 } TA_TestId;
75
76 typedef struct
77 {
78 TA_Integer doRangeTestFlag;
79
80 TA_TestId theFunction;
81
82 TA_Integer unstablePeriod;
83
84 TA_Integer startIdx;
85 TA_Integer endIdx;
86 TA_Integer optInTimePeriod;
87
88 TA_RetCode expectedRetCode;
89
90 TA_Integer oneOfTheExpectedOutRealIndex;
91 TA_Real oneOfTheExpectedOutReal;
92
93 TA_Integer expectedBegIdx;
94 TA_Integer expectedNbElement;
95 } TA_Test;
96
97 typedef struct
98 {
99 const TA_Test *test;
100 const TA_Real *close;
101 } TA_RangeTestParam;
102
103 /**** Local functions declarations. ****/
104 static ErrorNumber do_test_per_ema( const TA_History *history,
105 const TA_Test *test );
106
107 /**** Local variables definitions. ****/
108
109 static TA_Test tableTest[] =
110 {
111 /****************/
112 /* TRIX TEST */
113 /****************/
114 { 0, TA_TRIX_TEST, 0, 0, 251, 5, TA_SUCCESS, 0, 0.2589, 13, 252-13 }, /* First Value */
115 { 0, TA_TRIX_TEST, 0, 0, 251, 5, TA_SUCCESS, 1, 0.010495, 13, 252-13 },
116 { 0, TA_TRIX_TEST, 0, 0, 251, 5, TA_SUCCESS, 252-15, -0.058, 13, 252-13 },
117 { 0, TA_TRIX_TEST, 0, 0, 251, 5, TA_SUCCESS, 252-14, -0.095, 13, 252-13 }, /* Last Value */
118
119 #if 0
120 /* Metastock values. */
121 { 0, TA_TRIX_TEST, 0, 0, 251, 5, TA_SUCCESS, 0, 0.221, 13, 252-13 }, /* First Value */
122 { 0, TA_TRIX_TEST, 0, 0, 251, 5, TA_SUCCESS, 1, -0.009, 13, 252-13 },
123 { 0, TA_TRIX_TEST, 0, 0, 251, 5, TA_SUCCESS, 252-15, -0.058, 13, 252-13 },
124 { 0, TA_TRIX_TEST, 0, 0, 251, 5, TA_SUCCESS, 252-14, -0.095, 13, 252-13 }, /* Last Value */
125 #endif
126
127 };
128
129 #define NB_TEST (sizeof(tableTest)/sizeof(TA_Test))
130
131 /**** Global functions definitions. ****/
test_func_per_ema(TA_History * history)132 ErrorNumber test_func_per_ema( TA_History *history )
133 {
134 unsigned int i;
135 ErrorNumber retValue;
136
137 /* Re-initialize all the unstable period to zero. */
138 TA_SetUnstablePeriod( TA_FUNC_UNST_ALL, 0 );
139
140 for( i=0; i < NB_TEST; i++ )
141 {
142 if( (int)tableTest[i].expectedNbElement > (int)history->nbBars )
143 {
144 printf( "TA_MA Failed Bad Parameter for Test #%d (%d,%d)\n",
145 i, tableTest[i].expectedNbElement, history->nbBars );
146 return TA_TESTUTIL_TFRR_BAD_PARAM;
147 }
148
149 retValue = do_test_per_ema( history, &tableTest[i] );
150 if( retValue != 0 )
151 {
152 printf( "TA_MA Failed Test #%d (Code=%d)\n", i, retValue );
153 return retValue;
154 }
155 }
156
157 /* Re-initialize all the unstable period to zero. */
158 TA_SetUnstablePeriod( TA_FUNC_UNST_ALL, 0 );
159
160 /* All test succeed. */
161 return TA_TEST_PASS;
162 }
163
164 /**** Local functions definitions. ****/
rangeTestFunction(TA_Integer startIdx,TA_Integer endIdx,TA_Real * outputBuffer,TA_Integer * outputBufferInt,TA_Integer * outBegIdx,TA_Integer * outNbElement,TA_Integer * lookback,void * opaqueData,unsigned int outputNb,unsigned int * isOutputInteger)165 static TA_RetCode rangeTestFunction( TA_Integer startIdx,
166 TA_Integer endIdx,
167 TA_Real *outputBuffer,
168 TA_Integer *outputBufferInt,
169 TA_Integer *outBegIdx,
170 TA_Integer *outNbElement,
171 TA_Integer *lookback,
172 void *opaqueData,
173 unsigned int outputNb,
174 unsigned int *isOutputInteger )
175 {
176 TA_RetCode retCode;
177 TA_RangeTestParam *testParam;
178
179 (void)outputNb;
180 (void)outputBufferInt;
181
182 *isOutputInteger = 0;
183
184 testParam = (TA_RangeTestParam *)opaqueData;
185
186 switch( testParam->test->theFunction )
187 {
188 case TA_TRIX_TEST:
189 retCode = TA_TRIX( startIdx,
190 endIdx,
191 testParam->close,
192 testParam->test->optInTimePeriod,
193 outBegIdx,
194 outNbElement,
195 outputBuffer );
196 *lookback = TA_TRIX_Lookback( testParam->test->optInTimePeriod );
197 default:
198 retCode = TA_INTERNAL_ERROR(131);
199 }
200
201 return retCode;
202 }
203
do_test_per_ema(const TA_History * history,const TA_Test * test)204 static ErrorNumber do_test_per_ema( const TA_History *history,
205 const TA_Test *test )
206 {
207 TA_RetCode retCode;
208 ErrorNumber errNb;
209 TA_Integer outBegIdx;
210 TA_Integer outNbElement;
211 TA_RangeTestParam testParam;
212
213 /* Set to NAN all the elements of the gBuffers. */
214 clearAllBuffers();
215
216 /* Build the input. */
217 setInputBuffer( 0, history->close, history->nbBars );
218 setInputBuffer( 1, history->close, history->nbBars );
219
220 /* Set the unstable period requested for that test. */
221 retCode = TA_SetUnstablePeriod( TA_FUNC_UNST_EMA, test->unstablePeriod );
222 if( retCode != TA_SUCCESS )
223 return TA_TEST_TFRR_SETUNSTABLE_PERIOD_FAIL;
224
225 /* Make a simple first call. */
226 switch( test->theFunction )
227 {
228 case TA_TRIX_TEST:
229 retCode = TA_TRIX( test->startIdx,
230 test->endIdx,
231 gBuffer[0].in,
232 test->optInTimePeriod,
233 &outBegIdx,
234 &outNbElement,
235 gBuffer[0].out0 );
236
237 }
238
239 errNb = checkDataSame( gBuffer[0].in, history->close,history->nbBars );
240
241 if( errNb != TA_TEST_PASS )
242 return errNb;
243
244 errNb = checkExpectedValue( gBuffer[0].out0,
245 retCode, test->expectedRetCode,
246 outBegIdx, test->expectedBegIdx,
247 outNbElement, test->expectedNbElement,
248 test->oneOfTheExpectedOutReal,
249 test->oneOfTheExpectedOutRealIndex );
250 if( errNb != TA_TEST_PASS )
251 return errNb;
252
253 outBegIdx = outNbElement = 0;
254
255 /* Make another call where the input and the output are the
256 * same buffer.
257 */
258 switch( test->theFunction )
259 {
260 case TA_TRIX_TEST:
261 retCode = TA_TRIX( test->startIdx,
262 test->endIdx,
263 gBuffer[1].in,
264 test->optInTimePeriod,
265 &outBegIdx,
266 &outNbElement,
267 gBuffer[1].in );
268 }
269
270 /* The previous call to TA_MA should have the same output
271 * as this call.
272 *
273 * checkSameContent verify that all value different than NAN in
274 * the first parameter is identical in the second parameter.
275 */
276 errNb = checkSameContent( gBuffer[0].out0, gBuffer[1].in );
277 if( errNb != TA_TEST_PASS )
278 return errNb;
279
280 errNb = checkExpectedValue( gBuffer[1].in,
281 retCode, test->expectedRetCode,
282 outBegIdx, test->expectedBegIdx,
283 outNbElement, test->expectedNbElement,
284 test->oneOfTheExpectedOutReal,
285 test->oneOfTheExpectedOutRealIndex );
286 if( errNb != TA_TEST_PASS )
287 return errNb;
288
289 /* Do a systematic test of most of the
290 * possible startIdx/endIdx range.
291 */
292 testParam.test = test;
293 testParam.close = history->close;
294
295 if( test->doRangeTestFlag )
296 {
297 errNb = doRangeTest( rangeTestFunction,
298 TA_FUNC_UNST_EMA,
299 (void *)&testParam, 1, 0 );
300 if( errNb != TA_TEST_PASS )
301 return errNb;
302 }
303
304 return TA_TEST_PASS;
305 }
306
307