先说一个我自己的真实场景。每天收盘后我要干一件特别机械的事:把策略选出来的二十几只股票,一只一只手动加到通达信自选股里。一开始还能忍,后来选股频率提到盘中出信号,手指在键盘上按到发酸,还经常漏加、重复加。直到某天我翻了通达信的安装目录,才意识到所谓的“自选股”压根不是什么加密数据库,而是一个个明明白白的文本文件。于是我写了一个Python脚本,把整个流程压缩成一句话:关掉通达信,双击运行脚本,选股结果几十只股票一次进自选股。
这个方案适合谁?只要你平时用通达信看盘、有自己的选股结果(不管来自公式选股、Python策略还是人工筛选),并且愿意复制一段代码改个路径,就能省下每天至少十分钟的机械劳动。不需要装任何第三方库,纯Python标准库实现,Windows系统直接用。下面我把原理、完整代码和踩坑过程一次讲透。
1. 手动加自选股的痛,以及为什么我盯上了blk文件
1.1 手动流程到底有多浪费时间
先说手动操作的完整链路:打开你的选股表格或文本 → 看一只代码 → 切到通达信 → 在自选股列表里按快捷键添加 → 再切回来 → 看下一只。如果选股结果有三十只,这一套动作就要重复三十遍,还不算中途接电话、弹窗打断导致漏掉某只的情况。
更麻烦的是,很多人的选股结果是多个策略的组合。今天A策略选出10只,B策略选出8只,中间还有交集,你手动加的时候还得自己记着哪只已经加过了。一旦某天加到一半被打断,后面就很难想起来加到哪里。这个过程不只是浪费时间,还很伤心态——看盘本来就需要集中注意力,全耗在这种重复劳动上太亏了。
1.2 两条自动化路线的取舍
网上解决这个问题的方案大致分两类。
第一类是模拟键鼠:用AutoHotkey或Python的pyautogui,读取代码之后自动切到通达信输入。这个方案我试过,能用,但很脆。通达信界面只要有一点变化(弹个广告、行情卡顿、窗口位置偏移),脚本就可能敲错地方。而且模拟键鼠占着键盘鼠标,你什么都干不了,盘中根本不敢用。
第二类就是今天要讲的:直接写通达信的自选股文件。通达信的自选股本质是一个纯文本板块文件,我们只要按它的格式把代码写进去,通达信再启动时就会读到。
这两条路线我做过对比,直接写文件明显更稳、更快、可以后台运行,唯一“缺点”是写入后需要让通达信重新读取,也就是重启一次通达信。相比每天省下的十几分钟,重启一次完全值得。下面是三种方案的对比:
| 方案 | 开发成本 | 稳定性 | 是否占键盘鼠标 | 是否需要重启通达信 |
|---|---|---|---|---|
| 手动复制粘贴 | 无 | 高 | 是 | 不需要 |
| 模拟键鼠自动点击 | 中 | 低,受界面变化影响 | 是 | 不需要 |
| 直接写入blk文件 | 低 | 高 | 否 | 需要 |
2. 通达信自选股的文件真相:T0002\blocknew目录里有什么
2.1 找对目录,事情就成功了一半
通达信安装完成后,数据目录一般长这样:安装目录\T0002\blocknew。比如我的经典版装在D盘,路径就是D:\new_tdx\T0002\blocknew。但这个路径在不同版本上不完全一样,券商定制版尤其喜欢改目录名,常见的有new_tdx、zd_zsone、hexin等。所以最靠谱的办法是:右键通达信桌面快捷方式 → 打开文件所在位置 → 在安装目录下找T0002 → 进去之后看有没有blocknew文件夹。
怎么确认你找对了?看这个目录里有没有.blk文件。正常情况下,只要你在通达信里添加过自选股,blocknew目录下就会出现类似这样的文件:
Z自选股.blk ZD自选股1.blk ZD自选股2.blk其中“Z自选股.blk”就是通达信默认的自选股板块。ZD开头的则是“自选股1”“自选股2”这类扩展板块。每个.blk文件都对应通达信界面里的一个板块,文件名里的中文就是板块名。
2.2 blk文件的编码、换行和格式
用记事本打开Z自选股.blk,你会看到内容非常简单,就是一行一个六位股票代码,没有市场前缀,没有价格,没有备注。比如:
600519 000001 300750这里有几个关键细节,写脚本前必须搞明白:
第一,文件编码是GBK(简体中文Windows上通常等同于ANSI),不是UTF-8。如果写入UTF-8编码的文件,通达信解析时可能把第一行读坏。第二,行尾建议用CRLF(\r\n),虽然实测通达信对单独的\n也能容忍,但既然要写就写规范,免得某些版本读取异常。第三,代码不带sh/sz前缀,纯六位数字。沪深主板、创业板、科创板、北交所,在blk文件里都统一存六位。
2.3 那些.dat文件要不要管
blocknew目录里除了.blk,还有一堆.dat文件。这些.dat文件保存的是板块的索引信息、板块名称、关联的.blk文件路径。实测下来,往已有板块里加股票,只需要改.blk文件就够了,.dat不用动。
那什么时候需要动.dat呢?如果你要用脚本创建一个全新板块,光写.blk可能不够,通达信界面上不一定认。我的建议是:板块的创建交给通达信界面来做,在通达信里手动新建好“实验池”“备用池”之类的板块,然后脚本只负责往现有板块文件里追加代码。这样分工最省心。
容易忽略的一点:如果你在通达信里从没添加过自选股,blocknew目录可能根本没有Z自选股.blk。别慌,先去通达信里手动加一只股票,这个文件就会自动生成,之后再用脚本操作。
3. 开工之前:Python环境和目录确认这两件事别搞错
3.1 Python版本与安装检查
脚本只用Python标准库,不需要pip install任何东西。版本建议Python 3.8及以上,太老的版本有些语法可能不支持。没装Python的话,去python.org下载安装包,安装时务必勾选“Add Python to PATH”这一项,否则命令行里运行python会提示找不到命令。
装好之后,打开命令行,输入:
python --version能输出版本号就说明环境OK。如果提示“python不是内部或外部命令”,先检查是不是安装时没勾选PATH,或者安装完没重新打开命令行窗口。
3.2 找到并确认blocknew目录
这一步非常关键,很多人脚本跑不通就是路径写错了。请打开通达信安装目录,找到T0002\blocknew这个文件夹,把路径完整复制下来。如果你电脑上装了多个通达信,比如一个自用的、一个券商定制的,务必确认你日常打开的是哪一个,找到对应的那个目录。我有个朋友就是路径写到了另一个没怎么用的通达信上,脚本每次跑完都提示成功,打开常用的通达信一看,自选股纹丝不动。
如果你打开blocknew目录发现是空的,或者连blocknew目录都没有,请先启动通达信,随便加一只股票到自选股,再回来刷新看,这时候文件应该出现了。
确认好目录后,建议先手动备份一下整个blocknew目录,放到一个临时文件夹里。后面无论怎么折腾,至少能恢复。这一步只要一分钟,但能救命。
3.3 脚本文件放在哪
脚本本身放哪里都行,但我建议放在blocknew目录所在的T0002上一级,也就是通达信安装目录下新建一个scripts文件夹。理由很简单:你的Python脚本、选股结果文件、日后的定时任务都集中在一个地方,不至于满硬盘找文件。路径里有中文也没关系,Python 3在Windows下处理中文路径没有问题。
还有一个建议:不要用记事本直接编辑.blk文件然后另存为UTF-8,因为你一旦动了编码,通达信可能直接不认。折腾脚本比手工整理自选股省力得多,但前提是别把源头文件搞乱。
4. 完整代码与逐段拆解:从选股结果到自选股只有一步
4.1 这个脚本能干哪些事
先说功能范围。脚本支持:从文本文件/CSV里自动提取股票代码;命令行直接传多个代码;自动去重,已存在的代码跳过;自动备份原板块文件;检测通达信是否在运行并提醒;支持指定写入哪个板块;支持清空板块后重新写入。对于日常“增量导入”和周末“整体刷新”这两种使用场景,这套功能足够了。
4.2 完整源码
下面是完整代码,命名我建议存为import_to_tdx.py,放哪都行。代码内部控制台输出是中文,Windows下默认编码可能显示乱码,可以按下面注释里说的处理。
# -*- coding: utf-8 -*- """ 一键把选股结果导入通达信自选股(Python标准库实现) 用法示例: python import_to_tdx.py 600519 000001 python import_to_tdx.py -f result.txt python import_to_tdx.py -f result.csv -b ZD自选股1.blk python import_to_tdx.py --clear -f new_codes.txt """ import os import sys import re import shutil import argparse import datetime import subprocess # ===== 配置区:改成你的实际路径 ===== # 注意:Windows路径建议用正斜杠,或者写成 r"D:\new_tdx\T0002\blocknew" BLOCK_DIR = "D:/new_tdx/T0002/blocknew" DEFAULT_BOARD_FILE = "Z自选股.blk" # 如果命令行没传代码也没传文件,会使用这个列表(临时用) STOCK_CODES = [] # =================================== def normalize_code(raw): """把各种格式的股票代码清洗成6位字符串。""" if raw is None: return None code = str(raw).strip() # 去掉常见市场前缀,如 sh600519 / sz.000001 / bj830799 code = re.sub(r"^(sh|sz|bj|eq|of)[\.\s:_-]*", "", code, flags=re.I) # 去掉常见市场后缀,如 600519.sh / 000001.sz code = re.sub(r"[\.\s:_-]*(sh|sz|bj|eq|of)$", "", code, flags=re.I) # 如果是纯数字且位数不足6位(比如CSV里把000001读成了1),补零 stripped = re.sub(r"[^0-9]", "", code) if stripped.isdigit() and len(stripped) <= 6: code = stripped.zfill(6) if len(code) == 6: return code # 从混合文本中提取连续的6位数字 m = re.search(r"(?<!\d)(\d{6})(?!\d)", code) if m: return m.group(1) return None def is_valid_code(code): """宽松校验:6位数字就放行。把过滤责任交给选股源。""" return len(code) == 6 and code.isdigit() def parse_from_text(text): """从任意文本中提取股票代码,兼容逗号、空格、换行、中文混排。""" result = [] seen = set() for m in re.finditer(r"(?<!\d)(\d{6})(?!\d)", text): code = m.group(1) if is_valid_code(code) and code not in seen: result.append(code) seen.add(code) return result def read_text_auto(path): """自动识别UTF-8/GBK并读取文本文件。""" with open(path, "rb") as f: raw = f.read() for enc in ("utf-8-sig", "utf-8", "gbk"): try: return raw.decode(enc) except UnicodeDecodeError: continue return raw.decode("gbk", errors="ignore") def load_existing(blk_path): """读取现有blk自选股,返回(保持顺序的列表, 快速去重集合)。""" codes_list = [] codes_set = set() if not os.path.exists(blk_path): return codes_list, codes_set try: # newline=None 表示按通用换行符读取,兼容 \r\n 和 \n with open(blk_path, "r", encoding="gbk", errors="ignore", newline=None) as f: for line in f: code = normalize_code(line) if code and code not in codes_set: codes_list.append(code) codes_set.add(code) except OSError as e: print(f"读取现有自选股文件失败:{e}") return codes_list, codes_set def is_tdx_running(): """粗略检测通达信相关进程是否在运行(仅Windows)。""" try: out = subprocess.run( ["tasklist"], capture_output=True, text=True, timeout=15, creationflags=getattr(subprocess, "CREATE_NO_WINDOW", 0), ).stdout for line in out.splitlines(): parts = line.split() if not parts: continue name = parts[0].lower() if "tdx" in name: return True except Exception: pass return False def write_block(blk_path, code_list, backup=True): """把代码列表写回blk文件,手动控制行尾为CRLF,避免Python默认换行转换。""" if backup and os.path.exists(blk_path): bak = f"{blk_path}.bak_{datetime.datetime.now():%Y%m%d_%H%M%S}" shutil.copy2(blk_path, bak) print(f"原文件已备份到:{bak}") try: # newline="" 很关键:禁用Python自动换行转换,否则 \r\n 会被写成 \r\r\n with open(blk_path, "w", encoding="gbk", newline="") as f: for code in code_list: f.write(code + "\r\n") except OSError as e: print(f"写入文件失败:{e}") raise SystemExit(1) def main(): parser = argparse.ArgumentParser(description="导入选股结果到通达信自选股") parser.add_argument("codes", nargs="*", help="股票代码,如 600519 000001") parser.add_argument("-f", "--file", help="选股结果文件(txt/csv都可以)") parser.add_argument("-b", "--board", default=DEFAULT_BOARD_FILE, help="板块文件名,默认Z自选股.blk") parser.add_argument("--clear", action="store_true", help="清空目标板块后重新写入") parser.add_argument("--no-backup", action="store_true", help="写入前不备份原文件") parser.add_argument("--force", action="store_true", help="通达信正在运行时也强制写入") args = parser.parse_args() new_codes = [] if args.file: if not os.path.exists(args.file): print(f"文件不存在:{args.file}") sys.exit(1) new_codes.extend(parse_from_text(read_text_auto(args.file))) for raw in args.codes: code = normalize_code(raw) if code: new_codes.append(code) if not new_codes: for raw in STOCK_CODES: code = normalize_code(raw) if code: new_codes.append(code) # 去重,保持输入顺序 unique = [] seen = set() for code in new_codes: if code not in seen: unique.append(code) seen.add(code) if not unique: print("没有识别到有效股票代码,请检查输入。") sys.exit(1) blk_path = os.path.join(BLOCK_DIR, args.board) # 以后每次跑都提示这个,很多人会忽略 if is_tdx_running() and not args.force: print("检测到通达信正在运行。为防止通达信退出时用旧数据覆盖写入结果,请关闭通达信后再执行。") print("如果你确认自己了解风险,可以追加 --force 参数强制写入。") sys.exit(2) old_list, old_set = load_existing(blk_path) already = [c for c in unique if c in old_set] append = [c for c in unique if c not in old_set] if already: print(f"以下代码已在自选股中,跳过:{', '.join(already)}") if args.clear: final_list = append action_info = f"清空后写入 {len(append)} 只" else: if not append: print("没有需要新增的代码,任务结束。") return final_list = old_list + append action_info = f"新增 {len(append)} 只" # 确保blocknew目录存在(首次使用时可能没有) os.makedirs(BLOCK_DIR, exist_ok=True) write_block(blk_path, final_list, backup=not args.no_backup) print(f"操作成功:{action_info}到 {args.board}") if append: print("新增代码:" + ", ".join(append)) print(f"该板块现有股票数量:{len(final_list)}") print("重新打开通达信后,自选股就会更新。") if __name__ == "__main__": main()4.3 核心函数的几个设计理由
先看normalize_code。这个函数专门处理各种“脏代码”:有人从Excel复制出来的是“SH600519”,有人从同花顺复制出来的是“600519.SH”,还有人CSV文件里把000001变成了数字1。这些情况我都遇到过。代码先用正则去掉sh/sz前缀和后缀,再对纯数字补零,最后用正则从混合文本里抠出连续六位。这套组合拳能覆盖绝大多数真实场景。
再看read_text_auto。选股结果文件的编码不能假设,很多策略脚本输出UTF-8,通达信导出的文本却是GBK。我用二进制方式读取,先尝试UTF-8(带BOM优先),再尝试GBK,总能解出正确文本。
load_existing返回列表和集合两个东西,而不是只返回一个set,原因是要保序。自选股文件里代码的顺序就是通达信界面里的显示顺序,你要是用set一装,顺序全乱,打开通达信看到自选股乱糟糟的,很难受。列表保序,集合用来快速查重,各司其职。
write_block里那个newline=""可能是全脚本最容易忽略但最重要的细节。Python在Windows上写文本文件时,默认会把\n自动转成\r\n。假如代码里写的是f.write(code + "\r\n"),最终落盘就会变成\r\r\n。通达信虽然对行尾容忍度挺高,但文件被写坏的时候,排查起来莫名其妙。传newline=""之后就禁用了自动转换,我们写什么就是什么。
is_tdx_running这个检测函数,用tasklist列出所有进程,找进程名里带“tdx”的。这个模糊匹配会误伤一些名字带tdx的程序,但影响不大,最多多提醒一句。真正的价值在于:防止通达信运行时写入文件,被通达信退出时的内存数据覆盖。这是我踩过一次的坑,后面详细说。
5. 三种使用方式与验证方法
5.1 方式一:临时用,直接改脚本内的STOCK_CODES
如果你只是偶尔往自选股里加几只股票,最省事的方式是打开脚本,在配置区改STOCK_CODES:
STOCK_CODES = [ "600519", "000001", "300750", ]命令行进入脚本目录,运行:
python import_to_tdx.py这个方式适合不想记命令行参数、一周只想手动跑一两次的人。缺点是每次要开编辑器改列表,代码多的时候容易改错,但作为临时手段完全够用。
5.2 方式二:从选股结果文件导入(日常最推荐)
我的日常用法是:策略脚本把选股结果输出成一个文本文件,然后调通达信导入脚本。假设文件名是result.txt,内容这样写:
600519,000001,300750 603259纯代码、逗号分隔、换行分隔、中文混排都没问题。脚本里的正则会把所有六位数字提取出来,无关文字自动过滤。
运行命令:
python import_to_tdx.py -f result.txt如果输出文件是CSV,也一样处理。如果是通达信自带的选股结果导出文件,通常每行是股票代码加股票名称,比如“600519 贵州茅台”,脚本也能正确提取600519。
还有一个常见场景:你从网页上复制了一段股票列表,里面混杂着代码、名称、涨跌幅,直接存成一个txt,然后传给-f参数,照样能用。
5.3 方式三:命令行直接传代码、换板块、清空重写
进阶用户可以直接在命令行传股票代码,多个代码用空格隔开:
python import_to_tdx.py 600519 000001 300750想写入“自选股1”而非默认的“Z自选股”,用-b指定blk文件名:
python import_to_tdx.py -f result.txt -b ZD自选股1.blk注意这里传的是blk文件名,不是板块中文名。自选股1对应的文件名是ZD自选股1.blk,这个最好打开blocknew目录对照着看,别猜。
周末想整体刷新一个板块,把旧的清空、写入全新名单:
python import_to_tdx.py --clear -f weekend_result.txt这个命令会先备份原文件,然后清空板块,再写入新代码。适合每周重新选股、不想保留旧股票的场景。
5.4 运行后怎么验证
脚本运行结束,控制台会打印“新增代码”和“该板块现有股票数量”。如果新增数量符合预期,重启通达信,打开自选股板块就能看到新代码。
有几个验证细节要提醒:
- 如果脚本提示“检测到通达信正在运行”,而你确实开着通达信,请保存通达信里的操作后退出,再跑一次。
- 看到“操作成功”但通达信自选股没变化,先确认通达信是不是真的重启过(不是最小化,而是进程退出后重新打开)。
- 写入的是“自选股1”但你去默认“自选股”界面里找,那肯定找不到。确认板块名和文件名对应关系。
6. 我踩过的五个坑:编码、进程占用、板块写错、重复爆炸和换行符
6.1 坑一:自选股全部乱码,罪魁祸首是UTF-8带BOM
第一次尝试写这个脚本时,我用的是平时写Python的习惯open(path, "w", encoding="utf-8")。写完之后打开通达信,第一只股票显示成了类似“锘?600519”的乱码,后面股票正常。我一度以为正则提取出了问题,后来用十六进制工具看了blk文件头部,才发现文件里多了三个字节EF BB BF,也就是UTF-8的BOM头。通达信把BOM当成股票代码的一部分,导致第一行解析失败。
这个问题的解法就是我上面代码里的写法:写入用encoding="gbk",不会产生BOM。另外,千万别用记事本打开.blk文件后另存为UTF-8,同理。
6.2 坑二:写入了但自选股没变化,通达信内存数据会覆盖掉你的修改
这是最隐蔽的一个坑。有一阵我为了省事,脚本跑完不想重启通达信,直接切到软件里看。结果自选股列表一动不动,我当时以为是文件没写进去。但用记事本打开blk文件,代码明明在里面。
真实原因是:通达信启动后,把自选股板块整个读进内存,界面显示的是内存里的那份数据。外部改了文件,界面不会实时刷新。更麻烦的是,如果你在这个状态下退出通达信,通达信会把内存里的旧板块数据写回文件,把你刚才辛辛苦苦写进去的代码覆盖掉。
所以我的脚本默认严格拒绝在通达信运行时执行。如果你确实在盘中需要写入,可以加--force强写,但写完最好别让通达信正常退出,不然白写了。
6.3 坑三:板块文件写错,自选股“消失”了
有次我想把代码写到“自选股1”板块,随手在命令行敲了-b Z自选股1.blk,结果文件名和真实文件名对不上(真实是ZD自选股1.blk)。脚本运行完提示成功,但打开通达信,默认自选股还是老样子,自选股1里也没新增。我一度以为脚本坏了,后来打开blocknew目录一看,才发现脚本创建了一个名为“Z自选股1.blk”的新文件,通达信根本不认这个文件名。
教训是:任何自定义板块,先把blocknew目录里的真实文件名列出来,再复制粘贴到命令行,不要靠记忆敲。用-b参数之前,养成先ls一下的习惯。
6.4 坑四:重复导入导致自选股爆炸
早期脚本没做去重,我连续跑了几次“增量导入”之后,某天打开自选股发现文件里有两千多行,大量代码重复出现,自选股列表滚动得手指冒火。手动清理?那等于又回到了手工劳动。
后来我才意识到,脚本必须做两层去重:第一层,输入源内部的重复要过滤;第二层,与已有自选股重复的要跳过。这两个逻辑现在的代码里都有。如果哪天你发现自选股已经乱了,也不用愁,先用--clear清空,再重新导入一份全量名单就行。
6.5 坑五:Python在Windows下的换行符陷阱
这个问题属于“不遇到就完全想不到”的类型。一开始我用write(code + "\r\n")写文件,自我感觉非常规范,但用十六进制工具打开blk文件,发现每行结尾是0D 0D 0A,也就是\r\r\n,多了一个回车符。原因是Python的open()在Windows上默认做换行转换,text模式写入时把字符串里的\n自动替换为\r\n,导致原本的\r\n被展开成了\r\r\n。
通达信解析数字的时候会把行尾空白strip掉,所以多数情况下看不出问题。但如果你某天写文件时不小心混入了其他字符,这个多出来的\r会成为压死骆驼的那根草。解决办法就是代码里的open(..., newline=""),关闭自动转换,我们手动控制行尾。
7. 让脚本每天自动跑起来:定时任务与策略联动
7.1 用Windows任务计划定时执行
脚本能手动跑不稀奇,能每天自动跑才算真正释放双手。Windows自带的“任务计划程序”就可以干这个。创建一个基本任务,触发器选每天,时间设在你想要的收盘后或盘中时段,操作选择“启动程序”,程序填你的python.exe完整路径,参数填脚本路径和选股结果文件路径。
举个例子,我用的是:
C:\Python311\python.exe D:\tdx_scripts\import_to_tdx.py -f D:\tdx_scripts\result.txt注意python.exe一定要用完整路径,因为任务计划程序运行时PATH可能不包含Python。如果有人不熟悉图形界面,也可以直接用命令行创建:
schtasks /create /tn "import_tdx" /tr "C:\Python311\python.exe D:\tdx_scripts\import_to_tdx.py -f D:\tdx_scripts\result.txt" /sc daily /st 15:30这里有个前提:选股结果文件必须在定时任务触发前生成好。如果你用通达信公式选股,可以先把选股结果导出到固定路径;如果你用Python策略,直接让策略脚本先产出结果,再调导入脚本。
7.2 和你的选股策略脚本联动起来
如果你本身就用Python做选股,那就更简单了。策略脚本跑完,拿到了股票代码列表,直接把导入函数拉进来用。假设你的策略输出是一个DataFrame,
import subprocess def push_to_tdx(codes): subprocess.run([ "python", r"D:\tdx_scripts\import_to_tdx.py", *codes ], check=True)或者更直接一点,把import_to_tdx.py里的函数import进你的策略脚本,在内存里直接把结果写进blk文件。不过这样耦合度高,我更喜欢用命令行参数这个口子,互不干扰。
7.3 更进一步:盘中信号与收盘稳定的两种用法
最后说下我的个人习惯。盘中策略出信号的时候,我只把信号代码记到日志文件里,不急着导入通达信,因为盘中导入还得重启通达信,而重启就断了实时行情。这时候我会等收盘后,把当日所有信号统一导进去,第二天开盘前就能看到板块里整理好的候选股。
周末或者月末,我会用--clear参数做一次全量刷新,把旧的、已经走完的股票清空,重新写入一份新的观察池。这样自选股永远是干净的,不会变成垃圾堆积场。
脚本带来的本质不是“省几分钟”,而是让你敢做更多轮的选股实验。以前手工时代,我每次都尽量控制选股数量,因为加自选股太费劲了。现在不管选出来一百只还是两百只,导进去也就一秒钟的事。这一秒钟省下来的时间,我会拿去检查策略本身的问题,而不是把精力消耗在复制粘贴上。这个工具不难,但它是我日常流程里最值的一段代码之一。