/*!
 * This file is generated by generate.ts, do not edit it.
 */

#include <nan.h>
#include "../ta-lib/c/include/ta_libc.h"

void TA_FUNC_ACCBANDS(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outRealUpperBand_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outRealMiddleBand_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outRealLowerBand_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(3);
        Nan::Set(outAll_JS, 0, outRealUpperBand_JS);
        Nan::Set(outAll_JS, 1, outRealMiddleBand_JS);
        Nan::Set(outAll_JS, 2, outRealLowerBand_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int optTime_Period = 20;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[2]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_ACCBANDS_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outRealUpperBand_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outRealMiddleBand_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outRealLowerBand_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(3);
        Nan::Set(outAll_JS, 0, outRealUpperBand_JS);
        Nan::Set(outAll_JS, 1, outRealMiddleBand_JS);
        Nan::Set(outAll_JS, 2, outRealLowerBand_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outRealUpperBand = new double[outLength];
    double *outRealMiddleBand = new double[outLength];
    double *outRealLowerBand = new double[outLength];
    TA_RetCode result = TA_ACCBANDS(startIdx, endIdx, inHigh, inLow, inClose, optTime_Period, &outBegIdx, &outNBElement, outRealUpperBand, outRealMiddleBand, outRealLowerBand);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outRealUpperBand;
        delete[] outRealMiddleBand;
        delete[] outRealLowerBand;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_ACCBANDS ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outRealUpperBand_JS = Nan::New<v8::Array>(outLength);
    v8::Local<v8::Array> outRealMiddleBand_JS = Nan::New<v8::Array>(outLength);
    v8::Local<v8::Array> outRealLowerBand_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = Nan::New<v8::Array>(3);
    Nan::Set(outAll_JS, 0, outRealUpperBand_JS);
    Nan::Set(outAll_JS, 1, outRealMiddleBand_JS);
    Nan::Set(outAll_JS, 2, outRealLowerBand_JS);
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outRealUpperBand_JS, i, Nan::New<v8::Number>(outRealUpperBand[i]));
        Nan::Set(outRealMiddleBand_JS, i, Nan::New<v8::Number>(outRealMiddleBand[i]));
        Nan::Set(outRealLowerBand_JS, i, Nan::New<v8::Number>(outRealLowerBand[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outRealUpperBand;
    delete[] outRealMiddleBand;
    delete[] outRealLowerBand;
}


void TA_FUNC_ACOS(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_ACOS_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_ACOS(startIdx, endIdx, inReal, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_ACOS ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_AD(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    double *inVolume = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inVolume_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inVolume[i] = Nan::Get(inVolume_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::String> inVolumeName = Nan::New("Volume").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
            inVolume[i] = Nan::Get(inObject, inVolumeName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_AD_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_AD(startIdx, endIdx, inHigh, inLow, inClose, inVolume, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] inVolume;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_AD ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] inVolume;
    delete[] outReal;
}


void TA_FUNC_ADD(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal0 = new double[inLength];
    double *inReal1 = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal0_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inReal1_JS = v8::Local<v8::Array>::Cast(info[1]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal0[i] = Nan::Get(inReal0_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inReal1[i] = Nan::Get(inReal1_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inReal0Name = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::String> inReal1Name = info[2]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal0[i] = Nan::Get(inObject, inReal0Name).ToLocalChecked()->NumberValue(context).FromJust();
            inReal1[i] = Nan::Get(inObject, inReal1Name).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_ADD_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_ADD(startIdx, endIdx, inReal0, inReal1, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal0;
        delete[] inReal1;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_ADD ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal0;
    delete[] inReal1;
    delete[] outReal;
}


void TA_FUNC_ADOSC(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    double *inVolume = new double[inLength];
    int optFast_Period = 3;
    int optSlow_Period = 10;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inVolume_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inVolume[i] = Nan::Get(inVolume_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optFast_Period = argc > 4 && info[4]->IsInt32() ?  info[4]->Int32Value(context).FromJust() : optFast_Period;
        optSlow_Period = argc > 5 && info[5]->IsInt32() ?  info[5]->Int32Value(context).FromJust() : optSlow_Period;
        startIdx = argc > 6 && info[6]->IsInt32() ? info[6]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 7 && info[7]->IsInt32() ? info[7]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::String> inVolumeName = Nan::New("Volume").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
            inVolume[i] = Nan::Get(inObject, inVolumeName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optFast_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optFast_Period;
        optSlow_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optSlow_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_ADOSC_Lookback(optFast_Period, optSlow_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_ADOSC(startIdx, endIdx, inHigh, inLow, inClose, inVolume, optFast_Period, optSlow_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] inVolume;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_ADOSC ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] inVolume;
    delete[] outReal;
}


void TA_FUNC_ADX(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[2]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_ADX_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_ADX(startIdx, endIdx, inHigh, inLow, inClose, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_ADX ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outReal;
}


void TA_FUNC_ADXR(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[2]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_ADXR_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_ADXR(startIdx, endIdx, inHigh, inLow, inClose, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_ADXR ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outReal;
}


void TA_FUNC_APO(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optFast_Period = 12;
    int optSlow_Period = 26;
    TA_MAType optMA_Type = TA_MAType_SMA;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optFast_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optFast_Period;
        optSlow_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optSlow_Period;
        optMA_Type = argc > 3 && info[3]->IsInt32() ? (TA_MAType)  info[3]->Int32Value(context).FromJust() : optMA_Type;
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optFast_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optFast_Period;
        optSlow_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optSlow_Period;
        optMA_Type = argc > 4 && info[4]->IsInt32() ? (TA_MAType)  info[4]->Int32Value(context).FromJust() : optMA_Type;
        startIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 6 && info[6]->IsInt32() ? info[6]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_APO_Lookback(optFast_Period, optSlow_Period, optMA_Type);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_APO(startIdx, endIdx, inReal, optFast_Period, optSlow_Period, optMA_Type, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_APO ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_AROON(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outAroonDown_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outAroonUp_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(2);
        Nan::Set(outAll_JS, 0, outAroonDown_JS);
        Nan::Set(outAll_JS, 1, outAroonUp_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_AROON_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outAroonDown_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outAroonUp_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(2);
        Nan::Set(outAll_JS, 0, outAroonDown_JS);
        Nan::Set(outAll_JS, 1, outAroonUp_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outAroonDown = new double[outLength];
    double *outAroonUp = new double[outLength];
    TA_RetCode result = TA_AROON(startIdx, endIdx, inHigh, inLow, optTime_Period, &outBegIdx, &outNBElement, outAroonDown, outAroonUp);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] outAroonDown;
        delete[] outAroonUp;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_AROON ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outAroonDown_JS = Nan::New<v8::Array>(outLength);
    v8::Local<v8::Array> outAroonUp_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = Nan::New<v8::Array>(2);
    Nan::Set(outAll_JS, 0, outAroonDown_JS);
    Nan::Set(outAll_JS, 1, outAroonUp_JS);
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outAroonDown_JS, i, Nan::New<v8::Number>(outAroonDown[i]));
        Nan::Set(outAroonUp_JS, i, Nan::New<v8::Number>(outAroonUp[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] outAroonDown;
    delete[] outAroonUp;
}


void TA_FUNC_AROONOSC(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_AROONOSC_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_AROONOSC(startIdx, endIdx, inHigh, inLow, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_AROONOSC ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] outReal;
}


void TA_FUNC_ASIN(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_ASIN_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_ASIN(startIdx, endIdx, inReal, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_ASIN ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_ATAN(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_ATAN_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_ATAN(startIdx, endIdx, inReal, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_ATAN ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_ATR(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[2]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_ATR_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_ATR(startIdx, endIdx, inHigh, inLow, inClose, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_ATR ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outReal;
}


void TA_FUNC_AVGPRICE(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_AVGPRICE_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_AVGPRICE(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_AVGPRICE ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outReal;
}


void TA_FUNC_AVGDEV(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_AVGDEV_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_AVGDEV(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_AVGDEV ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_BBANDS(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outRealUpperBand_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outRealMiddleBand_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outRealLowerBand_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(3);
        Nan::Set(outAll_JS, 0, outRealUpperBand_JS);
        Nan::Set(outAll_JS, 1, outRealMiddleBand_JS);
        Nan::Set(outAll_JS, 2, outRealLowerBand_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 5;
    double optDeviations_up = 2.000000e+0;
    double optDeviations_down = 2.000000e+0;
    TA_MAType optMA_Type = TA_MAType_SMA;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        optDeviations_up = argc > 2 && info[2]->IsNumber() ?  info[2]->NumberValue(context).FromJust() : optDeviations_up;
        optDeviations_down = argc > 3 && info[3]->IsNumber() ?  info[3]->NumberValue(context).FromJust() : optDeviations_down;
        optMA_Type = argc > 4 && info[4]->IsInt32() ? (TA_MAType)  info[4]->Int32Value(context).FromJust() : optMA_Type;
        startIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 6 && info[6]->IsInt32() ? info[6]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        optDeviations_up = argc > 3 && info[3]->IsNumber() ?  info[3]->NumberValue(context).FromJust() : optDeviations_up;
        optDeviations_down = argc > 4 && info[4]->IsNumber() ?  info[4]->NumberValue(context).FromJust() : optDeviations_down;
        optMA_Type = argc > 5 && info[5]->IsInt32() ? (TA_MAType)  info[5]->Int32Value(context).FromJust() : optMA_Type;
        startIdx = argc > 6 && info[6]->IsInt32() ? info[6]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 7 && info[7]->IsInt32() ? info[7]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_BBANDS_Lookback(optTime_Period, optDeviations_up, optDeviations_down, optMA_Type);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outRealUpperBand_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outRealMiddleBand_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outRealLowerBand_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(3);
        Nan::Set(outAll_JS, 0, outRealUpperBand_JS);
        Nan::Set(outAll_JS, 1, outRealMiddleBand_JS);
        Nan::Set(outAll_JS, 2, outRealLowerBand_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outRealUpperBand = new double[outLength];
    double *outRealMiddleBand = new double[outLength];
    double *outRealLowerBand = new double[outLength];
    TA_RetCode result = TA_BBANDS(startIdx, endIdx, inReal, optTime_Period, optDeviations_up, optDeviations_down, optMA_Type, &outBegIdx, &outNBElement, outRealUpperBand, outRealMiddleBand, outRealLowerBand);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outRealUpperBand;
        delete[] outRealMiddleBand;
        delete[] outRealLowerBand;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_BBANDS ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outRealUpperBand_JS = Nan::New<v8::Array>(outLength);
    v8::Local<v8::Array> outRealMiddleBand_JS = Nan::New<v8::Array>(outLength);
    v8::Local<v8::Array> outRealLowerBand_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = Nan::New<v8::Array>(3);
    Nan::Set(outAll_JS, 0, outRealUpperBand_JS);
    Nan::Set(outAll_JS, 1, outRealMiddleBand_JS);
    Nan::Set(outAll_JS, 2, outRealLowerBand_JS);
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outRealUpperBand_JS, i, Nan::New<v8::Number>(outRealUpperBand[i]));
        Nan::Set(outRealMiddleBand_JS, i, Nan::New<v8::Number>(outRealMiddleBand[i]));
        Nan::Set(outRealLowerBand_JS, i, Nan::New<v8::Number>(outRealLowerBand[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outRealUpperBand;
    delete[] outRealMiddleBand;
    delete[] outRealLowerBand;
}


void TA_FUNC_BETA(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal0 = new double[inLength];
    double *inReal1 = new double[inLength];
    int optTime_Period = 5;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal0_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inReal1_JS = v8::Local<v8::Array>::Cast(info[1]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal0[i] = Nan::Get(inReal0_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inReal1[i] = Nan::Get(inReal1_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inReal0Name = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::String> inReal1Name = info[2]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal0[i] = Nan::Get(inObject, inReal0Name).ToLocalChecked()->NumberValue(context).FromJust();
            inReal1[i] = Nan::Get(inObject, inReal1Name).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_BETA_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_BETA(startIdx, endIdx, inReal0, inReal1, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal0;
        delete[] inReal1;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_BETA ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal0;
    delete[] inReal1;
    delete[] outReal;
}


void TA_FUNC_BOP(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_BOP_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_BOP(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_BOP ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outReal;
}


void TA_FUNC_CCI(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[2]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CCI_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_CCI(startIdx, endIdx, inHigh, inLow, inClose, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CCI ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outReal;
}


void TA_FUNC_CDL2CROWS(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDL2CROWS_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDL2CROWS(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDL2CROWS ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDL3BLACKCROWS(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDL3BLACKCROWS_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDL3BLACKCROWS(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDL3BLACKCROWS ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDL3INSIDE(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDL3INSIDE_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDL3INSIDE(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDL3INSIDE ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDL3LINESTRIKE(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDL3LINESTRIKE_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDL3LINESTRIKE(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDL3LINESTRIKE ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDL3OUTSIDE(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDL3OUTSIDE_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDL3OUTSIDE(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDL3OUTSIDE ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDL3STARSINSOUTH(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDL3STARSINSOUTH_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDL3STARSINSOUTH(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDL3STARSINSOUTH ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDL3WHITESOLDIERS(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDL3WHITESOLDIERS_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDL3WHITESOLDIERS(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDL3WHITESOLDIERS ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLABANDONEDBABY(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    double optPenetration = 3.000000e-1;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optPenetration = argc > 4 && info[4]->IsNumber() ?  info[4]->NumberValue(context).FromJust() : optPenetration;
        startIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 6 && info[6]->IsInt32() ? info[6]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optPenetration = argc > 1 && info[1]->IsNumber() ?  info[1]->NumberValue(context).FromJust() : optPenetration;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLABANDONEDBABY_Lookback(optPenetration);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLABANDONEDBABY(startIdx, endIdx, inOpen, inHigh, inLow, inClose, optPenetration, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLABANDONEDBABY ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLADVANCEBLOCK(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLADVANCEBLOCK_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLADVANCEBLOCK(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLADVANCEBLOCK ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLBELTHOLD(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLBELTHOLD_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLBELTHOLD(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLBELTHOLD ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLBREAKAWAY(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLBREAKAWAY_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLBREAKAWAY(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLBREAKAWAY ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLCLOSINGMARUBOZU(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLCLOSINGMARUBOZU_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLCLOSINGMARUBOZU(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLCLOSINGMARUBOZU ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLCONCEALBABYSWALL(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLCONCEALBABYSWALL_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLCONCEALBABYSWALL(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLCONCEALBABYSWALL ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLCOUNTERATTACK(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLCOUNTERATTACK_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLCOUNTERATTACK(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLCOUNTERATTACK ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLDARKCLOUDCOVER(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    double optPenetration = 5.000000e-1;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optPenetration = argc > 4 && info[4]->IsNumber() ?  info[4]->NumberValue(context).FromJust() : optPenetration;
        startIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 6 && info[6]->IsInt32() ? info[6]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optPenetration = argc > 1 && info[1]->IsNumber() ?  info[1]->NumberValue(context).FromJust() : optPenetration;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLDARKCLOUDCOVER_Lookback(optPenetration);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLDARKCLOUDCOVER(startIdx, endIdx, inOpen, inHigh, inLow, inClose, optPenetration, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLDARKCLOUDCOVER ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLDOJI(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLDOJI_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLDOJI(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLDOJI ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLDOJISTAR(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLDOJISTAR_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLDOJISTAR(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLDOJISTAR ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLDRAGONFLYDOJI(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLDRAGONFLYDOJI_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLDRAGONFLYDOJI(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLDRAGONFLYDOJI ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLENGULFING(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLENGULFING_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLENGULFING(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLENGULFING ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLEVENINGDOJISTAR(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    double optPenetration = 3.000000e-1;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optPenetration = argc > 4 && info[4]->IsNumber() ?  info[4]->NumberValue(context).FromJust() : optPenetration;
        startIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 6 && info[6]->IsInt32() ? info[6]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optPenetration = argc > 1 && info[1]->IsNumber() ?  info[1]->NumberValue(context).FromJust() : optPenetration;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLEVENINGDOJISTAR_Lookback(optPenetration);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLEVENINGDOJISTAR(startIdx, endIdx, inOpen, inHigh, inLow, inClose, optPenetration, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLEVENINGDOJISTAR ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLEVENINGSTAR(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    double optPenetration = 3.000000e-1;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optPenetration = argc > 4 && info[4]->IsNumber() ?  info[4]->NumberValue(context).FromJust() : optPenetration;
        startIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 6 && info[6]->IsInt32() ? info[6]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optPenetration = argc > 1 && info[1]->IsNumber() ?  info[1]->NumberValue(context).FromJust() : optPenetration;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLEVENINGSTAR_Lookback(optPenetration);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLEVENINGSTAR(startIdx, endIdx, inOpen, inHigh, inLow, inClose, optPenetration, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLEVENINGSTAR ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLGAPSIDESIDEWHITE(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLGAPSIDESIDEWHITE_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLGAPSIDESIDEWHITE(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLGAPSIDESIDEWHITE ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLGRAVESTONEDOJI(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLGRAVESTONEDOJI_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLGRAVESTONEDOJI(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLGRAVESTONEDOJI ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLHAMMER(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLHAMMER_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLHAMMER(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLHAMMER ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLHANGINGMAN(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLHANGINGMAN_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLHANGINGMAN(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLHANGINGMAN ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLHARAMI(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLHARAMI_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLHARAMI(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLHARAMI ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLHARAMICROSS(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLHARAMICROSS_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLHARAMICROSS(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLHARAMICROSS ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLHIGHWAVE(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLHIGHWAVE_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLHIGHWAVE(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLHIGHWAVE ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLHIKKAKE(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLHIKKAKE_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLHIKKAKE(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLHIKKAKE ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLHIKKAKEMOD(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLHIKKAKEMOD_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLHIKKAKEMOD(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLHIKKAKEMOD ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLHOMINGPIGEON(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLHOMINGPIGEON_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLHOMINGPIGEON(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLHOMINGPIGEON ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLIDENTICAL3CROWS(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLIDENTICAL3CROWS_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLIDENTICAL3CROWS(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLIDENTICAL3CROWS ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLINNECK(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLINNECK_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLINNECK(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLINNECK ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLINVERTEDHAMMER(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLINVERTEDHAMMER_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLINVERTEDHAMMER(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLINVERTEDHAMMER ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLKICKING(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLKICKING_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLKICKING(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLKICKING ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLKICKINGBYLENGTH(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLKICKINGBYLENGTH_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLKICKINGBYLENGTH(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLKICKINGBYLENGTH ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLLADDERBOTTOM(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLLADDERBOTTOM_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLLADDERBOTTOM(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLLADDERBOTTOM ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLLONGLEGGEDDOJI(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLLONGLEGGEDDOJI_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLLONGLEGGEDDOJI(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLLONGLEGGEDDOJI ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLLONGLINE(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLLONGLINE_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLLONGLINE(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLLONGLINE ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLMARUBOZU(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLMARUBOZU_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLMARUBOZU(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLMARUBOZU ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLMATCHINGLOW(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLMATCHINGLOW_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLMATCHINGLOW(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLMATCHINGLOW ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLMATHOLD(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    double optPenetration = 5.000000e-1;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optPenetration = argc > 4 && info[4]->IsNumber() ?  info[4]->NumberValue(context).FromJust() : optPenetration;
        startIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 6 && info[6]->IsInt32() ? info[6]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optPenetration = argc > 1 && info[1]->IsNumber() ?  info[1]->NumberValue(context).FromJust() : optPenetration;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLMATHOLD_Lookback(optPenetration);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLMATHOLD(startIdx, endIdx, inOpen, inHigh, inLow, inClose, optPenetration, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLMATHOLD ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLMORNINGDOJISTAR(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    double optPenetration = 3.000000e-1;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optPenetration = argc > 4 && info[4]->IsNumber() ?  info[4]->NumberValue(context).FromJust() : optPenetration;
        startIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 6 && info[6]->IsInt32() ? info[6]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optPenetration = argc > 1 && info[1]->IsNumber() ?  info[1]->NumberValue(context).FromJust() : optPenetration;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLMORNINGDOJISTAR_Lookback(optPenetration);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLMORNINGDOJISTAR(startIdx, endIdx, inOpen, inHigh, inLow, inClose, optPenetration, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLMORNINGDOJISTAR ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLMORNINGSTAR(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    double optPenetration = 3.000000e-1;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optPenetration = argc > 4 && info[4]->IsNumber() ?  info[4]->NumberValue(context).FromJust() : optPenetration;
        startIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 6 && info[6]->IsInt32() ? info[6]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optPenetration = argc > 1 && info[1]->IsNumber() ?  info[1]->NumberValue(context).FromJust() : optPenetration;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLMORNINGSTAR_Lookback(optPenetration);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLMORNINGSTAR(startIdx, endIdx, inOpen, inHigh, inLow, inClose, optPenetration, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLMORNINGSTAR ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLONNECK(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLONNECK_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLONNECK(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLONNECK ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLPIERCING(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLPIERCING_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLPIERCING(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLPIERCING ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLRICKSHAWMAN(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLRICKSHAWMAN_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLRICKSHAWMAN(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLRICKSHAWMAN ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLRISEFALL3METHODS(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLRISEFALL3METHODS_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLRISEFALL3METHODS(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLRISEFALL3METHODS ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLSEPARATINGLINES(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLSEPARATINGLINES_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLSEPARATINGLINES(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLSEPARATINGLINES ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLSHOOTINGSTAR(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLSHOOTINGSTAR_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLSHOOTINGSTAR(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLSHOOTINGSTAR ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLSHORTLINE(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLSHORTLINE_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLSHORTLINE(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLSHORTLINE ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLSPINNINGTOP(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLSPINNINGTOP_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLSPINNINGTOP(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLSPINNINGTOP ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLSTALLEDPATTERN(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLSTALLEDPATTERN_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLSTALLEDPATTERN(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLSTALLEDPATTERN ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLSTICKSANDWICH(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLSTICKSANDWICH_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLSTICKSANDWICH(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLSTICKSANDWICH ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLTAKURI(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLTAKURI_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLTAKURI(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLTAKURI ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLTASUKIGAP(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLTASUKIGAP_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLTASUKIGAP(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLTASUKIGAP ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLTHRUSTING(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLTHRUSTING_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLTHRUSTING(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLTHRUSTING ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLTRISTAR(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLTRISTAR_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLTRISTAR(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLTRISTAR ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLUNIQUE3RIVER(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLUNIQUE3RIVER_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLUNIQUE3RIVER(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLUNIQUE3RIVER ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLUPSIDEGAP2CROWS(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLUPSIDEGAP2CROWS_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLUPSIDEGAP2CROWS(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLUPSIDEGAP2CROWS ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CDLXSIDEGAP3METHODS(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CDLXSIDEGAP3METHODS_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_CDLXSIDEGAP3METHODS(startIdx, endIdx, inOpen, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CDLXSIDEGAP3METHODS ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outInteger;
}


void TA_FUNC_CEIL(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CEIL_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_CEIL(startIdx, endIdx, inReal, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CEIL ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_CMO(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CMO_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_CMO(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CMO ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_CORREL(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal0 = new double[inLength];
    double *inReal1 = new double[inLength];
    int optTime_Period = 30;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal0_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inReal1_JS = v8::Local<v8::Array>::Cast(info[1]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal0[i] = Nan::Get(inReal0_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inReal1[i] = Nan::Get(inReal1_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inReal0Name = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::String> inReal1Name = info[2]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal0[i] = Nan::Get(inObject, inReal0Name).ToLocalChecked()->NumberValue(context).FromJust();
            inReal1[i] = Nan::Get(inObject, inReal1Name).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_CORREL_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_CORREL(startIdx, endIdx, inReal0, inReal1, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal0;
        delete[] inReal1;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_CORREL ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal0;
    delete[] inReal1;
    delete[] outReal;
}


void TA_FUNC_COS(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_COS_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_COS(startIdx, endIdx, inReal, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_COS ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_COSH(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_COSH_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_COSH(startIdx, endIdx, inReal, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_COSH ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_DEMA(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 30;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_DEMA_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_DEMA(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_DEMA ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_DIV(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal0 = new double[inLength];
    double *inReal1 = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal0_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inReal1_JS = v8::Local<v8::Array>::Cast(info[1]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal0[i] = Nan::Get(inReal0_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inReal1[i] = Nan::Get(inReal1_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inReal0Name = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::String> inReal1Name = info[2]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal0[i] = Nan::Get(inObject, inReal0Name).ToLocalChecked()->NumberValue(context).FromJust();
            inReal1[i] = Nan::Get(inObject, inReal1Name).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_DIV_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_DIV(startIdx, endIdx, inReal0, inReal1, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal0;
        delete[] inReal1;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_DIV ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal0;
    delete[] inReal1;
    delete[] outReal;
}


void TA_FUNC_DX(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[2]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_DX_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_DX(startIdx, endIdx, inHigh, inLow, inClose, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_DX ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outReal;
}


void TA_FUNC_EMA(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 30;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_EMA_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_EMA(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_EMA ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_EXP(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_EXP_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_EXP(startIdx, endIdx, inReal, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_EXP ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_FLOOR(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_FLOOR_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_FLOOR(startIdx, endIdx, inReal, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_FLOOR ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_HT_DCPERIOD(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_HT_DCPERIOD_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_HT_DCPERIOD(startIdx, endIdx, inReal, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_HT_DCPERIOD ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_HT_DCPHASE(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_HT_DCPHASE_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_HT_DCPHASE(startIdx, endIdx, inReal, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_HT_DCPHASE ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_HT_PHASOR(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInPhase_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outQuadrature_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(2);
        Nan::Set(outAll_JS, 0, outInPhase_JS);
        Nan::Set(outAll_JS, 1, outQuadrature_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_HT_PHASOR_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInPhase_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outQuadrature_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(2);
        Nan::Set(outAll_JS, 0, outInPhase_JS);
        Nan::Set(outAll_JS, 1, outQuadrature_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outInPhase = new double[outLength];
    double *outQuadrature = new double[outLength];
    TA_RetCode result = TA_HT_PHASOR(startIdx, endIdx, inReal, &outBegIdx, &outNBElement, outInPhase, outQuadrature);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outInPhase;
        delete[] outQuadrature;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_HT_PHASOR ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInPhase_JS = Nan::New<v8::Array>(outLength);
    v8::Local<v8::Array> outQuadrature_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = Nan::New<v8::Array>(2);
    Nan::Set(outAll_JS, 0, outInPhase_JS);
    Nan::Set(outAll_JS, 1, outQuadrature_JS);
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInPhase_JS, i, Nan::New<v8::Number>(outInPhase[i]));
        Nan::Set(outQuadrature_JS, i, Nan::New<v8::Number>(outQuadrature[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outInPhase;
    delete[] outQuadrature;
}


void TA_FUNC_HT_SINE(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outSine_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outLeadSine_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(2);
        Nan::Set(outAll_JS, 0, outSine_JS);
        Nan::Set(outAll_JS, 1, outLeadSine_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_HT_SINE_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outSine_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outLeadSine_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(2);
        Nan::Set(outAll_JS, 0, outSine_JS);
        Nan::Set(outAll_JS, 1, outLeadSine_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outSine = new double[outLength];
    double *outLeadSine = new double[outLength];
    TA_RetCode result = TA_HT_SINE(startIdx, endIdx, inReal, &outBegIdx, &outNBElement, outSine, outLeadSine);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outSine;
        delete[] outLeadSine;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_HT_SINE ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outSine_JS = Nan::New<v8::Array>(outLength);
    v8::Local<v8::Array> outLeadSine_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = Nan::New<v8::Array>(2);
    Nan::Set(outAll_JS, 0, outSine_JS);
    Nan::Set(outAll_JS, 1, outLeadSine_JS);
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outSine_JS, i, Nan::New<v8::Number>(outSine[i]));
        Nan::Set(outLeadSine_JS, i, Nan::New<v8::Number>(outLeadSine[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outSine;
    delete[] outLeadSine;
}


void TA_FUNC_HT_TRENDLINE(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_HT_TRENDLINE_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_HT_TRENDLINE(startIdx, endIdx, inReal, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_HT_TRENDLINE ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_HT_TRENDMODE(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_HT_TRENDMODE_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_HT_TRENDMODE(startIdx, endIdx, inReal, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_HT_TRENDMODE ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outInteger;
}


void TA_FUNC_IMI(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inOpen = new double[inLength];
    double *inClose = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inOpen_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[1]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inOpen[i] = Nan::Get(inOpen_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inOpenName = Nan::New("Open").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inOpen[i] = Nan::Get(inObject, inOpenName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_IMI_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_IMI(startIdx, endIdx, inOpen, inClose, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inOpen;
        delete[] inClose;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_IMI ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inOpen;
    delete[] inClose;
    delete[] outReal;
}


void TA_FUNC_KAMA(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 30;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_KAMA_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_KAMA(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_KAMA ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_LINEARREG(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_LINEARREG_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_LINEARREG(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_LINEARREG ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_LINEARREG_ANGLE(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_LINEARREG_ANGLE_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_LINEARREG_ANGLE(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_LINEARREG_ANGLE ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_LINEARREG_INTERCEPT(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_LINEARREG_INTERCEPT_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_LINEARREG_INTERCEPT(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_LINEARREG_INTERCEPT ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_LINEARREG_SLOPE(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_LINEARREG_SLOPE_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_LINEARREG_SLOPE(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_LINEARREG_SLOPE ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_LN(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_LN_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_LN(startIdx, endIdx, inReal, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_LN ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_LOG10(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_LOG10_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_LOG10(startIdx, endIdx, inReal, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_LOG10 ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_MA(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 30;
    TA_MAType optMA_Type = TA_MAType_SMA;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        optMA_Type = argc > 2 && info[2]->IsInt32() ? (TA_MAType)  info[2]->Int32Value(context).FromJust() : optMA_Type;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        optMA_Type = argc > 3 && info[3]->IsInt32() ? (TA_MAType)  info[3]->Int32Value(context).FromJust() : optMA_Type;
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_MA_Lookback(optTime_Period, optMA_Type);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_MA(startIdx, endIdx, inReal, optTime_Period, optMA_Type, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_MA ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_MACD(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outMACD_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outMACDSignal_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outMACDHist_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(3);
        Nan::Set(outAll_JS, 0, outMACD_JS);
        Nan::Set(outAll_JS, 1, outMACDSignal_JS);
        Nan::Set(outAll_JS, 2, outMACDHist_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optFast_Period = 12;
    int optSlow_Period = 26;
    int optSignal_Period = 9;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optFast_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optFast_Period;
        optSlow_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optSlow_Period;
        optSignal_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optSignal_Period;
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optFast_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optFast_Period;
        optSlow_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optSlow_Period;
        optSignal_Period = argc > 4 && info[4]->IsInt32() ?  info[4]->Int32Value(context).FromJust() : optSignal_Period;
        startIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 6 && info[6]->IsInt32() ? info[6]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_MACD_Lookback(optFast_Period, optSlow_Period, optSignal_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outMACD_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outMACDSignal_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outMACDHist_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(3);
        Nan::Set(outAll_JS, 0, outMACD_JS);
        Nan::Set(outAll_JS, 1, outMACDSignal_JS);
        Nan::Set(outAll_JS, 2, outMACDHist_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outMACD = new double[outLength];
    double *outMACDSignal = new double[outLength];
    double *outMACDHist = new double[outLength];
    TA_RetCode result = TA_MACD(startIdx, endIdx, inReal, optFast_Period, optSlow_Period, optSignal_Period, &outBegIdx, &outNBElement, outMACD, outMACDSignal, outMACDHist);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outMACD;
        delete[] outMACDSignal;
        delete[] outMACDHist;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_MACD ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outMACD_JS = Nan::New<v8::Array>(outLength);
    v8::Local<v8::Array> outMACDSignal_JS = Nan::New<v8::Array>(outLength);
    v8::Local<v8::Array> outMACDHist_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = Nan::New<v8::Array>(3);
    Nan::Set(outAll_JS, 0, outMACD_JS);
    Nan::Set(outAll_JS, 1, outMACDSignal_JS);
    Nan::Set(outAll_JS, 2, outMACDHist_JS);
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outMACD_JS, i, Nan::New<v8::Number>(outMACD[i]));
        Nan::Set(outMACDSignal_JS, i, Nan::New<v8::Number>(outMACDSignal[i]));
        Nan::Set(outMACDHist_JS, i, Nan::New<v8::Number>(outMACDHist[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outMACD;
    delete[] outMACDSignal;
    delete[] outMACDHist;
}


void TA_FUNC_MACDEXT(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outMACD_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outMACDSignal_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outMACDHist_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(3);
        Nan::Set(outAll_JS, 0, outMACD_JS);
        Nan::Set(outAll_JS, 1, outMACDSignal_JS);
        Nan::Set(outAll_JS, 2, outMACDHist_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optFast_Period = 12;
    TA_MAType optFast_MA = TA_MAType_SMA;
    int optSlow_Period = 26;
    TA_MAType optSlow_MA = TA_MAType_SMA;
    int optSignal_Period = 9;
    TA_MAType optSignal_MA = TA_MAType_SMA;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optFast_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optFast_Period;
        optFast_MA = argc > 2 && info[2]->IsInt32() ? (TA_MAType)  info[2]->Int32Value(context).FromJust() : optFast_MA;
        optSlow_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optSlow_Period;
        optSlow_MA = argc > 4 && info[4]->IsInt32() ? (TA_MAType)  info[4]->Int32Value(context).FromJust() : optSlow_MA;
        optSignal_Period = argc > 5 && info[5]->IsInt32() ?  info[5]->Int32Value(context).FromJust() : optSignal_Period;
        optSignal_MA = argc > 6 && info[6]->IsInt32() ? (TA_MAType)  info[6]->Int32Value(context).FromJust() : optSignal_MA;
        startIdx = argc > 7 && info[7]->IsInt32() ? info[7]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 8 && info[8]->IsInt32() ? info[8]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optFast_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optFast_Period;
        optFast_MA = argc > 3 && info[3]->IsInt32() ? (TA_MAType)  info[3]->Int32Value(context).FromJust() : optFast_MA;
        optSlow_Period = argc > 4 && info[4]->IsInt32() ?  info[4]->Int32Value(context).FromJust() : optSlow_Period;
        optSlow_MA = argc > 5 && info[5]->IsInt32() ? (TA_MAType)  info[5]->Int32Value(context).FromJust() : optSlow_MA;
        optSignal_Period = argc > 6 && info[6]->IsInt32() ?  info[6]->Int32Value(context).FromJust() : optSignal_Period;
        optSignal_MA = argc > 7 && info[7]->IsInt32() ? (TA_MAType)  info[7]->Int32Value(context).FromJust() : optSignal_MA;
        startIdx = argc > 8 && info[8]->IsInt32() ? info[8]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 9 && info[9]->IsInt32() ? info[9]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_MACDEXT_Lookback(optFast_Period, optFast_MA, optSlow_Period, optSlow_MA, optSignal_Period, optSignal_MA);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outMACD_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outMACDSignal_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outMACDHist_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(3);
        Nan::Set(outAll_JS, 0, outMACD_JS);
        Nan::Set(outAll_JS, 1, outMACDSignal_JS);
        Nan::Set(outAll_JS, 2, outMACDHist_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outMACD = new double[outLength];
    double *outMACDSignal = new double[outLength];
    double *outMACDHist = new double[outLength];
    TA_RetCode result = TA_MACDEXT(startIdx, endIdx, inReal, optFast_Period, optFast_MA, optSlow_Period, optSlow_MA, optSignal_Period, optSignal_MA, &outBegIdx, &outNBElement, outMACD, outMACDSignal, outMACDHist);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outMACD;
        delete[] outMACDSignal;
        delete[] outMACDHist;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_MACDEXT ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outMACD_JS = Nan::New<v8::Array>(outLength);
    v8::Local<v8::Array> outMACDSignal_JS = Nan::New<v8::Array>(outLength);
    v8::Local<v8::Array> outMACDHist_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = Nan::New<v8::Array>(3);
    Nan::Set(outAll_JS, 0, outMACD_JS);
    Nan::Set(outAll_JS, 1, outMACDSignal_JS);
    Nan::Set(outAll_JS, 2, outMACDHist_JS);
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outMACD_JS, i, Nan::New<v8::Number>(outMACD[i]));
        Nan::Set(outMACDSignal_JS, i, Nan::New<v8::Number>(outMACDSignal[i]));
        Nan::Set(outMACDHist_JS, i, Nan::New<v8::Number>(outMACDHist[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outMACD;
    delete[] outMACDSignal;
    delete[] outMACDHist;
}


void TA_FUNC_MACDFIX(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outMACD_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outMACDSignal_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outMACDHist_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(3);
        Nan::Set(outAll_JS, 0, outMACD_JS);
        Nan::Set(outAll_JS, 1, outMACDSignal_JS);
        Nan::Set(outAll_JS, 2, outMACDHist_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optSignal_Period = 9;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optSignal_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optSignal_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optSignal_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optSignal_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_MACDFIX_Lookback(optSignal_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outMACD_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outMACDSignal_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outMACDHist_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(3);
        Nan::Set(outAll_JS, 0, outMACD_JS);
        Nan::Set(outAll_JS, 1, outMACDSignal_JS);
        Nan::Set(outAll_JS, 2, outMACDHist_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outMACD = new double[outLength];
    double *outMACDSignal = new double[outLength];
    double *outMACDHist = new double[outLength];
    TA_RetCode result = TA_MACDFIX(startIdx, endIdx, inReal, optSignal_Period, &outBegIdx, &outNBElement, outMACD, outMACDSignal, outMACDHist);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outMACD;
        delete[] outMACDSignal;
        delete[] outMACDHist;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_MACDFIX ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outMACD_JS = Nan::New<v8::Array>(outLength);
    v8::Local<v8::Array> outMACDSignal_JS = Nan::New<v8::Array>(outLength);
    v8::Local<v8::Array> outMACDHist_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = Nan::New<v8::Array>(3);
    Nan::Set(outAll_JS, 0, outMACD_JS);
    Nan::Set(outAll_JS, 1, outMACDSignal_JS);
    Nan::Set(outAll_JS, 2, outMACDHist_JS);
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outMACD_JS, i, Nan::New<v8::Number>(outMACD[i]));
        Nan::Set(outMACDSignal_JS, i, Nan::New<v8::Number>(outMACDSignal[i]));
        Nan::Set(outMACDHist_JS, i, Nan::New<v8::Number>(outMACDHist[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outMACD;
    delete[] outMACDSignal;
    delete[] outMACDHist;
}


void TA_FUNC_MAMA(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outMAMA_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outFAMA_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(2);
        Nan::Set(outAll_JS, 0, outMAMA_JS);
        Nan::Set(outAll_JS, 1, outFAMA_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    double optFast_Limit = 5.000000e-1;
    double optSlow_Limit = 5.000000e-2;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optFast_Limit = argc > 1 && info[1]->IsNumber() ?  info[1]->NumberValue(context).FromJust() : optFast_Limit;
        optSlow_Limit = argc > 2 && info[2]->IsNumber() ?  info[2]->NumberValue(context).FromJust() : optSlow_Limit;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optFast_Limit = argc > 2 && info[2]->IsNumber() ?  info[2]->NumberValue(context).FromJust() : optFast_Limit;
        optSlow_Limit = argc > 3 && info[3]->IsNumber() ?  info[3]->NumberValue(context).FromJust() : optSlow_Limit;
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_MAMA_Lookback(optFast_Limit, optSlow_Limit);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outMAMA_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outFAMA_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(2);
        Nan::Set(outAll_JS, 0, outMAMA_JS);
        Nan::Set(outAll_JS, 1, outFAMA_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outMAMA = new double[outLength];
    double *outFAMA = new double[outLength];
    TA_RetCode result = TA_MAMA(startIdx, endIdx, inReal, optFast_Limit, optSlow_Limit, &outBegIdx, &outNBElement, outMAMA, outFAMA);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outMAMA;
        delete[] outFAMA;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_MAMA ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outMAMA_JS = Nan::New<v8::Array>(outLength);
    v8::Local<v8::Array> outFAMA_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = Nan::New<v8::Array>(2);
    Nan::Set(outAll_JS, 0, outMAMA_JS);
    Nan::Set(outAll_JS, 1, outFAMA_JS);
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outMAMA_JS, i, Nan::New<v8::Number>(outMAMA[i]));
        Nan::Set(outFAMA_JS, i, Nan::New<v8::Number>(outFAMA[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outMAMA;
    delete[] outFAMA;
}


void TA_FUNC_MAVP(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    double *inPeriods = new double[inLength];
    int optMinimum_Period = 2;
    int optMaximum_Period = 30;
    TA_MAType optMA_Type = TA_MAType_SMA;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inPeriods_JS = v8::Local<v8::Array>::Cast(info[1]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inPeriods[i] = Nan::Get(inPeriods_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optMinimum_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optMinimum_Period;
        optMaximum_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optMaximum_Period;
        optMA_Type = argc > 4 && info[4]->IsInt32() ? (TA_MAType)  info[4]->Int32Value(context).FromJust() : optMA_Type;
        startIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 6 && info[6]->IsInt32() ? info[6]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::String> inPeriodsName = info[2]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
            inPeriods[i] = Nan::Get(inObject, inPeriodsName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optMinimum_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optMinimum_Period;
        optMaximum_Period = argc > 4 && info[4]->IsInt32() ?  info[4]->Int32Value(context).FromJust() : optMaximum_Period;
        optMA_Type = argc > 5 && info[5]->IsInt32() ? (TA_MAType)  info[5]->Int32Value(context).FromJust() : optMA_Type;
        startIdx = argc > 6 && info[6]->IsInt32() ? info[6]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 7 && info[7]->IsInt32() ? info[7]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_MAVP_Lookback(optMinimum_Period, optMaximum_Period, optMA_Type);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_MAVP(startIdx, endIdx, inReal, inPeriods, optMinimum_Period, optMaximum_Period, optMA_Type, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] inPeriods;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_MAVP ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] inPeriods;
    delete[] outReal;
}


void TA_FUNC_MAX(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 30;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_MAX_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_MAX(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_MAX ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_MAXINDEX(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 30;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_MAXINDEX_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_MAXINDEX(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_MAXINDEX ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outInteger;
}


void TA_FUNC_MEDPRICE(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_MEDPRICE_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_MEDPRICE(startIdx, endIdx, inHigh, inLow, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_MEDPRICE ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] outReal;
}


void TA_FUNC_MFI(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    double *inVolume = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[2]);
        v8::Local<v8::Array> inVolume_JS = v8::Local<v8::Array>::Cast(info[3]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inVolume[i] = Nan::Get(inVolume_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 4 && info[4]->IsInt32() ?  info[4]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 6 && info[6]->IsInt32() ? info[6]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::String> inVolumeName = Nan::New("Volume").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
            inVolume[i] = Nan::Get(inObject, inVolumeName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_MFI_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_MFI(startIdx, endIdx, inHigh, inLow, inClose, inVolume, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] inVolume;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_MFI ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] inVolume;
    delete[] outReal;
}


void TA_FUNC_MIDPOINT(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_MIDPOINT_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_MIDPOINT(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_MIDPOINT ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_MIDPRICE(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_MIDPRICE_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_MIDPRICE(startIdx, endIdx, inHigh, inLow, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_MIDPRICE ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] outReal;
}


void TA_FUNC_MIN(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 30;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_MIN_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_MIN(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_MIN ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_MININDEX(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 30;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_MININDEX_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outInteger_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outInteger = new int[outLength];
    TA_RetCode result = TA_MININDEX(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outInteger);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outInteger;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_MININDEX ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outInteger_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outInteger_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outInteger_JS, i, Nan::New<v8::Number>(outInteger[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outInteger;
}


void TA_FUNC_MINMAX(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outMin_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outMax_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(2);
        Nan::Set(outAll_JS, 0, outMin_JS);
        Nan::Set(outAll_JS, 1, outMax_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 30;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_MINMAX_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outMin_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outMax_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(2);
        Nan::Set(outAll_JS, 0, outMin_JS);
        Nan::Set(outAll_JS, 1, outMax_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outMin = new double[outLength];
    double *outMax = new double[outLength];
    TA_RetCode result = TA_MINMAX(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outMin, outMax);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outMin;
        delete[] outMax;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_MINMAX ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outMin_JS = Nan::New<v8::Array>(outLength);
    v8::Local<v8::Array> outMax_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = Nan::New<v8::Array>(2);
    Nan::Set(outAll_JS, 0, outMin_JS);
    Nan::Set(outAll_JS, 1, outMax_JS);
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outMin_JS, i, Nan::New<v8::Number>(outMin[i]));
        Nan::Set(outMax_JS, i, Nan::New<v8::Number>(outMax[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outMin;
    delete[] outMax;
}


void TA_FUNC_MINMAXINDEX(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outMinIdx_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outMaxIdx_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(2);
        Nan::Set(outAll_JS, 0, outMinIdx_JS);
        Nan::Set(outAll_JS, 1, outMaxIdx_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 30;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_MINMAXINDEX_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outMinIdx_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outMaxIdx_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(2);
        Nan::Set(outAll_JS, 0, outMinIdx_JS);
        Nan::Set(outAll_JS, 1, outMaxIdx_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int *outMinIdx = new int[outLength];
    int *outMaxIdx = new int[outLength];
    TA_RetCode result = TA_MINMAXINDEX(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outMinIdx, outMaxIdx);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outMinIdx;
        delete[] outMaxIdx;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_MINMAXINDEX ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outMinIdx_JS = Nan::New<v8::Array>(outLength);
    v8::Local<v8::Array> outMaxIdx_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = Nan::New<v8::Array>(2);
    Nan::Set(outAll_JS, 0, outMinIdx_JS);
    Nan::Set(outAll_JS, 1, outMaxIdx_JS);
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outMinIdx_JS, i, Nan::New<v8::Number>(outMinIdx[i]));
        Nan::Set(outMaxIdx_JS, i, Nan::New<v8::Number>(outMaxIdx[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outMinIdx;
    delete[] outMaxIdx;
}


void TA_FUNC_MINUS_DI(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[2]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_MINUS_DI_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_MINUS_DI(startIdx, endIdx, inHigh, inLow, inClose, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_MINUS_DI ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outReal;
}


void TA_FUNC_MINUS_DM(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_MINUS_DM_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_MINUS_DM(startIdx, endIdx, inHigh, inLow, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_MINUS_DM ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] outReal;
}


void TA_FUNC_MOM(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 10;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_MOM_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_MOM(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_MOM ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_MULT(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal0 = new double[inLength];
    double *inReal1 = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal0_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inReal1_JS = v8::Local<v8::Array>::Cast(info[1]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal0[i] = Nan::Get(inReal0_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inReal1[i] = Nan::Get(inReal1_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inReal0Name = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::String> inReal1Name = info[2]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal0[i] = Nan::Get(inObject, inReal0Name).ToLocalChecked()->NumberValue(context).FromJust();
            inReal1[i] = Nan::Get(inObject, inReal1Name).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_MULT_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_MULT(startIdx, endIdx, inReal0, inReal1, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal0;
        delete[] inReal1;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_MULT ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal0;
    delete[] inReal1;
    delete[] outReal;
}


void TA_FUNC_NATR(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[2]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_NATR_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_NATR(startIdx, endIdx, inHigh, inLow, inClose, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_NATR ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outReal;
}


void TA_FUNC_OBV(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    double *inVolume = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inVolume_JS = v8::Local<v8::Array>::Cast(info[1]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inVolume[i] = Nan::Get(inVolume_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::String> inVolumeName = Nan::New("Volume").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
            inVolume[i] = Nan::Get(inObject, inVolumeName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_OBV_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_OBV(startIdx, endIdx, inReal, inVolume, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] inVolume;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_OBV ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] inVolume;
    delete[] outReal;
}


void TA_FUNC_PLUS_DI(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[2]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_PLUS_DI_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_PLUS_DI(startIdx, endIdx, inHigh, inLow, inClose, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_PLUS_DI ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outReal;
}


void TA_FUNC_PLUS_DM(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_PLUS_DM_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_PLUS_DM(startIdx, endIdx, inHigh, inLow, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_PLUS_DM ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] outReal;
}


void TA_FUNC_PPO(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optFast_Period = 12;
    int optSlow_Period = 26;
    TA_MAType optMA_Type = TA_MAType_SMA;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optFast_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optFast_Period;
        optSlow_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optSlow_Period;
        optMA_Type = argc > 3 && info[3]->IsInt32() ? (TA_MAType)  info[3]->Int32Value(context).FromJust() : optMA_Type;
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optFast_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optFast_Period;
        optSlow_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optSlow_Period;
        optMA_Type = argc > 4 && info[4]->IsInt32() ? (TA_MAType)  info[4]->Int32Value(context).FromJust() : optMA_Type;
        startIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 6 && info[6]->IsInt32() ? info[6]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_PPO_Lookback(optFast_Period, optSlow_Period, optMA_Type);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_PPO(startIdx, endIdx, inReal, optFast_Period, optSlow_Period, optMA_Type, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_PPO ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_ROC(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 10;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_ROC_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_ROC(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_ROC ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_ROCP(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 10;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_ROCP_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_ROCP(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_ROCP ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_ROCR(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 10;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_ROCR_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_ROCR(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_ROCR ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_ROCR100(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 10;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_ROCR100_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_ROCR100(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_ROCR100 ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_RSI(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_RSI_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_RSI(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_RSI ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_SAR(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double optAcceleration_Factor = 2.000000e-2;
    double optAF_Maximum = 2.000000e-1;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optAcceleration_Factor = argc > 2 && info[2]->IsNumber() ?  info[2]->NumberValue(context).FromJust() : optAcceleration_Factor;
        optAF_Maximum = argc > 3 && info[3]->IsNumber() ?  info[3]->NumberValue(context).FromJust() : optAF_Maximum;
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optAcceleration_Factor = argc > 1 && info[1]->IsNumber() ?  info[1]->NumberValue(context).FromJust() : optAcceleration_Factor;
        optAF_Maximum = argc > 2 && info[2]->IsNumber() ?  info[2]->NumberValue(context).FromJust() : optAF_Maximum;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_SAR_Lookback(optAcceleration_Factor, optAF_Maximum);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_SAR(startIdx, endIdx, inHigh, inLow, optAcceleration_Factor, optAF_Maximum, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_SAR ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] outReal;
}


void TA_FUNC_SAREXT(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double optStart_Value = 0.000000e+0;
    double optOffset_on_Reverse = 0.000000e+0;
    double optAF_Init_Long = 2.000000e-2;
    double optAF_Long = 2.000000e-2;
    double optAF_Max_Long = 2.000000e-1;
    double optAF_Init_Short = 2.000000e-2;
    double optAF_Short = 2.000000e-2;
    double optAF_Max_Short = 2.000000e-1;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optStart_Value = argc > 2 && info[2]->IsNumber() ?  info[2]->NumberValue(context).FromJust() : optStart_Value;
        optOffset_on_Reverse = argc > 3 && info[3]->IsNumber() ?  info[3]->NumberValue(context).FromJust() : optOffset_on_Reverse;
        optAF_Init_Long = argc > 4 && info[4]->IsNumber() ?  info[4]->NumberValue(context).FromJust() : optAF_Init_Long;
        optAF_Long = argc > 5 && info[5]->IsNumber() ?  info[5]->NumberValue(context).FromJust() : optAF_Long;
        optAF_Max_Long = argc > 6 && info[6]->IsNumber() ?  info[6]->NumberValue(context).FromJust() : optAF_Max_Long;
        optAF_Init_Short = argc > 7 && info[7]->IsNumber() ?  info[7]->NumberValue(context).FromJust() : optAF_Init_Short;
        optAF_Short = argc > 8 && info[8]->IsNumber() ?  info[8]->NumberValue(context).FromJust() : optAF_Short;
        optAF_Max_Short = argc > 9 && info[9]->IsNumber() ?  info[9]->NumberValue(context).FromJust() : optAF_Max_Short;
        startIdx = argc > 10 && info[10]->IsInt32() ? info[10]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 11 && info[11]->IsInt32() ? info[11]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optStart_Value = argc > 1 && info[1]->IsNumber() ?  info[1]->NumberValue(context).FromJust() : optStart_Value;
        optOffset_on_Reverse = argc > 2 && info[2]->IsNumber() ?  info[2]->NumberValue(context).FromJust() : optOffset_on_Reverse;
        optAF_Init_Long = argc > 3 && info[3]->IsNumber() ?  info[3]->NumberValue(context).FromJust() : optAF_Init_Long;
        optAF_Long = argc > 4 && info[4]->IsNumber() ?  info[4]->NumberValue(context).FromJust() : optAF_Long;
        optAF_Max_Long = argc > 5 && info[5]->IsNumber() ?  info[5]->NumberValue(context).FromJust() : optAF_Max_Long;
        optAF_Init_Short = argc > 6 && info[6]->IsNumber() ?  info[6]->NumberValue(context).FromJust() : optAF_Init_Short;
        optAF_Short = argc > 7 && info[7]->IsNumber() ?  info[7]->NumberValue(context).FromJust() : optAF_Short;
        optAF_Max_Short = argc > 8 && info[8]->IsNumber() ?  info[8]->NumberValue(context).FromJust() : optAF_Max_Short;
        startIdx = argc > 9 && info[9]->IsInt32() ? info[9]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 10 && info[10]->IsInt32() ? info[10]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_SAREXT_Lookback(optStart_Value, optOffset_on_Reverse, optAF_Init_Long, optAF_Long, optAF_Max_Long, optAF_Init_Short, optAF_Short, optAF_Max_Short);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_SAREXT(startIdx, endIdx, inHigh, inLow, optStart_Value, optOffset_on_Reverse, optAF_Init_Long, optAF_Long, optAF_Max_Long, optAF_Init_Short, optAF_Short, optAF_Max_Short, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_SAREXT ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] outReal;
}


void TA_FUNC_SIN(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_SIN_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_SIN(startIdx, endIdx, inReal, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_SIN ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_SINH(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_SINH_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_SINH(startIdx, endIdx, inReal, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_SINH ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_SMA(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 30;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_SMA_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_SMA(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_SMA ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_SQRT(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_SQRT_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_SQRT(startIdx, endIdx, inReal, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_SQRT ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_STDDEV(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 5;
    double optDeviations = 1.000000e+0;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        optDeviations = argc > 2 && info[2]->IsNumber() ?  info[2]->NumberValue(context).FromJust() : optDeviations;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        optDeviations = argc > 3 && info[3]->IsNumber() ?  info[3]->NumberValue(context).FromJust() : optDeviations;
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_STDDEV_Lookback(optTime_Period, optDeviations);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_STDDEV(startIdx, endIdx, inReal, optTime_Period, optDeviations, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_STDDEV ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_STOCH(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outSlowK_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outSlowD_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(2);
        Nan::Set(outAll_JS, 0, outSlowK_JS);
        Nan::Set(outAll_JS, 1, outSlowD_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int optFastK_Period = 5;
    int optSlowK_Period = 3;
    TA_MAType optSlowK_MA = TA_MAType_SMA;
    int optSlowD_Period = 3;
    TA_MAType optSlowD_MA = TA_MAType_SMA;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[2]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optFastK_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optFastK_Period;
        optSlowK_Period = argc > 4 && info[4]->IsInt32() ?  info[4]->Int32Value(context).FromJust() : optSlowK_Period;
        optSlowK_MA = argc > 5 && info[5]->IsInt32() ? (TA_MAType)  info[5]->Int32Value(context).FromJust() : optSlowK_MA;
        optSlowD_Period = argc > 6 && info[6]->IsInt32() ?  info[6]->Int32Value(context).FromJust() : optSlowD_Period;
        optSlowD_MA = argc > 7 && info[7]->IsInt32() ? (TA_MAType)  info[7]->Int32Value(context).FromJust() : optSlowD_MA;
        startIdx = argc > 8 && info[8]->IsInt32() ? info[8]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 9 && info[9]->IsInt32() ? info[9]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optFastK_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optFastK_Period;
        optSlowK_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optSlowK_Period;
        optSlowK_MA = argc > 3 && info[3]->IsInt32() ? (TA_MAType)  info[3]->Int32Value(context).FromJust() : optSlowK_MA;
        optSlowD_Period = argc > 4 && info[4]->IsInt32() ?  info[4]->Int32Value(context).FromJust() : optSlowD_Period;
        optSlowD_MA = argc > 5 && info[5]->IsInt32() ? (TA_MAType)  info[5]->Int32Value(context).FromJust() : optSlowD_MA;
        startIdx = argc > 6 && info[6]->IsInt32() ? info[6]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 7 && info[7]->IsInt32() ? info[7]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_STOCH_Lookback(optFastK_Period, optSlowK_Period, optSlowK_MA, optSlowD_Period, optSlowD_MA);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outSlowK_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outSlowD_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(2);
        Nan::Set(outAll_JS, 0, outSlowK_JS);
        Nan::Set(outAll_JS, 1, outSlowD_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outSlowK = new double[outLength];
    double *outSlowD = new double[outLength];
    TA_RetCode result = TA_STOCH(startIdx, endIdx, inHigh, inLow, inClose, optFastK_Period, optSlowK_Period, optSlowK_MA, optSlowD_Period, optSlowD_MA, &outBegIdx, &outNBElement, outSlowK, outSlowD);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outSlowK;
        delete[] outSlowD;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_STOCH ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outSlowK_JS = Nan::New<v8::Array>(outLength);
    v8::Local<v8::Array> outSlowD_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = Nan::New<v8::Array>(2);
    Nan::Set(outAll_JS, 0, outSlowK_JS);
    Nan::Set(outAll_JS, 1, outSlowD_JS);
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outSlowK_JS, i, Nan::New<v8::Number>(outSlowK[i]));
        Nan::Set(outSlowD_JS, i, Nan::New<v8::Number>(outSlowD[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outSlowK;
    delete[] outSlowD;
}


void TA_FUNC_STOCHF(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outFastK_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outFastD_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(2);
        Nan::Set(outAll_JS, 0, outFastK_JS);
        Nan::Set(outAll_JS, 1, outFastD_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int optFastK_Period = 5;
    int optFastD_Period = 3;
    TA_MAType optFastD_MA = TA_MAType_SMA;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[2]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optFastK_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optFastK_Period;
        optFastD_Period = argc > 4 && info[4]->IsInt32() ?  info[4]->Int32Value(context).FromJust() : optFastD_Period;
        optFastD_MA = argc > 5 && info[5]->IsInt32() ? (TA_MAType)  info[5]->Int32Value(context).FromJust() : optFastD_MA;
        startIdx = argc > 6 && info[6]->IsInt32() ? info[6]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 7 && info[7]->IsInt32() ? info[7]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optFastK_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optFastK_Period;
        optFastD_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optFastD_Period;
        optFastD_MA = argc > 3 && info[3]->IsInt32() ? (TA_MAType)  info[3]->Int32Value(context).FromJust() : optFastD_MA;
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_STOCHF_Lookback(optFastK_Period, optFastD_Period, optFastD_MA);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outFastK_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outFastD_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(2);
        Nan::Set(outAll_JS, 0, outFastK_JS);
        Nan::Set(outAll_JS, 1, outFastD_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outFastK = new double[outLength];
    double *outFastD = new double[outLength];
    TA_RetCode result = TA_STOCHF(startIdx, endIdx, inHigh, inLow, inClose, optFastK_Period, optFastD_Period, optFastD_MA, &outBegIdx, &outNBElement, outFastK, outFastD);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outFastK;
        delete[] outFastD;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_STOCHF ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outFastK_JS = Nan::New<v8::Array>(outLength);
    v8::Local<v8::Array> outFastD_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = Nan::New<v8::Array>(2);
    Nan::Set(outAll_JS, 0, outFastK_JS);
    Nan::Set(outAll_JS, 1, outFastD_JS);
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outFastK_JS, i, Nan::New<v8::Number>(outFastK[i]));
        Nan::Set(outFastD_JS, i, Nan::New<v8::Number>(outFastD[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outFastK;
    delete[] outFastD;
}


void TA_FUNC_STOCHRSI(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outFastK_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outFastD_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(2);
        Nan::Set(outAll_JS, 0, outFastK_JS);
        Nan::Set(outAll_JS, 1, outFastD_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 14;
    int optFastK_Period = 5;
    int optFastD_Period = 3;
    TA_MAType optFastD_MA = TA_MAType_SMA;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        optFastK_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optFastK_Period;
        optFastD_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optFastD_Period;
        optFastD_MA = argc > 4 && info[4]->IsInt32() ? (TA_MAType)  info[4]->Int32Value(context).FromJust() : optFastD_MA;
        startIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 6 && info[6]->IsInt32() ? info[6]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        optFastK_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optFastK_Period;
        optFastD_Period = argc > 4 && info[4]->IsInt32() ?  info[4]->Int32Value(context).FromJust() : optFastD_Period;
        optFastD_MA = argc > 5 && info[5]->IsInt32() ? (TA_MAType)  info[5]->Int32Value(context).FromJust() : optFastD_MA;
        startIdx = argc > 6 && info[6]->IsInt32() ? info[6]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 7 && info[7]->IsInt32() ? info[7]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_STOCHRSI_Lookback(optTime_Period, optFastK_Period, optFastD_Period, optFastD_MA);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outFastK_JS = Nan::New<v8::Array>(outLength);
        v8::Local<v8::Array> outFastD_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = Nan::New<v8::Array>(2);
        Nan::Set(outAll_JS, 0, outFastK_JS);
        Nan::Set(outAll_JS, 1, outFastD_JS);
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outFastK = new double[outLength];
    double *outFastD = new double[outLength];
    TA_RetCode result = TA_STOCHRSI(startIdx, endIdx, inReal, optTime_Period, optFastK_Period, optFastD_Period, optFastD_MA, &outBegIdx, &outNBElement, outFastK, outFastD);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outFastK;
        delete[] outFastD;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_STOCHRSI ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outFastK_JS = Nan::New<v8::Array>(outLength);
    v8::Local<v8::Array> outFastD_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = Nan::New<v8::Array>(2);
    Nan::Set(outAll_JS, 0, outFastK_JS);
    Nan::Set(outAll_JS, 1, outFastD_JS);
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outFastK_JS, i, Nan::New<v8::Number>(outFastK[i]));
        Nan::Set(outFastD_JS, i, Nan::New<v8::Number>(outFastD[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outFastK;
    delete[] outFastD;
}


void TA_FUNC_SUB(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal0 = new double[inLength];
    double *inReal1 = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal0_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inReal1_JS = v8::Local<v8::Array>::Cast(info[1]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal0[i] = Nan::Get(inReal0_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inReal1[i] = Nan::Get(inReal1_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inReal0Name = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::String> inReal1Name = info[2]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal0[i] = Nan::Get(inObject, inReal0Name).ToLocalChecked()->NumberValue(context).FromJust();
            inReal1[i] = Nan::Get(inObject, inReal1Name).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_SUB_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_SUB(startIdx, endIdx, inReal0, inReal1, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal0;
        delete[] inReal1;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_SUB ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal0;
    delete[] inReal1;
    delete[] outReal;
}


void TA_FUNC_SUM(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 30;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_SUM_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_SUM(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_SUM ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_T3(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 5;
    double optVolume_Factor = 7.000000e-1;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        optVolume_Factor = argc > 2 && info[2]->IsNumber() ?  info[2]->NumberValue(context).FromJust() : optVolume_Factor;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        optVolume_Factor = argc > 3 && info[3]->IsNumber() ?  info[3]->NumberValue(context).FromJust() : optVolume_Factor;
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_T3_Lookback(optTime_Period, optVolume_Factor);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_T3(startIdx, endIdx, inReal, optTime_Period, optVolume_Factor, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_T3 ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_TAN(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_TAN_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_TAN(startIdx, endIdx, inReal, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_TAN ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_TANH(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_TANH_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_TANH(startIdx, endIdx, inReal, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_TANH ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_TEMA(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 30;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_TEMA_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_TEMA(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_TEMA ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_TRANGE(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[2]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_TRANGE_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_TRANGE(startIdx, endIdx, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_TRANGE ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outReal;
}


void TA_FUNC_TRIMA(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 30;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_TRIMA_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_TRIMA(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_TRIMA ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_TRIX(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 30;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_TRIX_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_TRIX(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_TRIX ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_TSF(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_TSF_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_TSF(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_TSF ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_TYPPRICE(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[2]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_TYPPRICE_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_TYPPRICE(startIdx, endIdx, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_TYPPRICE ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outReal;
}


void TA_FUNC_ULTOSC(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int optFirst_Period = 7;
    int optSecond_Period = 14;
    int optThird_Period = 28;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[2]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optFirst_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optFirst_Period;
        optSecond_Period = argc > 4 && info[4]->IsInt32() ?  info[4]->Int32Value(context).FromJust() : optSecond_Period;
        optThird_Period = argc > 5 && info[5]->IsInt32() ?  info[5]->Int32Value(context).FromJust() : optThird_Period;
        startIdx = argc > 6 && info[6]->IsInt32() ? info[6]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 7 && info[7]->IsInt32() ? info[7]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optFirst_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optFirst_Period;
        optSecond_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optSecond_Period;
        optThird_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optThird_Period;
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_ULTOSC_Lookback(optFirst_Period, optSecond_Period, optThird_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_ULTOSC(startIdx, endIdx, inHigh, inLow, inClose, optFirst_Period, optSecond_Period, optThird_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_ULTOSC ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outReal;
}


void TA_FUNC_VAR(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 5;
    double optDeviations = 1.000000e+0;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        optDeviations = argc > 2 && info[2]->IsNumber() ?  info[2]->NumberValue(context).FromJust() : optDeviations;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        optDeviations = argc > 3 && info[3]->IsNumber() ?  info[3]->NumberValue(context).FromJust() : optDeviations;
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_VAR_Lookback(optTime_Period, optDeviations);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_VAR(startIdx, endIdx, inReal, optTime_Period, optDeviations, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_VAR ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void TA_FUNC_WCLPRICE(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[2]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        startIdx = argc > 1 && info[1]->IsInt32() ? info[1]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_WCLPRICE_Lookback();
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_WCLPRICE(startIdx, endIdx, inHigh, inLow, inClose, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_WCLPRICE ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outReal;
}


void TA_FUNC_WILLR(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inHigh = new double[inLength];
    double *inLow = new double[inLength];
    double *inClose = new double[inLength];
    int optTime_Period = 14;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inHigh_JS = v8::Local<v8::Array>::Cast(info[0]);
        v8::Local<v8::Array> inLow_JS = v8::Local<v8::Array>::Cast(info[1]);
        v8::Local<v8::Array> inClose_JS = v8::Local<v8::Array>::Cast(info[2]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inHigh[i] = Nan::Get(inHigh_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inLow_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inClose_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 3 && info[3]->IsInt32() ?  info[3]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 5 && info[5]->IsInt32() ? info[5]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inHighName = Nan::New("High").ToLocalChecked();
        v8::Local<v8::String> inLowName = Nan::New("Low").ToLocalChecked();
        v8::Local<v8::String> inCloseName = Nan::New("Close").ToLocalChecked();
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inHigh[i] = Nan::Get(inObject, inHighName).ToLocalChecked()->NumberValue(context).FromJust();
            inLow[i] = Nan::Get(inObject, inLowName).ToLocalChecked()->NumberValue(context).FromJust();
            inClose[i] = Nan::Get(inObject, inCloseName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_WILLR_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_WILLR(startIdx, endIdx, inHigh, inLow, inClose, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inHigh;
        delete[] inLow;
        delete[] inClose;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_WILLR ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inHigh;
    delete[] inLow;
    delete[] inClose;
    delete[] outReal;
}


void TA_FUNC_WMA(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
    v8::Local<v8::Array> inFirst = v8::Local<v8::Array>::Cast(info[0]);
    int inLength = inFirst->Length();
    int outLength = 0;
    if (inLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    int firstIsRecord = 0;
    if (Nan::Get(inFirst, 0).ToLocalChecked()->IsObject()) {
        firstIsRecord = 1;
    }
    double *inReal = new double[inLength];
    int optTime_Period = 30;
    int startIdx = 0;
    int endIdx = inLength - 1;
    int outBegIdx = 0;
    int outNBElement = 0;
    uint32_t i = 0;
    int argc = info.Length();
    if (firstIsRecord == 0) {
        v8::Local<v8::Array> inReal_JS = v8::Local<v8::Array>::Cast(info[0]);
        for (i = 0; i < (uint32_t) inLength; i++) {
            inReal[i] = Nan::Get(inReal_JS, i).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 1 && info[1]->IsInt32() ?  info[1]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 2 && info[2]->IsInt32() ? info[2]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : endIdx;
    } else {
        v8::Local<v8::String> inRealName = info[1]->ToString(context).ToLocalChecked();;
        v8::Local<v8::Object> inObject;
        for (i = 0; i < (uint32_t) inLength; i++) {
            inObject = Nan::Get(inFirst, i).ToLocalChecked()->ToObject(context).ToLocalChecked();
            inReal[i] = Nan::Get(inObject, inRealName).ToLocalChecked()->NumberValue(context).FromJust();
        }
        optTime_Period = argc > 2 && info[2]->IsInt32() ?  info[2]->Int32Value(context).FromJust() : optTime_Period;
        startIdx = argc > 3 && info[3]->IsInt32() ? info[3]->Int32Value(context).FromJust() : startIdx;
        endIdx = argc > 4 && info[4]->IsInt32() ? info[4]->Int32Value(context).FromJust() : endIdx;
    }
    if (startIdx < 0 || endIdx >= inLength || startIdx > endIdx) {
        Nan::ThrowRangeError("`startIdx` or `endIdx` out of range");
        return;
    }
    int lookback = TA_WMA_Lookback(optTime_Period);
    int temp = lookback > startIdx ? lookback : startIdx;
    outLength = temp > endIdx ? 0 : endIdx - temp + 1;
    if (outLength == 0) {
        v8::Local<v8::Array> outAll_JS;
        v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
        outAll_JS = outReal_JS;
        info.GetReturnValue().Set(outAll_JS);
        return;
    }
    double *outReal = new double[outLength];
    TA_RetCode result = TA_WMA(startIdx, endIdx, inReal, optTime_Period, &outBegIdx, &outNBElement, outReal);
    if (result != TA_SUCCESS) {
        delete[] inReal;
        delete[] outReal;
        TA_RetCodeInfo retCodeInfo;
        TA_SetRetCodeInfo(result, &retCodeInfo);
        char error[100];
        strcpy(error, "TA_WMA ERROR: ");
        strcat(error, retCodeInfo.enumStr);
        strcat(error, " - ");
        strcat(error, retCodeInfo.infoStr);
        Nan::ThrowError(error);
        return;
    }
    v8::Local<v8::Array> outAll_JS;
    v8::Local<v8::Array> outReal_JS = Nan::New<v8::Array>(outLength);
    outAll_JS = outReal_JS;
    for (i = 0; i < (uint32_t) outLength; i++) {
        Nan::Set(outReal_JS, i, Nan::New<v8::Number>(outReal[i]));
    }
    info.GetReturnValue().Set(outAll_JS);
    delete[] inReal;
    delete[] outReal;
}


void Init(v8::Local<v8::Object> exports, v8::Local<v8::Object> module) {
    TA_RetCode retCode = TA_Initialize();
    if (retCode != TA_SUCCESS) {
        Nan::ThrowError("TA initialize failed!");
        return;
    }
    Nan::Set(exports, Nan::New("ACCBANDS").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_ACCBANDS)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("ACOS").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_ACOS)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("AD").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_AD)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("ADD").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_ADD)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("ADOSC").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_ADOSC)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("ADX").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_ADX)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("ADXR").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_ADXR)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("APO").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_APO)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("AROON").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_AROON)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("AROONOSC").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_AROONOSC)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("ASIN").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_ASIN)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("ATAN").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_ATAN)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("ATR").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_ATR)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("AVGPRICE").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_AVGPRICE)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("AVGDEV").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_AVGDEV)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("BBANDS").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_BBANDS)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("BETA").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_BETA)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("BOP").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_BOP)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CCI").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CCI)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDL2CROWS").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDL2CROWS)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDL3BLACKCROWS").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDL3BLACKCROWS)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDL3INSIDE").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDL3INSIDE)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDL3LINESTRIKE").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDL3LINESTRIKE)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDL3OUTSIDE").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDL3OUTSIDE)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDL3STARSINSOUTH").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDL3STARSINSOUTH)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDL3WHITESOLDIERS").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDL3WHITESOLDIERS)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLABANDONEDBABY").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLABANDONEDBABY)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLADVANCEBLOCK").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLADVANCEBLOCK)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLBELTHOLD").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLBELTHOLD)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLBREAKAWAY").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLBREAKAWAY)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLCLOSINGMARUBOZU").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLCLOSINGMARUBOZU)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLCONCEALBABYSWALL").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLCONCEALBABYSWALL)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLCOUNTERATTACK").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLCOUNTERATTACK)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLDARKCLOUDCOVER").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLDARKCLOUDCOVER)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLDOJI").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLDOJI)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLDOJISTAR").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLDOJISTAR)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLDRAGONFLYDOJI").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLDRAGONFLYDOJI)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLENGULFING").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLENGULFING)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLEVENINGDOJISTAR").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLEVENINGDOJISTAR)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLEVENINGSTAR").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLEVENINGSTAR)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLGAPSIDESIDEWHITE").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLGAPSIDESIDEWHITE)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLGRAVESTONEDOJI").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLGRAVESTONEDOJI)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLHAMMER").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLHAMMER)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLHANGINGMAN").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLHANGINGMAN)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLHARAMI").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLHARAMI)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLHARAMICROSS").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLHARAMICROSS)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLHIGHWAVE").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLHIGHWAVE)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLHIKKAKE").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLHIKKAKE)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLHIKKAKEMOD").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLHIKKAKEMOD)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLHOMINGPIGEON").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLHOMINGPIGEON)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLIDENTICAL3CROWS").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLIDENTICAL3CROWS)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLINNECK").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLINNECK)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLINVERTEDHAMMER").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLINVERTEDHAMMER)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLKICKING").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLKICKING)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLKICKINGBYLENGTH").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLKICKINGBYLENGTH)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLLADDERBOTTOM").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLLADDERBOTTOM)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLLONGLEGGEDDOJI").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLLONGLEGGEDDOJI)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLLONGLINE").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLLONGLINE)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLMARUBOZU").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLMARUBOZU)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLMATCHINGLOW").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLMATCHINGLOW)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLMATHOLD").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLMATHOLD)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLMORNINGDOJISTAR").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLMORNINGDOJISTAR)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLMORNINGSTAR").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLMORNINGSTAR)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLONNECK").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLONNECK)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLPIERCING").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLPIERCING)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLRICKSHAWMAN").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLRICKSHAWMAN)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLRISEFALL3METHODS").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLRISEFALL3METHODS)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLSEPARATINGLINES").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLSEPARATINGLINES)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLSHOOTINGSTAR").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLSHOOTINGSTAR)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLSHORTLINE").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLSHORTLINE)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLSPINNINGTOP").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLSPINNINGTOP)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLSTALLEDPATTERN").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLSTALLEDPATTERN)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLSTICKSANDWICH").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLSTICKSANDWICH)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLTAKURI").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLTAKURI)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLTASUKIGAP").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLTASUKIGAP)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLTHRUSTING").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLTHRUSTING)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLTRISTAR").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLTRISTAR)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLUNIQUE3RIVER").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLUNIQUE3RIVER)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLUPSIDEGAP2CROWS").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLUPSIDEGAP2CROWS)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CDLXSIDEGAP3METHODS").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CDLXSIDEGAP3METHODS)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CEIL").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CEIL)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CMO").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CMO)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("CORREL").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_CORREL)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("COS").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_COS)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("COSH").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_COSH)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("DEMA").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_DEMA)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("DIV").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_DIV)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("DX").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_DX)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("EMA").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_EMA)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("EXP").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_EXP)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("FLOOR").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_FLOOR)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("HT_DCPERIOD").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_HT_DCPERIOD)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("HT_DCPHASE").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_HT_DCPHASE)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("HT_PHASOR").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_HT_PHASOR)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("HT_SINE").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_HT_SINE)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("HT_TRENDLINE").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_HT_TRENDLINE)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("HT_TRENDMODE").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_HT_TRENDMODE)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("IMI").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_IMI)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("KAMA").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_KAMA)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("LINEARREG").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_LINEARREG)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("LINEARREG_ANGLE").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_LINEARREG_ANGLE)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("LINEARREG_INTERCEPT").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_LINEARREG_INTERCEPT)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("LINEARREG_SLOPE").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_LINEARREG_SLOPE)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("LN").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_LN)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("LOG10").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_LOG10)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("MA").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_MA)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("MACD").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_MACD)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("MACDEXT").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_MACDEXT)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("MACDFIX").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_MACDFIX)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("MAMA").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_MAMA)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("MAVP").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_MAVP)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("MAX").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_MAX)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("MAXINDEX").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_MAXINDEX)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("MEDPRICE").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_MEDPRICE)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("MFI").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_MFI)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("MIDPOINT").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_MIDPOINT)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("MIDPRICE").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_MIDPRICE)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("MIN").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_MIN)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("MININDEX").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_MININDEX)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("MINMAX").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_MINMAX)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("MINMAXINDEX").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_MINMAXINDEX)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("MINUS_DI").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_MINUS_DI)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("MINUS_DM").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_MINUS_DM)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("MOM").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_MOM)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("MULT").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_MULT)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("NATR").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_NATR)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("OBV").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_OBV)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("PLUS_DI").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_PLUS_DI)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("PLUS_DM").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_PLUS_DM)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("PPO").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_PPO)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("ROC").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_ROC)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("ROCP").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_ROCP)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("ROCR").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_ROCR)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("ROCR100").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_ROCR100)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("RSI").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_RSI)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("SAR").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_SAR)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("SAREXT").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_SAREXT)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("SIN").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_SIN)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("SINH").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_SINH)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("SMA").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_SMA)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("SQRT").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_SQRT)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("STDDEV").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_STDDEV)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("STOCH").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_STOCH)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("STOCHF").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_STOCHF)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("STOCHRSI").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_STOCHRSI)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("SUB").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_SUB)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("SUM").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_SUM)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("T3").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_T3)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("TAN").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_TAN)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("TANH").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_TANH)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("TEMA").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_TEMA)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("TRANGE").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_TRANGE)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("TRIMA").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_TRIMA)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("TRIX").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_TRIX)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("TSF").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_TSF)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("TYPPRICE").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_TYPPRICE)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("ULTOSC").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_ULTOSC)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("VAR").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_VAR)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("WCLPRICE").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_WCLPRICE)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("WILLR").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_WILLR)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    Nan::Set(exports, Nan::New("WMA").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(TA_FUNC_WMA)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked());
    v8::Local<v8::Object> MATypes = Nan::New<v8::Object>();
    Nan::Set(MATypes, Nan::New("SMA").ToLocalChecked(), Nan::New<v8::Number>(0));
    Nan::Set(MATypes, Nan::New("EMA").ToLocalChecked(), Nan::New<v8::Number>(1));
    Nan::Set(MATypes, Nan::New("WMA").ToLocalChecked(), Nan::New<v8::Number>(2));
    Nan::Set(MATypes, Nan::New("DEMA").ToLocalChecked(), Nan::New<v8::Number>(3));
    Nan::Set(MATypes, Nan::New("TEMA").ToLocalChecked(), Nan::New<v8::Number>(4));
    Nan::Set(MATypes, Nan::New("TRIMA").ToLocalChecked(), Nan::New<v8::Number>(5));
    Nan::Set(MATypes, Nan::New("KAMA").ToLocalChecked(), Nan::New<v8::Number>(6));
    Nan::Set(MATypes, Nan::New("MAMA").ToLocalChecked(), Nan::New<v8::Number>(7));
    Nan::Set(MATypes, Nan::New("T3").ToLocalChecked(), Nan::New<v8::Number>(8));
    Nan::Set(exports, Nan::New("MATypes").ToLocalChecked(), MATypes);
}

NODE_MODULE(talib_binding, Init)
