以CDL2CROWS爲例, 看一看c語言的源碼:app
i = startIdx; /* Proceed with the calculation for the requested range. * Must have: * - first candle: long white candle * - second candle: black real body * - gap between the first and the second candle's real bodies * - third candle: black candle that opens within the second real body and closes within the first real body * The meaning of "long" is specified with TA_SetCandleSettings * outInteger is negative (-1 to -100): two crows is always bearish; * the user should consider that two crows is significant when it appears in an uptrend, while this function * does not consider the trend */ outIdx = 0; do { if( TA_CANDLECOLOR(i-2) == 1 && // 1st: white TA_REALBODY(i-2) > TA_CANDLEAVERAGE( BodyLong, BodyLongPeriodTotal, i-2 ) && // long TA_CANDLECOLOR(i-1) == -1 && // 2nd: black TA_REALBODYGAPUP(i-1,i-2) && // gapping up TA_CANDLECOLOR(i) == -1 && // 3rd: black inOpen[i] < inOpen[i-1] && inOpen[i] > inClose[i-1] && // opening within 2nd rb inClose[i] > inOpen[i-2] && inClose[i] < inClose[i-2] // closing within 1st rb ) outInteger[outIdx++] = -100; else outInteger[outIdx++] = 0; /* add the current range and subtract the first range: this is done after the pattern recognition * when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) */ BodyLongPeriodTotal += TA_CANDLERANGE( BodyLong, i-2 ) - TA_CANDLERANGE( BodyLong, BodyLongTrailingIdx ); i++; BodyLongTrailingIdx++; } while( i <= endIdx ); TA_RetCode TA_RestoreCandleDefaultSettings( TA_CandleSettingType settingType ) { const TA_CandleSetting TA_CandleDefaultSettings[] = { /* real body is long when it's longer than the average of the 10 previous candles' real body */ { TA_BodyLong, TA_RangeType_RealBody, 10, 1.0 }, /* real body is very long when it's longer than 3 times the average of the 10 previous candles' real body */ { TA_BodyVeryLong, TA_RangeType_RealBody, 10, 3.0 }, /* real body is short when it's shorter than the average of the 10 previous candles' real bodies */ { TA_BodyShort, TA_RangeType_RealBody, 10, 1.0 }, /* real body is like doji's body when it's shorter than 10% the average of the 10 previous candles' high-low range */ { TA_BodyDoji, TA_RangeType_HighLow, 10, 0.1 }, /* shadow is long when it's longer than the real body */ { TA_ShadowLong, TA_RangeType_RealBody, 0, 1.0 }, /* shadow is very long when it's longer than 2 times the real body */ { TA_ShadowVeryLong, TA_RangeType_RealBody, 0, 2.0 }, /* shadow is short when it's shorter than half the average of the 10 previous candles' sum of shadows */ { TA_ShadowShort, TA_RangeType_Shadows, 10, 1.0 }, /* shadow is very short when it's shorter than 10% the average of the 10 previous candles' high-low range */ { TA_ShadowVeryShort, TA_RangeType_HighLow, 10, 0.1 }, /* when measuring distance between parts of candles or width of gaps */ /* "near" means "<= 20% of the average of the 5 previous candles' high-low range" */ { TA_Near, TA_RangeType_HighLow, 5, 0.2 }, /* when measuring distance between parts of candles or width of gaps */ /* "far" means ">= 60% of the average of the 5 previous candles' high-low range" */ { TA_Far, TA_RangeType_HighLow, 5, 0.6 }, /* when measuring distance between parts of candles or width of gaps */ /* "equal" means "<= 5% of the average of the 5 previous candles' high-low range" */ { TA_Equal, TA_RangeType_HighLow, 5, 0.05 } }; /* Candlestick macros (used by candlestick functions, where the parameters are always called inClose, inOpen, etc. * Don't use i++ or func(i) with these macros ! */ #define TA_REALBODY(IDX) ( std_fabs( inClose[IDX] - inOpen[IDX] ) ) #define TA_UPPERSHADOW(IDX) ( inHigh[IDX] - ( inClose[IDX] >= inOpen[IDX] ? inClose[IDX] : inOpen[IDX] ) ) #define TA_LOWERSHADOW(IDX) ( ( inClose[IDX] >= inOpen[IDX] ? inOpen[IDX] : inClose[IDX] ) - inLow[IDX] ) #define TA_HIGHLOWRANGE(IDX) ( inHigh[IDX] - inLow[IDX] ) #define TA_CANDLECOLOR(IDX) ( inClose[IDX] >= inOpen[IDX] ? 1 : -1 ) #if defined( _MANAGED ) #define TA_CANDLERANGETYPE(SET) (Globals->candleSettings[(int)CandleSettingType::SET]->rangeType) #define TA_CANDLEAVGPERIOD(SET) (Globals->candleSettings[(int)CandleSettingType::SET]->avgPeriod) #define TA_CANDLEFACTOR(SET) (Globals->candleSettings[(int)CandleSettingType::SET]->factor) #elif defined( _JAVA ) #define TA_CANDLERANGETYPE(SET) (this.candleSettings[CandleSettingType.SET.ordinal()].rangeType) #define TA_CANDLEAVGPERIOD(SET) (this.candleSettings[CandleSettingType.SET.ordinal()].avgPeriod) #define TA_CANDLEFACTOR(SET) (this.candleSettings[CandleSettingType.SET.ordinal()].factor) #else #define TA_CANDLERANGETYPE(SET) (TA_Globals->candleSettings[TA_##SET].rangeType) #define TA_CANDLEAVGPERIOD(SET) (TA_Globals->candleSettings[TA_##SET].avgPeriod) #define TA_CANDLEFACTOR(SET) (TA_Globals->candleSettings[TA_##SET].factor) #endif #define TA_CANDLERANGE(SET,IDX) \ ( TA_CANDLERANGETYPE(SET) == ENUM_VALUE(RangeType,TA_RangeType_RealBody,RealBody) ? TA_REALBODY(IDX) : \ ( TA_CANDLERANGETYPE(SET) == ENUM_VALUE(RangeType,TA_RangeType_HighLow,HighLow) ? TA_HIGHLOWRANGE(IDX) : \ ( TA_CANDLERANGETYPE(SET) == ENUM_VALUE(RangeType,TA_RangeType_Shadows,Shadows) ? TA_UPPERSHADOW(IDX) + TA_LOWERSHADOW(IDX) : \ 0 ) ) ) #define TA_CANDLEAVERAGE(SET,SUM,IDX) \ ( TA_CANDLEFACTOR(SET) \ * ( TA_CANDLEAVGPERIOD(SET) != 0.0? SUM / TA_CANDLEAVGPERIOD(SET) : TA_CANDLERANGE(SET,IDX) ) \ / ( TA_CANDLERANGETYPE(SET) == ENUM_VALUE(RangeType,TA_RangeType_Shadows,Shadows) ? 2.0 : 1.0 ) \ ) #define TA_REALBODYGAPUP(IDX2,IDX1) ( min(inOpen[IDX2],inClose[IDX2]) > max(inOpen[IDX1],inClose[IDX1]) ) #define TA_REALBODYGAPDOWN(IDX2,IDX1) ( max(inOpen[IDX2],inClose[IDX2]) < min(inOpen[IDX1],inClose[IDX1]) ) #define TA_CANDLEGAPUP(IDX2,IDX1) ( inLow[IDX2] > inHigh[IDX1] ) #define TA_CANDLEGAPDOWN(IDX2,IDX1) ( inHigh[IDX2] < inLow[IDX1] )