Skip to content

Commit

Permalink
Merge pull request #75 from z-hao-wang/master
Browse files Browse the repository at this point in the history
supporting synchronized call and fix running in child thread
  • Loading branch information
oransel committed Jun 6, 2019
2 parents 9874ba3 + 22bf9d4 commit 6992a92
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 71 deletions.
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);
}

0 comments on commit 6992a92

Please sign in to comment.