mirror of
https://github.com/ZhuLinsen/daily_stock_analysis
synced 2026-09-20 10:53:33 +08:00
chore: prepare v3.24.0 release
This commit is contained in:
@@ -9,70 +9,69 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
- [改进] TickFlow 扩展为可选 A 股日 K、实时行情、股票列表/名称数据源,并为日 K 请求增加 count、完整性校验和批量预取缓存保护。
|
||||
- [新功能] #1777 新增台股三大法人(institutional flows)资料层 fetcher `TwInstitutionalFetcher`:上市走 TWSE T86 legacy `rwd` 端点、上柜走 TPEx OpenAPI,正规化外资/投信/自营商/三大法人每日买卖超(单位股数,民国↔西元日期转换有单测),按日期+市场单日缓存,失败/限流/空响应一律 fail-open;仅 `.TW`/`.TWO` 生效、严格 additive,不改动现有市场流程、不接报告/Web/评分/`capital_flow_signal`。资料来源为政府开放资料(OGDL v1)。
|
||||
- [修复] API 异步批量分析共享概念板块排行缓存,避免同批多股重复拉取全市场概念排行。
|
||||
- [文档] 补齐概念板块排行字段契约与通知报告行业/概念类型列展示说明。
|
||||
- [新功能] #1742 新增信号归因分析功能(dashboard.signal_attribution),解释推荐理由的构成(技术指标、新闻舆情、基本面、市场环境的贡献度,以及最强看多/看空信号)。支持默认通知报告和 Jinja2 模板渲染,包含中英文国际化标签。归一化函数在 _parse_response() 和 parse_dashboard_json() 中显式调用,确保有效非零贡献度归一化到 100,all-zero 保留为 0(表示无有效信号)。
|
||||
- [改进] Agent 路径同步:更新 executor.py 和 decision_agent.py 的 prompt,确保 agent/multi-agent 分析时也生成 signal_attribution 字段。
|
||||
- [新功能] #1815 Phase 2 大盘复盘新增 `jp`/`kr` 市场:支持日经225/TOPIX、KOSPI/KOSDAQ 指数复盘,扩展 `MARKET_REVIEW_REGION`、交易日过滤、Web 设置枚举、市场 profile/strategy、文档与回归测试。
|
||||
- [改进] #1815 Phase 1 硬化日本/韩国 suffix-only 个股 MVP:集中 JP/KR/TW suffix 识别规则,扩充日韩股票种子索引,并为 yfinance 报价/基本面上下文补充市场、币种与数据质量元数据。
|
||||
- [文档] #1815 补充 JP/KR/TW suffix-only MVP 在外部 API、provider/model/base URL 与运行时配置上的边界说明:当前为结构化字段兼容验证且可回退到旧链路。
|
||||
- [文档] #1815 细化 PR 提交流程约束:.github/PULL_REQUEST_TEMPLATE.md 补充 Head CI 一致性、Web 设置变更可视证据、第三方兼容性声明与回滚说明要求,避免描述与验证状态/变更影响不一致。
|
||||
- [修复] 修复通知 Markdown 表格转换在空单元格后将后续内容错配到错误表头的问题。
|
||||
- [改进] #1815 Phase 3 收敛 JP/KR Portfolio 与 Market Light 边界:JP/KR 持仓快照标记 partial/limitations,Market Light 告警继续限定 cn/hk/us,并同步 Web 选项、文档和测试。
|
||||
- [修复] 修复 Market Light 区域归一化仍拒绝 `jp`/`kr`,导致 JP/KR 大盘复盘历史快照读取回归失败的问题。
|
||||
- [文档] #1815 明确 JP/KR Phase 3 收敛时的兼容与回退路径:`MARKET_REVIEW_REGION=jp/kr` 仅扩展复盘输入;Market Light 告警、LLM provider/model/base URL、运行时配置持久化与清理语义保持不变,并补充官方来源、当前 LiteLLM 依赖窗口与回归测试证据。
|
||||
- [文档] #1815 集中补充 `MARKET_REVIEW_REGION` 保存/校验/回退矩阵、旧 `both` 三市场边界到 `cn,hk,us` 的迁移说明、JP/KR yfinance 指数依赖边界,以及 Market Light 告警与设置页 UI 变更的可替代验证证据;补充冲突解决后最终 head 的 backend gate 与 Web lint/build 验证结论。
|
||||
- [修复] 将 Docker 可安装的 Longbridge SDK 版本固定为 0.2.75,避免 `longbridge>=0.2.77` 从包索引消失后导致 docker-build 失败。
|
||||
- [修复] 持仓快照今日估值改为受限并发预取多只持仓实时价,减少持仓较多时 Web 组合页面刷新超时。
|
||||
- [修复] Web 首页重新分析完成后自动切换到同一股票最新生成的报告,避免仍停留在旧报告内容。
|
||||
- [改进] AlphaSift 默认依赖 pin 更新到 `0a7b9cd59e81718f851890535241bc105d4ddc64`,纳入上游日线数据源健康度、硬过滤诊断、策略评估摘要和 LLM 排名解析稳定性改进。
|
||||
- [改进] AlphaSift 热点默认走 DSA EastMoney 兜底 provider,选股运行期默认提高日线抓取重试并在状态接口暴露 snapshot/daily source health,便于定位不稳定数据源。
|
||||
- [文档] 新增数据源稳定性与故障处理图示,说明 Tushare、TickFlow、AkShare、Efinance、YFinance、Longbridge 等已接入源的使用场景、fallback 链路和推荐配置。
|
||||
- [新功能] #1754 在 Web AI 建议页新增单股信号时间线,并为自动生成与历史回填的 DecisionSignal 写入默认 decision_profile metadata。
|
||||
|
||||
- [修复] 默认通知报告补充展示 `dashboard.phase_decision` 盘中决策护栏字段,避免与模板渲染路径展示不一致。
|
||||
- [修复] 修复 Windows 环境下 Web/Desktop 静态 JS 资源可能被识别为 `text/plain` 导致前端黑屏的问题。
|
||||
- [改进] Web 设置页新增首次启动配置检查卡,串联基础配置状态、自选股入口、模型配置入口和一次简短试跑。
|
||||
- [改进] 通知报告的分析结果摘要不再展开 AI 决策信号明细,完整信号保留在个股详情和单股报告中。
|
||||
- [新功能] #1595 P1.5 新增 Provider Cache Capability Registry,按 provider、api surface、gateway 和 verification status 建模 prompt cache 能力,未知 OpenAI-compatible route 默认 telemetry only。
|
||||
- [改进] #1595 P1 新增 prompt cache telemetry / analysis-path hints / diagnostics 最小配置,默认不改变 provider 请求 shape,并复用 LLM usage HMAC secret 做 domain-separated cache hint 派生。
|
||||
- [新功能] 大盘复盘、Web 报告页和通知关联板块补齐概念板块排行与概念信号展示。
|
||||
- [改进] 将 Docker Compose 默认内存建议从 512M 提升到 1G,并补充低配部署说明。
|
||||
- [改进] 每日分析 workflow 兼容误将 `STOCK_LIST` 配到同名 Environment variables 的场景,同时保留 Repository variables 作为推荐配置入口。
|
||||
- [新功能] #1743 Phase 3 新增 reserved Hermes 本地 HTTP generation 渠道,提供 JSON generation、no-proxy 本地调用、saved secret endpoint 绑定,并明确不支持 stream/SSE、tools、Vision、Agent tools 与 remote Hermes。
|
||||
- [新功能] #1772 新增台湾(台股)suffix-only 个股分析 MVP(**市场识别与数据路由层**):手输 `.TW`(TWSE 上市)/ `.TWO`(TPEx 上柜)代码可走 YFinance 日线与近实时行情,补充市场识别、交易日历(XTAI / Asia/Taipei)、Prompt 语义与能力边界文档;加权指数 `^TWII`、柜买指数 `^TWOII`。台股股票索引/种子、Web 自动补全与告警(大盘红绿灯)市场放行作为后续 PR。
|
||||
- [文档] #1772 明确本次为台股 suffix 仅路由兼容改造,对齐 #1718 日韩模式;不涉及 provider/model/base URL/运行时配置变更;回退方式为 revert 本次改动或移除 tw 入口恢复既有行为。
|
||||
- [新功能] #1772 台股 `tw` 纳入 DecisionSignal / Portfolio / Intelligence 服务层与 API 市场枚举(VALID_MARKETS / _ALLOWED_MARKETS + Pydantic Literal + api_spec.json),修复数据层 MVP 下 tw 分析在 pipeline 自动抽取 DecisionSignal 时被 _normalize_market 静默丢弃的缺陷,并同步放行 DecisionSignal/Portfolio 前端市场类型与筛选及相关专题文档,对齐 #1720 日韩;告警(大盘红绿灯)市场仍为 cn/hk/us。
|
||||
<!-- 新条目格式:- [类型] 描述(类型取值:新功能/改进/修复/文档/测试/chore)-->
|
||||
<!-- 每条独立一行追加到本段末尾,无需分类标题,合并时冲突最小 -->
|
||||
|
||||
- [修复] 修复日股/韩股历史列表重建市场阶段摘要时将 non_trading 等结果阶段误传为 analysis_phase 导致列表查询失败的问题。
|
||||
- [新功能] 支持 SCHEDULE_TIMES 多时间定时推送,并让 Web/API/Desktop 长运行进程保存调度配置后热启停或重建 runtime scheduler。
|
||||
- [改进] Web 设置页以“定时任务”面板维护多时间定时推送、状态刷新和立即执行一次,不再向用户直接暴露 SCHEDULE_TIMES 等内部配置键。
|
||||
- [修复] 修复 `--serve --schedule` 下 CLI 调度器与 Web/API runtime scheduler 状态脱节的问题,并避免设置页把失败执行时间显示为上次成功。
|
||||
- [修复] runtime scheduler 的立即执行接口在已有分析运行时返回 409 忙碌状态,Web 设置页不再把未排队的请求提示为已提交。
|
||||
- [修复] 避免 runtime scheduler 重建定时任务时重复立即运行事件监控,减少重复告警和后台任务状态丢失。
|
||||
- [修复] Web/API runtime scheduler 接管 `--serve --schedule` 后保留 `--dry-run`、`--no-notify` 等启动参数语义。
|
||||
- [改进] Web 历史报告详情不再内嵌展示 AI 建议卡片,结构化决策信号集中在 AI 建议页查询,并保留按来源报告 ID 筛选或 URL 参数精确定位入口。
|
||||
- [改进] 新增 GenerationBackend Phase 1 抽象与 LiteLLM backend 配置,默认保持普通分析、`generate_text()` 和 Agent Chat 的 LiteLLM 行为不变。
|
||||
- [新功能] #1743 Phase 2 新增显式 opt-in 的 `codex_cli` 本地 CLI generation backend,固定安全 preset、结构化错误、fallback、stream 降级和 usage unavailable contract。
|
||||
- [改进] `GENERATION_BACKEND=codex_cli` 下普通分析与大盘复盘不再因缺少 LiteLLM API Key 被误判不可用,local CLI 失败会暴露结构化错误或按配置回退 LiteLLM。
|
||||
- [改进] `codex_cli` preset 改用 `--output-last-message` 文件读取最终响应,stdout/stderr 仅作为诊断预览,避免 Codex CLI session 元数据混入主分析 JSON。
|
||||
- [修复] `codex_cli` preset 不再把 Codex CLI 同时打印到 stdout 的最终响应重复计入输出上限,也不在 `stdout_preview` 暴露重复的最终响应内容。
|
||||
- [修复] 恢复主分析 JSON 解析的宽松 schema fallback 语义,完整报告 schema 校验失败时继续按 raw JSON 解析,避免有效字段被错误降级为文本 fallback。
|
||||
- [改进] 本地 CLI backend 对诊断 stdout/stderr 与最终响应实行执行期总量上限,并为新增 generation backend 数字配置补齐最大值校验。
|
||||
- [文档] 补充本地 CLI backend 隐私边界、非离线模型说明、Docker/CI 登录态限制,以及 `codex_cli` experimental/limited 状态。
|
||||
- [修复] unsupported `GENERATION_BACKEND` 在 `generate_text()` 与大盘复盘路径中显式报配置错误,避免被当成空响应或模板报告 fallback。
|
||||
- [改进] Web 设置页明确 `AGENT_GENERATION_BACKEND=auto` 当前使用 LiteLLM 工具调用路径,避免暗示已有动态 backend 选择。
|
||||
- [改进] Web 首页“任务已存在”重复分析提示新增手动关闭按钮与 5 秒后自动消失。
|
||||
- [修复] `main.py --serve-only` 在低配主机上因 uvicorn 在 3.0s 启动自检窗口内才惰性 import 应用(litellm + 整个 app 树)导致超时退出、容器反复重启;改为在计时前于调用线程预先 import app 对象再交给 uvicorn,启动自检不再误杀慢启动。
|
||||
- [修复] Docker 镜像预置 efinance 缓存目录(efinance/data)属主给非 root 运行用户 dsa,修复 A 股 efinance 数据源因写 search-cache.json 触发 PermissionError 而每次抓取失败降级的问题。
|
||||
- [修复] Docker 部署中 Web 设置页保存自定义 Webhook 模板时自动转义 `$content_json` 等应用占位符,并在运行时还原,避免 Compose 重新部署将其展开为空。
|
||||
- [修复] 修复 Web 回测运行未传分析日期范围、股票代码未归一化导致后端成功返回但结果为空的问题,并为空候选和行情不足返回诊断信息。
|
||||
- [文档] 补充回测请求链路说明:`analysis_date_from/analysis_date_to` 与 `code` 的输入边界、归一化与筛选顺序,以及历史行情不足或候选集为空时回测返回成功响应,在 `message` 与 `diagnostics`(含 `empty_reason`)中提供可诊断信息,并同步更新 `docs/full-guide.md`、`docs/full-guide_EN.md` 示例。
|
||||
- [修复] 回测代码匹配新增非法市场后缀/长度兜底:如 `600519.HK`、`600519.SZ`、`SH000001` 不再静默回落到其它有效代码,并在日期筛选重跑时对齐旧回测结果的分析日期,避免历史快照日期命中但结果列表仍为空。
|
||||
## [3.24.0] - 2026-06-28
|
||||
|
||||
### 发布亮点
|
||||
|
||||
- feat: 扩展台股、日股、韩股市场支持,覆盖台股 suffix-only 分析、台股三大法人资料层、JP/KR 大盘复盘和跨服务市场枚举。
|
||||
- feat: 新增 GenerationBackend 抽象、`codex_cli` 本地 CLI backend、reserved Hermes 本地 HTTP 渠道和 prompt cache capability registry。
|
||||
- feat: Web/API/Desktop 支持多时间定时推送与 runtime scheduler 热重建,Web 设置页补齐首次启动检查与定时任务面板。
|
||||
- feat: 报告链路补齐信号归因、单股信号时间线、概念板块排行和通知/报告关联板块展示。
|
||||
- fix: 修复 Docker/启动探针、静态资源 MIME、回测空结果、组合估值、通知 Markdown、AlphaSift 数据源和测试环境隔离等稳定性问题。
|
||||
|
||||
### 新功能
|
||||
|
||||
- 新增台股 suffix-only 个股分析 MVP:`.TW`/`.TWO` 代码可走 YFinance 日线与近实时行情,并补齐市场识别、交易日历和 Prompt 能力边界。
|
||||
- 台股 `tw` 纳入 DecisionSignal、Portfolio、Intelligence 服务层、API 枚举和 Web 筛选,避免台股分析信号被市场归一化静默丢弃。
|
||||
- 新增台股三大法人资料层 fetcher `TwInstitutionalFetcher`,支持 TWSE/TPEx 来源、日期转换、单日缓存和 fail-open 退化。
|
||||
- 大盘复盘新增 `jp`/`kr` 市场,支持日经225/TOPIX、KOSPI/KOSDAQ 指数复盘,并扩展 `MARKET_REVIEW_REGION`、交易日过滤和 Web 设置枚举。
|
||||
- 新增 GenerationBackend Phase 1 抽象和显式 opt-in 的 `codex_cli` 本地 CLI generation backend,提供结构化错误、fallback、stream 降级和 usage unavailable contract。
|
||||
- 新增 reserved Hermes 本地 HTTP generation 渠道,提供 JSON generation、no-proxy 本地调用和 saved secret endpoint 绑定。
|
||||
- 新增 Provider Cache Capability Registry,按 provider、API surface、gateway 与 verification status 建模 prompt cache 能力。
|
||||
- 支持 `SCHEDULE_TIMES` 多时间定时推送,长运行 Web/API/Desktop 进程保存调度配置后可热启停或重建 runtime scheduler。
|
||||
- 新增信号归因分析和 Web AI 建议页单股信号时间线,并为自动生成与历史回填的 DecisionSignal 写入默认 `decision_profile` metadata。
|
||||
- 大盘复盘、Web 报告页和通知关联板块补齐概念板块排行与概念信号展示。
|
||||
|
||||
### 改进
|
||||
|
||||
- TickFlow 扩展为可选 A 股日 K、实时行情、股票列表/名称数据源,并增加 count、完整性校验和批量预取缓存保护。
|
||||
- 硬化 JP/KR/TW suffix 识别、日韩股票种子索引、YFinance 报价/基本面上下文,以及 JP/KR Portfolio 与 Market Light 边界。
|
||||
- Web 设置页新增首次启动配置检查卡与定时任务面板,隐藏内部 `SCHEDULE_TIMES` 键,并改善重复任务提示的关闭与自动消失体验。
|
||||
- Web 历史报告详情不再内嵌 AI 建议卡片,结构化决策信号集中到 AI 建议页,并保留来源报告 ID/URL 参数精确定位。
|
||||
- `GENERATION_BACKEND=codex_cli` 下普通分析与大盘复盘不再因缺少 LiteLLM API Key 被误判不可用,并改用 `--output-last-message` 文件读取最终响应。
|
||||
- 本地 CLI backend 对 stdout/stderr 诊断预览和最终响应实行执行期总量上限,并补齐新增 generation backend 数字配置最大值校验。
|
||||
- AlphaSift 默认依赖 pin 更新到 `0a7b9cd59e81718f851890535241bc105d4ddc64`,并默认走 DSA EastMoney 兜底 provider、暴露 source health 诊断。
|
||||
- Docker Compose 默认内存建议提升到 1G;每日分析 workflow 兼容误将 `STOCK_LIST` 配到同名 Environment variables 的场景。
|
||||
- Agent 路径同步 signal attribution prompt,通知报告摘要不再展开 AI 决策信号明细,完整信号保留在个股详情与单股报告。
|
||||
|
||||
### 修复
|
||||
|
||||
- API 异步批量分析共享概念板块排行缓存,避免同批多股重复拉取全市场概念排行。
|
||||
- 修复通知 Markdown 表格转换在空单元格后将后续内容错配到错误表头的问题。
|
||||
- 修复 Market Light 区域归一化拒绝 `jp`/`kr`、日韩历史列表市场阶段摘要误传 `analysis_phase` 和默认通知报告缺少 `dashboard.phase_decision` 的问题。
|
||||
- 固定 Docker 可安装的 Longbridge SDK 版本为 0.2.75,并修复 Docker 镜像中 efinance 缓存目录属主导致 A 股数据源降级的问题。
|
||||
- 持仓快照今日估值改为受限并发预取实时价,减少持仓较多时 Web 组合页面刷新超时。
|
||||
- Web 首页重新分析完成后自动切换到同一股票最新报告,并修复 Windows 环境下 Web/Desktop 静态 JS 资源可能以 `text/plain` 返回导致黑屏的问题。
|
||||
- 修复 `--serve --schedule` 与 Web/API runtime scheduler 状态脱节、立即执行忙碌状态误提示、重建定时任务重复监听和启动参数语义丢失。
|
||||
- 修复 `main.py --serve-only` 在低配主机上因惰性 import 应用超出 uvicorn 启动自检窗口而反复重启的问题。
|
||||
- 修复 Web 回测未传分析日期范围、股票代码未归一化导致成功响应但结果为空的问题,并为空候选、行情不足和非法后缀提供诊断信息。
|
||||
- 修复 unsupported `GENERATION_BACKEND` 被当成空响应/模板 fallback、`codex_cli` stdout 重复计入输出上限和主分析 JSON schema fallback 语义回退的问题。
|
||||
- Docker 部署中 Web 设置页保存自定义 Webhook 模板时会转义 `$content_json` 等占位符,并在运行时还原,避免 Compose 重新部署展开为空。
|
||||
|
||||
### 文档
|
||||
|
||||
- 补齐概念板块排行字段契约、通知报告行业/概念类型列展示和数据源稳定性与故障处理图示。
|
||||
- 补充 JP/KR/TW suffix-only MVP、`MARKET_REVIEW_REGION` 保存/校验/回退矩阵、Market Light 边界和 PR 提交流程约束。
|
||||
- 补充本地 CLI backend 隐私边界、非离线模型说明、Docker/CI 登录态限制和 `codex_cli` experimental/limited 状态。
|
||||
- 补充回测请求链路说明,并同步更新 `docs/full-guide.md` 与 `docs/full-guide_EN.md` 示例。
|
||||
|
||||
### 测试
|
||||
|
||||
- 新增/更新台股、JP/KR 大盘复盘、GenerationBackend、`codex_cli`、Hermes、本地 CLI、runtime scheduler、回测和概念板块排行相关回归测试。
|
||||
- 加强 `tests/test_analysis_api_contract.py`、`tests/test_analysis_history.py` 与 `tests/test_backtest_service.py` 的临时 `.env` 隔离,避免本地真实 `.env` 污染系统配置测试。
|
||||
|
||||
## [3.23.0] - 2026-06-20
|
||||
|
||||
@@ -1891,7 +1890,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
||||
|
||||
---
|
||||
|
||||
[Unreleased]: https://github.com/ZhuLinsen/daily_stock_analysis/compare/v3.22.0...HEAD
|
||||
[Unreleased]: https://github.com/ZhuLinsen/daily_stock_analysis/compare/v3.24.0...HEAD
|
||||
[3.24.0]: https://github.com/ZhuLinsen/daily_stock_analysis/compare/v3.23.0...v3.24.0
|
||||
[3.23.0]: https://github.com/ZhuLinsen/daily_stock_analysis/compare/v3.22.0...v3.23.0
|
||||
[3.22.0]: https://github.com/ZhuLinsen/daily_stock_analysis/compare/v3.21.1...v3.22.0
|
||||
[3.21.1]: https://github.com/ZhuLinsen/daily_stock_analysis/compare/v3.21.0...v3.21.1
|
||||
[3.21.0]: https://github.com/ZhuLinsen/daily_stock_analysis/compare/v3.20.0...v3.21.0
|
||||
|
||||
@@ -5,12 +5,19 @@ import asyncio
|
||||
from concurrent.futures import Future
|
||||
from datetime import datetime
|
||||
import json
|
||||
import os
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import ANY, MagicMock, patch
|
||||
|
||||
_ORIGINAL_ENVIRON = dict(os.environ)
|
||||
_MODULE_TEMP_DIR = tempfile.TemporaryDirectory()
|
||||
_MODULE_ENV_FILE = Path(_MODULE_TEMP_DIR.name) / ".env"
|
||||
_MODULE_ENV_FILE.write_text("STOCK_LIST=600519,000001\n", encoding="utf-8")
|
||||
os.environ["ENV_FILE"] = str(_MODULE_ENV_FILE)
|
||||
|
||||
from tests.litellm_stub import ensure_litellm_stub
|
||||
|
||||
ensure_litellm_stub()
|
||||
@@ -44,6 +51,19 @@ from src.services.image_stock_extractor import _call_litellm_vision
|
||||
from src.services.task_queue import AnalysisTaskQueue, TaskStatus
|
||||
|
||||
|
||||
def tearDownModule() -> None:
|
||||
current_test = os.environ.get("PYTEST_CURRENT_TEST")
|
||||
for key in list(os.environ):
|
||||
if key == "PYTEST_CURRENT_TEST":
|
||||
continue
|
||||
if key not in _ORIGINAL_ENVIRON:
|
||||
os.environ.pop(key, None)
|
||||
os.environ.update(_ORIGINAL_ENVIRON)
|
||||
if current_test is not None:
|
||||
os.environ["PYTEST_CURRENT_TEST"] = current_test
|
||||
_MODULE_TEMP_DIR.cleanup()
|
||||
|
||||
|
||||
def _analysis_context_pack_overview() -> dict:
|
||||
return {
|
||||
"pack_version": "1.0",
|
||||
|
||||
@@ -124,6 +124,18 @@ class AnalysisHistoryTestCase(unittest.TestCase):
|
||||
auth._auth_enabled = False
|
||||
self._temp_dir = tempfile.TemporaryDirectory()
|
||||
self._db_path = os.path.join(self._temp_dir.name, "test_analysis_history.db")
|
||||
self._original_env = {
|
||||
key: os.environ.get(key)
|
||||
for key in (
|
||||
"ENV_FILE",
|
||||
"DATABASE_PATH",
|
||||
)
|
||||
}
|
||||
self._env_path = os.path.join(self._temp_dir.name, ".env")
|
||||
with open(self._env_path, "w", encoding="utf-8") as env_file:
|
||||
env_file.write("STOCK_LIST=600519,000001\n")
|
||||
|
||||
os.environ["ENV_FILE"] = self._env_path
|
||||
os.environ["DATABASE_PATH"] = self._db_path
|
||||
|
||||
Config._instance = None
|
||||
@@ -132,7 +144,13 @@ class AnalysisHistoryTestCase(unittest.TestCase):
|
||||
|
||||
def tearDown(self) -> None:
|
||||
"""清理资源"""
|
||||
Config._instance = None
|
||||
DatabaseManager.reset_instance()
|
||||
for key, value in self._original_env.items():
|
||||
if value is None:
|
||||
os.environ.pop(key, None)
|
||||
else:
|
||||
os.environ[key] = value
|
||||
self._temp_dir.cleanup()
|
||||
|
||||
def _build_result(self) -> AnalysisResult:
|
||||
|
||||
@@ -24,6 +24,19 @@ class BacktestServiceTestCase(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
self._temp_dir = tempfile.TemporaryDirectory()
|
||||
self._db_path = os.path.join(self._temp_dir.name, "test_backtest_service.db")
|
||||
self._original_env = {
|
||||
key: os.environ.get(key)
|
||||
for key in (
|
||||
"ENV_FILE",
|
||||
"DATABASE_PATH",
|
||||
"BACKTEST_EVAL_WINDOW_DAYS",
|
||||
)
|
||||
}
|
||||
self._env_path = os.path.join(self._temp_dir.name, ".env")
|
||||
with open(self._env_path, "w", encoding="utf-8") as env_file:
|
||||
env_file.write("STOCK_LIST=600519,000001\n")
|
||||
|
||||
os.environ["ENV_FILE"] = self._env_path
|
||||
os.environ["DATABASE_PATH"] = self._db_path
|
||||
os.environ["BACKTEST_EVAL_WINDOW_DAYS"] = "3"
|
||||
|
||||
@@ -145,7 +158,13 @@ class BacktestServiceTestCase(unittest.TestCase):
|
||||
session.commit()
|
||||
|
||||
def tearDown(self) -> None:
|
||||
Config._instance = None
|
||||
DatabaseManager.reset_instance()
|
||||
for key, value in self._original_env.items():
|
||||
if value is None:
|
||||
os.environ.pop(key, None)
|
||||
else:
|
||||
os.environ[key] = value
|
||||
self._temp_dir.cleanup()
|
||||
|
||||
def _count_results(self) -> int:
|
||||
|
||||
Reference in New Issue
Block a user