alpha-visualizer 0.3.0__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (419) hide show
  1. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.github/workflows/lighthouse.yml +4 -4
  2. alpha_visualizer-0.3.0/.hypothesis/constants/069853a4f8389a49 → alpha_visualizer-0.4.0/.hypothesis/constants/11405f641e79317e +1 -1
  3. alpha_visualizer-0.4.0/.hypothesis/constants/14f71fc9be9bf497 +4 -0
  4. alpha_visualizer-0.4.0/.hypothesis/constants/4720ae237de2a683 +4 -0
  5. alpha_visualizer-0.4.0/.hypothesis/constants/4726660442f99a00 +4 -0
  6. alpha_visualizer-0.3.0/.hypothesis/constants/7b2b6a48db4df50a → alpha_visualizer-0.4.0/.hypothesis/constants/6d12ac81de32365c +1 -1
  7. alpha_visualizer-0.4.0/.hypothesis/constants/ab4df659c6b192db +4 -0
  8. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/CHANGELOG.md +27 -0
  9. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/PKG-INFO +2 -1
  10. alpha_visualizer-0.4.0/docs/screenshots/en/strategy-signal-tv.png +0 -0
  11. alpha_visualizer-0.4.0/docs/screenshots/ja/strategy-signal-tv.png +0 -0
  12. alpha_visualizer-0.4.0/frontend/e2e/fixtures/forge/data/historical/SPY_1d.parquet +0 -0
  13. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/e2e/fixtures/forge/forge.yaml +2 -0
  14. alpha_visualizer-0.4.0/frontend/e2e/screenshots/strategy-signal-tv.spec.ts +49 -0
  15. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/openapi.json +191 -1
  16. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/playwright.config.ts +1 -1
  17. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/playwright.screenshots.config.ts +2 -2
  18. alpha_visualizer-0.4.0/frontend/src/api/__tests__/client.test.ts +101 -0
  19. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/api/client.ts +16 -1
  20. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/api/types.gen.ts +108 -0
  21. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/api/types.ts +10 -0
  22. alpha_visualizer-0.4.0/frontend/src/charts/tv/StrategySignalChartTV.stories.tsx +243 -0
  23. alpha_visualizer-0.4.0/frontend/src/charts/tv/StrategySignalChartTV.tsx +174 -0
  24. alpha_visualizer-0.4.0/frontend/src/charts/tv/__tests__/StrategySignalChartTV.test.tsx +250 -0
  25. alpha_visualizer-0.4.0/frontend/src/charts/tv/__tests__/trades.test.ts +219 -0
  26. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/tv/data.ts +41 -0
  27. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/tv/theme.ts +75 -0
  28. alpha_visualizer-0.4.0/frontend/src/charts/tv/trades.ts +181 -0
  29. alpha_visualizer-0.4.0/frontend/src/hooks/__tests__/useStrategyHistorical.test.tsx +101 -0
  30. alpha_visualizer-0.4.0/frontend/src/hooks/useStrategyHistorical.ts +35 -0
  31. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/pages/DetailPage.tsx +9 -1
  32. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/screens/StrategyScreen.tsx +10 -2
  33. alpha_visualizer-0.4.0/frontend/src/screens/strategy/SignalChartCard.tsx +145 -0
  34. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/pyproject.toml +3 -2
  35. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/__init__.py +1 -1
  36. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/app.py +2 -0
  37. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/forge_config.py +9 -0
  38. alpha_visualizer-0.4.0/src/alpha_visualizer/routers/historical.py +57 -0
  39. alpha_visualizer-0.4.0/src/alpha_visualizer/schemas/historical.py +41 -0
  40. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/schemas/results.py +9 -1
  41. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/services/backtest.py +36 -2
  42. alpha_visualizer-0.4.0/src/alpha_visualizer/services/historical.py +145 -0
  43. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/fixtures/build_e2e_fixture.py +48 -1
  44. alpha_visualizer-0.4.0/tests/routers/test_historical.py +102 -0
  45. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/schemas/test_schemas.py +69 -0
  46. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/services/test_backtest.py +137 -0
  47. alpha_visualizer-0.4.0/tests/services/test_historical.py +156 -0
  48. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/test_forge_config.py +40 -0
  49. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/uv.lock +46 -1
  50. alpha_visualizer-0.3.0/.hypothesis/constants/150dfae7c64cc789 +0 -4
  51. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.agents/skills/source-command-audit-licenses/SKILL.md +0 -0
  52. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.agents/skills/source-command-pre-release/SKILL.md +0 -0
  53. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.claude/commands/audit-licenses.md +0 -0
  54. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.claude/commands/pre-release.md +0 -0
  55. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.codex/hooks.json +0 -0
  56. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  57. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.github/ISSUE_TEMPLATE/bug_report_ja.yml +0 -0
  58. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  59. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  60. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.github/ISSUE_TEMPLATE/feature_request_ja.yml +0 -0
  61. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  62. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.github/codeql/README.md +0 -0
  63. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.github/codeql/codeql-config.yml +0 -0
  64. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.github/dependabot.yml +0 -0
  65. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.github/workflows/ci.yml +0 -0
  66. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.github/workflows/codeql.yml +0 -0
  67. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.github/workflows/release.yml +0 -0
  68. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.gitignore +0 -0
  69. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/.gitignore +0 -0
  70. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/0bf3463e8f4751b8 +0 -0
  71. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/152293548dfa1dc4 +0 -0
  72. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/291dc4c40995bea6 +0 -0
  73. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/312a7aaf12a1fd47 +0 -0
  74. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/331e194303817b32 +0 -0
  75. /alpha_visualizer-0.3.0/.hypothesis/constants/0a940b6ee0f389fc → /alpha_visualizer-0.4.0/.hypothesis/constants/368f2bae545df6be +0 -0
  76. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/3c70931be7dd2e4e +0 -0
  77. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/3f7b61d4b4a660e1 +0 -0
  78. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/4577b97f57a8a832 +0 -0
  79. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/4a1c4d1532cab28e +0 -0
  80. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/508b282112ab038e +0 -0
  81. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/5c12d3619c3f5d5b +0 -0
  82. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/757b1f8305546439 +0 -0
  83. /alpha_visualizer-0.3.0/.hypothesis/constants/0b2de83fbd38f835 → /alpha_visualizer-0.4.0/.hypothesis/constants/76d133f3ba15df09 +0 -0
  84. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/7aec89cee7c5a592 +0 -0
  85. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/7d3b67d825fc154a +0 -0
  86. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/7f90c9d611001617 +0 -0
  87. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/828ed73d45fcee28 +0 -0
  88. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/85f15eb28ea04389 +0 -0
  89. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/89aaa48f251cd53d +0 -0
  90. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/8add761403393fca +0 -0
  91. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/96ca93165140d446 +0 -0
  92. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/97982d8e7c8d4a95 +0 -0
  93. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/a5b6e9cccb23f349 +0 -0
  94. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/a636a4647020033d +0 -0
  95. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/b5803992d2e76cf5 +0 -0
  96. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/b76328deebb21ae6 +0 -0
  97. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/b9ff5bcd3a53e3a7 +0 -0
  98. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/c5349cb90ddc7968 +0 -0
  99. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/c5f6cf064ffb412d +0 -0
  100. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/c9814af66187059c +0 -0
  101. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/da39a3ee5e6b4b0d +0 -0
  102. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/dd2b62c354789905 +0 -0
  103. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/e44a457d795e56c2 +0 -0
  104. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/ea2d606acbfff989 +0 -0
  105. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/ee487c54cd5ca7dc +0 -0
  106. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/eed5e66c16ae84b8 +0 -0
  107. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/f7c4a04c97c0daf8 +0 -0
  108. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/fa443af6269a6e02 +0 -0
  109. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/.hypothesis/constants/ff4517cbfe51fea1 +0 -0
  110. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/AGENTS.md +0 -0
  111. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/CLAUDE.md +0 -0
  112. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/CODE_OF_CONDUCT.en.md +0 -0
  113. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/CODE_OF_CONDUCT.md +0 -0
  114. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/CONTRIBUTING.en.md +0 -0
  115. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/CONTRIBUTING.md +0 -0
  116. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/LICENSE +0 -0
  117. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/README.en.md +0 -0
  118. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/README.md +0 -0
  119. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/SECURITY.en.md +0 -0
  120. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/SECURITY.md +0 -0
  121. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/THIRDPARTY_LICENSES.txt +0 -0
  122. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/cliff.toml +0 -0
  123. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/docs/adr/0001-pages-vs-screens.md +0 -0
  124. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/docs/adr/0002-charts-visx-vs-components.md +0 -0
  125. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/docs/adr/0003-openapi-typescript-codegen.md +0 -0
  126. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/docs/adr/0004-condition-node-discriminated-union.md +0 -0
  127. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/docs/lighthouse-ci.md +0 -0
  128. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/docs/screenshots/en/browse.png +0 -0
  129. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/docs/screenshots/en/compare.png +0 -0
  130. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/docs/screenshots/en/detail.png +0 -0
  131. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/docs/screenshots/en/ideas.png +0 -0
  132. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/docs/screenshots/en/optimize.png +0 -0
  133. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/docs/screenshots/en/strategy.png +0 -0
  134. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/docs/screenshots/ja/browse.png +0 -0
  135. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/docs/screenshots/ja/compare.png +0 -0
  136. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/docs/screenshots/ja/detail.png +0 -0
  137. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/docs/screenshots/ja/ideas.png +0 -0
  138. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/docs/screenshots/ja/optimize.png +0 -0
  139. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/docs/screenshots/ja/strategy.png +0 -0
  140. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/.gitignore +0 -0
  141. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/.npmrc +0 -0
  142. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/.size-limit.json +0 -0
  143. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/.storybook/main.ts +0 -0
  144. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/.storybook/preview.ts +0 -0
  145. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/CLAUDE.md +0 -0
  146. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/README.md +0 -0
  147. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/THIRDPARTY_FONTS.md +0 -0
  148. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/e2e/fixtures/README.md +0 -0
  149. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/e2e/fixtures/forge/data/ideas/ideas.json +0 -0
  150. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/e2e/fixtures/forge/data/results/backtest_results.db +0 -0
  151. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/e2e/fixtures/forge/data/strategies/momo_breakout.json +0 -0
  152. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/e2e/fixtures/forge/data/strategies/rsi_reversal.json +0 -0
  153. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/e2e/fixtures/forge/data/strategies/sma_cross.json +0 -0
  154. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/e2e/helpers/locators.ts +0 -0
  155. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/e2e/samples/sample-fixture.spec.ts +0 -0
  156. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/e2e/screenshots/capture.spec.ts +0 -0
  157. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/e2e/screenshots/equity-tv.spec.ts +0 -0
  158. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/e2e/specs/browse.spec.ts +0 -0
  159. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/e2e/specs/compare.spec.ts +0 -0
  160. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/e2e/specs/detail.spec.ts +0 -0
  161. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/e2e/specs/i18n.spec.ts +0 -0
  162. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/eslint.config.js +0 -0
  163. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/index.html +0 -0
  164. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/package.json +0 -0
  165. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/playwright.samples.config.ts +0 -0
  166. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/pnpm-lock.yaml +0 -0
  167. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/pnpm-workspace.yaml +0 -0
  168. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/public/favicon.svg +0 -0
  169. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/public/icons.svg +0 -0
  170. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/tv/CompareEquityTV.stories.tsx +0 -0
  171. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/tv/CompareEquityTV.tsx +0 -0
  172. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/tv/EquityDrawdownPaneTV.stories.tsx +0 -0
  173. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/tv/EquityDrawdownPaneTV.tsx +0 -0
  174. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/tv/RollingMetricsChartTV.stories.tsx +0 -0
  175. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/tv/RollingMetricsChartTV.tsx +0 -0
  176. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/tv/WFOEquityTV.stories.tsx +0 -0
  177. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/tv/WFOEquityTV.tsx +0 -0
  178. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/tv/__tests__/CompareEquityTV.test.tsx +0 -0
  179. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/tv/__tests__/EquityDrawdownPaneTV.test.tsx +0 -0
  180. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/tv/__tests__/RollingMetricsChartTV.test.tsx +0 -0
  181. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/tv/__tests__/WFOEquityTV.test.tsx +0 -0
  182. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/tv/__tests__/data.test.ts +0 -0
  183. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/tv/__tests__/theme.test.ts +0 -0
  184. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/visx/AnnualReturnsBarV.tsx +0 -0
  185. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/visx/CompareEquityV.tsx +0 -0
  186. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/visx/CorrelationHeatmapV.tsx +0 -0
  187. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/visx/DrawdownChartV.tsx +0 -0
  188. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/visx/EquityChartV.tsx +0 -0
  189. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/visx/MAEMFEScatterV.tsx +0 -0
  190. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/visx/MonthlyHeatmapV.tsx +0 -0
  191. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/visx/OptimizeScatterV.tsx +0 -0
  192. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/visx/Sparkline.stories.tsx +0 -0
  193. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/visx/Sparkline.tsx +0 -0
  194. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/visx/__tests__/EquityChartV.regime.test.ts +0 -0
  195. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/charts/visx/regimeBands.ts +0 -0
  196. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/CommandPalette.tsx +0 -0
  197. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/DetailToolbar.tsx +0 -0
  198. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/MetricsSummaryBarV2.stories.tsx +0 -0
  199. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/MetricsSummaryBarV2.tsx +0 -0
  200. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/RootLayout.tsx +0 -0
  201. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/SettingsToggles.tsx +0 -0
  202. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/StrategyHero.tsx +0 -0
  203. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/__tests__/CommandPalette.test.tsx +0 -0
  204. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/__tests__/CorrelationHeatmap.test.tsx +0 -0
  205. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/__tests__/responsive-styles.test.tsx +0 -0
  206. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/browser/CompareFloatingBar.tsx +0 -0
  207. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/browser/FilterBar.tsx +0 -0
  208. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/browser/GroupByToggle.tsx +0 -0
  209. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/browser/Heroline.tsx +0 -0
  210. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/browser/RunHistoryTab.tsx +0 -0
  211. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/browser/SavedViews.tsx +0 -0
  212. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/browser/StrategySlidePanel.tsx +0 -0
  213. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/browser/StrategyTable.tsx +0 -0
  214. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/browser/SymbolAtlas.tsx +0 -0
  215. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/browser/SymbolCard.tsx +0 -0
  216. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/charts/AnnualReturnsBar.tsx +0 -0
  217. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/charts/CorrelationHeatmap.tsx +0 -0
  218. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/charts/DrawdownDetailChart.tsx +0 -0
  219. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/charts/MAEMFEScatter.tsx +0 -0
  220. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/charts/MonteCarloChart.tsx +0 -0
  221. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/charts/OptimizeScatter.tsx +0 -0
  222. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/charts/ReturnDistributionChart.tsx +0 -0
  223. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/charts/RollingMetricsChart.tsx +0 -0
  224. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/charts/VaRChart.tsx +0 -0
  225. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/charts/WFOTimeline.tsx +0 -0
  226. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/charts/WeekdayPerformanceChart.tsx +0 -0
  227. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/live/LiveTab.tsx +0 -0
  228. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/live/__tests__/LiveTab.test.tsx +0 -0
  229. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/live/__tests__/format.test.ts +0 -0
  230. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/live/format.ts +0 -0
  231. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/metrics/CompareTable.tsx +0 -0
  232. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/metrics/ISOOSMetrics.tsx +0 -0
  233. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/metrics/MetricsGrid.tsx +0 -0
  234. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/metrics/RegimeBreakdownCards.tsx +0 -0
  235. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/metrics/SignalQualityBadge.tsx +0 -0
  236. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/metrics/__tests__/evaluateGood.test.ts +0 -0
  237. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/metrics/evaluate.ts +0 -0
  238. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/nav.ts +0 -0
  239. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/components/trades/TradeTable.tsx +0 -0
  240. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/constants/featureFlags.ts +0 -0
  241. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/constants/metricDefinitions.ts +0 -0
  242. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/contexts/DashboardContext.tsx +0 -0
  243. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/contexts/dashboardConstants.ts +0 -0
  244. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/design/a11y.css +0 -0
  245. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/design/primitives/Button.tsx +0 -0
  246. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/design/primitives/Card.tsx +0 -0
  247. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/design/primitives/Chip.tsx +0 -0
  248. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/design/primitives/Divider.tsx +0 -0
  249. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/design/primitives/KeyValue.tsx +0 -0
  250. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/design/primitives/OverflowMenu.tsx +0 -0
  251. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/design/primitives/Pill.stories.tsx +0 -0
  252. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/design/primitives/Pill.tsx +0 -0
  253. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/design/primitives/SectionHeader.tsx +0 -0
  254. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/design/primitives/Stat.stories.tsx +0 -0
  255. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/design/primitives/Stat.tsx +0 -0
  256. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/design/primitives/TabBar.tsx +0 -0
  257. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/design/primitives/Toolbar.tsx +0 -0
  258. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/design/primitives/__tests__/OverflowMenu.test.tsx +0 -0
  259. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/design/primitives/index.ts +0 -0
  260. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/design/tokens.css +0 -0
  261. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/design/useChartTheme.ts +0 -0
  262. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/hooks/__tests__/useEquityViewport.test.ts +0 -0
  263. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/hooks/__tests__/useFetchByKey.test.ts +0 -0
  264. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/hooks/__tests__/useScrollRestoration.test.tsx +0 -0
  265. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/hooks/__tests__/useStrategyList.test.tsx +0 -0
  266. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/hooks/__tests__/useTheme.test.tsx +0 -0
  267. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/hooks/useBacktestData.ts +0 -0
  268. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/hooks/useDebounce.ts +0 -0
  269. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/hooks/useEquityViewport.ts +0 -0
  270. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/hooks/useFetchByKey.ts +0 -0
  271. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/hooks/useIdeasList.ts +0 -0
  272. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/hooks/useRecentStrategies.ts +0 -0
  273. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/hooks/useScrollRestoration.ts +0 -0
  274. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/hooks/useSparklineCache.ts +0 -0
  275. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/hooks/useStrategyList.ts +0 -0
  276. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/hooks/useSymbolStats.ts +0 -0
  277. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/hooks/useTheme.ts +0 -0
  278. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/i18n/__tests__/strings.test.ts +0 -0
  279. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/i18n/strings.ts +0 -0
  280. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/__tests__/correlation.test.ts +0 -0
  281. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/__tests__/distribution.test.ts +0 -0
  282. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/__tests__/drawdown.test.ts +0 -0
  283. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/__tests__/format.test.ts +0 -0
  284. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/__tests__/monteCarlo.properties.test.ts +0 -0
  285. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/__tests__/monteCarlo.test.ts +0 -0
  286. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/__tests__/rolling.test.ts +0 -0
  287. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/__tests__/searchParams.test.ts +0 -0
  288. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/__tests__/searchStrategies.test.ts +0 -0
  289. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/__tests__/walkForward.test.ts +0 -0
  290. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/__tests__/weekday.test.ts +0 -0
  291. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/assetClass.ts +0 -0
  292. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/correlation.ts +0 -0
  293. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/csv.ts +0 -0
  294. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/distribution.ts +0 -0
  295. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/drawdown.ts +0 -0
  296. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/exportPng.ts +0 -0
  297. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/format.ts +0 -0
  298. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/monteCarlo.ts +0 -0
  299. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/rolling.ts +0 -0
  300. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/searchParams.ts +0 -0
  301. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/searchStrategies.ts +0 -0
  302. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/walkForward.ts +0 -0
  303. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/lib/weekday.ts +0 -0
  304. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/main.tsx +0 -0
  305. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/mock/btData.ts +0 -0
  306. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/pages/BrowsePage.tsx +0 -0
  307. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/pages/ComparePage.tsx +0 -0
  308. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/pages/IdeasPage.tsx +0 -0
  309. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/router.tsx +0 -0
  310. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/screens/BacktestScreen.stories.tsx +0 -0
  311. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/screens/BacktestScreen.tsx +0 -0
  312. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/screens/BrowseScreen.tsx +0 -0
  313. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/screens/CompareScreen.stories.tsx +0 -0
  314. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/screens/CompareScreen.tsx +0 -0
  315. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/screens/ISOOSScreen.tsx +0 -0
  316. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/screens/IdeasScreen.stories.tsx +0 -0
  317. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/screens/IdeasScreen.tsx +0 -0
  318. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/screens/OptimizeScreen.stories.tsx +0 -0
  319. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/screens/OptimizeScreen.tsx +0 -0
  320. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/screens/WFOScreen.stories.tsx +0 -0
  321. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/screens/WFOScreen.tsx +0 -0
  322. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/src/test-setup.ts +0 -0
  323. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/tsconfig.app.json +0 -0
  324. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/tsconfig.e2e.json +0 -0
  325. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/tsconfig.json +0 -0
  326. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/tsconfig.node.json +0 -0
  327. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/frontend/vite.config.ts +0 -0
  328. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/lighthouserc.json +0 -0
  329. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/release.sh +0 -0
  330. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/README.en.md +0 -0
  331. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/README.md +0 -0
  332. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/__init__.py +0 -0
  333. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/_generators/__init__.py +0 -0
  334. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/_generators/compatibility_matrix.py +0 -0
  335. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/_generators/ideas_defs.py +0 -0
  336. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/_generators/pseudo_backtest.py +0 -0
  337. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/_generators/pseudo_grid.py +0 -0
  338. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/_generators/pseudo_wfo.py +0 -0
  339. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/_generators/strategy_defs.py +0 -0
  340. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/_generators/synthetic_ohlcv.py +0 -0
  341. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/_generators/writers.py +0 -0
  342. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/build_samples.py +0 -0
  343. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/sample-forge/data/ideas/ideas.json +0 -0
  344. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/sample-forge/data/results/backtest_results.db +0 -0
  345. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/sample-forge/data/strategies/bbands_breakout_v1.json +0 -0
  346. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/sample-forge/data/strategies/donchian_turtle_v1.json +0 -0
  347. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/sample-forge/data/strategies/ema_adx_macd_v1.json +0 -0
  348. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/sample-forge/data/strategies/macd_crossover_v1.json +0 -0
  349. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/sample-forge/data/strategies/range_reversion_v1.json +0 -0
  350. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/sample-forge/data/strategies/rsi_reversion_v1.json +0 -0
  351. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/sample-forge/data/strategies/sma_crossover_v1.json +0 -0
  352. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/sample-forge/data/strategies/supertrend_adx_v1.json +0 -0
  353. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/samples/sample-forge/forge.yaml +0 -0
  354. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/scripts/generate_openapi.py +0 -0
  355. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/cli.py +0 -0
  356. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/db.py +0 -0
  357. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/dependencies.py +0 -0
  358. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/errors.py +0 -0
  359. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/log_sanitize.py +0 -0
  360. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/repositories/__init__.py +0 -0
  361. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/repositories/backtest_results.py +0 -0
  362. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/repositories/ideas.py +0 -0
  363. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/repositories/live.py +0 -0
  364. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/repositories/optimization.py +0 -0
  365. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/repositories/strategies.py +0 -0
  366. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/routers/__init__.py +0 -0
  367. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/routers/ideas.py +0 -0
  368. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/routers/live.py +0 -0
  369. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/routers/optimize.py +0 -0
  370. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/routers/results.py +0 -0
  371. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/routers/run.py +0 -0
  372. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/routers/strategies.py +0 -0
  373. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/routers/wfo.py +0 -0
  374. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/schemas/__init__.py +0 -0
  375. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/schemas/ideas.py +0 -0
  376. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/schemas/live.py +0 -0
  377. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/schemas/optimize.py +0 -0
  378. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/schemas/strategies.py +0 -0
  379. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/schemas/wfo.py +0 -0
  380. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/services/__init__.py +0 -0
  381. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/services/live.py +0 -0
  382. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/src/alpha_visualizer/services/walk_forward.py +0 -0
  383. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/__init__.py +0 -0
  384. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/conftest.py +0 -0
  385. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/factories.py +0 -0
  386. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/repositories/__init__.py +0 -0
  387. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/repositories/test_backtest_results_repo.py +0 -0
  388. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/repositories/test_ideas_reader.py +0 -0
  389. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/repositories/test_live_repo.py +0 -0
  390. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/repositories/test_optimization_repo.py +0 -0
  391. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/repositories/test_strategies_repo.py +0 -0
  392. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/routers/__init__.py +0 -0
  393. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/routers/test_forge_yaml_integration.py +0 -0
  394. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/routers/test_ideas.py +0 -0
  395. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/routers/test_live.py +0 -0
  396. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/routers/test_optimize.py +0 -0
  397. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/routers/test_results.py +0 -0
  398. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/routers/test_run.py +0 -0
  399. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/routers/test_strategies.py +0 -0
  400. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/routers/test_wfo.py +0 -0
  401. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/samples/__init__.py +0 -0
  402. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/samples/test_pseudo_backtest.py +0 -0
  403. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/samples/test_pseudo_grid.py +0 -0
  404. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/samples/test_pseudo_wfo.py +0 -0
  405. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/samples/test_sample_forge.py +0 -0
  406. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/samples/test_strategy_defs.py +0 -0
  407. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/samples/test_synthetic_ohlcv.py +0 -0
  408. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/samples/test_writers.py +0 -0
  409. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/schemas/__init__.py +0 -0
  410. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/services/__init__.py +0 -0
  411. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/services/test_backtest_properties.py +0 -0
  412. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/services/test_live.py +0 -0
  413. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/services/test_wfo.py +0 -0
  414. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/test_app.py +0 -0
  415. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/test_cli.py +0 -0
  416. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/test_db.py +0 -0
  417. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/test_dependencies.py +0 -0
  418. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/test_errors.py +0 -0
  419. {alpha_visualizer-0.3.0 → alpha_visualizer-0.4.0}/tests/test_log_sanitize.py +0 -0
@@ -54,20 +54,20 @@ jobs:
54
54
  working-directory: frontend
55
55
  run: pnpm run build
56
56
 
57
- - name: Start vis serve
57
+ - name: Start alpha-vis serve
58
58
  run: |
59
- uv run vis serve \
59
+ uv run alpha-vis serve \
60
60
  --forge-dir frontend/e2e/fixtures/forge \
61
61
  --port 8123 &
62
62
  # 起動待機(最大 30 秒)
63
63
  for i in $(seq 1 30); do
64
64
  if curl -fsS http://127.0.0.1:8123/health > /dev/null 2>&1; then
65
- echo "vis serve is up"
65
+ echo "alpha-vis serve is up"
66
66
  exit 0
67
67
  fi
68
68
  sleep 1
69
69
  done
70
- echo "::error::vis serve did not start within 30s"
70
+ echo "::error::alpha-vis serve did not start within 30s"
71
71
  exit 1
72
72
 
73
73
  - name: Run Lighthouse CI
@@ -1,4 +1,4 @@
1
1
  # file: /home/runner/work/alpha-visualizer/alpha-visualizer/src/alpha_visualizer/forge_config.py
2
2
  # hypothesis_version: 6.152.4
3
3
 
4
- ['FORGE_CONFIG', 'backtest_results.db', 'data', 'db_filename', 'forge.yaml', 'ideas', 'ideas.json', 'ideas_path', 'live', 'output_path', 'path', 'report', 'results', 'strategies', 'strategies.db', 'use_db', 'utf-8']
4
+ ['FORGE_CONFIG', 'backtest_results.db', 'data', 'db_filename', 'forge.yaml', 'historical', 'ideas', 'ideas.json', 'ideas_path', 'live', 'output_path', 'path', 'report', 'results', 'storage_path', 'strategies', 'strategies.db', 'use_db', 'utf-8']
@@ -0,0 +1,4 @@
1
+ # file: /home/runner/work/alpha-visualizer/alpha-visualizer/src/alpha_visualizer/services/backtest.py
2
+ # hypothesis_version: 6.152.4
3
+
4
+ [0.0, 1.0, 100.0, '+00:00', '-', '1d', 'Z', 'aggregates', 'annual_returns', 'avg_holding_days', 'build_detail', 'buy_hold_curve', 'buy_hold_equity', 'cagr_pct', 'calmar_ratio', 'compute_drawdown', 'daily_returns', 'date', 'dates', 'direction', 'drawdown', 'end', 'entry_date', 'entry_price', 'equity', 'equity_curve', 'exit_date', 'exit_price', 'filter_by_since', 'holding_days', 'id', 'index', 'is_cutoff', 'is_metrics', 'label_names', 'long', 'mae_pct', 'max_drawdown_pct', 'metrics', 'mfe_pct', 'monthly_returns', 'n_states', 'oos_metrics', 'oos_start', 'parse_dt', 'per_trade_mae_pct', 'per_trade_mfe_pct', 'period', 'periods', 'pnl', 'profit_factor', 'regime_breakdown', 'regime_series', 'return_pct', 'row_to_dict', 'run_at', 'run_id', 'shape_annual_returns', 'shape_equity', 'shape_regime_series', 'shape_trades', 'sharpe_ratio', 'short', 'signal', 'sl_price', 'sortino_ratio', 'split_metrics', 'start', 'states', 'strategy_id', 'strategy_name', 'summarize_row', 'symbol', 'timeframe', 'total_return_pct', 'total_trades', 'tp_price', 'trade_analysis', 'trades', 'value', 'values', 'win_rate_pct']
@@ -0,0 +1,4 @@
1
+ # file: /home/runner/work/alpha-visualizer/alpha-visualizer/src/alpha_visualizer/services/historical.py
2
+ # hypothesis_version: 6.152.4
3
+
4
+ ['\x00', '%Y-%m-%d', '%Y-%m-%dT%H:%M:%S', '..', '/', 'Close', 'High', 'Low', 'Open', 'Volume', '\\', 'close', 'coerce', 'high', 'low', 'open', 'symbol が空です', 'time', 'volume']
@@ -0,0 +1,4 @@
1
+ # file: /home/runner/work/alpha-visualizer/alpha-visualizer/src/alpha_visualizer/schemas/historical.py
2
+ # hypothesis_version: 6.152.4
3
+
4
+ ['allow']
@@ -1,4 +1,4 @@
1
1
  # file: /home/runner/work/alpha-visualizer/alpha-visualizer/src/alpha_visualizer/__init__.py
2
2
  # hypothesis_version: 6.152.4
3
3
 
4
- ['0.3.0']
4
+ ['0.4.0']
@@ -0,0 +1,4 @@
1
+ # file: /home/runner/work/alpha-visualizer/alpha-visualizer/src/alpha_visualizer/routers/historical.py
2
+ # hypothesis_version: 6.152.4
3
+
4
+ ['/historical/{symbol}', '1d', 'bars', 'interval', 'router', 'symbol']
@@ -3,6 +3,33 @@
3
3
  alpha-visualizer の全バージョン変更履歴です。
4
4
 
5
5
 
6
+ ## [0.4.0] - 2026-05-17
7
+
8
+ ### Features
9
+
10
+ - **TradingView lightweight-charts による「シグナル時系列」セクションを `StrategyScreen` に新規追加** (#191, #186, #197)
11
+ - OHLC ローソク + entry / exit markers (long/short × win/loss で 4 色分け) + SL / TP / entry の priceLine(focus trade は open trade 優先、無ければ最新 closed)
12
+ - regime 切替点に circle marker(`?tv=1` ON 時、`BacktestDetail.regime_series` 経由)
13
+ - `chart.takeScreenshot()` による PNG export ハンドル
14
+ - feature flag `?tv=1` OFF 時は実験機能 placeholder
15
+ - Storybook 6 stories(AtelierClosedTrades / LabOpenTrade / SLHit / TPHit / DenseMarkers / WithRegime)
16
+ - **OHLC 時系列 API** `GET /api/historical/{symbol}?interval=1d&start=&end=` を追加 (#189)
17
+ - `{symbol}_{interval}.parquet` を読んで lightweight-charts 互換の bars 配列を返す
18
+ - `ForgeConfig.historical_dir` を `forge.yaml` の `data.storage_path` から解決(既定 `<forge_dir>/data/historical`)
19
+ - 依存 `pyarrow>=15.0` を追加
20
+ - **`schemas/results.Trade` に `exit_price` / `sl_price` / `tp_price` を追加** (#189)
21
+ - alpha-forge の `_calc_trade_list` 拡張(ysakae/alpha-forge#751)の出力を透過 pickup
22
+ - **frontend `api.getHistorical(symbol, interval, range?)` と `useStrategyHistorical(symbol)` フック追加** (#190)
23
+ - `useFetchByKey` ベースの薄いラッパー、interval 切替時の再 fetch にも対応
24
+
25
+ ### Fixes
26
+
27
+ - **trades のソースを `metrics_json.trades` 優先に切替** (#198)
28
+ - alpha-forge は trades を 2 経路で保存(`metrics_json.trades` は snake_case、`trades_json` 列は vectorbt records_readable の PascalCase)
29
+ - 旧実装は PascalCase 列のみ参照しており `shape_trades` が値を読めず、実 backtest 結果で entry/exit markers / exit_price / sl_price / tp_price が常に機能しなかった
30
+ - snake_case → PascalCase の優先順位で解決し、新規・既存両方の backtest 結果で markers / priceLine が描画されるよう修正
31
+
32
+
6
33
  ## [0.3.0] - 2026-05-16
7
34
 
8
35
  ### ⚠️ Breaking Changes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alpha-visualizer
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Web visualization tool for AlphaForge backtest results
5
5
  Project-URL: Homepage, https://github.com/alforge-labs/alpha-visualizer
6
6
  Project-URL: Repository, https://github.com/alforge-labs/alpha-visualizer
@@ -23,6 +23,7 @@ Requires-Python: >=3.12
23
23
  Requires-Dist: click>=8.1
24
24
  Requires-Dist: fastapi>=0.115
25
25
  Requires-Dist: pandas>=2.0
26
+ Requires-Dist: pyarrow>=15.0
26
27
  Requires-Dist: pyyaml>=6.0
27
28
  Requires-Dist: rich>=13.0
28
29
  Requires-Dist: sqlalchemy>=2.0
@@ -7,3 +7,5 @@ strategies:
7
7
  use_db: false
8
8
  ideas:
9
9
  ideas_path: ./data/ideas
10
+ data:
11
+ storage_path: ./data/historical
@@ -0,0 +1,49 @@
1
+ import { test } from '@playwright/test'
2
+ import { mkdir } from 'node:fs/promises'
3
+ import { dirname, resolve } from 'node:path'
4
+ import { fileURLToPath } from 'node:url'
5
+ import { clearViewerSettings } from '../helpers/locators'
6
+
7
+ const __filename = fileURLToPath(import.meta.url)
8
+ const __dirname = dirname(__filename)
9
+
10
+ /**
11
+ * issue #191 — StrategyScreen の `<SignalChartCard>` (TV candlestick + markers + priceLine)
12
+ * を `?tv=1` で有効化して撮影。
13
+ *
14
+ * 出力先: <repo-root>/docs/screenshots/{ja,en}/strategy-signal-tv.png
15
+ */
16
+
17
+ const STRATEGY_ID = 'sma_cross'
18
+ const SCREENSHOT_DIR = resolve(__dirname, '../../../docs/screenshots')
19
+
20
+ async function ensureDir(filePath: string): Promise<void> {
21
+ await mkdir(dirname(filePath), { recursive: true })
22
+ }
23
+
24
+ test.describe.serial('StrategySignalChartTV スクリーンショット', () => {
25
+ for (const lang of ['ja', 'en'] as const) {
26
+ test(`strategy-signal-tv (${lang})`, async ({ page }) => {
27
+ await clearViewerSettings(page)
28
+ const suffix = `?tv=1${lang === 'en' ? '&lang=en' : ''}`
29
+ await page.goto(`/detail/${STRATEGY_ID}${suffix}`)
30
+ await page.waitForLoadState('networkidle')
31
+
32
+ // Strategy タブをクリックして SignalChartCard を表示させる
33
+ const tabName = lang === 'ja' ? '戦略構成' : 'Strategy'
34
+ const tab = page.getByRole('tab', { name: tabName }).first()
35
+ if (await tab.count()) {
36
+ await tab.click()
37
+ }
38
+
39
+ // SignalChartCard の chart コンテナを待つ
40
+ await page.locator('[data-testid="strategy-signal-chart-tv"]').waitFor()
41
+ // チャート描画完了の余裕(lightweight-charts の Canvas 初期化)
42
+ await page.waitForTimeout(300)
43
+
44
+ const out = resolve(SCREENSHOT_DIR, lang, 'strategy-signal-tv.png')
45
+ await ensureDir(out)
46
+ await page.screenshot({ path: out })
47
+ })
48
+ }
49
+ })
@@ -502,6 +502,89 @@
502
502
  }
503
503
  }
504
504
  },
505
+ "/api/historical/{symbol}": {
506
+ "get": {
507
+ "summary": "Get Historical",
508
+ "description": "指定 symbol × interval の OHLC ローソク足を返す。\n\n404: historical_dir 不在 or parquet ファイル不在\n400: symbol が不正、または start/end の形式不正",
509
+ "operationId": "get_historical_api_historical__symbol__get",
510
+ "parameters": [
511
+ {
512
+ "name": "symbol",
513
+ "in": "path",
514
+ "required": true,
515
+ "schema": {
516
+ "type": "string",
517
+ "title": "Symbol"
518
+ }
519
+ },
520
+ {
521
+ "name": "interval",
522
+ "in": "query",
523
+ "required": false,
524
+ "schema": {
525
+ "type": "string",
526
+ "pattern": "^(1m|2m|5m|15m|30m|60m|90m|1h|4h|1d|5d|1wk|1mo|3mo)$",
527
+ "default": "1d",
528
+ "title": "Interval"
529
+ }
530
+ },
531
+ {
532
+ "name": "start",
533
+ "in": "query",
534
+ "required": false,
535
+ "schema": {
536
+ "anyOf": [
537
+ {
538
+ "type": "string"
539
+ },
540
+ {
541
+ "type": "null"
542
+ }
543
+ ],
544
+ "title": "Start"
545
+ }
546
+ },
547
+ {
548
+ "name": "end",
549
+ "in": "query",
550
+ "required": false,
551
+ "schema": {
552
+ "anyOf": [
553
+ {
554
+ "type": "string"
555
+ },
556
+ {
557
+ "type": "null"
558
+ }
559
+ ],
560
+ "title": "End"
561
+ }
562
+ }
563
+ ],
564
+ "responses": {
565
+ "200": {
566
+ "description": "Successful Response",
567
+ "content": {
568
+ "application/json": {
569
+ "schema": {
570
+ "$ref": "#/components/schemas/HistoricalResponse"
571
+ }
572
+ }
573
+ }
574
+ },
575
+ "422": {
576
+ "description": "Validation Error",
577
+ "content": {
578
+ "application/json": {
579
+ "schema": {
580
+ "$ref": "#/components/schemas/HTTPValidationError"
581
+ }
582
+ }
583
+ }
584
+ }
585
+ }
586
+ }
587
+ },
505
588
  "/health": {
506
589
  "get": {
507
590
  "summary": "Health",
@@ -844,6 +927,34 @@
844
927
  "type": "object",
845
928
  "title": "HTTPValidationError"
846
929
  },
930
+ "HistoricalResponse": {
931
+ "properties": {
932
+ "symbol": {
933
+ "type": "string",
934
+ "title": "Symbol"
935
+ },
936
+ "interval": {
937
+ "type": "string",
938
+ "title": "Interval"
939
+ },
940
+ "bars": {
941
+ "items": {
942
+ "$ref": "#/components/schemas/OhlcBar"
943
+ },
944
+ "type": "array",
945
+ "title": "Bars"
946
+ }
947
+ },
948
+ "additionalProperties": true,
949
+ "type": "object",
950
+ "required": [
951
+ "symbol",
952
+ "interval",
953
+ "bars"
954
+ ],
955
+ "title": "HistoricalResponse",
956
+ "description": "OHLC 時系列のレスポンスエンベロープ。\n\n`bars` 配列に加えて symbol / interval を返すことで、フロント側で\n複数 symbol のキャッシュを取り違えないよう識別子を付与する。"
957
+ },
847
958
  "Idea": {
848
959
  "properties": {
849
960
  "idea_id": {
@@ -1300,6 +1411,52 @@
1300
1411
  "title": "LiveTrade",
1301
1412
  "description": "live trades JSON を正規化した 1 件。"
1302
1413
  },
1414
+ "OhlcBar": {
1415
+ "properties": {
1416
+ "time": {
1417
+ "type": "string",
1418
+ "title": "Time"
1419
+ },
1420
+ "open": {
1421
+ "type": "number",
1422
+ "title": "Open"
1423
+ },
1424
+ "high": {
1425
+ "type": "number",
1426
+ "title": "High"
1427
+ },
1428
+ "low": {
1429
+ "type": "number",
1430
+ "title": "Low"
1431
+ },
1432
+ "close": {
1433
+ "type": "number",
1434
+ "title": "Close"
1435
+ },
1436
+ "volume": {
1437
+ "anyOf": [
1438
+ {
1439
+ "type": "number"
1440
+ },
1441
+ {
1442
+ "type": "null"
1443
+ }
1444
+ ],
1445
+ "title": "Volume"
1446
+ }
1447
+ },
1448
+ "additionalProperties": true,
1449
+ "type": "object",
1450
+ "required": [
1451
+ "time",
1452
+ "open",
1453
+ "high",
1454
+ "low",
1455
+ "close"
1456
+ ],
1457
+ "title": "OhlcBar",
1458
+ "description": "1 本のローソク足 (open / high / low / close + volume)。\n\n`time` は ISO 8601 文字列(日足は ``YYYY-MM-DD``、intraday は\n``YYYY-MM-DDTHH:MM:SS``)。`volume` は無いカラムの parquet では None。"
1459
+ },
1303
1460
  "OptimizationHistoryEntry": {
1304
1461
  "properties": {
1305
1462
  "trial": {
@@ -1924,6 +2081,39 @@
1924
2081
  "title": "Entry Price",
1925
2082
  "default": 0.0
1926
2083
  },
2084
+ "exit_price": {
2085
+ "anyOf": [
2086
+ {
2087
+ "type": "number"
2088
+ },
2089
+ {
2090
+ "type": "null"
2091
+ }
2092
+ ],
2093
+ "title": "Exit Price"
2094
+ },
2095
+ "sl_price": {
2096
+ "anyOf": [
2097
+ {
2098
+ "type": "number"
2099
+ },
2100
+ {
2101
+ "type": "null"
2102
+ }
2103
+ ],
2104
+ "title": "Sl Price"
2105
+ },
2106
+ "tp_price": {
2107
+ "anyOf": [
2108
+ {
2109
+ "type": "number"
2110
+ },
2111
+ {
2112
+ "type": "null"
2113
+ }
2114
+ ],
2115
+ "title": "Tp Price"
2116
+ },
1927
2117
  "return_pct": {
1928
2118
  "type": "number",
1929
2119
  "title": "Return Pct",
@@ -1957,7 +2147,7 @@
1957
2147
  "direction"
1958
2148
  ],
1959
2149
  "title": "Trade",
1960
- "description": "``BacktestDetail.trades`` の 1 件。"
2150
+ "description": "``BacktestDetail.trades`` の 1 件。\n\n``exit_price`` / ``sl_price`` / ``tp_price`` は TradingView lightweight-charts\nの markers / priceLine 表示用に追加されたフィールド (#189)。\nalpha-forge 側が値を出力していない場合 ``None`` のままになる。"
1961
2151
  },
1962
2152
  "ValidationError": {
1963
2153
  "properties": {
@@ -32,7 +32,7 @@ export default defineConfig({
32
32
  // FORGE_CONFIG が外部 forge.yaml を指しているとフィクスチャが上書きされるので明示クリア。
33
33
  // --forge-config も併せて明示することで二重に保護する。
34
34
  command:
35
- 'env FORGE_CONFIG= uv run vis serve --forge-dir frontend/e2e/fixtures/forge --forge-config frontend/e2e/fixtures/forge/forge.yaml --host 127.0.0.1 --port 8123 --no-open',
35
+ 'env FORGE_CONFIG= uv run alpha-vis serve --forge-dir frontend/e2e/fixtures/forge --forge-config frontend/e2e/fixtures/forge/forge.yaml --host 127.0.0.1 --port 8123 --no-open',
36
36
  url: `${BASE_URL}/health`,
37
37
  cwd: '..',
38
38
  reuseExistingServer: !process.env.CI,
@@ -5,7 +5,7 @@ const BASE_URL = `http://127.0.0.1:${PORT}`
5
5
 
6
6
  /**
7
7
  * README / alforge-labs サイト掲載用スクリーンショット撮影専用 config。
8
- * 既存の e2e フィクスチャを流用して `vis serve` を自動起動し、
8
+ * 既存の e2e フィクスチャを流用して `alpha-vis serve` を自動起動し、
9
9
  * `e2e/screenshots/capture.spec.ts` から各画面を順次撮影する。
10
10
  *
11
11
  * 出力先: ../docs/screenshots/{ja,en}/<page>.png
@@ -32,7 +32,7 @@ export default defineConfig({
32
32
  ],
33
33
  webServer: {
34
34
  command:
35
- 'env FORGE_CONFIG= uv run vis serve --forge-dir frontend/e2e/fixtures/forge --forge-config frontend/e2e/fixtures/forge/forge.yaml --host 127.0.0.1 --port 8124 --no-open',
35
+ 'env FORGE_CONFIG= uv run alpha-vis serve --forge-dir frontend/e2e/fixtures/forge --forge-config frontend/e2e/fixtures/forge/forge.yaml --host 127.0.0.1 --port 8124 --no-open',
36
36
  url: `${BASE_URL}/health`,
37
37
  cwd: '..',
38
38
  reuseExistingServer: !process.env.CI,
@@ -0,0 +1,101 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
2
+ import { ApiError, api } from '../client'
3
+ import type { HistoricalResponse } from '../types'
4
+
5
+ /**
6
+ * `api.getHistorical` の URL 構築と response handling を検証する。
7
+ * fetch を vi.spyOn で乗っ取り、呼び出し URL と返却値を直接アサートする。
8
+ */
9
+ describe('api.getHistorical', () => {
10
+ const sampleResponse: HistoricalResponse = {
11
+ symbol: 'SPY',
12
+ interval: '1d',
13
+ bars: [
14
+ { time: '2025-01-02', open: 400, high: 405, low: 399, close: 403.5, volume: 1_000_000 },
15
+ ],
16
+ }
17
+
18
+ let fetchSpy: ReturnType<typeof vi.spyOn>
19
+
20
+ beforeEach(() => {
21
+ fetchSpy = vi.spyOn(globalThis, 'fetch')
22
+ })
23
+
24
+ afterEach(() => {
25
+ fetchSpy.mockRestore()
26
+ })
27
+
28
+ function mockJsonResponse(body: unknown, status = 200): void {
29
+ fetchSpy.mockResolvedValueOnce(
30
+ new Response(JSON.stringify(body), {
31
+ status,
32
+ headers: { 'Content-Type': 'application/json' },
33
+ }),
34
+ )
35
+ }
36
+
37
+ it('既定 interval=1d で /api/historical/{symbol}?interval=1d を呼ぶ', async () => {
38
+ mockJsonResponse(sampleResponse)
39
+
40
+ const result = await api.getHistorical('SPY')
41
+
42
+ expect(fetchSpy).toHaveBeenCalledTimes(1)
43
+ const url = String(fetchSpy.mock.calls[0]?.[0])
44
+ expect(url).toBe('/api/historical/SPY?interval=1d')
45
+ expect(result).toEqual(sampleResponse)
46
+ })
47
+
48
+ it('interval を指定するとクエリに反映される', async () => {
49
+ mockJsonResponse(sampleResponse)
50
+
51
+ await api.getHistorical('AAPL', '1h')
52
+
53
+ const url = String(fetchSpy.mock.calls[0]?.[0])
54
+ expect(url).toBe('/api/historical/AAPL?interval=1h')
55
+ })
56
+
57
+ it('range の start/end がクエリに乗る', async () => {
58
+ mockJsonResponse(sampleResponse)
59
+
60
+ await api.getHistorical('SPY', '1d', { start: '2024-01-02', end: '2024-03-25' })
61
+
62
+ const url = String(fetchSpy.mock.calls[0]?.[0])
63
+ expect(url).toBe(
64
+ '/api/historical/SPY?interval=1d&start=2024-01-02&end=2024-03-25',
65
+ )
66
+ })
67
+
68
+ it('range の start のみでも end が無ければ start のみ乗る', async () => {
69
+ mockJsonResponse(sampleResponse)
70
+
71
+ await api.getHistorical('SPY', '1d', { start: '2024-01-02' })
72
+
73
+ const url = String(fetchSpy.mock.calls[0]?.[0])
74
+ expect(url).toBe('/api/historical/SPY?interval=1d&start=2024-01-02')
75
+ })
76
+
77
+ it('symbol に special 文字が含まれていれば encode される', async () => {
78
+ mockJsonResponse(sampleResponse)
79
+
80
+ await api.getHistorical('CL=F')
81
+
82
+ const url = String(fetchSpy.mock.calls[0]?.[0])
83
+ expect(url).toBe('/api/historical/CL%3DF?interval=1d')
84
+ })
85
+
86
+ it('404 のとき ApiError を throw する', async () => {
87
+ mockJsonResponse({ detail: 'not found' }, 404)
88
+
89
+ const err = await api.getHistorical('UNKNOWN').then(
90
+ () => {
91
+ throw new Error('expected getHistorical to reject')
92
+ },
93
+ (e: unknown) => e,
94
+ )
95
+ expect(err).toBeInstanceOf(ApiError)
96
+ expect(err).toMatchObject({
97
+ status: 404,
98
+ url: '/api/historical/UNKNOWN?interval=1d',
99
+ })
100
+ })
101
+ })
@@ -1,4 +1,4 @@
1
- import type { BacktestDetail, IdeaItem, LiveDetailResponse, LiveListItem, OptimizeResult, StrategyComparison, StrategyDetail, StrategyListItem, StrategyRun, WFOResult } from './types'
1
+ import type { BacktestDetail, HistoricalResponse, IdeaItem, LiveDetailResponse, LiveListItem, OptimizeResult, StrategyComparison, StrategyDetail, StrategyListItem, StrategyRun, WFOResult } from './types'
2
2
 
3
3
  const API_BASE = '/api'
4
4
 
@@ -98,6 +98,21 @@ export const api = {
98
98
  const qs = runId ? `?run_id=${encodeURIComponent(runId)}` : ''
99
99
  return request<LiveDetailResponse>(`/live/${encodeURIComponent(strategyId)}${qs}`)
100
100
  },
101
+
102
+ // OHLC 時系列(#189 で backend に追加)。
103
+ // backend の /api/historical/{symbol} を呼び lightweight-charts 互換の bars を取得する。
104
+ getHistorical: (
105
+ symbol: string,
106
+ interval: string = '1d',
107
+ range?: { start?: string; end?: string },
108
+ ): Promise<HistoricalResponse> => {
109
+ const params = new URLSearchParams({ interval })
110
+ if (range?.start) params.set('start', range.start)
111
+ if (range?.end) params.set('end', range.end)
112
+ return request<HistoricalResponse>(
113
+ `/historical/${encodeURIComponent(symbol)}?${params.toString()}`,
114
+ )
115
+ },
101
116
  }
102
117
 
103
118
  export { ApiError }