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'])
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)
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)
def prepare_symbol_signals(file, dc): signals = io.read_pkl(file) df = pd.DataFrame(signals) keys = [x for x in df.columns if len(x.split("_")) == 3] nb = dc.pro_bar(signals[0]['symbol'], start_date=signals[0]['dt'], end_date=signals[-1]['dt'], freq='D', asset="E", raw_bar=False) df = df.merge(nb, left_on='dt', right_on='trade_date') for f in keys: if df[f].dtype == 'O' or df[f].dtype == 'bool': itm_list = list(df[f].unique()) for itm in itm_list: ecol = '%s_%s' % (f, itm) df[ecol] = df[f].apply(lambda x: 1 if x == itm else 0) return df
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)
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)
s.update(signals.get_s_d0_bi(c)) s.update(signals.get_s_three_k(c, 1)) s.update(signals.get_s_di_bi(c, 1)) s.update(signals.get_s_macd(c, 1)) s.update(signals.get_s_k(c, 1)) s.update(signals.get_s_bi_status(c)) s.update(signals.get_s_three_bi(c, di=1)) s.update(signals.get_s_base_xt(c, di=1)) s.update(signals.get_s_like_bs(c, di=1)) 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,
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)
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)