def find_largerise_range(codes, start=None, end=None, save_result=False, args=None): """ 查找大涨的股票数据 参数说明: start - 起始日期,未设置默认分析3个月以内的数据 end - 截止日期 save_result - 是否保存结果 args - args[0]表示最少30个点涨幅;arg[1]表示至少包括两个涨停板 返回结果: 区间列表如[{item-1}, {item-2}, ... , {itemn-}] """ ### 数据库连接初始化 db = dogen.DbMongo(uri=mongo_server, database=mongo_database) if not db.connect(): logger.error("Cannot connect to mongo-server %s" % mongo_server) return None ### 股票代码过滤,如科创板 codes = dogen.drop_codes(codes) ### 依次统计检查 match_list = [] for code in codes: try: ### 从数据库读取basic数据 basic = db.lookup_stock_basic(code) ### 从数据库读取日线数据,必须按索引(日期)降序排列 if end is None: end = dogen.date_today() if start is None: start = dogen.date_delta(end, -30) kdata = db.lookup_stock_kdata(code, start=start, end=end) if kdata is None or kdata.index.size <= 0: continue dogen.drop_fresh_stock_trades(basic, kdata) ### 统计分析 if kdata is not None and kdata.index.size > 0: logger.debug("Begin in analyzing %s from %s to %s" % (code, start, end)) match = __statistics_analyze(db, basic, kdata, save_result, args) if match is None: continue ### 输出结果 match_list.extend(match) except Exception: logger.error('Trggered in handling code %s: %s' % (code, traceback.format_exc())) continue pass return match_list
def dispatcher_of_daily_pull_update_kdata(codes=None, full=False, start=None, end=None, slice=1000): """ 拆分股票更新任务 """ try: if codes is None: ### 下载股票代码数据 basics = dogen.download_basics() if basics is None: db = dogen.DbMongo(uri=mongo_server, database=mongo_database) basics = db.lookup_stock_basics() codes = basics.index.tolist() codes.sort() ### 添加指数 codes.append(dogen.get_index_of_sh()) codes.append(dogen.get_index_of_sz()) except Exception: traceback.print_exc() return None ### 分配任务, 聚合结果 logger.info('%s called to dispatch %d codes into sub-task with slice=%d' % ('dispatcher_of_daily_pull_update_kdata', len(codes), slice)) reply = [] while True: tasks = len(reply) if (tasks * slice) >= len(codes): break reply.append( celery_dogen.daily_pull_update_kdata.delay( codes[tasks * slice:(tasks + 1) * slice], full=full, start=start, end=end)) result = [] for i in range(0, len(reply)): while not reply[i].ready(): time.sleep(0.05) continue result.extend(reply[i].result) return result
def update_all_concept_from_html(filename='thsgn_total_cnpt.html', blackfile='thsgn_black_list.html'): """ 从同花顺文件更新概念 """ ### 数据库连接初始化 db = dogen.DbMongo(uri=mongo_server, database=mongo_database) if not db.connect(): logger.error("Cannot connect to mongo-server %s" % mongo_server) return None try: cnpt = dogen.parse_thsgn_file(filename, blackfile) db.delete_stock_concept() db.insert_stock_concept(cnpt) except Exception: traceback.print_exc() return None
def dispatcher_of_up_ma20touch_match(codes=None, start=None, end=None, save_result=False, policy_args=None, slice=1000): """ up_ma20touch策略任务拆分 参数说明: start - 样本起始交易日(数据库样本可能晚于该日期, 如更新不全);若未指定默认取end-$max_days做起始日 end - 样本截止交易日(数据库样本可能早于该日期, 如停牌) save_result - 保存命中结果 返回结果: 列表数据如[{item-1}, {item-2}, ..., {item-n}],根据股票的流通市值、收盘价、成交量、涨跌幅等数据决策。 """ ### 数据库连接初始化 db = dogen.DbMongo(uri=mongo_server, database=mongo_database) if not db.connect(): logger.error("Cannot connect to mongo-server %s" % mongo_server) return None ### 获取代码列表 if codes is None: codes = db.lookup_stock_codes() codes.sort() ### 拆分任务, 聚合结果 logger.info('%s called to dispatch %d codes into sub-task with slice=%d' % ('dispatcher_of_up_ma20touch_match', len(codes), slice)) reply = [] while True: tasks = len(reply) if (tasks * slice) >= len(codes): break reply.append( celery_dogen.up_ma20touch_match.delay( codes[tasks * slice:(tasks + 1) * slice], start=start, end=end, save_result=save_result, policy_args=policy_args)) ### 聚合子任务结果 return dispatcher_poll_result(reply)
def dispatcher_of_daily_statistics_find_largerise_range( codes=None, start=None, end=None, save_result=False, args=None, slice=1000): """ 拆分统计股票上涨区间任务 """ ### 数据库连接初始化 db = dogen.DbMongo(uri=mongo_server, database=mongo_database) if not db.connect(): logger.error("Cannot connect to mongo-server %s" % mongo_server) return None ### 获取代码列表 if codes is None: codes = db.lookup_stock_codes() codes.sort() ### 分配任务, 聚合结果 logger.info('%s called to dispatch %d codes into sub-task with slice=%d' % ('dispatcher_of_daily_statistics_find_largerise_range', len(codes), slice)) reply = [] while True: tasks = len(reply) if (tasks * slice) >= len(codes): break reply.append( celery_dogen.daily_statistics_find_largerise_range.delay( codes[tasks * slice:(tasks + 1) * slice], start=start, end=end, save_result=save_result, args=args)) ### 聚合子任务结果 return dispatcher_poll_result(reply)
def match(codes, start=None, end=None, save_result=False, policy_args=None): """ 涨停上涨策略, 满足条件: >>> 基本条件 一 仅有一个涨停在[min_hl, max_hl]交易区间以内; 二 买入信号(take-trade),有效期由take_valid限定: 1) 5日以内收盘价均维持在涨停价以上,且相对涨停价涨幅不高于5个点; 2) 5日以外累积上涨幅度达5个点或单日涨幅3点以上,且收盘价突破涨停价, 下面情况更新take-trade; a. 若take-trade之后限一个交易日缩量下跌; b. 若take-trade之后最后交易日收盘价突破,更新为买入信号; >>> 排它条件 三 股价市值在outstanding(100亿)和maxi_close(50以下)限制范围内 四 股价成本合理: 1) 在最近一个月内,最高涨幅由maxi_rise限制; 五 take-trade限制: 1) take-trade交易日收盘价高于涨停价-3%,但不超过回调最低价+15%; 2) 维持上涨趋势:MA5上涨,MA20上涨 3) 排除放量上影线 六 形态限制: 1) 涨停之后保持碗底弧形上涨趋势, 碗底收盘价低于涨停价-3个点以上,二次拟合系数大于0.008; 2) 涨停之后回调超过-3之后,只允许一次突破前高;(暂未实现) 七 碗底之后若放量下跌必须突破开盘价 八 回调最低价之后交易日必须满足下面条件: 1) 没有超过7%的单日涨幅 2) 存在振幅5个点以上交易日 3) 每三日累积涨幅不超过前一日涨停价 参数说明: start - 样本起始交易日(数据库样本可能晚于该日期, 如更新不全);若未指定默认取end-$max_days做起始日 end - 样本截止交易日(数据库样本可能早于该日期, 如停牌) save_result - 保存命中结果 返回结果: 列表数据如[{item-1}, {item-2}, ..., {item-n}],根据股票的流通市值、收盘价、成交量、涨跌幅等数据决策。 """ ### 数据库连接初始化 db = dogen.DbMongo(uri=mongo_server, database=mongo_database) if not db.connect(): logger.error("Cannot connect to mongo-server %s" % mongo_server) return None ### 截至日期修正 expon = db.lookup_stock_kdata(dogen.get_index_of_sh(), end=end) if expon is None: logger.error("Don't get expon data") return None else: end = expon.index[0] start = dogen.date_delta(end, -__parse_policy_args(policy_args, MAX_TRADES)) ### 依次策略检查 match_list = [] for code in codes: try: ### 从数据库读取basic数据 basic = db.lookup_stock_basic(code) if dogen.drop_stock_check(code, basic): continue ### 从数据库读取日线数据,必须按索引(日期)降序排列 kdata = db.lookup_stock_kdata(code, start=start, end=end) if kdata is None: continue elif kdata.index[0] != end: logger.debug("End date don't match") continue else: dogen.drop_fresh_stock_trades(basic, kdata) ### 策略分析 if kdata is not None and kdata.index.size > 0: logger.debug("Begin in analyzing %s from %s to %s" % (code, kdata.index[-1], kdata.index[0])) match = stock_analyze(basic, kdata, policy_args) if match is None: continue ### 输出结果 match_list.append(match) except Exception: logger.error('Trggered in handling code %s: %s' % (code, traceback.format_exc())) continue pass ### 保存结果到数据库 if save_result and len(match_list) > 0: db.insert_policy_result(__name__.split('.')[-1], match_list, key_name=dogen.RST_COL_INDEX) return match_list
def match(codes, start=None, end=None, save_result=False, policy_args=None): """ 上涨均线策略, 股价维持在某一均线之上,调整回踩均线: >>> 基本条件 一 ma5维持在ma20之上; 二 买入交易日take-trade,满足条件: 1) 最低价回踩ma20(如何精细定义???); >>> 排它条件 参数说明: start - 样本起始交易日(数据库样本可能晚于该日期, 如更新不全);若未指定默认取end-$max_days做起始日 end - 样本截止交易日(数据库样本可能早于该日期, 如停牌) save_result - 保存命中结果 返回结果: 列表数据如[{item-1}, {item-2}, ..., {item-n}],根据股票的流通市值、收盘价、成交量、涨跌幅等数据决策。 """ ### 数据库连接初始化 db = dogen.DbMongo(uri=mongo_server, database=mongo_database) if not db.connect(): logger.error("Cannot connect to mongo-server %s" % mongo_server) return None ### 截至日期修正 expon = db.lookup_stock_kdata(dogen.get_index_of_sh(), end=end) if expon is None: logger.error("Don't get expon data") return None else: end = expon.index[0] start = dogen.date_delta(end, -__parse_policy_args(policy_args, MAX_TRADES)) ### 依次策略检查 match_list = [] for code in codes: try: ### 从数据库读取basic数据 basic = db.lookup_stock_basic(code) if dogen.drop_stock_check(code, basic): continue ### 从数据库读取日线数据,必须按索引(日期)降序排列 kdata = db.lookup_stock_kdata(code, start=start, end=end) if kdata is None: continue elif kdata.index[0] != end: logger.debug("End date don't match") continue else: dogen.drop_fresh_stock_trades(basic, kdata) ### 策略分析 if kdata is not None and kdata.index.size > 0: logger.debug("Begin in analyzing %s from %s to %s" % (code, kdata.index[-1], kdata.index[0])) match = stock_analyze(basic, kdata, policy_args) if match is None: continue ### 输出结果 match_list.append(match) except Exception: logger.error('Trggered in handling code %s: %s' % (code, traceback.format_exc())) continue pass ### 保存结果到数据库 if save_result and len(match_list) > 0: db.insert_policy_result(__name__.split('.')[-1], match_list, key_name=dogen.RST_COL_INDEX) return match_list
def match(codes, start=None, end=None, save_result=False, policy_args=None): """ 两连涨停策略, 满足条件: >>> 基本条件 一 两周内两连板上涨; 1) 存在次板收盘价之下的回调; 2) 次板非烂板(暂无法判断) 二 买入信号(take-trade),有效期由take_valid限定: 1) 收盘价在次板收盘价0.97倍之上,且涨幅小于7%; >>> 排它条件 三 股价市值在outstanding(100亿)和maxi_close(50以下)限制范围内 四 股价成本合理: 1) 在最近一个月内,最高涨幅由maxi_rise限制; 参数说明: start - 样本起始交易日(数据库样本可能晚于该日期, 如更新不全);若未指定默认取end-$max_days做起始日 end - 样本截止交易日(数据库样本可能早于该日期, 如停牌) save_result - 保存命中结果 返回结果: 列表数据如[{item-1}, {item-2}, ..., {item-n}],根据股票的流通市值、收盘价、成交量、涨跌幅等数据决策。 """ ### 数据库连接初始化 db = dogen.DbMongo(uri=mongo_server, database=mongo_database) if not db.connect(): logger.error("Cannot connect to mongo-server %s" % mongo_server) return None ### 截至日期修正 expon = db.lookup_stock_kdata(dogen.get_index_of_sh(), end=end) if expon is None: logger.error("Don't get expon data") return None else: end = expon.index[0] start = dogen.date_delta(end, -__parse_policy_args(policy_args, MAX_TRADES)) ### 依次策略检查 match_list = [] for code in codes: try: ### 从数据库读取basic数据 basic = db.lookup_stock_basic(code) if dogen.drop_stock_check(code, basic): continue ### 从数据库读取日线数据,必须按索引(日期)降序排列 kdata = db.lookup_stock_kdata(code, start=start, end=end) if kdata is None: continue elif kdata.index[0] != end: logger.debug("End date don't match") continue else: dogen.drop_fresh_stock_trades(basic, kdata) ### 策略分析 if kdata is not None and kdata.index.size > 0: logger.debug("Begin in analyzing %s from %s to %s" % (code, kdata.index[-1], kdata.index[0])) match = stock_analyze(basic, kdata, policy_args) if match is None: continue ### 输出结果 match_list.append(match) except Exception: logger.error('Trggered in handling code %s: %s' % (code, traceback.format_exc())) continue pass ### 保存结果到数据库 if save_result and len(match_list) > 0: db.insert_policy_result(__name__.split('.')[-1], match_list, key_name=dogen.RST_COL_INDEX) return match_list
def match(codes, start=None, end=None, save_result=False, policy_args=None): """ 反弹策略, 满足条件: >>> 基本条件 一 下跌min_falls以上,最低价之后ma5不大于ma20; 二 买入信号(take-trade),有效期由take_valid限定: 1) 最低价后最多5个交易日,单日涨停(不限最小区间长度); 2) 最低价后至少5个交易日,累积上涨超过5个点,或者单日涨幅超过3个点(MA5上涨); 3) 最低价后至少5个交易日,保持横盘,出现振幅大于5%的上涨交易日(MA5上涨); >>> 排它条件 三 股价市值在outstanding(100亿)和maxi_close(50以下)限制范围内 四 pick-trade校验: 1) pick-trade之后最高价不超过15%; 五 若当前MACD值低于-0.1,那么其预测值必须大于-0.1 参数说明: start - 样本起始交易日(数据库样本可能晚于该日期, 如更新不全);若未指定默认取end-$max_days做起始日 end - 样本截止交易日(数据库样本可能早于该日期, 如停牌) save_result - 保存命中结果 返回结果: 列表数据如[{item-1}, {item-2}, ..., {item-n}],根据股票的流通市值、收盘价、成交量、涨跌幅等数据决策。 """ ### 数据库连接初始化 db = dogen.DbMongo(uri=mongo_server, database=mongo_database) if not db.connect(): logger.error("Cannot connect to mongo-server %s" % mongo_server) return None ### 截至日期修正 expon = db.lookup_stock_kdata(dogen.get_index_of_sh(), end=end) if expon is None: logger.error("Don't get expon data") return None else: end = expon.index[0] start = dogen.date_delta(end, -__parse_policy_args(policy_args, MAX_TRADES)) ### 依次策略检查 match_list = [] for code in codes: try: ### 从数据库读取basic数据 basic = db.lookup_stock_basic(code) if dogen.drop_stock_check(code, basic): continue ### 从数据库读取日线数据,必须按索引(日期)降序排列 kdata = db.lookup_stock_kdata(code, start=start, end=end) if kdata is None: continue elif kdata.index[0] != end: logger.debug("End date don't match") continue else: dogen.drop_fresh_stock_trades(basic, kdata) ### 策略分析 if kdata is not None and kdata.index.size > 0: logger.debug("Begin in analyzing %s from %s to %s" % (code, kdata.index[-1], kdata.index[0])) match = stock_analyze(basic, kdata, policy_args) if match is None: continue ### 输出结果 match_list.append(match) except Exception: logger.error('Trggered in handling code %s: %s' % (code, traceback.format_exc())) continue pass ### 保存结果到数据库 if save_result and len(match_list) > 0: db.insert_policy_result(__name__.split('.')[-1], match_list, key_name=dogen.RST_COL_INDEX) return match_list
def update_hot_concept(end=None, num=1, save_result=False): """ 找热点概念 参数: start: 开始日期 end: 截止时间,None取最近交易日 num: 计算日期数,0表示所有的 """ db = dogen.DbMongo(uri=mongo_server, database=mongo_database) if not db.connect(): logger.error("Cannot connect to mongo-server %s" % mongo_server) return None rd = dogen.DbRedis() if not rd.connect(): logger.error("Cannot connect to redis-server %s" % redis_server) return None ### 获取指数 expon = db.lookup_stock_kdata(dogen.get_index_of_sh(), end=end) if expon is None: logger.debug("Don't get valid expon data") return None ### 截取有效交易日 if num==0 or num > expon.index.size: num = expon.index.size ### 清理临时缓存 rd.clear_hot_concept(expon.index[0:num].to_list()) ### 读取代码 codes = db.lookup_stock_codes() for code in codes: basic = db.lookup_stock_basic(code) kdata = db.lookup_stock_kdata(code, end=end) indt = dogen.lookup_industry(db, code) # 行业 cnpt = dogen.lookup_concept(db, code) # 概念 if kdata is None or indt is None or cnpt is None: continue dogen.drop_fresh_stock_trades(basic, kdata) for temp_index in range(0, num): if (temp_index >= kdata.index.size)\ or (kdata.iloc[temp_index][dogen.P_CLOSE] < kdata.iloc[temp_index][dogen.L_HIGH]): continue if (temp_index+1 >= kdata.index.size)\ or (kdata.iloc[temp_index+1][dogen.P_CLOSE] < kdata.iloc[temp_index+1][dogen.L_HIGH]): continue rd.incry_hot_concept(kdata.index[temp_index], cnpt) pass rst = [] ### 排序获取结果&清除临时数据 for temp_index in range(0, num): hots = rd.fetch_hot_concept(expon.index[temp_index]) ### 写数据库 if save_result: db.insert_hot_concept(expon.index[temp_index], hots) rst.append((expon.index[temp_index], hots)) rd.clear_hot_concept(expon.index[temp_index]) return rst
def update_kdata(codes, full=False, start=None, end=None): """ 从网络侧更新股票数据 参数说明: codes - 更新股票列表 full - 是否进行全量更新 start - 起始交易日 end - 截止交易日 返回结果: 成功更新数据列表 """ ### 数据库连接初始化 db = dogen.DbMongo(uri=mongo_server, database=mongo_database) if not db.connect(): logger.error("Cannot connect to mongo-server %s" % mongo_server) return None ### 设置截止日期 if end is None: end = dogen.date_today() ### 下载basic数据 basics = dogen.download_basics() if basics is None: db = dogen.DbMongo(uri=mongo_server, database=mongo_database) basics = db.lookup_stock_basics() ### 下载参数指定股票数据 success_list = [] for code in codes: ### 如果全量下载, 则清除数据库 try: if full: db.delete_stock_basic(code=code) db.delete_stock_kdata(code) from_trade = None last_trade = None else: ### 读取数据区间 from_trade, last_trade = db.lookup_stock_kdata_range(code) ### 区间数据不存在, 默认下载end之前两年数据 if full or from_trade is None or last_trade is None: if start is None: start = dogen.date_delta(end, -365*2) pass else: ### 增量下载需要保证数据处理加工的正确性(MA20/MACD) start = dogen.date_delta(last_trade, -90) ### 下载日线数据 logger.debug("Begin download %s's kdata from %s to %s." % (code, start, end)) kdata = dogen.download_kdata(code, start=start, end=end) if kdata is None or kdata.index.size <= 0: continue ### 截取新增数据插入, 数据已存在会导致出错 if from_trade is not None and last_trade is not None: kdata = kdata.loc[(kdata.index<from_trade) | (kdata.index>last_trade)] ### 写数据库 if kdata is not None and kdata.index.size > 0: ### 非指数写基本信息 if code.isdigit(): basic = basics.loc[code] db.insert_stock_basic(code, basic) db.insert_stock_kdata(code, kdata, kdata.index) success_list.append(code) logger.debug("Success update %s with %d items." % (code, kdata.index.size)) except Exception: logger.error('Trggered in handling code %s: %s' % (code, traceback.format_exc())) continue pass return success_list