def stock_analyze(basic, kdata, policy_args): ### 基本条件选取 get_index = include_analyze(basic, kdata, policy_args) if get_index is None: logger.debug("include_analyze() return None") return None else: [pick_index, take_index] = get_index ### 排它条件过滤 if exclude_analyze(basic, kdata, pick_index, take_index, policy_args): logger.debug("exclude_analyze() return True") return None ### 构造结果 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_TAKE_TRADE] = kdata.index[take_index] # 命中交易日 result[dogen.RST_COL_LAST_CLOSE] = kdata.iloc[0][dogen.P_CLOSE] # 最后一日收盘价 result[dogen.RST_COL_OUTSTANDING] = round(kdata.iloc[0][dogen.P_CLOSE] * basic[dogen.OUTSTANDING], 2) # 流通市值 result[dogen.RST_COL_INC_HL] = dogen.get_highlimit_trades(kdata, eIdx=pick_index+22).size result[dogen.RST_COL_SCORE] = score_analyze(basic, kdata, pick_index, take_index, policy_args) result[dogen.RST_COL_MATCH_TIME] = dogen.datetime_now() # 选中时间 result[dogen.RST_COL_INDEX] = '%s_%s' % (basic.name, kdata.index[take_index]) # 唯一标识,用于持久化去重 return result
def include_analyze(basic, kdata, policy_args): ### 策略参数处理 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) if pick_index == 0: logger.debug("Fallback didn't occur") return None pass if kdata.iloc[pick_index-1][dogen.R_CLOSE] > 0 or kdata.iloc[pick_index-1][dogen.VOLUME] < kdata.iloc[pick_index][dogen.VOLUME]: ### 涨停后缩量下跌 list_index = trade_analyze1(basic, kdata, pick_index, policy_args) else: ### 涨停后首日放量下跌 list_index = trade_analyze2(basic, kdata, pick_index, policy_args) if list_index is not None: [pick_index, take_index] = list_index if take_index is None or take_index > take_valid: logger.debug("Don't match valid fallback trade") return None pass return list_index
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
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]