def run(dt: str, min_val_score=50): """ 参考 cal_val 筛选最后 val_score > min_val_score 的 :return: """ s: Session = db_client.get_session() s.query(MqSharePool).filter(MqSharePool.strategy == __strategy, MqSharePool.dt == dt).delete() daily_list: list = s.query(MqDailyMetric) \ .filter(MqDailyMetric.update_date == dt, MqDailyMetric.name == mq_daily_metric_enum.val_score.name, MqDailyMetric.value > min_val_score) \ .all() if len(daily_list) == 0: log.info('No dividend pool in %s' % dt) return to_insert = [] for mq in daily_list: # type: MqDailyMetric to_insert.append( MqSharePool(dt=dt, strategy=__strategy, ts_code=mq.ts_code)) db_client.batch_insert(to_insert) log.info('Dividend strategy done. Dt: %s. Total: %d' % (dt, len(to_insert)))
def calculate_and_insert(ts_code: str, share_name: str, to_date: str = date_utils.get_current_dt()): result_list = calculate_one(ts_code, share_name, to_date) if len(result_list) > 0: start_time = time.time() db_client.batch_insert(result_list) log.info("Insert %s for %s: %s seconds" % (MqDailyMetric.__tablename__, ts_code, time.time() - start_time)) else: log.info('Nothing to insert into %s %s' % (MqDailyMetric.__tablename__, ts_code))
def insert_with_msg(ts_code: str, to_insert: list): """ 插入数据,打印日志 :param ts_code: 股票编码 :param to_insert: 插入数据 :return: """ if len(to_insert) > 0: start_time = time.time() db_client.batch_insert(to_insert) log.info( "Insert %s for %s: %s seconds" % (MqDailyPrice.__tablename__, ts_code, time.time() - start_time)) else: log.info('Nothing to insert into %s %s' % (MqDailyPrice.__tablename__, ts_code))
def cal_by_ths_index_code(index_code, index_name, to_date: str = date_utils.get_current_dt()): from_date = get_from_date(index_code) history_avl = get_history_percent(index_code, from_date) s: Session = db_client.get_session() member_list = s.query(ThsMember).filter( ThsMember.ts_code == index_code).all() s.close() share_code_list = [m.code for m in member_list] result_list = [] while from_date <= to_date: log.info('Calculating %s %s %s' % (MqIndexTradeAmount.__tablename__, index_code, from_date)) s: Session = db_client.get_session() trade_list = s.query(TsDailyTradeInfo) \ .filter(TsDailyTradeInfo.trade_date == from_date) \ .all() s.close() if len(trade_list) > 0: total_amount = Decimal(0) target_amount = Decimal(0) for i in trade_list: # type: TsDailyTradeInfo total_amount += i.amount if i.ts_code in share_code_list: target_amount += i.amount val = float(decimal_utils.div(target_amount, total_amount)) history_percent = get_history_high_percent(history_avl, val) history_avl.add(val) result_list.append( MqIndexTradeAmount(index_code=index_code, index_name=index_name, trade_date=from_date, amount=target_amount, percent=val, history_high_ratio=history_percent)) from_date = date_utils.format_delta(from_date, 1) if len(result_list) >= 1000: db_client.batch_insert(result_list) result_list = [] db_client.batch_insert(result_list)
def calculate_by_code(ts_code, to_date: str = date_utils.get_current_dt()): session: Session = db_client.get_session() basic: TsBasic = session.query(TsBasic).filter( TsBasic.ts_code == ts_code).one() session.close() if basic is None: log.error("Cant find ts_basic of %s" % ts_code) return report_message_list = generate_report_message_by_code( ts_code, basic.name, to_date) if len(report_message_list) > 0: start = time.time() db_client.batch_insert(report_message_list) log.info("Insert mq_message for %s: %s seconds" % (ts_code, time.time() - start)) else: log.info('Nothing to insert into mq_message %s' % ts_code)
def cal_top_amount_share(to_date: str = date_utils.get_current_dt()): from_date = get_from_date(mq_index.top_amount_code) history_avl = get_history_percent(mq_index.top_amount_code, from_date) result_list = [] while from_date <= to_date: log.info('Calculating %s %s %s' % (MqIndexTradeAmount.__tablename__, mq_index.top_amount_code, from_date)) s: Session = db_client.get_session() trade_list = s.query(TsDailyTradeInfo) \ .filter(TsDailyTradeInfo.trade_date == from_date) \ .order_by(TsDailyTradeInfo.amount.desc()) \ .all() s.close() if len(trade_list) > 0: top_to_count = math.floor(len(trade_list) * 0.05) total_amount = Decimal(0) top_amount = Decimal(0) for i in range(len(trade_list)): total_amount += trade_list[i].amount if i <= top_to_count: top_amount += trade_list[i].amount val = float(decimal_utils.div(top_amount, total_amount)) history_percent = get_history_high_percent(history_avl, val) history_avl.add(val) result_list.append( MqIndexTradeAmount(index_code=mq_index.top_amount_code, index_name=mq_index.top_amount_name, trade_date=from_date, amount=top_amount, percent=val, history_high_ratio=history_percent)) from_date = date_utils.format_delta(from_date, 1) if len(result_list) >= 1000: db_client.batch_insert(result_list) result_list = [] db_client.batch_insert(result_list)
def run(dt: str, min_mv=5e10, gap_num=3): """ 2022年开始市值 > 500亿 一个月内出现三个以上向下缺口时买入,只能在新缺口当天买入 一字跌停缺口不算 少于1%的缺口不算 买入日回补缺口则次日开盘价卖出 买入日没回补缺口则次日挂补缺价卖出 最后收盘价无脑卖出 :param dt: 对应日期 :param min_mv: 最低市值要求 :param gap_num: 需要达到多少个缺口 :return: """ delete_old(dt) ts = ts_client.get_ts() pro = ts_client.get_pro() trade_df = pro.trade_cal(exchange='SSE', start_date=dt, end_date=dt, is_open=1) if len(trade_df) == 0: log.info('[Down Gap] Not trade date') return trade_df = pro.trade_cal(exchange='SSE', start_date='20220101', end_date=dt, is_open=1) first_trade_date = trade_df.iloc[0]['cal_date'] basic = pro.daily_basic(trade_date=first_trade_date, fields=['ts_code', 'total_mv']) start = date_utils.format_delta(dt, -30) info = pro.stock_basic(fields=["ts_code", "name"]).set_index('ts_code') candidate_num = 0 for ts_code in basic.loc[basic['total_mv'] * 10000 > min_mv]['ts_code']: log.info('[Down Gap] %s' % ts_code) strategy_record = [] gap_record = {} from_dt = start last_price = None price_df = ts.pro_bar(ts_code=ts_code, start_date=from_dt, adj='qfq').set_index('trade_date') current_trade = None while from_dt <= dt: can_buy_today = current_trade is None # 如果今天持股,即使有卖出也不该再买入了 if from_dt not in price_df.index: # 非交易日 from_dt = date_utils.format_delta(from_dt, 1) continue current_price = price_df.loc[from_dt] if last_price is not None: # 判断是否应该无脑卖出 按开盘价卖出 if current_trade is not None and current_trade['should_sell']: current_trade['sell_date'] = from_dt current_trade['sell_price'] = current_price['open'] strategy_record.append(current_trade) current_trade = None # 先判断开盘有没有下缺口 if current_price['open'] < last_price['low'] and last_price[ 'low'] / current_price['open'] > 1.01: down_limit = current_price['open'] == current_price['close'] and current_price['open'] == \ current_price['high'] and current_price['open'] == current_price['low'] new_gap = { 'trade_date': from_dt, 'low': last_price['low'], 'high': current_price['open'], 'down_limit': down_limit } gap_record[from_dt] = new_gap # 达到3个下缺口时按开盘价买入 if can_buy_today and can_buy(gap_record, from_dt, gap_num): current_trade = { 'ts_code': ts_code, 'buy_date': from_dt, 'buy_price': current_price['open'], 'target_price': last_price['low'], 'should_sell': False } # 判断最高价回补了多少个缺口 high = current_price['high'] for d in list(gap_record.keys()): if high >= gap_record[d]['low']: # 补缺了 del (gap_record[d]) elif from_dt >= date_utils.format_delta(d, 30): # 超过30天了 del (gap_record[d]) elif current_price['high'] > gap_record[d]['high']: gap_record[d]['high'] = current_price['high'] # 判断今天有没有卖出 if current_trade is not None: if high >= current_trade['target_price']: # 补缺了 # 当天买的,卖不了,等第二天 if current_trade['buy_date'] == from_dt: current_trade['should_sell'] = True else: current_trade['sell_date'] = from_dt current_trade['sell_price'] = current_trade[ 'target_price'] strategy_record.append(current_trade) current_trade = None else: # 没补缺 看是不是收盘卖 if current_trade['buy_date'] != from_dt: current_trade['sell_date'] = from_dt current_trade['sell_price'] = current_price[ 'close'] strategy_record.append(current_trade) current_trade = None last_price = current_price from_dt = date_utils.format_delta(from_dt, 1) if len(strategy_record) > 0: last_trade = strategy_record[-1] if last_trade['buy_date'] == dt: # 今日买入 strategy_buy = MqStrategyTrade( strategy=__strategy, strategy_version=__version, strategy_intro=__wiki, ts_code=ts_code, share_name=info.loc[ts_code]['name'], buy_date=last_trade['buy_price'], buy_price=last_trade['buy_date']) db_client.batch_insert([strategy_buy]) elif last_trade['sell_date'] == dt: # 今日卖出 s: Session = db_client.get_session() s.query(MqStrategyTrade).filter( MqStrategyTrade.strategy == __strategy, MqStrategyTrade.strategy_version == __version, MqStrategyTrade.ts_code == ts_code, MqStrategyTrade.buy_date == last_trade['buy_date']).delete() s.close() strategy_sell = MqStrategyTrade( strategy=__strategy, strategy_version=__version, strategy_intro=__wiki, ts_code=ts_code, share_name=info.loc[ts_code]['name'], buy_date=last_trade['buy_date'], buy_price=last_trade['buy_price'], sell_date=last_trade['sell_date'], sell_price=last_trade['sell_price']) db_client.batch_insert([strategy_sell]) if valid_gap_num(gap_record, dt) == gap_num - 1: to_insert = MqSharePool( dt=dt, strategy=__strategy, ts_code=ts_code, share_name=info.loc[ts_code]['name'], suggest_price=decimal_utils.cal_price_with_gain_percent( current_price['low'], -1), suggest_comment='次日下缺口超1%买入') db_client.batch_insert([to_insert]) candidate_num += 1 log.info('[Down Gap] Done. Dt: %s. Total: %d' % (dt, candidate_num))