Exemple #1
0
            if long_stocks:
                msg = msg + '买入: ' + entity_ids_to_msg(self.region,
                                                       long_stocks) + '\n'

            if short_stocks:
                msg = msg + '卖出: ' + entity_ids_to_msg(self.region,
                                                       short_stocks) + '\n'

            # 账户情况
            account = self.get_current_account()

            pct = round((account.all_value - account.input_money) /
                        account.input_money * 100, 4)

            msg = msg + f'投入金额:{account.input_money},目前总市值:{account.all_value},收益率:{pct}%'

            email_action.send_message("*****@*****.**", f'{target_date} 交易信号',
                                      msg)

        super().on_trading_signals(trading_signals)


if __name__ == '__main__':
    init_log('ma250_trader.log')

    trader = MaVolTrader(region=Region.CHN,
                         start_timestamp='2020-01-01',
                         end_timestamp='2021-01-01')
    trader.run()
Exemple #2
0
from zvt.recorders.eastmoney.meta.china_stock_meta_recorder import ChinaStockMetaRecorder

logger = logging.getLogger(__name__)

sched = BackgroundScheduler()


@sched.scheduled_job('cron', hour=1, minute=00)
def run():
    while True:
        try:
            ChinaStockListRecorder(provider='eastmoney').run()

            ChinaStockCategoryRecorder().run()

            ChinaStockMetaRecorder().run()
            break
        except Exception as e:
            logger.exception('meta runner error:{}'.format(e))
            time.sleep(60)


if __name__ == '__main__':
    init_log('eastmoney_china_stock_meta.log')

    run()

    sched.start()

    sched._thread.join()
Exemple #3
0
        email_action = EmailInformer()

        try:
            StockValuation.record_data(provider='joinquant',
                                       sleeping_time=0,
                                       day_data=True)

            email_action.send_message("*****@*****.**",
                                      'joinquant record valuation finished',
                                      '')
            break
        except Exception as e:
            msg = f'joinquant record valuation error:{e}'
            logger.exception(msg)

            email_action.send_message("*****@*****.**",
                                      'joinquant record valuation error', msg)
            time.sleep(60)


if __name__ == '__main__':
    init_log('joinquant_fund_runner.log')

    record_fund()

    record_valuation()

    sched.start()

    sched._thread.join()
Exemple #4
0
            if long_targets:
                stocks = get_entities(provider='joinquant', entity_schema=Stock, entity_ids=long_targets,
                                      return_type='domain')
                info = [f'{stock.name}({stock.code})' for stock in stocks]
                msg = ' '.join(info)
            else:
                msg = 'no targets'

            logger.info(msg)

            email_action.send_message(["*****@*****.**","*****@*****.**",'*****@*****.**'], f'{target_date} 放量突破年线选股结果', msg)

            break
        except Exception as e:
            logger.exception('report_vol_up_250 error:{}'.format(e))
            time.sleep(60 * 3)
            error_count = error_count + 1
            if error_count == 10:
                email_action.send_message("*****@*****.**", f'report_vol_up_250 error',
                                          'report_vol_up_250 error:{}'.format(e))


if __name__ == '__main__':
    init_log('report_vol_up_250.log')

    report_vol_up_250()

    sched.start()

    sched._thread.join()
Exemple #5
0
sched = BackgroundScheduler()


@sched.scheduled_job("cron", hour=1, minute=00, day_of_week=2)
def record_actor_data(data_provider="em", entity_provider="em"):
    run_data_recorder(
        domain=StockInstitutionalInvestorHolder,
        data_provider=data_provider,
        entity_provider=entity_provider,
        day_data=True,
    )
    run_data_recorder(domain=StockTopTenFreeHolder,
                      data_provider=data_provider,
                      entity_provider=entity_provider,
                      day_data=True)
    run_data_recorder(domain=StockActorSummary,
                      data_provider=data_provider,
                      entity_provider=entity_provider,
                      day_data=True)


if __name__ == "__main__":
    init_log("actor_runner.log")

    record_actor_data()

    sched.start()

    sched._thread.join()
        email_action = EmailInformer()

        try:
            Stock.record_data(provider='eastmoney')
            StockDetail.record_data(provider='eastmoney')
            FinanceFactor.record_data(provider='eastmoney')
            BalanceSheet.record_data(provider='eastmoney')
            IncomeStatement.record_data(provider='eastmoney')
            CashFlowStatement.record_data(provider='eastmoney')

            email_action.send_message(zvt_config['email_username'],
                                      'eastmoney runner1 finished', '')
            break
        except Exception as e:
            msg = f'eastmoney runner1 error:{e}'
            logger.exception(msg)

            email_action.send_message(zvt_config['email_username'],
                                      'eastmoney runner1 error', msg)
            time.sleep(60)


if __name__ == '__main__':
    init_log('eastmoney_data_runner1.log')

    run()

    sched.start()

    sched._thread.join()
def record_kdata():
    while True:
        try:
            # items = get_entities(entity_type='stock', provider='joinquant')
            # entity_ids = items['entity_id'].to_list()
            #
            # try:
            #     Stock1dKdata.record_data(provider='joinquant', entity_ids=entity_ids[4172:], sleeping_time=0.5)
            # except Exception as e:
            #     logger.exception('report_tm error:{}'.format(e))
            # 日线前复权和后复权数据
            # Stock1dKdata.record_data(provider='joinquant', sleeping_time=0)
            Stock1dHfqKdata.record_data(provider='joinquant',
                                        sleeping_time=0,
                                        day_data=True)
            # StockMoneyFlow.record_data(provider='joinquant', sleeping_time=0, day_data=True)
            # IndexMoneyFlow.record_data(provider='joinquant', sleeping_time=0, day_data=True)
            break
        except Exception as e:
            msg = f'joinquant record kdata:{e}'
            logger.exception(msg)

            time.sleep(60 * 5)


if __name__ == '__main__':
    init_log('joinquant_kdata_runner.log')
    record_stock()
    record_kdata()
Exemple #8
0
            logger.info(f'selected:{len(long_targets)}')

            if long_targets:
                long_targets = list(set(long_targets))
                df = get_entities(provider='eastmoney', entity_schema=Stock, entity_ids=long_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('report2 sched error:{}'.format(e))
            time.sleep(60 * 3)


if __name__ == '__main__':
    init_log('report2.log')

    every_day_report()

    sched.start()

    sched._thread.join()
Exemple #9
0
logger = logging.getLogger(__name__)

sched = BackgroundScheduler()


@sched.scheduled_job('cron', hour=16, minute=00)
def run():
    while True:
        try:
            week_kdata = ChinaStockKdataRecorder(
                level=IntervalLevel.LEVEL_1WEEK)
            week_kdata.run()

            mon_kdata = ChinaStockKdataRecorder(level=IntervalLevel.LEVEL_1MON)
            mon_kdata.run()

            break
        except Exception as e:
            logger.exception('quote runner error:{}'.format(e))
            time.sleep(60)


if __name__ == '__main__':
    init_log('eastmoney_quote.log')

    run()

    sched.start()

    sched._thread.join()
Exemple #10
0
            # CashFlowStatement.record_data(codes=['300628'],provider='emquantapi')
            # IncomeStatement.record_data(codes=['300628'],provider='emquantapi')
            FinanceDerivative.record_data(codes=['300628'],
                                          provider='emquantapi')
            # BalanceSheet.record_data(codes=['300628'],provider='emquantapi')
            # {
            # None: zvt.recorders.emquantapi.finance_qtr.china_stock_income_statement_qtr_recorder.ChinaStockIncomeStatementQtrRecorder}
            # ManagerTrading.record_data(provider='eastmoney')
            # TopTenHolder.record_data(provider='eastmoney')
            # TopTenTradableHolder.record_data(provider='eastmoney')

            # email_action.send_message("*****@*****.**", 'eastmoney runner2 finished', '')
            break
        except Exception as e:
            msg = f'eastmoney runner2 error:{e}'
            logger.exception(msg)

            email_action.send_message("*****@*****.**",
                                      'eastmoney runner2 error', msg)
            time.sleep(60)


if __name__ == '__main__':
    init_log('emquantapi_data_runner.log')

    run()

    sched.start()

    sched._thread.join()
Exemple #11
0

__all__ = ['YahooUsStockKdataRecorder']

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--level',
                        help='trading level',
                        default='1d',
                        choices=[item.value for item in IntervalLevel])
    parser.add_argument('--codes', help='codes', default=['000001'], nargs='+')

    args = parser.parse_args()

    level = IntervalLevel(args.level)
    codes = args.codes

    init_log('yahoo_us_stock_{}_kdata.log'.format(args.level))
    YahooUsStockKdataRecorder(level=level,
                              sleeping_time=0,
                              codes=codes,
                              real_time=False,
                              adjust_type=AdjustType.hfq).run()

    print(
        get_kdata(region=Region.US,
                  entity_id='stock_nyse_a',
                  limit=10,
                  order=Stock1dKdata.timestamp.desc(),
                  adjust_type=AdjustType.hfq))
Exemple #12
0
                    pass
                eastmoneypy.create_group('躺尸一年')
                for entity_id in vol_df.index[:50]:
                    _, _, code = decode_entity_id(entity_id)
                    eastmoneypy.add_to_group(code=code, group_name='躺尸一年')
            except Exception as e:
                logger.exception(e)
                email_action.send_message("*****@*****.**", f'report_top_stats error',
                                          'report_top_stats error:{}'.format(e))

    for s in stats:
        msg = msg + s + '\n'

    for up in ups:
        msg = msg + up + '\n'

    for down in downs:
        msg = msg + down + '\n'

    email_action.send_message('*****@*****.**', f'{current_timestamp} 统计报告', msg)


if __name__ == '__main__':
    init_log('report_top_stats.log')

    report_top_stats()

    sched.start()

    sched._thread.join()
                        help='exchanges',
                        default='binance',
                        nargs='+',
                        choices=[item for item in COIN_EXCHANGES])
    parser.add_argument('--codes',
                        help='codes',
                        default='EOS/USDT',
                        nargs='+',
                        choices=[item for item in COIN_PAIRS])

    args = parser.parse_args()

    level = IntervalLevel(args.level)

    exchanges = args.exchanges
    if type(exchanges) != list:
        exchanges = [exchanges]

    codes = args.codes
    if type(codes) != list:
        codes = [codes]

    init_log('coin_{}_{}_{}_kdata.log'.format('-'.join(exchanges),
                                              '-'.join(codes).replace('/', ''),
                                              args.level))

    CoinKdataRecorder(exchanges=exchanges,
                      codes=codes,
                      level=level,
                      real_time=True).run()
Exemple #14
0
        security_item = param["security_item"]
        size = param["size"]

        url = ChinaETFDayKdataRecorder.url.format(security_item.exchange,
                                                  security_item.code, size)

        response = requests.get(url)
        response_json = demjson3.decode(response.text)

        if response_json is None or len(response_json) == 0:
            return []

        df = pd.DataFrame(response_json)
        df.rename(columns={"day": "timestamp"}, inplace=True)
        df["timestamp"] = pd.to_datetime(df["timestamp"])
        df["name"] = security_item.name
        df["provider"] = "sina"
        df["level"] = param["level"]

        return df.to_dict(orient="records")


__all__ = ["ChinaETFDayKdataRecorder"]

if __name__ == "__main__":
    init_log("sina_china_etf_day_kdata.log")
    ChinaETFDayKdataRecorder(level=IntervalLevel.LEVEL_1DAY).run()
# the __all__ is generated
__all__ = ["ChinaETFDayKdataRecorder"]
Exemple #15
0
            if long_targets:
                stocks = get_entities(provider='joinquant', entity_schema=Stock, entity_ids=long_targets,
                                      return_type='domain')
                info = [f'{stock.name}({stock.code})' for stock in stocks]
                msg = ' '.join(info)
            else:
                msg = 'no targets'

            logger.info(msg)

            email_action.send_message(['*****@*****.**','*****@*****.**','*****@*****.**','*****@*****.**'], f'{to_time_str(target_date)} 核心资产选股结果', msg)

            break
        except Exception as e:
            logger.exception('report_core_company error:{}'.format(e))
            time.sleep(60 * 3)
            error_count = error_count + 1
            if error_count == 10:
                email_action.send_message("*****@*****.**", f'report_core_company error',
                                          'report_core_company error:{}'.format(e))


if __name__ == '__main__':
    init_log('report_core_company.log')

    report_core_company()

    sched.start()

    sched._thread.join()
Exemple #16
0
                        "*****@*****.**", f'report_vol_up_120 error',
                        'report_vol_up_120 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} 改进版放量突破半年线选股结果', msg)

            break
        except Exception as e:
            logger.exception('report_vol_up_120 error:{}'.format(e))
            time.sleep(60 * 3)
            error_count = error_count + 1
            if error_count == 10:
                email_action.send_message(
                    "*****@*****.**", f'report_vol_up_120 error',
                    'report_vol_up_120 error:{}'.format(e))


if __name__ == '__main__':
    init_log('report_vol_up_120.log')

    report_vol_up_120()

    sched.start()

    sched._thread.join()

__all__ = ['BaoChinaStockKdataRecorder']

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--level',
                        help='trading level',
                        default='1d',
                        choices=[item.value for item in IntervalLevel])
    parser.add_argument('--codes', help='codes', default=['000001'], nargs='+')

    args = parser.parse_args()

    level = IntervalLevel(args.level)
    codes = args.codes

    init_log('bao_china_stock_{}_kdata.log'.format(args.level))
    BaoChinaStockKdataRecorder(level=level,
                               sleeping_time=0,
                               codes=codes,
                               real_time=False,
                               adjust_type=AdjustType.hfq).run()

    print(
        get_kdata(region=Region.CHN,
                  entity_id='stock_sz_000001',
                  limit=10,
                  order=Stock1dHfqKdata.timestamp.desc(),
                  adjust_type=AdjustType.hfq))
Exemple #18
0
    )

    report_top_entities(
        entity_type="stockhk",
        entity_provider="em",
        data_provider="em",
        top_count=20,
        periods=[365, 750],
        ignore_new_stock=True,
        ignore_st=False,
        adjust_type=None,
        turnover_threshold=50000000,
        turnover_rate_threshold=0.005,
        informer=email_informer,
        em_group="谁有我惨",
        em_group_over_write=False,
        return_type=TopType.negative,
    )


if __name__ == "__main__":
    init_log("report_tops.log")

    report_top_stocks()
    report_top_blocks()
    report_top_stockhks()

    sched.start()

    sched._thread.join()
Exemple #19
0
    while True:
        email_action = EmailInformer()

        try:
            # 日线前复权和后复权数据
            # Stock1dKdata.record_data(provider='joinquant', sleeping_time=0)
            Stock1dHfqKdata.record_data(provider='joinquant', sleeping_time=0)
            StockMoneyFlow.record_data(provider='joinquant',
                                       sleeping_time=0,
                                       compute_index_money_flow=True)
            email_action.send_message("*****@*****.**",
                                      'joinquant record kdata finished', '')
            break
        except Exception as e:
            msg = f'joinquant record kdata:{e}'
            logger.exception(msg)

            email_action.send_message("*****@*****.**",
                                      'joinquant record kdata error', msg)
            time.sleep(60)


if __name__ == '__main__':
    init_log('joinquant_data_runner1.log')

    record_kdata()

    sched.start()

    sched._thread.join()
Exemple #20
0
    report_targets(
        factor_cls=VolumeUpMaFactor,
        entity_provider="em",
        data_provider="em",
        informer=email_informer,
        em_group="年线股票",
        title="放量突破(半)年线港股",
        entity_type="stockhk",
        em_group_over_write=False,
        filter_by_volume=False,
        adjust_type=AdjustType.hfq,
        start_timestamp="2019-01-01",
        # factor args
        windows=[120, 250],
        over_mode="or",
        up_intervals=20,
        turnover_threshold=100000000,
        turnover_rate_threshold=0.01,
    )


if __name__ == "__main__":
    init_log("report_vol_up.log")

    report_vol_up()

    sched.start()

    sched._thread.join()
Exemple #21
0
# -*- coding: utf-8 -*-
import logging

from apscheduler.schedulers.background import BackgroundScheduler

from zvt import init_log
from zvt.factors.ma.common import cal_ma_states
from zvt.contract.common import Region

logger = logging.getLogger(__name__)

sched = BackgroundScheduler()


@sched.scheduled_job('cron', hour=19, minute=0)
def run():
    cal_ma_states(Region.CHN, start='3000000', end='600000')


if __name__ == '__main__':
    init_log('ma_stats_runner3.log')

    run()

    sched.start()

    sched._thread.join()
Exemple #22
0
from zvt import init_log

logger = logging.getLogger(__name__)

sched = BackgroundScheduler()


@sched.scheduled_job('cron', hour=2, minute=00)
def run():
    while True:
        try:
            DividendFinancingRecorder().run()
            RightsIssueDetailRecorder().run()
            SPODetailRecorder().run()
            DividendDetailRecorder().run()

            break
        except Exception as e:
            logger.exception('dividend_financing runner error:{}'.format(e))
            time.sleep(60)


if __name__ == '__main__':
    init_log('eastmoney_dividend_financing.log')

    run()

    sched.start()

    sched._thread.join()
Exemple #23
0
                           filters=[Etf1dKdata.cumulative_net_value.is_(None)])

        if kdatas and len(kdatas) > 0:
            start = kdatas[0].timestamp
            end = kdatas[-1].timestamp

            # 从东方财富获取基金累计净值
            df = self.fetch_cumulative_net_value(entity, start, end,
                                                 http_session)

            if pd_is_not_null(df):
                for kdata in kdatas:
                    if kdata.timestamp in df.index:
                        kdata.cumulative_net_value = df.loc[kdata.timestamp,
                                                            'LJJZ']
                        kdata.change_pct = df.loc[kdata.timestamp, 'JZZZL']
                session = get_db_session(region=self.region,
                                         provider=self.provider,
                                         data_schema=self.data_schema)
                session.commit()
                self.logger.info(f'{entity.code} - {entity.name}累计净值更新完成...')


__all__ = ['ChinaETFDayKdataRecorder']

if __name__ == '__main__':
    from zvt import init_log

    init_log('sina_china_etf_day_kdata.log')
    ChinaETFDayKdataRecorder(level=IntervalLevel.LEVEL_1DAY).run()
Exemple #24
0
                    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))


if __name__ == '__main__':
    init_log('report_state.log')

    report_state()

    sched.start()

    sched._thread.join()
Exemple #25
0
                    'provider': 'ccxt',
                    # 'id': trade['id'],
                    'level': 'tick',
                    'order': trade['order'],
                    'timestamp': to_pd_timestamp(trade['timestamp']),
                    'price': trade['price'],
                    'volume': trade['amount'],
                    'direction': trade['side'],
                    'order_type': trade['type'],
                    'turnover': trade['price'] * trade['amount']
                }
                kdata_list.append(kdata_json)

            return kdata_list
        else:
            self.logger.warning("exchange:{} not support fetchOHLCV".format(entity.exchange))


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--exchanges', help='exchanges', default='binance', nargs='+',
                        choices=[item for item in COIN_EXCHANGES])
    parser.add_argument('--codes', help='codes', default='EOS/USDT', nargs='+',
                        choices=[item for item in COIN_PAIRS])

    args = parser.parse_args()

    init_log('coin_tick_kdata.log')

    CoinTickRecorder(codes=['EOS/USDT']).run()
Exemple #26
0
from zvt_tm.factors.tsi_factor import TSIFactor
from zvt_tm.informer.tradingview_informer import add_list_to_group

logger = logging.getLogger(__name__)


def to_tradingview_code(code, exchange):
    code = code.replace('/', '')
    if exchange == 'binance':
        return f'BINANCE:{code}'
    elif exchange == 'huobipro':
        return f'HUOBI:{code}'


if __name__ == '__main__':
    init_log('repot_crypto_tsi.log')
    print('start')
    start_from_last_n_day_num = 320
    target_date = now_pd_timestamp() - timedelta(1)
    start_date = target_date - timedelta(start_from_last_n_day_num)
    COIN_EXCHANGES = ["binance"]
    items = get_entities(entity_type='coin', provider='ccxt', exchanges=COIN_EXCHANGES)
    entity_ids = [eid for eid in items['entity_id'].to_list() if "USDT" in eid]

    factor = TSIFactor(entity_schema=Coin, entity_ids=entity_ids, provider='ccxt', level=IntervalLevel.LEVEL_1DAY,
                       start_timestamp=start_date, need_persist=False)
    df = factor.result_df
    musts = []
    if len(df.columns) > 1:
        s = df.agg("and", axis="columns")
        s.name = 'score'
Exemple #27
0
                                      return_type='domain')
                info = [f'{stock.name}({stock.code})' for stock in stocks]
                msg = ' '.join(info)
            else:
                msg = 'no targets'

            logger.info(msg)

            email_action.send_message("*****@*****.**",
                                      f'{target_date} 均线选股结果', msg)

            break
        except Exception as e:
            logger.exception('report_cross_ma error:{}'.format(e))
            time.sleep(60 * 3)
            error_count = error_count + 1
            if error_count == 10:
                email_action.send_message("*****@*****.**",
                                          f'report_cross_ma error',
                                          'report_cross_ma error:{}'.format(e))


if __name__ == '__main__':
    init_log('report_cross_ma.log')

    report_cross_ma()

    sched.start()

    sched._thread.join()
Exemple #28
0
            discord_informer.send_message(f'{target_date} TM选股结果 {msg}')

            break
        except Exception as e:
            logger.exception('report_tm error:{}'.format(e))
            time.sleep(60 * 3)
            error_count = error_count + 1
            if error_count == 10:
                discord_informer.send_message(f'report_tm error',
                                              'report_tm error:{}'.format(e))


def get_turning_point(df, timestamp):
    if pd_is_not_null(df):
        if timestamp in df.index:
            df['difference'] = df.groupby('entity_id')['timestamp'].diff().fillna(0)
            df = df[df['difference'] > timedelta(days=1)]
            target_df = df.loc[[to_pd_timestamp(timestamp)], :]
            return target_df['entity_id'].tolist()
    return []


if __name__ == '__main__':
    init_log('repot_crypto_tm.log')
    report_tm()

    sched.start()

    sched._thread.join()
Exemple #29
0
                blocks: List[Block] = Block.query_data(
                    provider='sina',
                    entity_ids=concept_long_blocks,
                    return_type='domain')

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

            logger.info(msg)
            email_action.send_message('*****@*****.**',
                                      f'{target_date} 资金流入板块评分结果', msg)
            break
        except Exception as e:
            logger.exception('report_block error:{}'.format(e))
            time.sleep(60 * 3)
            error_count = error_count + 1
            if error_count == 10:
                email_action.send_message("*****@*****.**",
                                          f'report_block error',
                                          'report_block error:{}'.format(e))


if __name__ == '__main__':
    init_log('report_block.log')

    report_block()

    sched.start()

    sched._thread.join()
Exemple #30
0
    df = Stock1dHfqKdata.query_data(
        provider=data_provider,
        entity_ids=selected,
        filters=[
            Stock1dHfqKdata.turnover_rate > 0.02,
            Stock1dHfqKdata.timestamp == to_pd_timestamp(target_date),
            Stock1dHfqKdata.turnover > 300000000,
        ],
        index=["entity_id"],
    )
    inform(
        action=email_action,
        entity_ids=df.index.tolist(),
        target_date=current_date(),
        title="report 龙虎榜",
        entity_provider=entity_provider,
        entity_type="stock",
        em_group="重要指数",
        em_group_over_write=False,
    )


if __name__ == "__main__":
    init_log("trading_runner.log")

    record_dragon_tiger()

    sched.start()

    sched._thread.join()