Esempio n. 1
0
def exclude_analyze(basic, kdata, pick_index, take_index, policy_args):
    """ 根据日线做排除性校验
    """
    max_rise     = __parse_policy_args(policy_args, MAX_RISE)
    max_pclose   = __parse_policy_args(policy_args, MAX_PCLOSE)
    outstanding  = __parse_policy_args(policy_args, OUTSTANDING)

    ### 净资产为负数的
    if basic[dogen.BVPS] < 0:
        logger.debug("Invalid bvps")
        return True

    ### 特征三
    if kdata.iloc[take_index][dogen.P_CLOSE] > max_pclose:
        logger.debug("Too high close price at %s" % kdata.index[take_index])
        return True
    if kdata.iloc[take_index][dogen.P_CLOSE] * basic[dogen.OUTSTANDING] > outstanding:
        logger.debug("Too large outstanding at %s" % kdata.index[take_index])
        return True
    
    ### 特征四
    rise_range = dogen.get_last_rise_range(kdata, max_rise, max_fall=max_rise/2, eIdx=22)
    if rise_range is not None:
        [min_index, max_index, inc_close, get_lhigh, tmp_index] = rise_range
        if max_rise < dogen.caculate_incr_percentage(kdata.iloc[take_index][dogen.P_CLOSE], kdata.iloc[min_index][dogen.P_CLOSE]):
            logger.debug("Too large rise-range")
            return True
        pass

    ### 特征五
    if kdata.iloc[take_index][dogen.MA5] < kdata.iloc[take_index+1][dogen.MA5] and kdata.iloc[take_index][dogen.MA20] < kdata.iloc[take_index+1][dogen.MA20]:
        logger.debug("Invalid MA5&MA20 at %s" % kdata.index[take_index])
        return True

    return False
Esempio n. 2
0
def exclude_analyze(basic, kdata, pick_index, take_index, policy_args):
    max_rclose  = __parse_policy_args(policy_args, MAX_RCLOSE)
    min_ramp    = __parse_policy_args(policy_args, MIN_RAMP)
    max_rise    = __parse_policy_args(policy_args, MAX_RISE)
    max_pclose  = __parse_policy_args(policy_args, MAX_PCLOSE)
    outstanding = __parse_policy_args(policy_args, OUTSTANDING)

    ### 净资产为负数的
    if basic[dogen.BVPS] < 0.1:
        logger.debug("Invalid bvps")
        return True

    ### 特征三
    if kdata.iloc[take_index][dogen.P_CLOSE] > max_pclose:
        logger.debug("Too high close price at %s" % kdata.index[take_index])
        return True
    if kdata.iloc[take_index][dogen.P_CLOSE] * basic[dogen.OUTSTANDING] > outstanding:
        logger.debug("Too large outstanding at %s" % kdata.index[take_index])
        return True

    ### 特征四
    rise_range = dogen.get_last_rise_range(kdata, max_rise, max_fall=max_rise/2, eIdx=22)
    if rise_range is not None:
        [min_index, max_index, inc_close, get_lhigh, tmp_index] = rise_range
        if max_rise < dogen.caculate_incr_percentage(kdata.iloc[take_index][dogen.P_CLOSE], kdata.iloc[min_index][dogen.P_CLOSE]):
            logger.debug("Too large rise-range")
            return True
        pass

    ### 特征五
    tdata = kdata[0:5]
    if tdata[tdata[dogen.R_CLOSE]>0].index.size <= tdata.index.size/2:
        logger.debug("Don't contain enough up trades in last week")
        return True
    if dogen.get_highlimit_trades(tdata).size > 0:
        logger.debug("There is hl trade in last week")
        return True

    ### 特征六
    for temp_index in range(pick_index, -1, -1):
        ### 下跌
        if kdata.iloc[temp_index][dogen.R_CLOSE] >= 0 or kdata.iloc[temp_index+1][dogen.R_CLOSE] <= 0:
            continue
        if kdata.iloc[temp_index][dogen.VOLUME] <= kdata.iloc[temp_index+1][dogen.VOLUME]:
            continue
        ### 放量下跌之后未被上涨突破
        maxi_index = dogen.get_last_column_max(kdata, dogen.P_CLOSE, eIdx=temp_index)
        if maxi_index is None or kdata.iloc[temp_index][dogen.P_OPEN] > kdata.iloc[maxi_index][dogen.P_CLOSE]:
            logger.debug("Invalid fall-trade at %s" % kdata.index[temp_index])
            return True
        pass

    return False
Esempio n. 3
0
def include_analyze(basic, kdata, policy_args):
    ### 策略参数处理
    mini_hl = __parse_policy_args(policy_args, MINI_HL)
    hl_valid = __parse_policy_args(policy_args, HL_VALID)
    take_valid = __parse_policy_args(policy_args, TAKE_VALID)

    ### 特征一
    heap_trade = 0
    if kdata.index.size < hl_valid:
        hl_valid = kdata.index.size
    for temp_index in range(0, hl_valid):
        if kdata.iloc[temp_index][dogen.P_CLOSE] < kdata.iloc[temp_index][
                dogen.L_HIGH]:
            continue
        if kdata.iloc[temp_index +
                      1][dogen.P_CLOSE] < kdata.iloc[temp_index +
                                                     1][dogen.L_HIGH]:
            continue
        pick_index = temp_index
        heap_trade += 1
    if heap_trade != 1:
        logger.debug("Don't include valid serial hl-trade")
        return None
    if pick_index != 0:
        low_index = dogen.get_last_column_min(kdata,
                                              dogen.P_CLOSE,
                                              eIdx=pick_index)
        if kdata.iloc[low_index][dogen.P_CLOSE] > kdata.iloc[pick_index][
                dogen.P_CLOSE]:
            logger.debug("Don't include valid fallback trade")
            return None

        take_index = None
        for temp_index in range(low_index, -1, -1):
            temp_close = dogen.caculate_incr_percentage(
                kdata.iloc[temp_index][dogen.P_CLOSE],
                kdata.iloc[pick_index][dogen.P_CLOSE])
            if temp_close < -3:
                continue
            elif temp_close > 7:
                break
            take_index = temp_index
    else:
        ### 两连板
        take_index = pick_index
    if take_index is None or take_index > take_valid:
        logger.debug("Don't match valid take trade")
        return None

    return [pick_index, take_index]
Esempio n. 4
0
def exclude_analyze(basic, kdata, pick_index, take_index, fall_range,
                    policy_args):
    pick_start = __parse_policy_args(policy_args, PICK_START)
    max_take2low = __parse_policy_args(policy_args, MAX_TAKE2LOW)
    max_pclose = __parse_policy_args(policy_args, MAX_PCLOSE)
    outstanding = __parse_policy_args(policy_args, OUTSTANDING)
    [high_index, pick_index, dec_close, get_llow, tmpId] = fall_range

    ### 净资产为负数的
    if basic[dogen.BVPS] < 0:
        logger.debug("Invalid bvps")
        return True

    ### 特征三
    if kdata.iloc[take_index][dogen.P_CLOSE] > max_pclose:
        logger.debug("Too high close price at %s" % kdata.index[take_index])
        return True
    if kdata.iloc[take_index][dogen.P_CLOSE] * basic[
            dogen.OUTSTANDING] > outstanding:
        logger.debug("Too large outstanding at %s" % kdata.index[take_index])
        return True

    ### 特征四
    temp_index = dogen.get_last_column_max(kdata,
                                           dogen.P_CLOSE,
                                           eIdx=pick_index)
    if dogen.caculate_incr_percentage(
            kdata.iloc[temp_index][dogen.P_CLOSE],
            kdata.iloc[pick_index][dogen.P_CLOSE]) > max_take2low:
        logger.debug("Too high close at %s" % kdata.index[temp_index])
        return True

    ### 特征五
    if pick_index + 1 >= pick_start:
        macd = dogen.forecast_macd(kdata[dogen.MACD])
        if kdata.iloc[0][dogen.MACD] < -0.1 and macd < -0.1:
            logger.debug("Invalid MACD at %s" % kdata.index[0])
            return True
        pass

    return False
Esempio n. 5
0
def trade_analyze2(basic, kdata, pick_index, policy_args):
    min_falls    = __parse_policy_args(policy_args, MIN_FALLS)

    ### 特征二
    if dogen.caculate_incr_percentage(kdata.iloc[pick_index-1][dogen.P_OPEN], kdata.iloc[pick_index][dogen.P_CLOSE]) > 5:
        logger.debug("Too high open price at %s" % kdata.index[pick_index-1])
        return None

    take_index = None
    max_pclose = kdata.iloc[pick_index][dogen.P_CLOSE]*(1-min_falls*0.01)
    if kdata.iloc[pick_index-1][dogen.P_CLOSE] <= max_pclose:
        take_index = pick_index-1
    for temp_index in range(pick_index-2, -1, -1):
        if kdata.iloc[temp_index][dogen.R_CLOSE] > 0 or kdata.iloc[temp_index][dogen.VOLUME] > kdata.iloc[temp_index+1][dogen.VOLUME]:
            if take_index is not None:
                take_index = temp_index
            break
        elif kdata.iloc[temp_index][dogen.P_CLOSE] <= max_pclose:
            take_index = temp_index
        pass

    return [pick_index, take_index]
Esempio n. 6
0
def trade_analyze1(basic, kdata, pick_index, policy_args):
    volume_scale = __parse_policy_args(policy_args, VOLUME_SCALE)
    min_falls    = __parse_policy_args(policy_args, MIN_FALLS)

    ### 取最低回调价
    if (pick_index+1) >= kdata.index.size:
        min_pclose = 0
    else:
        min_pclose = kdata.iloc[pick_index+1][dogen.P_CLOSE]

    ### 特征二
    if kdata.iloc[pick_index-1][dogen.R_CLOSE] > 0:
        pick_index -= 1
        if pick_index == 0:
            logger.debug("Fallback didn't occur")
            return None
        if (kdata.iloc[pick_index+1][dogen.VOLUME] * volume_scale) > kdata.iloc[pick_index][dogen.VOLUME]:
            logger.debug("Too small volume at " + kdata.index[pick_index])
            return None
        if dogen.caculate_incr_percentage(kdata.iloc[pick_index][dogen.P_CLOSE], kdata.iloc[pick_index][dogen.P_OPEN]) <= -5:
            logger.debug("Invalid open&close at %s" % kdata.index[pick_index])
            return None
        pass
    
    take_index = None
    max_pclose = kdata.iloc[pick_index][dogen.P_CLOSE]*(1-min_falls*0.01)
    for temp_index in range(pick_index-1, -1, -1):
        if kdata.iloc[temp_index][dogen.P_CLOSE] < min_pclose:
            logger.debug("Get invalid fall trade at %s" % kdata.index[temp_index])
            return None
        if kdata.iloc[temp_index][dogen.R_CLOSE] > 0 or kdata.iloc[temp_index][dogen.VOLUME] > kdata.iloc[temp_index+1][dogen.VOLUME]:
            if take_index is not None:
                take_index = temp_index
            break
        elif kdata.iloc[temp_index][dogen.P_CLOSE] <= max_pclose:
            take_index = temp_index
        pass

    return [pick_index, take_index]
Esempio n. 7
0
def exclude_analyze(basic, kdata, pick_index, take_index, policy_args):
    """ 根据日线做排除性校验
    """
    max_rise = __parse_policy_args(policy_args, MAX_RISE)
    max_take2low = __parse_policy_args(policy_args, MAX_TAKE2LOW)
    min_falls = __parse_policy_args(policy_args, MIN_FALLS)
    max_rclose = __parse_policy_args(policy_args, MAX_RCLOSE)
    min_ramp = __parse_policy_args(policy_args, MIN_RAMP)
    min_polyf2 = __parse_policy_args(policy_args, MIN_POLYF2)
    max_pclose = __parse_policy_args(policy_args, MAX_PCLOSE)
    outstanding = __parse_policy_args(policy_args, OUTSTANDING)

    ### 取回调最低价
    mini_index = dogen.get_last_column_min(kdata,
                                           dogen.P_CLOSE,
                                           sIdx=take_index,
                                           eIdx=pick_index)

    ### 净资产为负数的
    if basic[dogen.BVPS] < 0:
        logger.debug("Invalid bvps")
        return True

    ### 特征三
    if kdata.iloc[take_index][dogen.P_CLOSE] > max_pclose:
        logger.debug("Too high close price at %s" % kdata.index[take_index])
        return True
    if kdata.iloc[take_index][dogen.P_CLOSE] * basic[
            dogen.OUTSTANDING] > outstanding:
        logger.debug("Too large outstanding at %s" % kdata.index[take_index])
        return True

    ### 特征四
    rise_range = dogen.get_last_rise_range(kdata,
                                           max_rise,
                                           max_fall=max_rise / 2,
                                           eIdx=22)
    if rise_range is not None:
        [min_index, max_index, inc_close, get_lhigh, tmp_index] = rise_range
        if max_rise < dogen.caculate_incr_percentage(
                kdata.iloc[take_index][dogen.P_CLOSE],
                kdata.iloc[min_index][dogen.P_CLOSE]):
            logger.debug("Too large rise-range")
            return True
        pass

    ### 特征五
    if pick_index >= 5:
        high_index = pick_index
        if kdata.iloc[pick_index - 1][dogen.R_CLOSE] > 0:
            high_index = pick_index - 1
        if dogen.caculate_incr_percentage(
                kdata.iloc[take_index][dogen.P_CLOSE],
                kdata.iloc[high_index][dogen.P_CLOSE]) < -min_falls:
            logger.debug("Too low P-CLOSE at take-trade %s" %
                         kdata.index[take_index])
            return True
        if kdata.iloc[take_index][dogen.MA5] < kdata.iloc[take_index +
                                                          1][dogen.MA5]:
            logger.debug("Invalid MA20 at %s" % kdata.index[take_index])
            return True
        if kdata.iloc[take_index][dogen.MA20] < kdata.iloc[take_index +
                                                           1][dogen.MA20]:
            logger.debug("Invalid MA20 at %s" % kdata.index[take_index])
            return True
        if kdata.iloc[take_index][
                dogen.VOLUME] > kdata.iloc[take_index + 1][dogen.VOLUME] * 1.1:
            h2l = dogen.caculate_incr_percentage(
                kdata.iloc[take_index][dogen.P_HIGH],
                kdata.iloc[take_index][dogen.P_LOW])
            c2l = dogen.caculate_incr_percentage(
                kdata.iloc[take_index][dogen.P_CLOSE],
                kdata.iloc[take_index][dogen.P_LOW])
            if c2l * 2 < h2l:
                logger.debug("Get up shadow at %s" % kdata.index[take_index])
                return True
            pass
        pass

    ### 特征七
    if pick_index >= 5:
        for temp_index in range(mini_index - 1, -1, -1):
            ### 下跌
            if kdata.iloc[temp_index][dogen.R_CLOSE] >= 0 or kdata.iloc[
                    temp_index + 1][dogen.R_CLOSE] <= 0:
                continue
            if kdata.iloc[temp_index][dogen.VOLUME] <= kdata.iloc[
                    temp_index + 1][dogen.VOLUME]:
                continue
            ### 放量下跌之后未被上涨突破
            maxi_index = dogen.get_last_column_max(kdata,
                                                   dogen.P_CLOSE,
                                                   eIdx=temp_index)
            if maxi_index is None or kdata.iloc[temp_index][
                    dogen.P_OPEN] > kdata.iloc[maxi_index][dogen.P_CLOSE]:
                logger.debug("Invalid fall-trade at %s" %
                             kdata.index[temp_index])
                return True
            pass
        pass

    ### 特征八
    if pick_index >= 5:
        tdata = kdata[0:mini_index]
        if tdata[tdata[dogen.R_AMP] >= min_ramp].index.size <= 0:
            logger.debug(
                "Don't include trade with 5 percentage R-AMP since %s" %
                kdata.index[mini_index])
            return True
        for temp_index in range(mini_index, 0, -1):
            hl_price = dogen.caculate_l_high(
                kdata.iloc[temp_index][dogen.P_CLOSE])
            tdata = kdata[temp_index - 4:temp_index - 1]
            if tdata[tdata[dogen.P_CLOSE] >= hl_price].index.size > 0:
                logger.debug("Too large heap-close from %s to %s" %
                             (tdata.index[-1], tdata.index[0]))
                return True
            pass
        pass

    return False
Esempio n. 8
0
def include_analyze(basic, kdata, policy_args):
    ### 策略参数处理
    mini_hl = __parse_policy_args(policy_args, MINI_HL)
    hl_valid = __parse_policy_args(policy_args, HL_VALID)
    take_valid = __parse_policy_args(policy_args, TAKE_VALID)

    ### 特征一
    index = dogen.get_highlimit_trades(kdata, eIdx=hl_valid + 1)
    if index.size == 0:
        logger.debug("Don't match highlimit trades")
        return None
    else:
        pick_trade = index[0]
        pick_index = kdata.index.get_loc(pick_trade)
        pick_close = kdata.iloc[pick_index][dogen.P_CLOSE]
        mini_index = pick_index + 1
        if mini_index < kdata.index.size:
            mini_close = kdata.iloc[pick_index + 1][dogen.P_CLOSE]
        else:
            mini_close = 0
    if pick_index < mini_hl:
        logger.debug("Invalid hl-trade at %s" % pick_trade)
        return None

    ### 特征二
    take_index = None
    if pick_index < 5 and pick_index >= 3:
        if dogen.caculate_incr_percentage(
                kdata.iloc[0][dogen.P_CLOSE],
                kdata.iloc[pick_index][dogen.P_CLOSE]) > 5:
            logger.debug("Invalid trade at %s" % kdata.index[0])
            return None
        tdata = kdata[0:pick_index]
        tdata = tdata[tdata[dogen.P_CLOSE] < pick_close]
        if tdata.index.size > 0:
            logger.debug("Invalid trade at %s" % tdata.index[0])
            return None
        take_index = 0
    else:
        heap_rises = 0
        for temp_index in range(pick_index - 1, -1, -1):
            temp_close = kdata.iloc[temp_index][dogen.R_CLOSE]
            if temp_close < 0:
                heap_rises = 0
            else:
                heap_rises += temp_close
            if heap_rises >= 5:
                take_index = temp_index
            if temp_close >= 3 and kdata.iloc[temp_index][
                    dogen.P_CLOSE] > kdata.iloc[temp_index][dogen.P_OPEN]:
                take_index = temp_index
            pass
        if take_index is not None:
            ### take_index之后缩量下跌(限一个交易日),也符合策略
            if take_index == 1\
            and kdata.iloc[take_index-1][dogen.R_CLOSE] < 0\
            and kdata.iloc[take_index-1][dogen.VOLUME]  < kdata.iloc[take_index][dogen.VOLUME]:
                take_index -= 1
            ### 最近收盘价比take_index(不能取更新后值)高更新
            elif take_index <= 3\
            and kdata.iloc[0][dogen.R_CLOSE] > 0\
            and kdata.iloc[0][dogen.P_CLOSE] > kdata.iloc[0][dogen.P_OPEN]\
            and kdata.iloc[0][dogen.P_CLOSE] >= kdata.iloc[take_index][dogen.P_CLOSE]:
                take_index = 0
            pass
        pass
    if take_index is None or take_index > take_valid:
        logger.debug("Don't match valid take trade")
        return None

    return [pick_index, take_index]
Esempio n. 9
0
def __statistics_analyze(db, basic, kdata, save_result, args):
    """ 统计单只股票上涨区间

        参数说明:
            basic - 股票基本信息
            kdata - 股票交易数据
            mini_rise - 区间最小涨幅
            mini_hl - 区间最少涨停板数
    """
    ### 参数处理
    mini_rise = __parse_policy_args(args, MINI_RISE)
    mini_hl = __parse_policy_args(args, MINI_HL)

    ### 循环检查
    tmpId = 0
    match = []
    while True:
        rise_range = dogen.get_last_rise_range(kdata, mini_rise, max_fall=round(mini_rise/2, 2), sIdx=tmpId)
        if rise_range is None:
            break
        else:
            [min_index, max_index, inc_close, get_hl, tmpId] = rise_range

        ### 忽略不符合连板要求的区间
        outstanding   = None
        max_hl_serial = 0
        tmp_hl_serial = 0
        for temp_index in range(min_index, max_index-1, -1):
            if kdata.iloc[temp_index][dogen.P_CLOSE] < kdata.iloc[temp_index][dogen.L_HIGH]:
                tmp_hl_serial = 0
                continue
            tmp_hl_serial += 1
            if tmp_hl_serial > max_hl_serial:
                max_hl_serial = tmp_hl_serial
            if tmp_hl_serial > 2 and outstanding is None:
                outstanding = round(kdata.iloc[temp_index][dogen.P_CLOSE] * basic[dogen.OUTSTANDING], 2)
            pass
        if max_hl_serial < mini_hl:
            continue
            
        ### 保存区间结果
        result = {}
        result[dogen.RST_COL_CODE]        = basic.name
        result[dogen.RST_COL_NAME]        = basic[dogen.NAME] #  证券简写
        result[dogen.RST_COL_INDUSTRY]    = basic[dogen.INDUSTRY]
        result[dogen.RST_COL_START]       = kdata.index[min_index]
        result[dogen.RST_COL_END]         = kdata.index[max_index]
        result[dogen.RST_COL_START_CLOSE] = kdata.iloc[min_index][dogen.P_CLOSE] # 起始收盘价
        result[dogen.RST_COL_LAST_CLOSE]  = kdata.iloc[max_index][dogen.P_CLOSE] # 最高收盘价
        result[dogen.RST_COL_RISE_RATE]   = dogen.caculate_incr_percentage(result[dogen.RST_COL_LAST_CLOSE], result[dogen.RST_COL_START_CLOSE])
        result[dogen.RST_COL_INC_HL]      = get_hl
        result[dogen.RST_COL_OUTSTANDING] = outstanding # 流通市值
        result[dogen.RST_COL_MATCH_TIME]  = dogen.datetime_now() # 选中时间
        result[dogen.RST_COL_INDEX]       = '%s_%s' % (basic.name, kdata.index[min_index])

        match.append(result)

        ### 保存结果
        if save_result:
            rdata = db.lookup_statistics_largerise_range(cond={dogen.RST_COL_CODE:basic.name}, descending_by=dogen.RST_COL_START)
            if rdata is None or len(rdata)<=0:
                db.insert_statistics_largerise_range([result], key_name=dogen.RST_COL_INDEX)
                continue
            rlast = rdata[0]
            if rlast[dogen.RST_COL_END] < result[dogen.RST_COL_START]:
                db.insert_statistics_largerise_range([result], key_name=dogen.RST_COL_INDEX)
                continue
            ### 重叠合并
            tdata = kdata[(kdata.index > rlast[dogen.RST_COL_END])&(kdata.index <= result[dogen.RST_COL_END])]

            rlast[dogen.RST_COL_INC_HL] = rlast[dogen.RST_COL_INC_HL] + tdata[tdata[dogen.P_CLOSE]>=tdata[dogen.L_HIGH]].index.size
            rlast[dogen.RST_COL_END] = result[dogen.RST_COL_END]
            rlast[dogen.RST_COL_LAST_CLOSE] = result[dogen.RST_COL_LAST_CLOSE]
            rlast[dogen.RST_COL_RISE_RATE] = dogen.caculate_incr_percentage(rlast[dogen.RST_COL_LAST_CLOSE], rlast[dogen.RST_COL_START_CLOSE])
            rlast[dogen.RST_COL_MATCH_TIME] = result[dogen.RST_COL_MATCH_TIME]
            db.insert_statistics_largerise_range([rlast], key_name=dogen.RST_COL_INDEX)

    return match
Esempio n. 10
0
def include_analyze(basic, kdata, policy_args):
    """ 
    """
    ### 参数解析
    take_valid = __parse_policy_args(policy_args, TAKE_VALID)
    pick_valid = __parse_policy_args(policy_args, PICK_VALID)
    min_rise = __parse_policy_args(policy_args, MIN_RISE)
    min_fallen = __parse_policy_args(policy_args, MIN_FALLEN)

    ### 预处理
    if kdata.iloc[0][dogen.MA5] > kdata.iloc[0][dogen.MA20]:
        logger.debug("Invalid MA5&MA20 at %s" % kdata.index[0])
        return None

    ### 特征一
    fall_range = dogen.get_last_fall_range(kdata,
                                           min_fallen,
                                           max_rise=min_rise)
    if fall_range is None:
        logger.debug("Don't get valid fall-range")
        return None
    else:
        [high_index, pick_index, dec_close, get_llow, tmpId] = fall_range
        for temp_index in range(high_index, -1, -1):
            if kdata.iloc[temp_index][dogen.MA5] > kdata.iloc[temp_index][
                    dogen.MA20]:
                continue
            break
    rise_range = dogen.get_last_rise_range(kdata,
                                           min_rise,
                                           max_fall=min_fallen,
                                           sIdx=high_index)
    if rise_range is None:
        logger.debug("Don't get valid rise-range")
        return None
    else:
        [from_index, max_index, inc_close, get_lhigh, tmpId] = rise_range
        if max_index != high_index:
            logger.debug("Invalid rise-range from %s to %s" %
                         (kdata.index[from_index], kdata.index[max_index]))
            return None
        if kdata.iloc[pick_index][dogen.P_CLOSE] < kdata.iloc[from_index][
                dogen.P_CLOSE]:
            logger.debug("Invalid pick-trade at %s" % kdata.index[pick_index])
            return None
        pass

    ### 特征二
    heap_rises = 0
    take_index = None
    if pick_index + 1 < pick_valid:
        for temp_index in range(pick_index - 1, -1, -1):
            if kdata.iloc[temp_index][dogen.P_CLOSE] >= dogen.caculate_l_high(
                    kdata.iloc[pick_index][dogen.P_CLOSE]):
                take_index = temp_index
            pass
        pass
    else:
        if dogen.caculate_incr_percentage(kdata.iloc[0][dogen.P_CLOSE],
                                          kdata.iloc[0][dogen.MA5]) < 3:
            for temp_index in range(pick_index, -1, -1):
                if kdata.iloc[temp_index][dogen.R_CLOSE] > 0 and kdata.iloc[
                        temp_index][dogen.R_AMP] >= 5:
                    if take_index is None or take_index > temp_index:
                        take_index = temp_index
                    pass
                pass
            pass
        for temp_index in range(pick_index, -1, -1):
            temp_close = kdata.iloc[temp_index][dogen.R_CLOSE]
            if temp_close < 0:
                heap_rises = 0
            else:
                heap_rises += temp_close
            if kdata.iloc[temp_index][dogen.P_CLOSE] < kdata.iloc[temp_index][
                    dogen.P_OPEN]:
                continue
            if heap_rises >= 5:
                if take_index is None or take_index > temp_index:
                    take_index = temp_index
                pass
            if temp_close >= 3 and kdata.iloc[temp_index][
                    dogen.P_CLOSE] > kdata.iloc[temp_index][dogen.P_OPEN]:
                if take_index is None or take_index > temp_index:
                    take_index = temp_index
                pass
            pass
        ### MACD点校验
        temp_index = 0
        if (kdata.iloc[temp_index][dogen.MACD] >= 0.01) and (
                dogen.forecast_macd(kdata[temp_index:-1][dogen.MACD]) <= 0.01):
            if take_index is None or take_index > temp_index:
                take_index = temp_index
            pass
        if take_index is not None:
            ### take_index之后缩量下跌(限一个交易日),也符合策略
            if take_index == 1\
            and kdata.iloc[take_index-1][dogen.R_CLOSE] < 0\
            and kdata.iloc[take_index-1][dogen.VOLUME]  < kdata.iloc[take_index][dogen.VOLUME]:
                take_index -= 1
            ### 最近收盘价比take_index(不能取更新后值)高更新
            elif take_index <= 3\
            and kdata.iloc[0][dogen.R_CLOSE] > 0\
            and kdata.iloc[0][dogen.P_CLOSE] > kdata.iloc[0][dogen.P_OPEN]\
            and kdata.iloc[0][dogen.P_CLOSE] >= kdata.iloc[take_index][dogen.P_CLOSE]:
                take_index = 0
            pass
        pass
    if take_index is None or take_index > take_valid:
        logger.debug("Don't get valid take-trade since %s" %
                     kdata.index[pick_index])
        return None

    return [pick_index, take_index, rise_range]