triangle-validator/batch_validate.py
褚宏光 430511e8c4 feat: 收敛三角形形态可视化验证工具
功能:
- 支持中文名称搜索股票(如"中控技术"、"英伟达")
- 支持 A 股和美股
- 趋势线从窗口起点延伸到终点(与前端一致)
- Y 轴自动调整以包含趋势线
- 支持 --window 参数(1Y/3Y/5Y/ALL)

用法:
python validate.py 中控技术 日 --window 3Y --save
python validate.py 英伟达 日 --window 3Y --save

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 14:51:16 +08:00

117 lines
3.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
batch_validate.py — 批量验证多只股票的收敛三角形形态HTTP 版)
用法:
python batch_validate.py [--no-show] [--save]
--no-show 不弹窗,直接生成所有图(适合无显示器/批量场景)
--save 保存图片到 output/ 目录
修改下方 BATCH_CASES 可自定义验证列表。
"""
import sys
import argparse
from pathlib import Path
from validate import run_formula, fetch_detail
_THIS_DIR = Path(__file__).parent.resolve()
# ── 批量验证列表(可自由修改)───────────────────────────────────────────────────
# 格式:(ticker, freq, mode=0, date=None)
BATCH_CASES = [
# 日 K —— 知名个股
('中远海控', '', 0, None),
('贵州茅台', '', 0, None),
('宁德时代', '', 0, None),
('中芯国际', '', 0, None),
# 周 K —— 宽基指数
('沪深300', '', 0, None),
('中证500', '', 0, None),
# 月 K
('贵州茅台', '', 0, None),
('中远海控', '', 0, None),
]
# ── 单条处理 ──────────────────────────────────────────────────────────────────
def process_one(ticker: str, freq: str, mode: int, date, save: bool, show: bool) -> bool:
print(f'[batch] → {ticker!r} {freq}K ...')
try:
index_id = run_formula(ticker, freq, mode, date)
except Exception as e:
print(f'[batch] ✗ 公式执行失败: {e}')
return False
try:
detail = fetch_detail(index_id)
except Exception as e:
print(f'[batch] ✗ 读取详情失败: {e}')
return False
cd = detail.get('chart_data', {})
strength = detail.get('strength', 0)
direction = detail.get('direction', 'none')
print(
f'[batch] ✓ 强度={strength:.4f} 方向={direction} '
f'窗口={cd.get("window_start_date", "?")}~{cd.get("window_end_date", "?")}'
)
if not cd.get('klines'):
print('[batch] ✗ 没有 klines跳过绘图')
return False
from chart import draw_triangle_chart
safe_ticker = ticker.replace('/', '_').replace('\\', '_')
output_path = None
if save:
output_dir = _THIS_DIR / 'output'
fname = f'{safe_ticker}_{freq}K_{cd.get("target_date", "")}.png'
output_path = str(output_dir / fname)
try:
draw_triangle_chart(detail=detail, output_path=output_path, show=show)
except Exception as e:
print(f'[batch] ✗ 绘图失败: {e}')
return False
return True
# ── 主函数 ────────────────────────────────────────────────────────────────────
def main():
parser = argparse.ArgumentParser(description='收敛三角形批量验证HTTP 版)')
parser.add_argument('--no-show', action='store_true', help='不弹出图形窗口')
parser.add_argument('--save', action='store_true', help='保存图片到 output/')
args = parser.parse_args()
show = not args.no_show
save = args.save
if not show and not save:
print('[batch] 提示:既未开启 --save 也未弹窗,将只打印摘要。')
ok_count = 0
fail_count = 0
for case in BATCH_CASES:
ticker, freq = case[0], case[1]
mode = case[2] if len(case) > 2 else 0
date = case[3] if len(case) > 3 else None
success = process_one(ticker, freq, mode, date, save, show)
if success:
ok_count += 1
else:
fail_count += 1
print(f'\n[batch] 完成 成功={ok_count} 失败={fail_count} 总计={ok_count + fail_count}')
if __name__ == '__main__':
main()