Example #1
0
def select_by_finance(timestamp=now_pd_timestamp(), entity_ids=None):
    if timestamp.dayofweek in (5, 6):
        logger.info(f'today:{timestamp} is {timestamp.day_name()},just ignore')

    today = to_time_str(timestamp)

    my_selector = TargetSelector(start_timestamp='2015-01-01',
                                 end_timestamp=today,
                                 entity_ids=entity_ids)
    # add the factors
    good_factor1 = GoodCompanyFactor(start_timestamp='2015-01-01',
                                     end_timestamp=today,
                                     entity_ids=entity_ids)
    good_factor2 = GoodCompanyFactor(
        start_timestamp='2015-01-01',
        end_timestamp=today,
        entity_ids=entity_ids,
        data_schema=CashFlowStatement,
        columns=[
            CashFlowStatement.report_period,
            CashFlowStatement.net_op_cash_flows
        ],
        filters=[CashFlowStatement.net_op_cash_flows > 0],
        col_threshold={'net_op_cash_flows': 100000000})

    my_selector.add_filter_factor(good_factor1)
    my_selector.add_filter_factor(good_factor2)
    my_selector.run()

    long_targets = my_selector.get_open_long_targets(today)

    logger.info(f'selected:{len(long_targets)}')

    return long_targets
Example #2
0
def every_day_report():
    while True:
        try:
            today = now_pd_timestamp()
            long_targets = select_by_finance(today)

            logger.info(f'selected:{len(long_targets)}')

            if long_targets:
                ma_factor = CrossMaFactor(start_timestamp='2015-01-01',
                                          end_timestamp=today,
                                          dry_run=True,
                                          persist_factor=False,
                                          entity_ids=long_targets,
                                          windows=[5, 30, 120])
                my_selector = TargetSelector(start_timestamp='2015-01-01',
                                             end_timestamp=today,
                                             entity_ids=long_targets)
                my_selector.add_filter_factor(ma_factor)
                my_selector.run()
                final_targets = my_selector.get_open_long_targets(today)

                final_targets = list(set(final_targets))

                logger.info(f'final selected:{len(final_targets)}')

                if final_targets:
                    df = get_entities(provider='eastmoney',
                                      entity_schema=Stock,
                                      entity_ids=final_targets,
                                      columns=['code', 'name'])
                    info = [
                        df.loc[i, 'code'] + ' ' + df.loc[i, 'name']
                        for i in df.index
                    ]
                    msg = ' '.join(info)
            else:
                msg = 'no targets'

            logger.info(msg)

            email_action = EmailInformer()
            email_action.send_message("*****@*****.**",
                                      f'{today} 基本面 + 技术面选股结果', msg)

            break
        except Exception as e:
            logger.exception('report3 sched error:{}'.format(e))
            time.sleep(60 * 3)
Example #3
0
def report_state():
    while True:
        error_count = 0
        email_action = EmailInformer(ssl=True)

        try:
            latest_day: Stock1dKdata = Stock1dKdata.query_data(order=Stock1dKdata.timestamp.desc(), limit=1,
                                                               return_type='domain')
            target_date = latest_day[0].timestamp
            # target_date = to_pd_timestamp('2020-01-02')

            # 计算均线
            my_selector = TargetSelector(start_timestamp='2018-01-01', end_timestamp=target_date)
            # add the factors
            factor1 = VolumeUpMa250Factor(start_timestamp='2018-01-01', end_timestamp=target_date)

            my_selector.add_filter_factor(factor1)

            my_selector.run()

            long_stocks = my_selector.get_open_long_targets(timestamp=target_date)

            msg = 'no targets'
            # 过滤亏损股
            # check StockValuation data
            pe_date = target_date - datetime.timedelta(10)
            if StockValuation.query_data(start_timestamp=pe_date, limit=1, return_type='domain'):
                positive_df = StockValuation.query_data(provider='joinquant', entity_ids=long_stocks,
                                                        start_timestamp=pe_date,
                                                        filters=[StockValuation.pe > 0],
                                                        columns=['entity_id'])
                bad_stocks = set(long_stocks) - set(positive_df['entity_id'].tolist())
                if bad_stocks:
                    stocks = get_entities(provider='joinquant', entity_schema=Stock, entity_ids=bad_stocks,
                                          return_type='domain')
                    info = [f'{stock.name}({stock.code})' for stock in stocks]
                    msg = '亏损股:' + ' '.join(info) + '\n'

                long_stocks = set(positive_df['entity_id'].tolist())

            if long_stocks:
                pre_date = target_date - datetime.timedelta(3 * 365)
                ma_state = MaStateStatsFactor(entity_ids=long_stocks, start_timestamp=pre_date,
                                              end_timestamp=target_date, persist_factor=False)
                bad_stocks = []
                for entity_id, df in ma_state.factor_df.groupby(level=0):
                    if df['current_pct'].max() >= 0.35:
                        bad_stocks.append(entity_id)
                        long_stocks.remove(entity_id)
                if bad_stocks:
                    stocks = get_entities(provider='joinquant', entity_schema=Stock, entity_ids=bad_stocks,
                                          return_type='domain')
                    info = [f'{stock.name}({stock.code})' for stock in stocks]
                    msg = msg + '3年内高潮过:' + ' '.join(info) + '\n'

            # 过滤风险股
            if long_stocks:
                risky_codes = risky_company(the_date=target_date, entity_ids=long_stocks)

                if risky_codes:
                    long_stocks = [entity_id for entity_id in long_stocks if
                                   get_entity_code(entity_id) not in risky_codes]

                    stocks = get_entities(provider='joinquant', entity_schema=Stock, entity_ids=risky_codes,
                                          return_type='domain')
                    info = [f'{stock.name}({stock.code})' for stock in stocks]
                    msg = msg + '风险股:' + ' '.join(info) + '\n'
            if long_stocks:
                stocks = get_entities(provider='joinquant', entity_schema=Stock, entity_ids=long_stocks,
                                      return_type='domain')
                # add them to eastmoney
                try:
                    try:
                        eastmoneypy.del_group('real')
                    except:
                        pass
                    eastmoneypy.create_group('real')
                    for stock in stocks:
                        eastmoneypy.add_to_group(stock.code, group_name='real')
                except Exception as e:
                    email_action.send_message("*****@*****.**", f'report state error',
                                              'report state error:{}'.format(e))

                info = [f'{stock.name}({stock.code})' for stock in stocks]
                msg = msg + '盈利股:' + ' '.join(info) + '\n'

            logger.info(msg)
            email_action.send_message('*****@*****.**', f'{target_date} 放量突破年线state选股结果', msg)
            break
        except Exception as e:
            logger.exception('report state error:{}'.format(e))
            time.sleep(60 * 3)
            error_count = error_count + 1
            if error_count == 10:
                email_action.send_message("*****@*****.**", f'report state error',
                                          'report state error:{}'.format(e))
Example #4
0
def report_real(region):
    while True:
        error_count = 0
        email_action = EmailInformer(ssl=True)

        try:
            latest_day: Stock1dKdata = Stock1dKdata.query_data(
                region=region,
                order=Stock1dKdata.timestamp.desc(),
                limit=1,
                return_type='domain')
            target_date = latest_day[0].timestamp
            # target_date = '2020-02-04'

            # 计算均线
            my_selector = TargetSelector(region=region,
                                         start_timestamp='2018-01-01',
                                         end_timestamp=target_date)
            # add the factors
            factor1 = VolumeUpMa250Factor(region=region,
                                          start_timestamp='2018-01-01',
                                          end_timestamp=target_date)

            my_selector.add_filter_factor(factor1)

            my_selector.run()

            long_stocks = my_selector.get_open_long_targets(
                timestamp=target_date)

            msg = 'no targets'
            # 过滤亏损股
            # check StockValuation data
            pe_date = target_date - datetime.timedelta(10)
            if StockValuation.query_data(region=region,
                                         start_timestamp=pe_date,
                                         limit=1,
                                         return_type='domain'):
                positive_df = StockValuation.query_data(
                    region=region,
                    provider=Provider.JoinQuant,
                    entity_ids=long_stocks,
                    start_timestamp=pe_date,
                    filters=[StockValuation.pe > 0],
                    columns=['entity_id'])
                bad_stocks = set(long_stocks) - set(
                    positive_df['entity_id'].tolist())
                if bad_stocks:
                    stocks = get_entities(region=region,
                                          provider=Provider.JoinQuant,
                                          entity_schema=Stock,
                                          entity_ids=bad_stocks,
                                          return_type='domain')
                    info = [f'{stock.name}({stock.code})' for stock in stocks]
                    msg = '亏损股:' + ' '.join(info) + '\n'

                long_stocks = set(positive_df['entity_id'].tolist())

            if long_stocks:
                # use block to filter
                block_selector = BlockSelector(region=region,
                                               start_timestamp='2020-01-01',
                                               long_threshold=0.8)
                block_selector.run()
                long_blocks = block_selector.get_open_long_targets(
                    timestamp=target_date)

                if long_blocks:
                    blocks: List[Block] = Block.query_data(
                        region=region,
                        provider=Provider.Sina,
                        entity_ids=long_blocks,
                        return_type='domain')

                    info = [f'{block.name}({block.code})' for block in blocks]
                    msg = ' '.join(info) + '\n'

                    block_stocks: List[BlockStock] = BlockStock.query_data(
                        region=region,
                        provider=Provider.Sina,
                        filters=[BlockStock.stock_id.in_(long_stocks)],
                        entity_ids=long_blocks,
                        return_type='domain')
                    if block_stocks:
                        # add them to eastmoney
                        try:
                            try:
                                eastmoneypy.del_group('real')
                            except:
                                pass
                            eastmoneypy.create_group('real')
                            for block_stock in block_stocks:
                                eastmoneypy.add_to_group(
                                    block_stock.stock_code, group_name='real')
                        except Exception as e:
                            email_action.send_message(
                                "*****@*****.**", f'report_real error',
                                'report_real error:{}'.format(e))

                        block_map_stocks = {}
                        for block_stock in block_stocks:
                            stocks = block_map_stocks.get(block_stock.name)
                            if not stocks:
                                stocks = []
                                block_map_stocks[block_stock.name] = stocks
                            stocks.append(
                                f'{block_stock.stock_name}({block_stock.stock_code})'
                            )

                        for block in block_map_stocks:
                            stocks = block_map_stocks[block]
                            stock_msg = ' '.join(stocks)
                            msg = msg + f'{block}:\n' + stock_msg + '\n'

            logger.info(msg)
            email_action.send_message('*****@*****.**',
                                      f'{target_date} 放量突破年线real选股结果', msg)
            break
        except Exception as e:
            logger.exception('report_real error:{}'.format(e))
            time.sleep(60 * 3)
            error_count = error_count + 1
            if error_count == 10:
                email_action.send_message("*****@*****.**",
                                          f'report_real error',
                                          'report_real error:{}'.format(e))
Example #5
0
def report_state(region):
    while True:
        error_count = 0
        email_action = EmailInformer(ssl=True)

        try:
            latest_day: Stock1dKdata = Stock1dKdata.query_data(
                region=region,
                order=Stock1dKdata.timestamp.desc(),
                limit=1,
                return_type='domain')
            target_date = latest_day[0].timestamp
            # target_date = to_pd_timestamp('2020-01-02')

            # 计算均线
            my_selector = TargetSelector(region=region,
                                         start_timestamp='2018-01-01',
                                         end_timestamp=target_date)
            # add the factors
            factor1 = ImprovedMaFactor(region=region,
                                       start_timestamp='2018-01-01',
                                       end_timestamp=target_date)

            my_selector.add_filter_factor(factor1)

            my_selector.run()

            long_stocks = my_selector.get_open_long_targets(
                timestamp=target_date)
            stock_map_slope = {}

            logger.info(long_stocks)

            msg = 'no targets'

            if long_stocks:
                pre_date = target_date - datetime.timedelta(2 * 365)
                ma_state = MaStateStatsFactor(region=region,
                                              entity_ids=long_stocks,
                                              start_timestamp=pre_date,
                                              end_timestamp=target_date,
                                              need_persist=False)

                ma_state.factor_df['slope'] = 100 * ma_state.factor_df[
                    'current_pct'] / ma_state.factor_df['current_count']

                high_stocks = []
                for entity_id, df in ma_state.factor_df.groupby(level=0):
                    if df['current_pct'].max() >= 0.7:
                        high_stocks.append(entity_id)

                    stock_map_slope[entity_id] = round(df['slope'].iat[-1], 2)

                if high_stocks:
                    stocks = get_entities(region=region,
                                          provider=Provider.JoinQuant,
                                          entity_schema=Stock,
                                          entity_ids=high_stocks,
                                          return_type='domain')
                    info = [
                        f'{stock.name}({stock.code})[{stock_map_slope.get(stock.entity_id)}]'
                        for stock in stocks
                    ]
                    msg = msg + '2年内高潮过:' + ' '.join(info) + '\n'

            # 过滤风险股
            if long_stocks:
                risky_codes = risky_company(region=region,
                                            the_date=target_date,
                                            entity_ids=long_stocks,
                                            income_yoy=-0.8,
                                            profit_yoy=-0.8)

                if risky_codes:
                    long_stocks = [
                        entity_id for entity_id in long_stocks
                        if get_entity_code(entity_id) not in risky_codes
                    ]

                    stocks = get_entities(region=region,
                                          provider=Provider.JoinQuant,
                                          entity_schema=Stock,
                                          codes=risky_codes,
                                          return_type='domain')
                    info = [
                        f'{stock.name}({stock.code})[{stock_map_slope.get(stock.entity_id)}]'
                        for stock in stocks
                    ]
                    msg = msg + '风险股:' + ' '.join(info) + '\n'
            if long_stocks:
                stocks = get_entities(region=region,
                                      provider=Provider.JoinQuant,
                                      entity_schema=Stock,
                                      entity_ids=long_stocks,
                                      return_type='domain')
                # add them to eastmoney
                try:
                    try:
                        eastmoneypy.del_group('real')
                    except:
                        pass
                    eastmoneypy.create_group('real')
                    for stock in stocks:
                        eastmoneypy.add_to_group(stock.code, group_name='real')
                except Exception as e:
                    email_action.send_message(
                        "*****@*****.**", f'report state error',
                        'report state error:{}'.format(e))

                info = [
                    f'{stock.name}({stock.code})[{stock_map_slope.get(stock.entity_id)}]'
                    for stock in stocks
                ]
                msg = msg + '选中:' + ' '.join(info) + '\n'

            logger.info(msg)
            email_action.send_message('*****@*****.**',
                                      f'{target_date} 放量突破年线state选股结果', msg)
            break
        except Exception as e:
            logger.exception('report state error:{}'.format(e))
            time.sleep(60 * 3)
            error_count = error_count + 1
            if error_count == 10:
                email_action.send_message("*****@*****.**",
                                          f'report state error',
                                          'report state error:{}'.format(e))
Example #6
0
def report_targets(
    factor_cls: Type[Factor],
    entity_provider,
    data_provider,
    title,
    entity_type="stock",
    informer: EmailInformer = None,
    em_group=None,
    em_group_over_write=True,
    filter_by_volume=True,
    adjust_type=None,
    start_timestamp="2019-01-01",
    **factor_kv,
):
    logger.info(
        f"entity_provider: {entity_provider}, data_provider: {data_provider}, entity_type: {entity_type}, start_timestamp: {start_timestamp}"
    )
    error_count = 0

    while error_count <= 10:
        try:
            if not adjust_type:
                adjust_type = default_adjust_type(entity_type=entity_type)

            target_date = get_latest_kdata_date(provider=data_provider,
                                                entity_type=entity_type,
                                                adjust_type=adjust_type)
            logger.info(f"target_date :{target_date}")

            current_entity_pool = None
            if filter_by_volume:
                # 成交量
                vol_df = get_top_volume_entities(
                    entity_type=entity_type,
                    start_timestamp=next_date(target_date, -30),
                    end_timestamp=target_date,
                    adjust_type=adjust_type,
                    pct=0.4,
                    data_provider=data_provider,
                )
                current_entity_pool = vol_df.index.tolist()
                logger.info(
                    f"current_entity_pool({len(current_entity_pool)}): {current_entity_pool}"
                )

            kdata_schema = get_kdata_schema(entity_type,
                                            level=IntervalLevel.LEVEL_1DAY,
                                            adjust_type=adjust_type)
            filters = []
            if "turnover_threshold" in factor_kv:
                filters = filters + [
                    kdata_schema.turnover >=
                    factor_kv.get("turnover_threshold")
                ]
            if "turnover_rate_threshold" in factor_kv:
                filters = filters + [
                    kdata_schema.turnover_rate >=
                    factor_kv.get("turnover_rate_threshold")
                ]
            if filters:
                filters = filters + [kdata_schema.timestamp == target_date]
                kdata_df = kdata_schema.query_data(
                    provider=data_provider,
                    filters=filters,
                    columns=["entity_id", "timestamp"],
                    index="entity_id")
                if current_entity_pool:
                    current_entity_pool = set(current_entity_pool) & set(
                        kdata_df.index.tolist())
                else:
                    current_entity_pool = kdata_df.index.tolist()

            if "entity_ids" in factor_kv:
                if current_entity_pool:
                    current_entity_pool = set(current_entity_pool) & set(
                        factor_kv.pop("entity_ids"))
                else:
                    current_entity_pool = set(factor_kv.pop("entity_ids"))

            # add the factor
            my_selector = TargetSelector(start_timestamp=start_timestamp,
                                         end_timestamp=target_date,
                                         select_mode=SelectMode.condition_or)
            entity_schema = get_entity_schema(entity_type=entity_type)
            tech_factor = factor_cls(
                entity_schema=entity_schema,
                entity_provider=entity_provider,
                provider=data_provider,
                entity_ids=current_entity_pool,
                start_timestamp=start_timestamp,
                end_timestamp=target_date,
                adjust_type=adjust_type,
                **factor_kv,
            )
            my_selector.add_factor(tech_factor)

            my_selector.run()

            long_stocks = my_selector.get_open_long_targets(
                timestamp=target_date)

            inform(
                informer,
                entity_ids=long_stocks,
                target_date=target_date,
                title=title,
                entity_provider=entity_provider,
                entity_type=entity_type,
                em_group=em_group,
                em_group_over_write=em_group_over_write,
            )

            break
        except Exception as e:
            logger.exception("report error:{}".format(e))
            time.sleep(60 * 3)
            error_count = error_count + 1
            if error_count == 10:
                informer.send_message(
                    zvt_config["email_username"],
                    f"report {entity_type}{factor_cls.__name__} error",
                    f"report {entity_type}{factor_cls.__name__} error: {e}",
                )
Example #7
0
def report_targets(
    factor_cls: Type[Factor],
    entity_provider,
    data_provider,
    title,
    entity_type="stock",
    em_group=None,
    em_group_over_write=True,
    filter_by_volume=True,
    adjust_type=None,
    start_timestamp="2019-01-01",
    **factor_kv,
):
    logger.info(
        f"entity_provider: {entity_provider}, data_provider: {data_provider}, entity_type: {entity_type}, start_timestamp: {start_timestamp}"
    )
    error_count = 0

    while error_count <= 10:
        email_action = EmailInformer()

        try:
            if entity_type == "stock" and not adjust_type:
                adjust_type = AdjustType.hfq

            target_date = get_latest_kdata_date(provider=data_provider,
                                                entity_type=entity_type,
                                                adjust_type=adjust_type)
            logger.info(f"target_date :{target_date}")

            current_entity_pool = None
            if filter_by_volume:
                # 成交量
                vol_df = get_top_volume_entities(
                    entity_type=entity_type,
                    start_timestamp=next_date(target_date, -30),
                    end_timestamp=target_date,
                    adjust_type=adjust_type,
                    pct=0.4,
                )
                current_entity_pool = vol_df.index.tolist()
                logger.info(
                    f"current_entity_pool({len(current_entity_pool)}): {current_entity_pool}"
                )

            # add the factor
            my_selector = TargetSelector(start_timestamp=start_timestamp,
                                         end_timestamp=target_date,
                                         select_mode=SelectMode.condition_or)
            entity_schema = get_entity_schema(entity_type=entity_type)
            tech_factor = factor_cls(
                entity_schema=entity_schema,
                entity_provider=entity_provider,
                provider=data_provider,
                entity_ids=current_entity_pool,
                start_timestamp=start_timestamp,
                end_timestamp=target_date,
                adjust_type=adjust_type,
                **factor_kv,
            )
            my_selector.add_factor(tech_factor)

            my_selector.run()

            long_stocks = my_selector.get_open_long_targets(
                timestamp=target_date)

            msg = "no targets"

            if long_stocks:
                entities = get_entities(provider=entity_provider,
                                        entity_type=entity_type,
                                        entity_ids=long_stocks,
                                        return_type="domain")
                if em_group:
                    try:
                        codes = [entity.code for entity in entities]
                        add_to_eastmoney(codes=codes,
                                         entity_type=entity_type,
                                         group=em_group,
                                         over_write=em_group_over_write)
                    except Exception as e:
                        email_action.send_message(
                            zvt_config["email_username"],
                            f"report {entity_type}{factor_cls.__name__} error",
                            f"report {entity_type}{factor_cls.__name__} error: {e}",
                        )

                infos = [
                    f"{entity.name}({entity.code})" for entity in entities
                ]
                msg = "\n".join(infos) + "\n"

            logger.info(msg)

            email_action.send_message(zvt_config["email_username"],
                                      f"{target_date} {title}", msg)

            break
        except Exception as e:
            logger.exception("report error:{}".format(e))
            time.sleep(60 * 3)
            error_count = error_count + 1
            if error_count == 10:
                email_action.send_message(
                    zvt_config["email_username"],
                    f"report {entity_type}{factor_cls.__name__} error",
                    f"report {entity_type}{factor_cls.__name__} error: {e}",
                )