Skip to content

Commit 39a0ee4

Browse files
committed
Fix true range calculation when called as a window function
1 parent f87c415 commit 39a0ee4

File tree

1 file changed

+33
-32
lines changed

1 file changed

+33
-32
lines changed

src/ta_tr_win.c

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include <mysql.h>
1010
#include <ctype.h>
11+
#include <float.h>
1112
#include "ta_libmysqludf_ta.h"
1213

1314
/*
@@ -18,7 +19,10 @@
1819
typedef struct ta_tr_win_data_ {
1920
double previous_close;
2021
double current_close;
22+
double group_high;
23+
double group_low;
2124
short int init;
25+
short int init_group;
2226
} ta_tr_win_data;
2327

2428
DLLEXP my_bool ta_tr_win_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
@@ -58,8 +62,12 @@ DLLEXP my_bool ta_tr_win_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
5862
return 1;
5963
}
6064

65+
data->current_close = 0.0;
66+
data->group_high = DBL_MIN;
67+
data->group_low = DBL_MAX;
6168
data->previous_close = 0.0;
62-
data->init = -1;
69+
data->init = 0;
70+
data->init_group = 0;
6371

6472
initid->ptr = (char*)data;
6573
/*
@@ -76,21 +84,14 @@ DLLEXP void ta_tr_win_deinit(UDF_INIT *initid)
7684

7785
DLLEXP double ta_tr_win(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
7886
{
79-
ta_tr_win_data *data = (ta_tr_win_data *)initid->ptr;
80-
double *high = (double *)args->args[0];
81-
double *low = (double *)args->args[1];
82-
double *close = (double *)args->args[2];
83-
84-
if (close == NULL) {
85-
*is_null = 1;
86-
return 0.0;
87-
}
87+
ta_tr_win_data *data = (ta_tr_win_data *)initid->ptr;
8888

89-
//fprintf(stderr, "tr\thigh=%f,low=%f,close=%f,previous_close=%f\n", *high, *low, *close, data->previous_close);
89+
90+
//fprintf(stderr, "tr\thigh=%f,low=%f,close=%f,previous_close=%f\n", data->group_high, data->group_low, data->current_close, data->previous_close);
9091
//fflush(stderr);
9192

92-
if (data->init > 0) {
93-
return (*high > data->previous_close ? *high : data->previous_close) - (*low < data->previous_close ? *low : data->previous_close);
93+
if (data->init_group > 0) {
94+
return (data->group_high > data->previous_close ? data->group_high : data->previous_close) - (data->group_low < data->previous_close ? data->group_low : data->previous_close);
9495
} else {
9596
*is_null = 1;
9697
return 0.0;
@@ -101,41 +102,41 @@ void ta_tr_win_clear(UDF_INIT *initid, char *is_null, char *error) {
101102
ta_tr_win_data *data = (ta_tr_win_data *)initid->ptr;
102103

103104
if (data->init > 0) {
105+
data->init_group = 1;
104106
data->previous_close = data->current_close;
107+
data->group_high = DBL_MIN;
108+
data->group_low = DBL_MAX;
105109
} else {
106110
*is_null = 1;
107-
data->init++;
108111
}
109-
//fprintf(stderr, "clear\tinit=%i\n", data->init);
112+
//fprintf(stderr, "clear\tinit=%i\tinit_group=%i\n", data->init, data->init_group);
110113
//fflush(stderr);
111114
}
112115

113116
void ta_tr_win_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) {
114117
ta_tr_win_data *data = (ta_tr_win_data *)initid->ptr;
115-
//double *high = (double *)args->args[0];
116-
//double *low = (double *)args->args[1];
117-
double *close = (double *)args->args[2];
118+
double *high = (double *)args->args[0];
119+
double *low = (double *)args->args[1];
120+
double *close = (double *)args->args[2];
118121

122+
data->init = 1;
119123
data->current_close = *close;
120-
if (data->init < 1) {
124+
if (*high > data->group_high) {
125+
data->group_high = *high;
126+
}
127+
if (*low < data->group_low) {
128+
data->group_low = *low;
129+
}
130+
if (data->init_group == 0) {
131+
//fprintf(stderr, "init group is false\n");
121132
*is_null = 1;
122133
}
123134
//fprintf(stderr, "add\thigh=%f,low=%f,close=%f,last_c=%f\n", *high, *low, *close, data->previous_close);
124135
//fflush(stderr);
125136
}
126137

127-
void ta_tr_win_reset(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) {
128-
129-
//double *value = (double*)args->args[0];
130-
131-
//fprintf(stderr, "reset %f\n", *value);
132-
//fflush(stderr);
133-
134-
}
135-
136138
void ta_tr_win_remove(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) {
137-
138-
//fprintf(stderr, "remove\n");
139-
//fflush(stderr);
140-
139+
// do not remove this function, the udf will return incorrect results if you do.
140+
//fprintf(stderr, "remove\n");
141+
//fflush(stderr);
141142
}

0 commit comments

Comments
 (0)