示例#1
0
文件: plates.py 项目: sjm44/czsc
    def __init__(self,
                 results_path: str,
                 sdt: str,
                 edt: str,
                 dc: TsDataCache,
                 get_signals: Callable,
                 get_event: Callable,
                 ths_index_type='N',
                 verbose: bool = False):
        """

        :param results_path: 结果保存路径
        :param sdt: 开始日期
        :param edt: 结束日期
        :param dc: 数据缓存对象
        :param get_signals: 信号获取函数
        :param get_event: 事件定义函数
        :param ths_index_type: 同花顺指数类型 N-板块指数 I-行业指数 S-同花顺特色指数
        :param verbose: 是否返回更详细的执行过程
        """
        self.name = self.__class__.__name__
        self.dc = dc
        self.get_signals = get_signals
        self.get_event = get_event
        self.event = get_event()
        self.base_freq = Freq.D.value
        self.freqs = [Freq.W.value, Freq.M.value]
        self.dc = dc
        self.ths_index_type = ths_index_type
        self.verbose = verbose
        self.cache = dict()
        self.results_path = results_path
        os.makedirs(self.results_path, exist_ok=True)

        self.sdt = sdt
        self.edt = edt
        self.file_docx = os.path.join(results_path, f'{self.event.name}_{self.ths_index_type}_{sdt}_{edt}.docx')
        writer = WordWriter(self.file_docx)
        if not os.path.exists(self.file_docx):
            writer.add_title(f"同花顺指数({self.ths_index_type})感应器报告")
            writer.add_page_break()
            writer.add_heading(f"{datetime.now().strftime('%Y-%m-%d %H:%M')} {self.event.name}", level=1)

            writer.add_heading("参数配置", level=2)
            writer.add_paragraph(f"测试方法描述:{self.event.name}")
            writer.add_paragraph(f"测试起止日期:{sdt} ~ {edt}")
            writer.add_paragraph(f"信号计算函数:\n{inspect.getsource(self.get_signals)}")
            writer.add_paragraph(f"事件具体描述:\n{inspect.getsource(self.get_event)}")
            writer.save()
        self.writer = writer
        self.file_ssd = os.path.join(results_path, f'ths_all_strong_days_{self.ths_index_type}.pkl')
        if os.path.exists(self.file_ssd):
            self.ssd, self.cache = io.read_pkl(self.file_ssd)
        else:
            self.ssd = self.get_all_strong_days()
            io.save_pkl([self.ssd, self.cache], self.file_ssd)

        self.betas = get_index_beta(dc, sdt, edt, freq='D',
                                    indices=['000001.SH', '000016.SH', '000905.SH',
                                             '000300.SH', '399001.SZ', '399006.SZ'])
示例#2
0
    def __init__(self, results_path: str, sdt: str, edt: str, dc: TsDataCache,
                 base_freq: str, freqs: List[str], get_signals: Callable,
                 get_factors: Callable):

        self.name = self.__class__.__name__
        self.version = "V20211213"
        os.makedirs(results_path, exist_ok=True)
        self.results_path = results_path
        self.sdt = sdt
        self.edt = edt

        self.get_signals = get_signals
        self.get_factors = get_factors
        self.factors: List[Factor] = get_factors()
        self.base_freq = base_freq
        self.freqs = freqs
        self.file_docx = os.path.join(results_path,
                                      f'factors_sensor_{sdt}_{edt}.docx')
        self.writer = WordWriter(self.file_docx)

        self.dc = dc
        self.betas = [
            '000001.SH', '000016.SH', '000905.SH', '000300.SH', '399001.SZ',
            '399006.SZ'
        ]

        self.file_sf = os.path.join(results_path, f'factors_{sdt}_{edt}.pkl')
        self.signals_path = os.path.join(results_path, 'signals')
        os.makedirs(self.signals_path, exist_ok=True)
        if os.path.exists(self.file_sf):
            self.sf = io.read_pkl(self.file_sf)
        else:
            self.sf = self.get_stock_factors()
            io.save_pkl(self.sf, self.file_sf)
示例#3
0
    def __init__(self, results_path: str, sdt: str, edt: str, dc: TsDataCache,
                 get_signals: Callable, get_event: Callable):
        """

        :param results_path: 结果保存路径
        :param sdt: 开始日期
        :param edt: 结束日期
        :param dc: 数据缓存对象
        :param get_signals: 信号计算函数
        :param get_event: 事件定义函数
        """
        self.name = self.__class__.__name__
        self.version = "V20211213"
        os.makedirs(results_path, exist_ok=True)
        self.results_path = results_path
        self.sdt = sdt
        self.edt = edt

        self.get_signals = get_signals
        self.get_event = get_event
        self.event: Event = get_event()
        self.base_freq = Freq.D.value
        self.freqs = [Freq.W.value, Freq.M.value]

        self.file_docx = os.path.join(results_path,
                                      f'{self.event.name}_{sdt}_{edt}.docx')
        writer = WordWriter(self.file_docx)
        if not os.path.exists(self.file_docx):
            writer.add_title("股票选股强度验证")
            writer.add_page_break()
            writer.add_heading(
                f"{datetime.now().strftime('%Y-%m-%d %H:%M')} {self.event.name}",
                level=1)

            writer.add_heading("参数配置", level=2)
            writer.add_paragraph(f"测试方法描述:{self.event.name}")
            writer.add_paragraph(f"测试起止日期:{sdt} ~ {edt}")
            writer.add_paragraph(
                f"信号计算函数:\n{inspect.getsource(self.get_signals)}")
            writer.add_paragraph(
                f"事件具体描述:\n{inspect.getsource(self.get_event)}")
            writer.save()
        self.writer = writer

        self.dc = dc
        self.betas = ['000905.SH', '000300.SH', '399006.SZ']
        self.all_cache = dict()
        self.res_cache = dict()
        self.file_ssd = os.path.join(results_path, 'stocks_strong_days.pkl')
        if os.path.exists(self.file_ssd):
            self.ssd = io.read_pkl(self.file_ssd)
        else:
            self.ssd = self.get_stocks_strong_days(
            )  # ssd 是 stocks_strong_days 的缩写,表示全市场股票的强势日期
            io.save_pkl(self.ssd, self.file_ssd)
示例#4
0
    def get_stock_factors(self):
        """获取全部股票的因子信息"""
        stocks = self.dc.stock_basic()

        all_factors = []
        for row in tqdm(stocks.to_dict('records'), desc="get_stock_factors"):
            ts_code = row['ts_code']
            name = row['name']
            try:
                signals, factors = self.get_share_factors(ts_code, name)
                all_factors.append(factors)
                file_signals = os.path.join(self.signals_path,
                                            f'{ts_code}.pkl')
                io.save_pkl(signals, file_signals)
            except:
                print(f"get_share_factors error: {ts_code}, {name}")
                traceback.print_exc()

        df_factors = pd.concat(all_factors, ignore_index=True)
        return df_factors
示例#5
0
def monitor(use_cache=True):
    push_text("自选股CZSC笔因子监控启动 @ {}".format(datetime.now().strftime("%Y-%m-%d %H:%M")), qywx_key)
    moni_path = os.path.join(ct_path, "monitor")
    # 首先清空历史快照
    if os.path.exists(moni_path):
        shutil.rmtree(moni_path)
    os.makedirs(moni_path, exist_ok=True)

    for s in symbols:
        print(s)
        try:
            file_ct = os.path.join(ct_path, "{}.ct".format(s))
            if os.path.exists(file_ct) and use_cache:
                ct: CzscTrader = read_pkl(file_ct)
                ct.update_factors()
            else:
                ct = CzscTrader(s, max_count=1000)
            save_pkl(ct, file_ct)

            # 每次执行,会在moni_path下面保存一份快照
            file_html_ = os.path.join(moni_path, f"{ct.symbol}_{ct.kf.end_dt.strftime('%Y%m%d%H%M')}.html")
            ct.take_snapshot(file_html_, width="1400px", height="580px")

            if ct.s['日线笔因子'] != Factors.Other.value:
                msg = "{} - {}\n".format(s, ct.s['日线笔因子'])
                msg += "同花顺F10:http://basic.10jqka.com.cn/{}".format(s[:6])
                push_text(msg, key=qywx_key)
                file_html_new = os.path.join(moni_path, f"{ct.symbol}_{ct.kf.end_dt.strftime('%Y%m%d%H%M')}.html")
                shutil.copyfile(file_html_, file_html_new)
                push_file(file_html_new, key=qywx_key)

        except Exception as e:
            traceback.print_exc()
            print("{} 执行失败 - {}".format(s, e))

    push_text("自选股CZSC笔因子监控结束 @ {}".format(datetime.now().strftime("%Y-%m-%d %H:%M")), qywx_key)
示例#6
0
文件: selector.py 项目: scanfyu/czsc
def stocks_dwm_selector(event: Event,
                        get_signals: Callable,
                        max_count: int = 3000,
                        end_date: [str, datetime] = datetime.now(),
                        wx_key=None):
    """大级别选股(日线&月线&周线)"""
    if isinstance(end_date, str):
        end_date = pd.to_datetime(end_date)
    kgd_path = "./data/kgd"
    os.makedirs(kgd_path, exist_ok=True)

    df = get_instruments(exchanges='SZSE,SHSE',
                         sec_types=1,
                         fields="symbol,sec_name",
                         df=True)
    records = df.to_dict('records')

    home_path = os.path.expanduser('~')

    push_text(content="start running selector", key=wx_key)
    results = []
    for row in tqdm(records, desc=f"{end_date} - get signals"):
        symbol = row['symbol']
        try:
            file_kgd = os.path.join(kgd_path, f'{symbol}.kgd')
            if os.path.exists(file_kgd):
                kgd: KlineGeneratorD = read_pkl(file_kgd)
                if kgd.end_dt.date() != datetime.now().date() and datetime.now(
                ).isoweekday() <= 5:
                    k0 = get_kline(symbol,
                                   freq="1d",
                                   end_time=datetime.now(),
                                   count=1)
                    k0 = [x for x in k0 if x.dt > kgd.end_dt]
                    if k0:
                        print(k0)
                        for bar in k0:
                            kgd.update(bar)
            else:
                k0 = get_kline(symbol,
                               end_time=end_date,
                               freq='1d',
                               count=10000,
                               adjust=ADJUST_PREV)
                kgd = KlineGeneratorD()
                for bar in k0:
                    kgd.update(bar)
            save_pkl(kgd, file_kgd)
            # assert kgd.end_dt.date() == datetime.now().date(), f"kgd.end_dt = {kgd.end_dt}"

            last_vols = [
                k_.open * k_.vol for k_ in kgd.bars[Freq.D.value][-10:]
            ]
            if min(last_vols) < 1e8:
                continue

            c0 = CZSC(kgd.bars[Freq.D.value][-max_count:],
                      get_signals=get_signals)
            c1 = CZSC(kgd.bars[Freq.W.value][-max_count:],
                      get_signals=get_signals)
            c2 = CZSC(kgd.bars[Freq.M.value][-max_count:],
                      get_signals=get_signals)

            s = OrderedDict(row)
            s.update(c0.signals)
            s.update(c1.signals)
            s.update(c2.signals)

            m, f = event.is_match(s)
            if m:
                msg = f"{s['sec_name']}: {f}\n"
                msg += f"最新时间:{kgd.end_dt.strftime(dt_fmt)}\n"
                msg += f"同花顺F10:http://basic.10jqka.com.cn/{symbol.split('.')[1]}\n"
                msg += f"新浪行情:https://finance.sina.com.cn/realstock/company/{symbol[:2].lower()}{symbol[-6:]}/nc.shtml"
                push_text(content=msg, key=wx_key)

                res = {
                    'symbol':
                    symbol,
                    'name':
                    s['sec_name'],
                    'reason':
                    f,
                    'end_dt':
                    kgd.end_dt.strftime(dt_fmt),
                    'F10':
                    f"http://basic.10jqka.com.cn/{symbol.split('.')[1]}",
                    'Kline':
                    f"https://finance.sina.com.cn/realstock/company/{symbol[:2].lower()}{symbol[-6:]}/nc.shtml"
                }
                results.append(res)
                print(res)
        except:
            print("fail on {}".format(symbol))
            traceback.print_exc()

    file_results = os.path.join(
        home_path, f"selector_results_{end_date.strftime('%Y%m%d')}.xlsx")
    df_r = pd.DataFrame(results)
    df_r.to_excel(file_results, index=False)
    push_file(file_results, key=wx_key)
    push_text(content="end running selector", key=wx_key)
示例#7
0
    return s


# 通过聚宽获取最近三年的1分钟数据,生成signals,signals可以重复使用
file_signals = os.path.join(data_path, f'{symbol}_signals.pkl')
if os.path.exists(file_signals):
    signals = read_pkl(file_signals)
else:
    f1_raw_bars = jq.get_kline_period(symbol=symbol,
                                      freq='1min',
                                      start_date='20180801',
                                      end_date='20210801')
    signals = generate_signals(f1_raw_bars,
                               init_count=50000,
                               get_signals=get_user_signals)
    save_pkl(signals, file_signals)


def evaluate_event():
    """对单个事件进行表现评估"""
    event = Event(name="单事件",
                  operate=Operate.LO,
                  factors=[
                      Factor(name="60分钟DIF多头向上",
                             signals_all=[
                                 Signal("60分钟_DIF_状态_多头_向上_任意_0"),
                             ]),
                  ])

    pairs1, pf1 = one_event_estimator(signals, event)
示例#8
0
def monitor(use_cache=True):
    push_text(
        "自选股CZSC笔因子监控启动 @ {}".format(
            datetime.now().strftime("%Y-%m-%d %H:%M")), qywx_key)
    moni_path = os.path.join(ct_path, "monitor")
    # 首先清空历史快照
    if os.path.exists(moni_path):
        shutil.rmtree(moni_path)
    os.makedirs(moni_path, exist_ok=True)
    events_monitor = [
        # 开多
        Event(name="一买",
              operate=Operate.LO,
              factors=[
                  Factor(name="5分钟类一买",
                         signals_all=[Signal("5分钟_倒1笔_类买卖点_类一买_任意_任意_0")]),
                  Factor(name="5分钟形一买",
                         signals_all=[Signal("5分钟_倒1笔_基础形态_类一买_任意_任意_0")]),
                  Factor(name="15分钟类一买",
                         signals_all=[Signal("15分钟_倒1笔_类买卖点_类一买_任意_任意_0")]),
                  Factor(name="15分钟形一买",
                         signals_all=[Signal("15分钟_倒1笔_基础形态_类一买_任意_任意_0")]),
                  Factor(name="30分钟类一买",
                         signals_all=[Signal("30分钟_倒1笔_类买卖点_类一买_任意_任意_0")]),
                  Factor(name="30分钟形一买",
                         signals_all=[Signal("30分钟_倒1笔_基础形态_类一买_任意_任意_0")]),
              ]),
        Event(name="二买",
              operate=Operate.LO,
              factors=[
                  Factor(name="5分钟类二买",
                         signals_all=[Signal("5分钟_倒1笔_类买卖点_类二买_任意_任意_0")]),
                  Factor(name="5分钟形二买",
                         signals_all=[Signal("5分钟_倒1笔_基础形态_类二买_任意_任意_0")]),
                  Factor(name="15分钟类二买",
                         signals_all=[Signal("15分钟_倒1笔_类买卖点_类二买_任意_任意_0")]),
                  Factor(name="15分钟形二买",
                         signals_all=[Signal("15分钟_倒1笔_基础形态_类二买_任意_任意_0")]),
                  Factor(name="30分钟类二买",
                         signals_all=[Signal("30分钟_倒1笔_类买卖点_类二买_任意_任意_0")]),
                  Factor(name="30分钟形二买",
                         signals_all=[Signal("30分钟_倒1笔_基础形态_类二买_任意_任意_0")]),
              ]),
        Event(name="三买",
              operate=Operate.LO,
              factors=[
                  Factor(name="5分钟类三买",
                         signals_all=[Signal("5分钟_倒1笔_类买卖点_类三买_任意_任意_0")]),
                  Factor(name="5分钟形三买",
                         signals_all=[Signal("5分钟_倒1笔_基础形态_类三买_任意_任意_0")]),
                  Factor(name="15分钟类三买",
                         signals_all=[Signal("15分钟_倒1笔_类买卖点_类三买_任意_任意_0")]),
                  Factor(name="15分钟形三买",
                         signals_all=[Signal("15分钟_倒1笔_基础形态_类三买_任意_任意_0")]),
                  Factor(name="30分钟类三买",
                         signals_all=[Signal("30分钟_倒1笔_类买卖点_类三买_任意_任意_0")]),
                  Factor(name="30分钟形三买",
                         signals_all=[Signal("30分钟_倒1笔_基础形态_类三买_任意_任意_0")]),
              ]),

        # 平多
        Event(name="一卖",
              operate=Operate.LE,
              factors=[
                  Factor(name="5分钟类一卖",
                         signals_all=[Signal("5分钟_倒1笔_类买卖点_类一卖_任意_任意_0")]),
                  Factor(name="5分钟形一卖",
                         signals_all=[Signal("5分钟_倒1笔_基础形态_类一卖_任意_任意_0")]),
                  Factor(name="15分钟类一卖",
                         signals_all=[Signal("15分钟_倒1笔_类买卖点_类一卖_任意_任意_0")]),
                  Factor(name="15分钟形一卖",
                         signals_all=[Signal("15分钟_倒1笔_基础形态_类一卖_任意_任意_0")]),
                  Factor(name="30分钟类一卖",
                         signals_all=[Signal("30分钟_倒1笔_类买卖点_类一卖_任意_任意_0")]),
                  Factor(name="30分钟形一卖",
                         signals_all=[Signal("30分钟_倒1笔_基础形态_类一卖_任意_任意_0")]),
              ]),
        Event(name="二卖",
              operate=Operate.LE,
              factors=[
                  Factor(name="5分钟类二卖",
                         signals_all=[Signal("5分钟_倒1笔_类买卖点_类二卖_任意_任意_0")]),
                  Factor(name="5分钟形二卖",
                         signals_all=[Signal("5分钟_倒1笔_基础形态_类二卖_任意_任意_0")]),
                  Factor(name="15分钟类二卖",
                         signals_all=[Signal("15分钟_倒1笔_类买卖点_类二卖_任意_任意_0")]),
                  Factor(name="15分钟形二卖",
                         signals_all=[Signal("15分钟_倒1笔_基础形态_类二卖_任意_任意_0")]),
                  Factor(name="30分钟类二卖",
                         signals_all=[Signal("30分钟_倒1笔_类买卖点_类二卖_任意_任意_0")]),
                  Factor(name="30分钟形二卖",
                         signals_all=[Signal("30分钟_倒1笔_基础形态_类二卖_任意_任意_0")]),
              ]),
        Event(name="三卖",
              operate=Operate.LE,
              factors=[
                  Factor(name="5分钟类三卖",
                         signals_all=[Signal("5分钟_倒1笔_类买卖点_类三卖_任意_任意_0")]),
                  Factor(name="5分钟形三卖",
                         signals_all=[Signal("5分钟_倒1笔_基础形态_类三卖_任意_任意_0")]),
                  Factor(name="15分钟类三卖",
                         signals_all=[Signal("15分钟_倒1笔_类买卖点_类三卖_任意_任意_0")]),
                  Factor(name="15分钟形三卖",
                         signals_all=[Signal("15分钟_倒1笔_基础形态_类三卖_任意_任意_0")]),
                  Factor(name="30分钟类三卖",
                         signals_all=[Signal("30分钟_倒1笔_类买卖点_类三卖_任意_任意_0")]),
                  Factor(name="30分钟形三卖",
                         signals_all=[Signal("30分钟_倒1笔_基础形态_类三卖_任意_任意_0")]),
              ]),
    ]
    for s in symbols:
        print(s)
        try:
            file_ct = os.path.join(ct_path, "{}.ct".format(s))
            if os.path.exists(file_ct) and use_cache:
                ct: CzscTrader = read_pkl(file_ct)
                ct.update_factors()
            else:
                ct = CzscTrader(s, max_count=1000)
            save_pkl(ct, file_ct)

            # 每次执行,会在moni_path下面保存一份快照
            file_html = os.path.join(
                moni_path,
                f"{ct.symbol}_{ct.end_dt.strftime('%Y%m%d%H%M')}.html")
            ct.take_snapshot(file_html, width="1400px", height="580px")

            msg = f"标的代码:{s}\n同花顺F10:http://basic.10jqka.com.cn/{s.split('.')[0]}\n"
            for event in events_monitor:
                m, f = event.is_match(ct.s)
                if m:
                    msg += "监控提醒:{}@{}\n".format(event.name, f)

            if "监控提醒" in msg:
                push_text(msg.strip("\n"), key=qywx_key)

        except Exception as e:
            traceback.print_exc()
            print("{} 执行失败 - {}".format(s, e))

    push_text(
        "自选股CZSC笔因子监控结束 @ {}".format(
            datetime.now().strftime("%Y-%m-%d %H:%M")), qywx_key)
示例#9
0
文件: monitor.py 项目: sjm44/czsc
def stocks_monitor(symbols, wx_key):
    """对实盘股票池进行定时监控"""
    events = [
        # 开多
        Event(name="一买", operate=Operate.LO, factors=[
            Factor(name="5分钟类一买", signals_all=[Signal("5分钟_倒1笔_类买卖点_类一买_任意_任意_0")]),
            Factor(name="5分钟形一买", signals_all=[Signal("5分钟_倒1笔_基础形态_类一买_任意_任意_0")]),

            Factor(name="15分钟类一买", signals_all=[Signal("15分钟_倒1笔_类买卖点_类一买_任意_任意_0")]),
            Factor(name="15分钟形一买", signals_all=[Signal("15分钟_倒1笔_基础形态_类一买_任意_任意_0")]),

            Factor(name="30分钟类一买", signals_all=[Signal("30分钟_倒1笔_类买卖点_类一买_任意_任意_0")]),
            Factor(name="30分钟形一买", signals_all=[Signal("30分钟_倒1笔_基础形态_类一买_任意_任意_0")]),
        ]),

        Event(name="二买", operate=Operate.LO, factors=[
            Factor(name="5分钟类二买", signals_all=[Signal("5分钟_倒1笔_类买卖点_类二买_任意_任意_0")]),
            Factor(name="5分钟形二买", signals_all=[Signal("5分钟_倒1笔_基础形态_类二买_任意_任意_0")]),

            Factor(name="15分钟类二买", signals_all=[Signal("15分钟_倒1笔_类买卖点_类二买_任意_任意_0")]),
            Factor(name="15分钟形二买", signals_all=[Signal("15分钟_倒1笔_基础形态_类二买_任意_任意_0")]),

            Factor(name="30分钟类二买", signals_all=[Signal("30分钟_倒1笔_类买卖点_类二买_任意_任意_0")]),
            Factor(name="30分钟形二买", signals_all=[Signal("30分钟_倒1笔_基础形态_类二买_任意_任意_0")]),
        ]),
        Event(name="三买", operate=Operate.LO, factors=[
            Factor(name="5分钟类三买", signals_all=[Signal("5分钟_倒1笔_类买卖点_类三买_任意_任意_0")]),
            Factor(name="5分钟形三买", signals_all=[Signal("5分钟_倒1笔_基础形态_类三买_任意_任意_0")]),

            Factor(name="15分钟类三买", signals_all=[Signal("15分钟_倒1笔_类买卖点_类三买_任意_任意_0")]),
            Factor(name="15分钟形三买", signals_all=[Signal("15分钟_倒1笔_基础形态_类三买_任意_任意_0")]),

            Factor(name="30分钟类三买", signals_all=[Signal("30分钟_倒1笔_类买卖点_类三买_任意_任意_0")]),
            Factor(name="30分钟形三买", signals_all=[Signal("30分钟_倒1笔_基础形态_类三买_任意_任意_0")]),
        ]),

        # 平多
        Event(name="一卖", operate=Operate.LE, factors=[
            Factor(name="5分钟类一卖", signals_all=[Signal("5分钟_倒1笔_类买卖点_类一卖_任意_任意_0")]),
            Factor(name="5分钟形一卖", signals_all=[Signal("5分钟_倒1笔_基础形态_类一卖_任意_任意_0")]),

            Factor(name="15分钟类一卖", signals_all=[Signal("15分钟_倒1笔_类买卖点_类一卖_任意_任意_0")]),
            Factor(name="15分钟形一卖", signals_all=[Signal("15分钟_倒1笔_基础形态_类一卖_任意_任意_0")]),

            Factor(name="30分钟类一卖", signals_all=[Signal("30分钟_倒1笔_类买卖点_类一卖_任意_任意_0")]),
            Factor(name="30分钟形一卖", signals_all=[Signal("30分钟_倒1笔_基础形态_类一卖_任意_任意_0")]),
        ]),
        Event(name="二卖", operate=Operate.LE, factors=[
            Factor(name="5分钟类二卖", signals_all=[Signal("5分钟_倒1笔_类买卖点_类二卖_任意_任意_0")]),
            Factor(name="5分钟形二卖", signals_all=[Signal("5分钟_倒1笔_基础形态_类二卖_任意_任意_0")]),

            Factor(name="15分钟类二卖", signals_all=[Signal("15分钟_倒1笔_类买卖点_类二卖_任意_任意_0")]),
            Factor(name="15分钟形二卖", signals_all=[Signal("15分钟_倒1笔_基础形态_类二卖_任意_任意_0")]),

            Factor(name="30分钟类二卖", signals_all=[Signal("30分钟_倒1笔_类买卖点_类二卖_任意_任意_0")]),
            Factor(name="30分钟形二卖", signals_all=[Signal("30分钟_倒1笔_基础形态_类二卖_任意_任意_0")]),
        ]),
        Event(name="三卖", operate=Operate.LE, factors=[
            Factor(name="5分钟类三卖", signals_all=[Signal("5分钟_倒1笔_类买卖点_类三卖_任意_任意_0")]),
            Factor(name="5分钟形三卖", signals_all=[Signal("5分钟_倒1笔_基础形态_类三卖_任意_任意_0")]),

            Factor(name="15分钟类三卖", signals_all=[Signal("15分钟_倒1笔_类买卖点_类三卖_任意_任意_0")]),
            Factor(name="15分钟形三卖", signals_all=[Signal("15分钟_倒1笔_基础形态_类三卖_任意_任意_0")]),

            Factor(name="30分钟类三卖", signals_all=[Signal("30分钟_倒1笔_类买卖点_类三卖_任意_任意_0")]),
            Factor(name="30分钟形三卖", signals_all=[Signal("30分钟_倒1笔_基础形态_类三卖_任意_任意_0")]),
        ]),
    ]

    shares = get_shares()
    data_path = './data/monitor'
    os.makedirs(data_path, exist_ok=True)
    push_text("实盘池监控启动 @ {}".format(datetime.now().strftime("%Y-%m-%d %H:%M")), wx_key)

    for symbol in symbols:
        try:
            file_ct = os.path.join(data_path, "{}.ct".format(symbol))
            if os.path.exists(file_ct):
                ct: GmCzscTrader = read_pkl(file_ct)
                ct.update_factors()
            else:
                ct = GmCzscTrader(symbol, max_count=2000, get_signals=get_monitor_signals)
            save_pkl(ct, file_ct)
            print(f"run monitor on {symbol} at {ct.end_dt}")
            msg = f"标的代码:{symbol}\n标的名称:{shares.get(symbol, '')}\n" \
                  f"同花顺F10:http://basic.10jqka.com.cn/{symbol.split('.')[1]}\n"
            msg += f"新浪行情:https://finance.sina.com.cn/realstock/company/{symbol[:2].lower()}{symbol[-6:]}/nc.shtml\n"
            for event in events:
                m, f = event.is_match(ct.s)
                if m:
                    msg += "监控提醒:{}@{}\n".format(event.name, f)

            if "监控提醒" in msg:
                push_text(msg.strip("\n"), key=wx_key)

        except Exception as e:
            traceback.print_exc()
            print("{} 执行失败 - {}".format(symbol, e))
    push_text("实盘池监控结束 @ {}".format(datetime.now().strftime("%Y-%m-%d %H:%M")), wx_key)