Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

supporting synchronized call and fix running in child thread #75

Merged
merged 11 commits into from
Jun 6, 2019
13 changes: 13 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,19 @@ talib.execute({
});
```

you can also make synchronized call
``` js
var result = talib.execute({
name: "ADX",
startIdx: 0,
endIdx: marketData.close.length - 1,
high: marketData.high,
low: marketData.low,
close: marketData.close,
optInTimePeriod: 9
});
```

Input parameters can be discovered by:

``` js
Expand Down
156 changes: 85 additions & 71 deletions src/talib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ using v8::Value;
using v8::String;
using v8::Number;
using v8::Array;
using v8::Context;
using Nan::GetFunction;
using Nan::Callback;
using Nan::New;
Expand Down Expand Up @@ -112,6 +113,72 @@ static double *V8_TO_DOUBLE_ARRAY(Local<Array> array) {

}

static Local<Object> generateResult(work_object *wo) {
// Create the outputs object
Local<Object> outputArray = New<Object>();

// Execution result object
Local<Object> result = New<Object>();

// Determine the number of results
int resultLength = wo->outNBElement;

// Function output parameter information
const TA_OutputParameterInfo *output_paraminfo;

// Check for execution error
if (wo->retCode != TA_SUCCESS) {
ThrowTypeError("Failed wo->retCode is not TA_SUCCESS");
}

// Set beginning index and number of elements
Set(result, New<String>("begIndex").ToLocalChecked(), New<Number>(wo->outBegIdx));
Set(result, New<String>("nbElement").ToLocalChecked(), New<Number>(wo->outNBElement));

// Loop for all the output parameters
for (int i=0; i < wo->nbOutput; i++) {

// Get the output parameter information
TA_GetOutputParameterInfo(wo->func_handle, i, &output_paraminfo);

// Create an array for results
Local<Array> resultArray = New<Array>(resultLength);

// Loop for all the results
for (int x = 0; x < resultLength; x++) {

// Determine the output type
switch(output_paraminfo->type) {

// Output type real is needed
case TA_Output_Real:

// Set the real output value
Set(resultArray, x, New<Number>(wo->outReal[i][x]));

break;

// Output type integer is needed
case TA_Output_Integer:

// Set the integer output value
Set(resultArray, x, New<Number>(wo->outInt[i][x]));

break;
}

}

// Set the result array
Set(outputArray, New<String>(output_paraminfo->paramName).ToLocalChecked(), resultArray);

}

// Set the outputs array
Set(result, New<String>("result").ToLocalChecked(), outputArray);
return result;
}

static Local<Value> TA_EXPLAIN_FUNCTION(const char *func_name) {

// Function flag counter
Expand Down Expand Up @@ -470,75 +537,12 @@ class ExecuteWorker : public AsyncWorker {
void HandleOKCallback () {
HandleScope scope;

// Create the outputs object
Local<Object> outputArray = New<Object>();

// Execution result object
Local<Object> result = New<Object>();

// Result info
Local<Value> argv[2];

// Determine the number of results
int resultLength = wo->outNBElement;

// Function output parameter information
const TA_OutputParameterInfo *output_paraminfo;

// Check for execution error
if (wo->retCode != TA_SUCCESS) {
return REPORT_TA_ERROR(callback, wo->retCode);
}

// Set beginning index and number of elements
Set(result, New<String>("begIndex").ToLocalChecked(), New<Number>(wo->outBegIdx));
Set(result, New<String>("nbElement").ToLocalChecked(), New<Number>(wo->outNBElement));

// Loop for all the output parameters
for (int i=0; i < wo->nbOutput; i++) {

// Get the output parameter information
TA_GetOutputParameterInfo(wo->func_handle, i, &output_paraminfo);

// Create an array for results
Local<Array> resultArray = New<Array>(resultLength);

// Loop for all the results
for (int x = 0; x < resultLength; x++) {

// Determine the output type
switch(output_paraminfo->type) {

// Output type real is needed
case TA_Output_Real:

// Set the real output value
Set(resultArray, x, New<Number>(wo->outReal[i][x]));

break;

// Output type integer is needed
case TA_Output_Integer:

// Set the integer output value
Set(resultArray, x, New<Number>(wo->outInt[i][x]));

break;
}

}

// Set the result array
Set(outputArray, New<String>(output_paraminfo->paramName).ToLocalChecked(), resultArray);

}

// Set the outputs array
Set(result, New<String>("result").ToLocalChecked(), outputArray);


// Return the execution result
argv[0] = Nan::Null();
argv[1] = result;
argv[1] = generateResult(wo);
callback->Call(2, argv);

};
Expand All @@ -554,6 +558,7 @@ NAN_METHOD(Execute) {

// Callback function
Callback *cb;
bool isSync = false;

// Price values
double *open = NULL;
Expand Down Expand Up @@ -587,8 +592,8 @@ NAN_METHOD(Execute) {
const TA_OutputParameterInfo *output_paraminfo;

// Check the arguments
if (info.Length() < 2) {
ThrowTypeError("Two arguments required - Object and Function");
if (info.Length() < 1) {
ThrowTypeError("argument required - Object");
return;
}

Expand All @@ -600,8 +605,7 @@ NAN_METHOD(Execute) {

// Check the callback parameter
if (!info[1]->IsFunction()) {
ThrowTypeError("Second argument must be a Function");
return;
isSync = true;
}

// Get the execute parameter
Expand Down Expand Up @@ -1048,12 +1052,18 @@ NAN_METHOD(Execute) {

}

if (isSync) {
wo->retCode = TA_CallFunc((const TA_ParamHolder *)wo->func_params, wo->startIdx, wo->endIdx, &wo->outBegIdx, &wo->outNBElement);
info.GetReturnValue().Set(generateResult(wo));
return;
}

// Queue the work
AsyncQueueWorker(new ExecuteWorker(cb, wo));
return;
}

void Init(Local<Object> exports, Local<Object> module) {
void Init(Local<Object> exports, Local<Context> context) {

// Initialize the engine
TA_Initialize();
Expand All @@ -1071,4 +1081,8 @@ void Init(Local<Object> exports, Local<Object> module) {
Set(exports, New<String>("setUnstablePeriod").ToLocalChecked(), GetFunction(New<FunctionTemplate>(SetUnstablePeriod)).ToLocalChecked());
}

NODE_MODULE(talib, Init)
// https://github.com/schroffl/node-lzo/pull/11/files
// Initialize this addon to be context-aware.
NODE_MODULE_INIT(/* exports, module, context */) {
Init(exports, context);
}