📄 ta_sarext.c
字号:
/* Generated */ double optInOffsetOnReverse, /* From 0 to TA_REAL_MAX *//* Generated */ double optInAccelerationInitLong, /* From 0 to TA_REAL_MAX *//* Generated */ double optInAccelerationLong, /* From 0 to TA_REAL_MAX *//* Generated */ double optInAccelerationMaxLong, /* From 0 to TA_REAL_MAX *//* Generated */ double optInAccelerationInitShort, /* From 0 to TA_REAL_MAX *//* Generated */ double optInAccelerationShort, /* From 0 to TA_REAL_MAX *//* Generated */ double optInAccelerationMaxShort, /* From 0 to TA_REAL_MAX *//* Generated */ [Out]int% outBegIdx,/* Generated */ [Out]int% outNBElement,/* Generated */ cli::array<double>^ outReal )/* Generated */ #elif defined( _JAVA )/* Generated */ public RetCode sarExt( int startIdx,/* Generated */ int endIdx,/* Generated */ double inHigh[],/* Generated */ double inLow[],/* Generated */ double optInStartValue, /* From TA_REAL_MIN to TA_REAL_MAX *//* Generated */ double optInOffsetOnReverse, /* From 0 to TA_REAL_MAX *//* Generated */ double optInAccelerationInitLong, /* From 0 to TA_REAL_MAX *//* Generated */ double optInAccelerationLong, /* From 0 to TA_REAL_MAX *//* Generated */ double optInAccelerationMaxLong, /* From 0 to TA_REAL_MAX *//* Generated */ double optInAccelerationInitShort, /* From 0 to TA_REAL_MAX *//* Generated */ double optInAccelerationShort, /* From 0 to TA_REAL_MAX *//* Generated */ double optInAccelerationMaxShort, /* From 0 to TA_REAL_MAX *//* Generated */ MInteger outBegIdx,/* Generated */ MInteger outNBElement,/* Generated */ double outReal[] )/* Generated */ #else/* Generated */ TA_RetCode TA_SAREXT( int startIdx,/* Generated */ int endIdx,/* Generated */ const double inHigh[],/* Generated */ const double inLow[],/* Generated */ double optInStartValue, /* From TA_REAL_MIN to TA_REAL_MAX *//* Generated */ double optInOffsetOnReverse, /* From 0 to TA_REAL_MAX *//* Generated */ double optInAccelerationInitLong, /* From 0 to TA_REAL_MAX *//* Generated */ double optInAccelerationLong, /* From 0 to TA_REAL_MAX *//* Generated */ double optInAccelerationMaxLong, /* From 0 to TA_REAL_MAX *//* Generated */ double optInAccelerationInitShort, /* From 0 to TA_REAL_MAX *//* Generated */ double optInAccelerationShort, /* From 0 to TA_REAL_MAX *//* Generated */ double optInAccelerationMaxShort, /* From 0 to TA_REAL_MAX *//* Generated */ int *outBegIdx,/* Generated */ int *outNBElement,/* Generated */ double outReal[] )/* Generated */ #endif/**** END GENCODE SECTION 3 - DO NOT DELETE THIS LINE ****/{ /* insert local variable here */ ENUM_DECLARATION(RetCode) retCode; int isLong; /* > 0 indicates long. == 0 indicates short */ int todayIdx, outIdx; VALUE_HANDLE_INT(tempInt); double newHigh, newLow, prevHigh, prevLow; double afLong, afShort, ep, sar; ARRAY_LOCAL(ep_temp,1);/**** START GENCODE SECTION 4 - DO NOT DELETE THIS LINE ****//* Generated */ /* Generated */ #ifndef TA_FUNC_NO_RANGE_CHECK/* Generated */ /* Generated */ /* Validate the requested output range. *//* Generated */ if( startIdx < 0 )/* Generated */ return ENUM_VALUE(RetCode,TA_OUT_OF_RANGE_START_INDEX,OutOfRangeStartIndex);/* Generated */ if( (endIdx < 0) || (endIdx < startIdx))/* Generated */ return ENUM_VALUE(RetCode,TA_OUT_OF_RANGE_END_INDEX,OutOfRangeEndIndex);/* Generated */ /* Generated */ #if !defined(_JAVA)/* Generated */ /* Verify required price component. *//* Generated */ if(!inHigh||!inLow)/* Generated */ return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);/* Generated */ /* Generated */ #endif /* !defined(_JAVA)*//* Generated */ if( optInStartValue == TA_REAL_DEFAULT )/* Generated */ optInStartValue = 0.000000e+0;/* Generated */ else if( (optInStartValue < -3.000000e+37) ||/* Generated */ (optInStartValue > 3.000000e+37) )/* Generated */ return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);/* Generated */ /* Generated */ if( optInOffsetOnReverse == TA_REAL_DEFAULT )/* Generated */ optInOffsetOnReverse = 0.000000e+0;/* Generated */ else if( (optInOffsetOnReverse < 0.000000e+0) ||/* Generated */ (optInOffsetOnReverse > 3.000000e+37) )/* Generated */ return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);/* Generated */ /* Generated */ if( optInAccelerationInitLong == TA_REAL_DEFAULT )/* Generated */ optInAccelerationInitLong = 2.000000e-2;/* Generated */ else if( (optInAccelerationInitLong < 0.000000e+0) ||/* Generated */ (optInAccelerationInitLong > 3.000000e+37) )/* Generated */ return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);/* Generated */ /* Generated */ if( optInAccelerationLong == TA_REAL_DEFAULT )/* Generated */ optInAccelerationLong = 2.000000e-2;/* Generated */ else if( (optInAccelerationLong < 0.000000e+0) ||/* Generated */ (optInAccelerationLong > 3.000000e+37) )/* Generated */ return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);/* Generated */ /* Generated */ if( optInAccelerationMaxLong == TA_REAL_DEFAULT )/* Generated */ optInAccelerationMaxLong = 2.000000e-1;/* Generated */ else if( (optInAccelerationMaxLong < 0.000000e+0) ||/* Generated */ (optInAccelerationMaxLong > 3.000000e+37) )/* Generated */ return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);/* Generated */ /* Generated */ if( optInAccelerationInitShort == TA_REAL_DEFAULT )/* Generated */ optInAccelerationInitShort = 2.000000e-2;/* Generated */ else if( (optInAccelerationInitShort < 0.000000e+0) ||/* Generated */ (optInAccelerationInitShort > 3.000000e+37) )/* Generated */ return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);/* Generated */ /* Generated */ if( optInAccelerationShort == TA_REAL_DEFAULT )/* Generated */ optInAccelerationShort = 2.000000e-2;/* Generated */ else if( (optInAccelerationShort < 0.000000e+0) ||/* Generated */ (optInAccelerationShort > 3.000000e+37) )/* Generated */ return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);/* Generated */ /* Generated */ if( optInAccelerationMaxShort == TA_REAL_DEFAULT )/* Generated */ optInAccelerationMaxShort = 2.000000e-1;/* Generated */ else if( (optInAccelerationMaxShort < 0.000000e+0) ||/* Generated */ (optInAccelerationMaxShort > 3.000000e+37) )/* Generated */ return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);/* Generated */ /* Generated */ #if !defined(_JAVA)/* Generated */ if( !outReal )/* Generated */ return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);/* Generated */ /* Generated */ #endif /* !defined(_JAVA) *//* Generated */ #endif /* TA_FUNC_NO_RANGE_CHECK *//* Generated */ /**** END GENCODE SECTION 4 - DO NOT DELETE THIS LINE ****/ /* Insert TA function code here. */ /* This function is the same as TA_SAR, except that the caller has * greater control on the SAR dynamic and initial state. * * In additon, the TA_SAREXT returns negative values when the position * is short. This allow to distinguish when the SAR do actually reverse. */ /* Implementation of the SAR has been a little bit open to interpretation * since Wilder (the original author) did not define a precise algorithm * on how to bootstrap the algorithm. Take any existing software application * and you will see slight variation on how the algorithm was adapted. * * What is the initial trade direction? Long or short? * =================================================== * The interpretation of what should be the initial SAR values is * open to interpretation, particularly since the caller to the function * does not specify the initial direction of the trade. * * In TA-Lib, the following default logic is used: * - Calculate +DM and -DM between the first and * second bar. The highest directional indication will * indicate the assumed direction of the trade for the second * price bar. * - In the case of a tie between +DM and -DM, * the direction is LONG by default. * * What is the initial "extreme point" and thus SAR? * ================================================= * The following shows how different people took different approach: * - Metastock use the first price bar high/low depending of * the direction. No SAR is calculated for the first price * bar. * - Tradestation use the closing price of the second bar. No * SAR are calculated for the first price bar. * - Wilder (the original author) use the SIP from the * previous trade (cannot be implement here since the * direction and length of the previous trade is unknonw). * - The Magazine TASC seems to follow Wilder approach which * is not practical here. * * TA-Lib "consume" the first price bar and use its high/low as the * initial SAR of the second price bar. I found that approach to be * the closest to Wilders idea of having the first entry day use * the previous extreme point, except that here the extreme point is * derived solely from the first price bar. I found the same approach * to be used by Metastock. * * * Can I force the initial SAR? * ============================ * Yes. Using the optInStartValue_0 parameter: * optInStartValue_0 > 0 : SAR is long at optInStartValue_0. * optInStartValue_0 < 0 : SAR is short at fabs(optInStartValue_0). * * And when optInStartValue_0 == 0, the logic is the same as for TA_SAR * (See previous two sections). */ /* Identify the minimum number of price bar needed * to calculate at least one output. * * Move up the start index if there is not * enough initial data. */ if( startIdx < 1 ) startIdx = 1; /* Make sure there is still something to evaluate. */ if( startIdx > endIdx ) { VALUE_HANDLE_DEREF_TO_ZERO(outBegIdx); VALUE_HANDLE_DEREF_TO_ZERO(outNBElement); return ENUM_VALUE(RetCode,TA_SUCCESS,Success); } /* Check if the acceleration factors are being defined by the user. * Make sure the acceleration and maximum are coherent. * If not, correct the acceleration. * Default afLong = 0.02 * Default afShort = 0.02 */ afLong = optInAccelerationInitLong; afShort = optInAccelerationInitShort; if( afLong > optInAccelerationMaxLong ) afLong = optInAccelerationInitLong = optInAccelerationMaxLong; if( optInAccelerationLong > optInAccelerationMaxLong ) optInAccelerationLong = optInAccelerationMaxLong; if( afShort > optInAccelerationMaxShort) afShort = optInAccelerationInitShort = optInAccelerationMaxShort; if( optInAccelerationShort > optInAccelerationMaxShort ) optInAccelerationShort = optInAccelerationMaxShort; /* Initialise SAR calculations */ if(optInStartValue == 0) /* Default action */ { /* Identify if the initial direction is long or short. * (ep is just used as a temp buffer here, the name * of the parameter is not significant). */ retCode = FUNCTION_CALL(MINUS_DM)( startIdx, startIdx, inHigh, inLow, 1, VALUE_HANDLE_OUT(tempInt), VALUE_HANDLE_OUT(tempInt), ep_temp ); if( ep_temp[0] > 0 ) isLong = 0; else isLong = 1; if( retCode != ENUM_VALUE(RetCode,TA_SUCCESS,Success) ) { VALUE_HANDLE_DEREF_TO_ZERO(outBegIdx); VALUE_HANDLE_DEREF_TO_ZERO(outNBElement); return retCode; } } else if( optInStartValue > 0 ) /* Start Long */ {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -