#include "include/xmim_cfunc_api.h"
#include <stdio.h>
//names for the input parameters
#define PRED_STOCK1 "stock1"
#define PRED_STOCK2 "stock2"
//names for the state parameters
#define PRED_TIME_SERIES "time_series"
#define PRED_RESULT "result"
//column to use when creating a time
//series for the stock symbols
#define DEFAULT_COLUMN "Asks"
//struct to store in the state
typedef struct {
double *values;
xmim_cfunc_date_time **dates;
int size;
} pred_result;
//specify the input parameters and the state
extern "C" int cfunc_instance_init_defaults (xmim_cfunc_args *args) {
int num = 2;
//security args
xmim_cfunc_security_args *sec = new xmim_cfunc_security_args;
sec->size = num;
sec->names = new char*[num];
sec->names[0] = PRED_STOCK1;
sec->names[1] = PRED_STOCK2;
sec->rels = new char*[num];
sec->rels[0] = NULL;
sec->rels[1] = NULL;
args->security_args = sec;
xmim_cfunc_state *state = new xmim_cfunc_state;
num = 2;
state->size = num;
state->ptr = new xmim_cfunc_obj_ptr[num];
for (int i = 0; i < num; i++)
state->ptr[i].obj = NULL;
state->names = new char*[num];
state->names[0] = PRED_TIME_SERIES;
state->names[1] = PRED_RESULT;
args->state = state;
return 1;
}
//initialize the state
extern "C" int cfunc_instance_init (xmim_cfunc_args *args) {
char *relname1 = NULL, *relname2 = NULL;
void *series1 = NULL, *series2 = NULL;
xmim_cfunc_date_time *from_date = NULL, *to_date = NULL, *date = NULL, *old_date = NULL;
void *offset;
pred_result *result = NULL;
int size = 0;
//first input argument
relname1 = (char *)xmim_cfunc_get_arg (args, P_SECURITY, PRED_STOCK1);
if (!relname1)
return 0;
//second input argument
relname2 = (char *)xmim_cfunc_get_arg (args, P_SECURITY, PRED_STOCK2);
if (!relname2)
return 0;
//create the time series for the first stock symbol
series1 = xmim_cfunc_get_time_series (args, relname1, DEFAULT_COLUMN);
if (!series1)
return 0;
//store the first time series in the state
if (!xmim_cfunc_set_arg (args, P_STATE, series1, PRED_TIME_SERIES))
return 0;
//create the time series for the second stock symbol
//will get deleted in the ~CoCompiler () [CoCompiler::deleteExObjects]
series2 = xmim_cfunc_get_time_series (args, relname2, DEFAULT_COLUMN);
if (!series2)
return 0;
// the from and to dates for the first time series
// the date range we are going to use
from_date = xmim_cfunc_get_from_date (args, series1);
to_date = xmim_cfunc_get_to_date (args, series1);
//calculate the number of values we have
date = xmim_cfunc_get_from_date (args, series1);
size = 1;
while (!xmim_cfunc_date_time_equal (args, date, to_date)) {
offset = xmim_cfunc_get_time_offset (args, 1, PL_DAYS, PL_LATER);
old_date = date;
date = xmim_cfunc_apply_time_offset (args, date, series1, offset);
xmim_cfunc_free_date_time (args, old_date);
xmim_cfunc_free_time_offset (args, offset);
size++;
}
//compute the result
result = new pred_result;
result->values = new double[size];
result->dates = new xmim_cfunc_date_time*[size];
result->size = size;
double v1, v2, prev_v1, prev_v2;
//the first value is a NaN since we do not have the
//value on the previous date
double zero = 0;
double *doubleNan = &zero;
xmim_cfunc_makeNan (args, doubleNan);
result->values[0] = *doubleNan;
result->dates[0] = from_date;
prev_v1 = xmim_cfunc_get_value (args, series1, from_date);
prev_v2 = xmim_cfunc_get_value (args, series2, from_date);
//compute the values using the two time series
for (int i = 1; i < size; i++) {
offset = xmim_cfunc_get_time_offset (args, i, PL_DAYS, PL_LATER);
date = xmim_cfunc_apply_time_offset (args, from_date, series1, offset);
v1 = xmim_cfunc_get_value (args, series1, date);
v2 = xmim_cfunc_get_value (args, series2, date);
result->values[i] = v1 +
(0.5 * v1 *
(((v1 - prev_v1) / prev_v1) +
((v2 - prev_v2) / prev_v2)));
result->dates[i] = date;
prev_v1 = v1;
prev_v2 = v2;
xmim_cfunc_free_time_offset (args, offset);
}
//store the result in the state
if (!xmim_cfunc_set_arg (args, P_STATE, result, PRED_RESULT))
return 0;
return 1;
}
extern "C" int cfunc_instance_compute_trading_pattern (xmim_cfunc_args *args) {
void *time_series = xmim_cfunc_get_arg (args, P_STATE, PRED_TIME_SERIES);
if (!time_series)
return 0;
xmim_cfunc_compute_trading_pattern (args, time_series);
return 1;
}
extern "C" int cfunc_instance_compute_trading_date_range (xmim_cfunc_args *args) {
void *time_series = xmim_cfunc_get_arg (args, P_STATE, PRED_TIME_SERIES);
if (!time_series)
return 0;
xmim_cfunc_compute_trading_date_range (args, time_series);
return 1;
}
extern "C" int cfunc_instance_get_value (xmim_cfunc_args *args, xmim_cfunc_date_time *dt) {
pred_result *result = (pred_result *)xmim_cfunc_get_arg (args, P_STATE, PRED_RESULT);
xmim_cfunc_date_time *date = NULL;
if (!result)
return 0;
for (int i = 0; i < result->size; i++) {
date = (xmim_cfunc_date_time *) result->dates[i];
if (xmim_cfunc_date_time_equal (args, date, dt)) {
args->result = result->values[i];
return 1;
}
}
//we do not have the requested date - return NaN.
double zero = 0;
double *doubleNan = &zero;
xmim_cfunc_makeNan (args, doubleNan);
args->result = *doubleNan;
return 1;
}
extern "C" int cfunc_instance_destroy (xmim_cfunc_args *args) {
delete[] args->security_args->rels;
delete[] args->security_args->names;
delete args->security_args;
args->security_args = NULL;
//the RelCol object pointed to by args->state->ptr[0].obj
//has already been deleted for us
//in the ~CoCompiler () [CoCompiler::deleteExObjects]
pred_result *result = (pred_result *)xmim_cfunc_get_arg (args, P_STATE, PRED_RESULT);
if (result) {
for (int i = 0; i < result->size; i++)
delete result->dates[i];
delete[] result->dates;
delete[] result->values;
delete result;
}
return 1;
}