Back to Daily Stock Analysis

分享图片模板与数据填充

docs/share-images.md

3.29.09.4 KB
Original Source

分享图片模板与数据填充

分享图片用于把个股分析和市场复盘转换为适合社交平台传播的 1080px 长图。个股和大盘使用两套独立的信息结构,但共用 DSA 品牌、仓库标识 ZhuLinsen/daily_stock_analysis 和风险声明。GitHub 区不放二维码;小红书区域由部署配置决定,未配置时整块隐藏,避免 fork 或私有部署默认宣传维护者账号。

运行时如何填充

现有通知链路不需要手工组装图片数据:

text
个股 AnalysisResult
  -> AnalysisResult.to_dict() 结构化 JSON + 稳定 Markdown
  -> share_image 优先读取 JSON,Markdown 兼容回退
  -> 个股决策卡 HTML
  -> wkhtmltoimage / markdown-to-file / Playwright 输出 PNG

大盘 MarketOverview + market_light + LLM 复盘
  -> MarketAnalyzer 生成 market_review_payload + 稳定 Markdown
  -> share_image 优先读取 payload,Markdown 兼容回退
  -> 市场复盘卡 HTML
  -> wkhtmltoimage / markdown-to-file / Playwright 输出 PNG

MARKDOWN_TO_IMAGE_CHANNELSMD2IMG_ENGINEMARKDOWN_TO_IMAGE_MAX_CHARS 继续控制哪些通知渠道转图、使用哪个引擎以及最大输入长度。转换失败时仍回退为文本通知。

小红书品牌使用以下可选配置,四项全部留空即关闭该区域:

dotenv
SHARE_IMAGE_XIAOHONGSHU_URL=https://example.com/my-xiaohongshu
SHARE_IMAGE_XIAOHONGSHU_HANDLE=@我的账号
SHARE_IMAGE_XIAOHONGSHU_ID=123456789
SHARE_IMAGE_XIAOHONGSHU_QR_PATH=assets/my-xiaohongshu-qr.png

二维码路径支持绝对路径或相对项目根目录路径;冻结桌面后端也会从 PyInstaller 资源目录解析相对路径。账号 URL 只接受 http://https://。二维码在转图时以内嵌 Data URI 渲染,不依赖运行时网络。

Web 一键分享

浏览器版历史个股报告、市场复盘和完整报告抽屉右上角都会显示“分享”按钮。页面加载报告时不会生成图片;只有用户点击“分享”后,页面才调用 GET /api/v1/history/{record_id}/share-image 按需生成或读取缓存 PNG。支持文件分享的浏览器会在图片准备好后提示“再次点击分享”,由第二次点击同步打开系统分享面板,避免异步生成过程使浏览器的用户激活状态失效;其他浏览器会在首次生成完成后直接下载 PNG。如果系统分享面板打开失败,除用户主动取消外也会自动回退下载已经生成的 PNG。

Electron 桌面运行时默认不展示该按钮。当前 Windows/macOS 打包版不会随包分发 wkhtmltoimagemarkdown-to-file 或 Playwright/Chromium renderer,避免桌面用户在页面加载时就命中 share_image_unavailable 失败态。

Web 手工生成不受 MARKDOWN_TO_IMAGE_CHANNELS 限制,但服务端仍需配置可用的 MD2IMG_ENGINE。使用 Playwright 时先执行:

bash
cd apps/dsa-web
npm ci
npx playwright install chromium

结构化数据用于精确填充名称、动作、评分、价格、宽度和板块等字段;Markdown 仍负责兼容旧调用以及计划、风险等文本章节。部分历史 JSON 只覆盖其中实际存在的字段,不会清空 Markdown 中已有的行情、技术参考或执行点位。模板不根据分数自行推导操作,也不补造价格或指标。字段为 N/A-、空值或没有对应模块时,相关卡片自动隐藏。

个股卡字段映射

图片区域项目字段 / 生成来源填充规则
股票名称、代码AnalysisResult.nameAnalysisResult.code直接读取结构化字段,Markdown 标题仅作回退
操作、评分、趋势action_label / operation_advicesentiment_scoretrend_predictionconfidence_level使用最终校准结果,评分范围 0–100,并标明结论置信度
核心结论dashboard.core_conclusion.one_sentence没有时隐藏
市场快照market_snapshot当前/收盘价、涨跌幅、量比、换手率按可用字段展示;数据源进入底部声明
执行计划dashboard.battle_plan.sniper_points只展示理想/确认买入、止损和首个目标价格;复杂触发条件保留在完整报告
技术参考dashboard.data_perspective展示均线状态、趋势分、MA5 乖离、支撑和压力;结构化量比/换手已进入快照时不重复展示冗长量能描述,旧记录缺失结构化量能时仍保留 Markdown 兜底
下一步观察dashboard.phase_decision展示行动窗口、下次检查时间和最多两条观察条件
催化与风险dashboard.intelligencepositive_catalystsrisk_alerts 最多各展示 2 条短摘要
持仓建议core_conclusion.position_advice只区分未持仓和已持仓,仓位、建仓、风控长文保留在完整报告

模板支持项目当前的中文、英文和韩文报告标签,海报栏目、指标标签和底部声明跟随报告语言。一个“决策仪表盘”只有一只股票时会自动使用个股卡;包含多只股票时保留多股报告布局,避免错误地把第一只股票当成整份报告。强烈买入Strong Buy 等复合动作会保留完整动作标签。

大盘卡字段映射

图片区域项目字段 / 生成来源填充规则
日期、市场范围MarketOverview.date、复盘区域生成 A股/美股/港股/日股/韩股市场复盘标题;多市场报告逐段匹配 market_review_payload.markets
市场信号market_light.scoretemperature_labellabelguidance使用确定性市场灯号结果,不由模板二次评分
指数表现MarketOverview.indicescolor_scheme最多展示 4 个主要指数的最新值和涨跌幅;结构化 payload 持久化生成时的 green_up / red_up 颜色语义
市场宽度up_countdown_countlimit_up_countlimit_down_counttotal_amount仅在数据源支持且报告包含结构化数据时展示
信号拆解market_light.dimensions只展示 available != false 的确定性评分;不把不支持的维度占位分 50 当作真实数据
强弱板块sectors.topsectors.bottom领涨、领跌各展示 Top 3;没有板块榜的市场自动隐藏
资金观察复盘“资金与情绪”章节提炼涨跌比、增量成交和资金风格,不把成交额或新闻推断伪装成净流入
重点跟踪复盘“明日交易计划”的关注/回避方向最多各展示 2 个板块或主题;当前 payload 没有 leader_stocks,因此不编造重点个股
明日策略复盘“明日交易计划”章节展示结论、仓位区间和失效条件,不与重点跟踪重复
风险提示复盘“风险提示”章节最多展示 2 条,过滤重复免责声明

手工填充或本地预览

模板仍接受项目生成的 Markdown;新链路会额外传入 AnalysisResult.to_dict()market_review_payload。仅调试兼容回退时,可以准备一份最小个股报告:

markdown
## 🟢 贵州茅台 (600519)

> 2026-07-31 15:00 | 评分: **72** | 看多

### 📌 核心结论

**买入**: 趋势偏强,等待回踩支撑后分批执行。

| 持仓情况 | 操作建议 |
| --- | --- |
| 空仓者 | 等待回踩确认,不追高。 |
| 持仓者 | 继续持有,跌破止损位退出。 |

### 🎯 作战计划

| 点位类型 | 价格 |
| --- | --- |
| 理想买入点 | 1420-1450 |
| 次优买入点 | 1380-1400 |
| 止损位 | 1350 |
| 目标位 | 1580 |

生成 HTML 预览:

python
from pathlib import Path
from src.share_image import ShareImageBranding, build_share_image_html

markdown_text = Path("reports/example.md").read_text(encoding="utf-8")
branding = ShareImageBranding(
    xiaohongshu_url="https://example.com/my-xiaohongshu",
    xiaohongshu_handle="@我的账号",
    xiaohongshu_qr_path="assets/my-xiaohongshu-qr.png",
)
html = build_share_image_html(markdown_text, branding=branding)
Path("share-preview.html").write_text(html, encoding="utf-8")

按真实运行数据预览时传入结构化结果:

python
html = build_share_image_html(
    markdown_text,
    structured_payload=analysis_result.to_dict(),
)

实际通知转 PNG 仍调用:

python
from src.md2img import markdown_to_image

png_bytes = markdown_to_image(
    markdown_text,
    structured_payload=analysis_result.to_dict(),
)

大盘报告应沿用 MarketAnalyzer 生成的“盘面信号、指数结构、板块主线、消息催化、明日交易计划、风险提示”章节;不建议在外部另造一套字段名称,否则模板会按缺失字段处理。

视觉与内容边界

  • 涨跌颜色优先使用结构化 payload 持久化的 color_scheme,旧记录则从最终报告颜色标记恢复;模板不按市场地区硬编码涨跌色。
  • 分享图中的买入、止损和目标只保留可扫描的价格或“等待企稳”;完整条件始终保留在原报告中。
  • 没有真实价格序列时不绘制伪 K 线;顶部仅保留非数据化的品牌光晕。
  • 小红书 URL、账号、ID 和二维码路径来自运行时配置;全部留空时不渲染小红书区域。GitHub 固定展示仓库标识 ZhuLinsen/daily_stock_analysis,不生成二维码。
  • 大盘报告在核心模块已成功提取时不重复附加完整 Markdown;额外的详情章节保留在原报告中,分享图只呈现结构化摘要。
  • 图片底部固定说明“AI 生成,仅供研究交流,不构成投资建议”。