aria-code 0.167.0__py3-none-win_amd64.whl

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 (601) hide show
  1. aria_bots/__init__.py +7 -0
  2. aria_bots/channels/README.md +97 -0
  3. aria_bots/channels/__init__.py +1 -0
  4. aria_bots/channels/approvals.py +263 -0
  5. aria_bots/channels/conversation.py +280 -0
  6. aria_bots/channels/digest.py +186 -0
  7. aria_bots/channels/registry.py +95 -0
  8. aria_bots/engine.py +144 -0
  9. aria_bots/feishu_bot.py +1385 -0
  10. aria_bots/logistics/__init__.py +1 -0
  11. aria_bots/logistics/carriers.py +253 -0
  12. aria_bots/logistics/freight.py +154 -0
  13. aria_bots/logistics/inventory.py +242 -0
  14. aria_bots/logistics/mcp_server.py +156 -0
  15. aria_bots/logistics/records.py +119 -0
  16. aria_bots/logistics/tenancy.py +152 -0
  17. aria_bots/market.py +91 -0
  18. aria_bots/relay_client.py +326 -0
  19. aria_bots/telegram_bot.py +299 -0
  20. aria_code/__init__.py +111 -0
  21. aria_code/_bin/aria-native.exe +0 -0
  22. aria_code/_bin/aria-runtime.exe +0 -0
  23. aria_code/_version.py +20 -0
  24. aria_code/account_memory.py +296 -0
  25. aria_code/account_session.py +166 -0
  26. aria_code/adk_apps/__init__.py +1 -0
  27. aria_code/adk_apps/aria_code_review/__init__.py +1 -0
  28. aria_code/adk_apps/aria_code_review/agent.py +32 -0
  29. aria_code/adk_apps/aria_research/__init__.py +1 -0
  30. aria_code/adk_apps/aria_research/agent.py +31 -0
  31. aria_code/agents/__init__.py +49 -0
  32. aria_code/agents/base.py +329 -0
  33. aria_code/agents/code_review.py +200 -0
  34. aria_code/agents/deep/__init__.py +37 -0
  35. aria_code/agents/deep/calibration_loop.py +144 -0
  36. aria_code/agents/deep/critic.py +125 -0
  37. aria_code/agents/deep/deepen.py +193 -0
  38. aria_code/agents/deep/models.py +149 -0
  39. aria_code/agents/deep/pipeline.py +164 -0
  40. aria_code/agents/deep/quant_fusion.py +192 -0
  41. aria_code/agents/deep/themes.py +95 -0
  42. aria_code/agents/deep/tiers.py +106 -0
  43. aria_code/agents/engineering/__init__.py +14 -0
  44. aria_code/agents/engineering/coder.py +222 -0
  45. aria_code/agents/engineering/tester.py +145 -0
  46. aria_code/agents/financial/__init__.py +21 -0
  47. aria_code/agents/financial/cashflow_burn.py +119 -0
  48. aria_code/agents/financial/catalyst.py +279 -0
  49. aria_code/agents/financial/corporate_finance.py +175 -0
  50. aria_code/agents/financial/debate.py +224 -0
  51. aria_code/agents/financial/earnings.py +315 -0
  52. aria_code/agents/financial/fundamental.py +178 -0
  53. aria_code/agents/financial/macro.py +111 -0
  54. aria_code/agents/financial/news.py +231 -0
  55. aria_code/agents/financial/risk.py +146 -0
  56. aria_code/agents/financial/sector.py +279 -0
  57. aria_code/agents/financial/strategist.py +121 -0
  58. aria_code/agents/financial/stripe_revenue.py +127 -0
  59. aria_code/agents/financial/synthesis.py +274 -0
  60. aria_code/agents/financial/technical.py +277 -0
  61. aria_code/agents/orchestrator.py +44 -0
  62. aria_code/agents/portfolio_agent.py +392 -0
  63. aria_code/agents/realty/__init__.py +62 -0
  64. aria_code/agents/realty/asset_diagnosis.py +152 -0
  65. aria_code/agents/realty/business_match.py +166 -0
  66. aria_code/agents/realty/cashflow_verify.py +209 -0
  67. aria_code/agents/realty/contract_rules.py +210 -0
  68. aria_code/agents/realty/energy_anomaly.py +189 -0
  69. aria_code/agents/realty/exit_settlement.py +208 -0
  70. aria_code/agents/realty/fulfillment_risk.py +206 -0
  71. aria_code/agents/realty/ops_optimize.py +160 -0
  72. aria_code/agents/realty/revenue_share.py +215 -0
  73. aria_code/agents/registry.py +168 -0
  74. aria_code/agents/signal_scheme.py +111 -0
  75. aria_code/agents/sports/__init__.py +0 -0
  76. aria_code/agents/sports/football_agent.py +197 -0
  77. aria_code/agents/supervisor.py +113 -0
  78. aria_code/agents/team.py +500 -0
  79. aria_code/agents/video/__init__.py +16 -0
  80. aria_code/agents/video/director.py +376 -0
  81. aria_code/agents/video/qa_agent.py +143 -0
  82. aria_code/agents/video/script_doctor.py +112 -0
  83. aria_code/agents/warehouse/__init__.py +25 -0
  84. aria_code/agents/warehouse/contracts.py +26 -0
  85. aria_code/agents/warehouse/dashboard.py +155 -0
  86. aria_code/agents/warehouse/fulfillment_leadtime.py +95 -0
  87. aria_code/agents/warehouse/inbound_exceptions.py +25 -0
  88. aria_code/agents/warehouse/inventory_health.py +24 -0
  89. aria_code/agents/warehouse/local_run.py +71 -0
  90. aria_code/agents/warehouse/local_snapshot.py +132 -0
  91. aria_code/agents/warehouse/logistics_cost.py +84 -0
  92. aria_code/agents/warehouse/logistics_sync.py +21 -0
  93. aria_code/agents/warehouse/navigation.schema.json +110 -0
  94. aria_code/agents/warehouse/task_agent.py +172 -0
  95. aria_code/agents/warehouse/workflow.py +31 -0
  96. aria_code/aliyun_data_client.py +4 -0
  97. aria_code/apps/README.md +12 -0
  98. aria_code/apps/__init__.py +2 -0
  99. aria_code/apps/channels/README.md +9 -0
  100. aria_code/apps/channels/__init__.py +17 -0
  101. aria_code/apps/channels/approvals.py +11 -0
  102. aria_code/apps/channels/conversation.py +11 -0
  103. aria_code/apps/channels/digest.py +11 -0
  104. aria_code/apps/channels/intake.py +92 -0
  105. aria_code/apps/channels/registry.py +11 -0
  106. aria_code/apps/channels/tradingview.py +94 -0
  107. aria_code/apps/cli/README.md +13 -0
  108. aria_code/apps/cli/__init__.py +2 -0
  109. aria_code/apps/cli/_optional.py +120 -0
  110. aria_code/apps/cli/app_server.py +656 -0
  111. aria_code/apps/cli/auto_update.py +125 -0
  112. aria_code/apps/cli/bootstrap.py +206 -0
  113. aria_code/apps/cli/broker_render.py +206 -0
  114. aria_code/apps/cli/chat_turn.py +1327 -0
  115. aria_code/apps/cli/cloud_models.py +231 -0
  116. aria_code/apps/cli/codegen_paths.py +29 -0
  117. aria_code/apps/cli/commands/__init__.py +34 -0
  118. aria_code/apps/cli/commands/_business_render.py +78 -0
  119. aria_code/apps/cli/commands/_ui.py +71 -0
  120. aria_code/apps/cli/commands/analysis_cmds.py +378 -0
  121. aria_code/apps/cli/commands/ashare_prediction_cmds.py +327 -0
  122. aria_code/apps/cli/commands/auth_cmds.py +215 -0
  123. aria_code/apps/cli/commands/backtest_cmds.py +2518 -0
  124. aria_code/apps/cli/commands/broker_cmds.py +1236 -0
  125. aria_code/apps/cli/commands/business_workflow_cmds.py +379 -0
  126. aria_code/apps/cli/commands/canvas_cmds.py +77 -0
  127. aria_code/apps/cli/commands/catalog.py +189 -0
  128. aria_code/apps/cli/commands/core_cmds.py +2748 -0
  129. aria_code/apps/cli/commands/data_cmds.py +521 -0
  130. aria_code/apps/cli/commands/diagnostic_cmds.py +285 -0
  131. aria_code/apps/cli/commands/diagnostic_ops_cmds.py +813 -0
  132. aria_code/apps/cli/commands/engineering_cmds.py +399 -0
  133. aria_code/apps/cli/commands/file_cmds.py +312 -0
  134. aria_code/apps/cli/commands/finance_service_cmds.py +60 -0
  135. aria_code/apps/cli/commands/fx_commodity_cmds.py +123 -0
  136. aria_code/apps/cli/commands/market.py +544 -0
  137. aria_code/apps/cli/commands/market_cmds.py +1419 -0
  138. aria_code/apps/cli/commands/market_context.py +432 -0
  139. aria_code/apps/cli/commands/market_render.py +7 -0
  140. aria_code/apps/cli/commands/model_cmds.py +2374 -0
  141. aria_code/apps/cli/commands/ops_cmds.py +721 -0
  142. aria_code/apps/cli/commands/orchestrator_cmds.py +181 -0
  143. aria_code/apps/cli/commands/pdf_export_cmds.py +125 -0
  144. aria_code/apps/cli/commands/portfolio_cmds.py +1316 -0
  145. aria_code/apps/cli/commands/report.py +476 -0
  146. aria_code/apps/cli/commands/scaffold_templates.py +617 -0
  147. aria_code/apps/cli/commands/session_cmds.py +236 -0
  148. aria_code/apps/cli/commands/session_ux_cmds.py +359 -0
  149. aria_code/apps/cli/commands/team.py +723 -0
  150. aria_code/apps/cli/commands/team_render.py +8 -0
  151. aria_code/apps/cli/commands/ui_cmds.py +401 -0
  152. aria_code/apps/cli/commands/warehouse_cmds.py +297 -0
  153. aria_code/apps/cli/commands/workflow_cmds.py +629 -0
  154. aria_code/apps/cli/commands/workspace_cmds.py +1543 -0
  155. aria_code/apps/cli/config_paths.py +73 -0
  156. aria_code/apps/cli/config_store.py +158 -0
  157. aria_code/apps/cli/constants.py +88 -0
  158. aria_code/apps/cli/context.py +34 -0
  159. aria_code/apps/cli/conversation_policy.py +53 -0
  160. aria_code/apps/cli/deterministic.py +200 -0
  161. aria_code/apps/cli/direct.py +48 -0
  162. aria_code/apps/cli/earnings_view.py +172 -0
  163. aria_code/apps/cli/endpoint_migration.py +64 -0
  164. aria_code/apps/cli/exec_events.py +255 -0
  165. aria_code/apps/cli/file_references.py +155 -0
  166. aria_code/apps/cli/finance_service_catalog.py +111 -0
  167. aria_code/apps/cli/football_reports.py +231 -0
  168. aria_code/apps/cli/github_app_auth.py +135 -0
  169. aria_code/apps/cli/google_login.py +239 -0
  170. aria_code/apps/cli/handlers/__init__.py +11 -0
  171. aria_code/apps/cli/handlers/broker_handlers.py +122 -0
  172. aria_code/apps/cli/handlers/chart_handlers.py +1314 -0
  173. aria_code/apps/cli/handlers/market_handlers.py +2570 -0
  174. aria_code/apps/cli/handlers/realty_handlers.py +114 -0
  175. aria_code/apps/cli/handlers/sports_handlers.py +22 -0
  176. aria_code/apps/cli/handlers/strategy_advice.py +82 -0
  177. aria_code/apps/cli/headless.py +352 -0
  178. aria_code/apps/cli/helpers.py +326 -0
  179. aria_code/apps/cli/hooks.py +180 -0
  180. aria_code/apps/cli/i18n.py +310 -0
  181. aria_code/apps/cli/intent.py +136 -0
  182. aria_code/apps/cli/intent_router.py +305 -0
  183. aria_code/apps/cli/intent_shadow.py +72 -0
  184. aria_code/apps/cli/intent_signals.py +347 -0
  185. aria_code/apps/cli/lifecycle_hooks.py +48 -0
  186. aria_code/apps/cli/local_tool_schemas.py +550 -0
  187. aria_code/apps/cli/main.py +39 -0
  188. aria_code/apps/cli/market_hours.py +100 -0
  189. aria_code/apps/cli/market_metadata.py +135 -0
  190. aria_code/apps/cli/market_universe.py +487 -0
  191. aria_code/apps/cli/message_processing.py +310 -0
  192. aria_code/apps/cli/mixin_binding.py +32 -0
  193. aria_code/apps/cli/model_catalog.py +652 -0
  194. aria_code/apps/cli/model_probe.py +169 -0
  195. aria_code/apps/cli/model_retirement.py +65 -0
  196. aria_code/apps/cli/native_branding.py +12 -0
  197. aria_code/apps/cli/native_bridge.py +118 -0
  198. aria_code/apps/cli/native_entry.py +58 -0
  199. aria_code/apps/cli/pdf_report.py +977 -0
  200. aria_code/apps/cli/plan_mode.py +139 -0
  201. aria_code/apps/cli/plotly_html.py +15 -0
  202. aria_code/apps/cli/prediction_feedback.py +202 -0
  203. aria_code/apps/cli/preflight.py +502 -0
  204. aria_code/apps/cli/project_aria.py +60 -0
  205. aria_code/apps/cli/prompt_assembly.py +78 -0
  206. aria_code/apps/cli/prompts/__init__.py +0 -0
  207. aria_code/apps/cli/prompts/coding.py +71 -0
  208. aria_code/apps/cli/prompts/select.py +193 -0
  209. aria_code/apps/cli/prompts/system_prompts.py +562 -0
  210. aria_code/apps/cli/prompts/ui.py +436 -0
  211. aria_code/apps/cli/provider_endpoints.py +237 -0
  212. aria_code/apps/cli/provider_keys.py +73 -0
  213. aria_code/apps/cli/providers/__init__.py +1 -0
  214. aria_code/apps/cli/providers/base.py +775 -0
  215. aria_code/apps/cli/providers/chat_routing.py +139 -0
  216. aria_code/apps/cli/providers/collaboration.py +98 -0
  217. aria_code/apps/cli/providers/llm/__init__.py +1 -0
  218. aria_code/apps/cli/providers/llm/offline_responses.py +68 -0
  219. aria_code/apps/cli/providers/llm/ollama_stream.py +1574 -0
  220. aria_code/apps/cli/providers/llm/response_cache.py +60 -0
  221. aria_code/apps/cli/providers/llm/sse_stream.py +298 -0
  222. aria_code/apps/cli/providers/runtime_bridge.py +586 -0
  223. aria_code/apps/cli/providers/vertexai_stream.py +592 -0
  224. aria_code/apps/cli/release_download.py +159 -0
  225. aria_code/apps/cli/review_runner.py +111 -0
  226. aria_code/apps/cli/runtime_consumer.py +769 -0
  227. aria_code/apps/cli/sandbox.py +32 -0
  228. aria_code/apps/cli/session_export.py +120 -0
  229. aria_code/apps/cli/session_jsonl.py +208 -0
  230. aria_code/apps/cli/session_refresh.py +123 -0
  231. aria_code/apps/cli/session_store.py +125 -0
  232. aria_code/apps/cli/skills_catalog.py +273 -0
  233. aria_code/apps/cli/task_isolation.py +211 -0
  234. aria_code/apps/cli/terminal_chrome.py +412 -0
  235. aria_code/apps/cli/todo_tracker.py +190 -0
  236. aria_code/apps/cli/tool_executor.py +932 -0
  237. aria_code/apps/cli/tool_registry.py +34 -0
  238. aria_code/apps/cli/tool_scope.py +113 -0
  239. aria_code/apps/cli/tools/__init__.py +40 -0
  240. aria_code/apps/cli/tools/context.py +46 -0
  241. aria_code/apps/cli/tools/file_tools.py +181 -0
  242. aria_code/apps/cli/tools/market_tools.py +626 -0
  243. aria_code/apps/cli/tools/notebook_tools.py +111 -0
  244. aria_code/apps/cli/tools/system_tools.py +656 -0
  245. aria_code/apps/cli/tools/write_tools.py +961 -0
  246. aria_code/apps/cli/tradingview_bridge.py +529 -0
  247. aria_code/apps/cli/transactions.py +269 -0
  248. aria_code/apps/cli/turn_planning.py +137 -0
  249. aria_code/apps/cli/update_check.py +257 -0
  250. aria_code/apps/cli/updater.py +373 -0
  251. aria_code/apps/cli/utils/__init__.py +0 -0
  252. aria_code/apps/cli/utils/market_detect.py +1663 -0
  253. aria_code/apps/cli/web_login.py +136 -0
  254. aria_code/apps/cli/workflow_runner.py +127 -0
  255. aria_code/apps/cli/workspace_route.py +121 -0
  256. aria_code/apps/daemon/README.md +14 -0
  257. aria_code/apps/vscode/README.md +115 -0
  258. aria_code/apps/vscode/package.json +70 -0
  259. aria_code/aria_cli.py +5244 -0
  260. aria_code/aria_daemon.py +1372 -0
  261. aria_code/aria_feishu_bot.py +16 -0
  262. aria_code/aria_mcp_server.py +61 -0
  263. aria_code/aria_relay_client.py +4 -0
  264. aria_code/aria_telegram_bot.py +11 -0
  265. aria_code/ariarc.py +385 -0
  266. aria_code/artifacts.py +581 -0
  267. aria_code/backtest_engine.py +4 -0
  268. aria_code/backtest_report.py +4 -0
  269. aria_code/brokers/__init__.py +78 -0
  270. aria_code/brokers/automation.py +193 -0
  271. aria_code/brokers/base.py +231 -0
  272. aria_code/brokers/capabilities.py +264 -0
  273. aria_code/brokers/cn/__init__.py +10 -0
  274. aria_code/brokers/cn/easytrader_broker.py +193 -0
  275. aria_code/brokers/cn/futu_broker.py +194 -0
  276. aria_code/brokers/cn/longbridge_broker.py +190 -0
  277. aria_code/brokers/cn/tiger_broker.py +196 -0
  278. aria_code/brokers/cn/xtquant_broker.py +225 -0
  279. aria_code/brokers/config.py +414 -0
  280. aria_code/brokers/intl/__init__.py +5 -0
  281. aria_code/brokers/intl/alpaca_broker.py +183 -0
  282. aria_code/brokers/intl/ibkr_broker.py +215 -0
  283. aria_code/brokers/intl/trading212_broker.py +183 -0
  284. aria_code/brokers/intl/webull_broker.py +156 -0
  285. aria_code/brokers/paper_broker.py +266 -0
  286. aria_code/brokers/planning.py +296 -0
  287. aria_code/brokers/registry.py +213 -0
  288. aria_code/brokers/trading.py +267 -0
  289. aria_code/canva_client.py +4 -0
  290. aria_code/change_store.py +127 -0
  291. aria_code/clients/__init__.py +0 -0
  292. aria_code/clients/aliyun_data_client.py +660 -0
  293. aria_code/clients/aria_relay_client.py +16 -0
  294. aria_code/clients/canva_client.py +284 -0
  295. aria_code/clients/figma_client.py +100 -0
  296. aria_code/clients/football_data_client.py +1671 -0
  297. aria_code/clients/kling_video_client.py +182 -0
  298. aria_code/clients/market_data_client.py +1985 -0
  299. aria_code/clients/openai_image_client.py +242 -0
  300. aria_code/clients/runway_video_client.py +157 -0
  301. aria_code/clients/warehouse_erp_client.py +105 -0
  302. aria_code/cloud_memory.py +190 -0
  303. aria_code/command_safety.py +19 -0
  304. aria_code/computer_use_server.py +276 -0
  305. aria_code/computer_use_tools.py +4 -0
  306. aria_code/dashboard_generator.py +579 -0
  307. aria_code/data_analysis_tools.py +4 -0
  308. aria_code/data_cleaner.py +483 -0
  309. aria_code/data_service.py +513 -0
  310. aria_code/datasources/__init__.py +23 -0
  311. aria_code/datasources/base.py +166 -0
  312. aria_code/datasources/router.py +253 -0
  313. aria_code/datasources/sec_statements.py +217 -0
  314. aria_code/datasources/sources/__init__.py +15 -0
  315. aria_code/datasources/sources/akshare_source.py +269 -0
  316. aria_code/datasources/sources/alpha_vantage_source.py +203 -0
  317. aria_code/datasources/sources/edgar_source.py +219 -0
  318. aria_code/datasources/sources/finnhub_source.py +198 -0
  319. aria_code/datasources/sources/fred_source.py +223 -0
  320. aria_code/datasources/sources/tushare_source.py +143 -0
  321. aria_code/datasources/sources/web_scraper_source.py +278 -0
  322. aria_code/datasources/sources/world_bank_source.py +206 -0
  323. aria_code/datasources/sources/yfinance_source.py +152 -0
  324. aria_code/doctor.py +860 -0
  325. aria_code/domain/__init__.py +0 -0
  326. aria_code/domain/_finance_core/__init__.py +5 -0
  327. aria_code/domain/_finance_core/backtest_engine.py +325 -0
  328. aria_code/domain/_finance_core/performance_stats.py +101 -0
  329. aria_code/domain/backtest_engine.py +75 -0
  330. aria_code/domain/backtest_report.py +488 -0
  331. aria_code/domain/finance_formulas.py +389 -0
  332. aria_code/domain/performance_stats.py +6 -0
  333. aria_code/domain/portfolio_ledger.py +307 -0
  334. aria_code/domain/strategy_vault.py +421 -0
  335. aria_code/evals/__init__.py +37 -0
  336. aria_code/evals/behavior.py +113 -0
  337. aria_code/evals/gap.py +93 -0
  338. aria_code/evals/harness.py +949 -0
  339. aria_code/evals/review_probe.py +132 -0
  340. aria_code/evals/runner.py +425 -0
  341. aria_code/evals/scorecard.py +322 -0
  342. aria_code/evals/summary.py +125 -0
  343. aria_code/external_agent_runner.py +115 -0
  344. aria_code/figma_client.py +4 -0
  345. aria_code/file_analysis_tools.py +4 -0
  346. aria_code/finance_formulas.py +4 -0
  347. aria_code/football_data_client.py +4 -0
  348. aria_code/image_gen_tools.py +4 -0
  349. aria_code/intent_classifier.py +459 -0
  350. aria_code/kling_video_client.py +4 -0
  351. aria_code/licensing.py +151 -0
  352. aria_code/local_finance_tools.py +4 -0
  353. aria_code/local_image_provider.py +4 -0
  354. aria_code/local_llm_provider.py +4 -0
  355. aria_code/macro_tools.py +4 -0
  356. aria_code/markdown_pdf.py +289 -0
  357. aria_code/market_data_client.py +4 -0
  358. aria_code/mcp_client.py +744 -0
  359. aria_code/memory_manager.py +273 -0
  360. aria_code/model_capability.py +512 -0
  361. aria_code/notification_tools.py +4 -0
  362. aria_code/openai_image_client.py +4 -0
  363. aria_code/packages/__init__.py +26 -0
  364. aria_code/packages/adk_bridge/__init__.py +11 -0
  365. aria_code/packages/adk_bridge/code_review_tools.py +49 -0
  366. aria_code/packages/adk_bridge/market_tools.py +125 -0
  367. aria_code/packages/aria_agents/__init__.py +5 -0
  368. aria_code/packages/aria_agents/manifest.py +78 -0
  369. aria_code/packages/aria_core/__init__.py +34 -0
  370. aria_code/packages/aria_core/architecture.py +269 -0
  371. aria_code/packages/aria_core/export.py +147 -0
  372. aria_code/packages/aria_core/manifest.py +65 -0
  373. aria_code/packages/aria_core/paths.py +57 -0
  374. aria_code/packages/aria_core/secure_file.py +68 -0
  375. aria_code/packages/aria_infra/__init__.py +15 -0
  376. aria_code/packages/aria_infra/arthera.py +58 -0
  377. aria_code/packages/aria_infra/doctor.py +246 -0
  378. aria_code/packages/aria_infra/product.py +40 -0
  379. aria_code/packages/aria_mcp/__init__.py +25 -0
  380. aria_code/packages/aria_mcp/bridge.py +232 -0
  381. aria_code/packages/aria_mcp/circuit.py +82 -0
  382. aria_code/packages/aria_mcp/config.py +162 -0
  383. aria_code/packages/aria_mcp/installer.py +95 -0
  384. aria_code/packages/aria_mcp/server.py +1705 -0
  385. aria_code/packages/aria_mcp/tools.py +81 -0
  386. aria_code/packages/aria_sdk/__init__.py +19 -0
  387. aria_code/packages/aria_sdk/client.py +393 -0
  388. aria_code/packages/aria_sdk/providers.py +70 -0
  389. aria_code/packages/aria_sdk/streaming.py +75 -0
  390. aria_code/packages/aria_sdk/types.py +86 -0
  391. aria_code/packages/aria_services/__init__.py +92 -0
  392. aria_code/packages/aria_services/cache.py +60 -0
  393. aria_code/packages/aria_services/context.py +356 -0
  394. aria_code/packages/aria_services/context_checkpoints.py +157 -0
  395. aria_code/packages/aria_services/data.py +11 -0
  396. aria_code/packages/aria_services/provider_health.py +304 -0
  397. aria_code/packages/aria_services/references.py +247 -0
  398. aria_code/packages/aria_services/registry.py +249 -0
  399. aria_code/packages/aria_services/research_protocol.py +137 -0
  400. aria_code/packages/aria_services/research_quality.py +186 -0
  401. aria_code/packages/aria_services/settings.py +160 -0
  402. aria_code/packages/aria_services/usage.py +151 -0
  403. aria_code/packages/aria_skills/__init__.py +46 -0
  404. aria_code/packages/aria_skills/catalog.py +149 -0
  405. aria_code/packages/aria_skills/loader.py +455 -0
  406. aria_code/packages/aria_skills/registry.py +84 -0
  407. aria_code/packages/aria_tools/__init__.py +5 -0
  408. aria_code/packages/aria_tools/financial/__init__.py +5 -0
  409. aria_code/packages/aria_tools/financial/_paths.py +92 -0
  410. aria_code/packages/aria_tools/registry.py +129 -0
  411. aria_code/packages/quant_engine/__init__.py +33 -0
  412. aria_code/packages/quant_engine/_namespace.py +24 -0
  413. aria_code/packages/quant_engine/backtest/__init__.py +10 -0
  414. aria_code/packages/quant_engine/backtest/core.py +53 -0
  415. aria_code/packages/quant_engine/backtest/engine.py +102 -0
  416. aria_code/packages/quant_engine/portfolio/__init__.py +9 -0
  417. aria_code/packages/quant_engine/portfolio/optimizer.py +85 -0
  418. aria_code/packages/quant_engine/sports/__init__.py +76 -0
  419. aria_code/packages/quant_engine/sports/calibrator.py +354 -0
  420. aria_code/packages/quant_engine/sports/dixon_coles.py +234 -0
  421. aria_code/packages/quant_engine/sports/elo.py +300 -0
  422. aria_code/packages/quant_engine/sports/form.py +188 -0
  423. aria_code/packages/quant_engine/sports/h2h.py +195 -0
  424. aria_code/packages/quant_engine/sports/predictor.py +312 -0
  425. aria_code/packages/quant_engine/sports/tracker.py +665 -0
  426. aria_code/packages/quant_engine/stochastic/__init__.py +31 -0
  427. aria_code/packages/quant_engine/stochastic/gbm_enhanced.py +195 -0
  428. aria_code/packages/quant_engine/stochastic/ito_calculus.py +477 -0
  429. aria_code/packages/quant_engine/stochastic/kelly_criterion.py +181 -0
  430. aria_code/packages/quant_engine/stochastic/monte_carlo_advanced.py +95 -0
  431. aria_code/packages/quant_engine/stochastic/options_pricing.py +576 -0
  432. aria_code/packages/quant_engine/stochastic/stochastic_processes.py +90 -0
  433. aria_code/packs/__init__.py +85 -0
  434. aria_code/packs/base.py +168 -0
  435. aria_code/packs/finance/__init__.py +250 -0
  436. aria_code/packs/healthcare/__init__.py +40 -0
  437. aria_code/packs/logistics/__init__.py +171 -0
  438. aria_code/packs/payments/__init__.py +139 -0
  439. aria_code/packs/realty/__init__.py +190 -0
  440. aria_code/packs/registry.py +202 -0
  441. aria_code/packs/rules.py +90 -0
  442. aria_code/plan_utils.py +194 -0
  443. aria_code/plugin_loader.py +328 -0
  444. aria_code/portfolio_ledger.py +4 -0
  445. aria_code/preview_server.py +449 -0
  446. aria_code/privacy/__init__.py +5 -0
  447. aria_code/privacy/feedback.py +123 -0
  448. aria_code/project_review.py +278 -0
  449. aria_code/project_review_api.py +235 -0
  450. aria_code/project_review_server.py +18 -0
  451. aria_code/project_tools.py +4 -0
  452. aria_code/providers/__init__.py +30 -0
  453. aria_code/providers/google_video_provider.py +256 -0
  454. aria_code/providers/llm/__init__.py +19 -0
  455. aria_code/providers/llm/anthropic.py +184 -0
  456. aria_code/providers/llm/arthera_gateway.py +90 -0
  457. aria_code/providers/llm/autoconfig.py +213 -0
  458. aria_code/providers/llm/base.py +139 -0
  459. aria_code/providers/llm/custom.py +158 -0
  460. aria_code/providers/llm/ollama.py +137 -0
  461. aria_code/providers/llm/openai_compat.py +350 -0
  462. aria_code/providers/llm/registry.py +457 -0
  463. aria_code/providers/local_image_provider.py +202 -0
  464. aria_code/providers/local_llm_provider.py +549 -0
  465. aria_code/providers/ollama_models.py +79 -0
  466. aria_code/providers/openai_params.py +32 -0
  467. aria_code/providers/tool_messages.py +100 -0
  468. aria_code/realty_data_tools.py +4 -0
  469. aria_code/report_exporters.py +150 -0
  470. aria_code/report_generator.py +1764 -0
  471. aria_code/review_service.py +497 -0
  472. aria_code/runtime/__init__.py +176 -0
  473. aria_code/runtime/acceptance.py +632 -0
  474. aria_code/runtime/agent_loop.py +1851 -0
  475. aria_code/runtime/agent_profiles.py +75 -0
  476. aria_code/runtime/approval.py +71 -0
  477. aria_code/runtime/baseline.py +219 -0
  478. aria_code/runtime/budget.py +232 -0
  479. aria_code/runtime/checkpoints.py +481 -0
  480. aria_code/runtime/consult.py +65 -0
  481. aria_code/runtime/contract.py +282 -0
  482. aria_code/runtime/delivery.py +432 -0
  483. aria_code/runtime/events.py +113 -0
  484. aria_code/runtime/gateway.py +167 -0
  485. aria_code/runtime/lsp.py +484 -0
  486. aria_code/runtime/native_index.py +153 -0
  487. aria_code/runtime/orchestrator.py +55 -0
  488. aria_code/runtime/processes.py +343 -0
  489. aria_code/runtime/project_graph.py +614 -0
  490. aria_code/runtime/repo_map.py +712 -0
  491. aria_code/runtime/research_bundle.py +105 -0
  492. aria_code/runtime/review.py +269 -0
  493. aria_code/runtime/run_state.py +127 -0
  494. aria_code/runtime/run_store.py +522 -0
  495. aria_code/runtime/scoped_runs.py +113 -0
  496. aria_code/runtime/self_healing.py +422 -0
  497. aria_code/runtime/semantic_diff.py +171 -0
  498. aria_code/runtime/subagent.py +721 -0
  499. aria_code/runtime/symbol_edit.py +117 -0
  500. aria_code/runtime/task_brief.py +46 -0
  501. aria_code/runtime/task_context.py +145 -0
  502. aria_code/runtime/task_ledger.py +108 -0
  503. aria_code/runtime/task_orchestrator.py +90 -0
  504. aria_code/runtime/task_outcome.py +33 -0
  505. aria_code/runtime/task_verification.py +266 -0
  506. aria_code/runtime/task_worktree.py +448 -0
  507. aria_code/runtime/tool_executor.py +329 -0
  508. aria_code/runtime/tool_policy.py +107 -0
  509. aria_code/runtime/transactions.py +216 -0
  510. aria_code/runtime/windows_job.py +115 -0
  511. aria_code/runtime/workflows.py +222 -0
  512. aria_code/runtime/worktrees.py +215 -0
  513. aria_code/runway_video_client.py +4 -0
  514. aria_code/safety/__init__.py +27 -0
  515. aria_code/safety/client_isolation.py +178 -0
  516. aria_code/safety/permissions.py +339 -0
  517. aria_code/safety/risk.py +699 -0
  518. aria_code/safety/sandbox.py +148 -0
  519. aria_code/safety/service.py +102 -0
  520. aria_code/service_endpoints.py +14 -0
  521. aria_code/setup_wizard.py +684 -0
  522. aria_code/spreadsheet_tools.py +4 -0
  523. aria_code/strategy_vault.py +4 -0
  524. aria_code/tools/__init__.py +0 -0
  525. aria_code/tools/artifact_tools.py +252 -0
  526. aria_code/tools/broker_tools.py +92 -0
  527. aria_code/tools/build_quant_engine.py +97 -0
  528. aria_code/tools/code_audit_tools.py +192 -0
  529. aria_code/tools/computer_use_tools.py +509 -0
  530. aria_code/tools/data_analysis_tools.py +831 -0
  531. aria_code/tools/enterprise_finance_tools.py +202 -0
  532. aria_code/tools/extended_tools.py +240 -0
  533. aria_code/tools/file_analysis_tools.py +880 -0
  534. aria_code/tools/image_gen_tools.py +114 -0
  535. aria_code/tools/local_finance_tools.py +3488 -0
  536. aria_code/tools/logistics_carriers.py +11 -0
  537. aria_code/tools/logistics_inventory.py +11 -0
  538. aria_code/tools/logistics_io.py +11 -0
  539. aria_code/tools/logistics_tenancy.py +11 -0
  540. aria_code/tools/logistics_tools.py +11 -0
  541. aria_code/tools/macro_tools.py +412 -0
  542. aria_code/tools/notification_tools.py +249 -0
  543. aria_code/tools/project_tools.py +525 -0
  544. aria_code/tools/realty_data_tools.py +662 -0
  545. aria_code/tools/spreadsheet_tools.py +399 -0
  546. aria_code/tools/stripe_tools.py +115 -0
  547. aria_code/tools/video_tools.py +500 -0
  548. aria_code/training/__init__.py +1 -0
  549. aria_code/training/compare.py +117 -0
  550. aria_code/training/prelude_commands.py +111 -0
  551. aria_code/training/prelude_eval.py +390 -0
  552. aria_code/training/prelude_real.py +183 -0
  553. aria_code/training/prelude_train.py +248 -0
  554. aria_code/training/sft_dataset.py +230 -0
  555. aria_code/training/trajectory_dataset.py +263 -0
  556. aria_code/ui/__init__.py +105 -0
  557. aria_code/ui/banner.py +404 -0
  558. aria_code/ui/completer.py +571 -0
  559. aria_code/ui/console.py +285 -0
  560. aria_code/ui/input_box.py +505 -0
  561. aria_code/ui/mentions.py +206 -0
  562. aria_code/ui/picker.py +248 -0
  563. aria_code/ui/render/__init__.py +11 -0
  564. aria_code/ui/render/actions.py +297 -0
  565. aria_code/ui/render/finance.py +1732 -0
  566. aria_code/ui/render/market.py +253 -0
  567. aria_code/ui/render/output.py +954 -0
  568. aria_code/ui/render/responsive.py +75 -0
  569. aria_code/ui/render/team.py +367 -0
  570. aria_code/ui/robot.py +239 -0
  571. aria_code/ui/startup_dashboard.py +110 -0
  572. aria_code/video_analysis.py +147 -0
  573. aria_code/video_editor.py +518 -0
  574. aria_code/video_workflow/__init__.py +8 -0
  575. aria_code/video_workflow/__main__.py +61 -0
  576. aria_code/video_workflow/engines/__init__.py +18 -0
  577. aria_code/video_workflow/engines/base.py +69 -0
  578. aria_code/video_workflow/engines/custom_model.py +204 -0
  579. aria_code/video_workflow/engines/google_veo.py +94 -0
  580. aria_code/video_workflow/engines/local_engine.py +71 -0
  581. aria_code/video_workflow/engines/registry.py +98 -0
  582. aria_code/video_workflow/google_models.py +278 -0
  583. aria_code/video_workflow/music/__init__.py +5 -0
  584. aria_code/video_workflow/music/foley_service.py +132 -0
  585. aria_code/video_workflow/music/service.py +212 -0
  586. aria_code/video_workflow/pipeline.py +620 -0
  587. aria_code/video_workflow/plan.py +202 -0
  588. aria_code/video_workflow/session.py +297 -0
  589. aria_code/workspace/__init__.py +6 -0
  590. aria_code/workspace/files.py +219 -0
  591. aria_code/workspace/verify.py +167 -0
  592. aria_code/workspace_changes.py +199 -0
  593. aria_code/workspace_service.py +196 -0
  594. aria_code/workspace_tools.py +150 -0
  595. aria_code-0.167.0.dist-info/METADATA +330 -0
  596. aria_code-0.167.0.dist-info/RECORD +601 -0
  597. aria_code-0.167.0.dist-info/WHEEL +5 -0
  598. aria_code-0.167.0.dist-info/entry_points.txt +5 -0
  599. aria_code-0.167.0.dist-info/licenses/LICENSE +201 -0
  600. aria_code-0.167.0.dist-info/licenses/NOTICE +49 -0
  601. aria_code-0.167.0.dist-info/top_level.txt +2 -0
File without changes
@@ -0,0 +1,5 @@
1
+ """Pure finance kernels owned by artheras/financial-service.
2
+
3
+ Files listed in finance-core.lock.json are imported unchanged from a reviewed
4
+ upstream commit. Keep host data access and broker adapters outside this package.
5
+ """
@@ -0,0 +1,325 @@
1
+ """backtest_engine.py — event-driven, multi-asset backtest engine.
2
+
3
+ A small, dependency-light engine that fixes the gaps of the template backtests:
4
+
5
+ * Event-driven: iterate bars chronologically; the strategy decides on each
6
+ bar's CLOSE and orders fill at the NEXT bar's OPEN (no look-ahead bias).
7
+ * Multi-asset portfolio: cash + per-symbol positions, target-weight rebalance.
8
+ * Realistic costs: commission + slippage on every fill.
9
+ * Backtest <-> live parity: a strategy implements ``Strategy.on_bar(ctx)`` and
10
+ returns ``StrategyOrder``s. The SAME strategy object can drive live trading —
11
+ ``strategy_order_to_intent`` converts an order into a broker ``OrderIntent``
12
+ for the preview -> risk -> (auto)execute pipeline.
13
+
14
+ The engine is pure (operates on provided ``Bar`` data) so it is fully unit
15
+ testable offline; ``load_bars`` bridges to DataService for real runs.
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ from abc import ABC, abstractmethod
21
+ from dataclasses import dataclass, field
22
+ from typing import Any, Callable, Dict, List, Optional
23
+
24
+ from . import performance_stats as stats
25
+
26
+
27
+ @dataclass
28
+ class Bar:
29
+ date: str
30
+ open: float
31
+ high: float
32
+ low: float
33
+ close: float
34
+ volume: float = 0.0
35
+
36
+
37
+ @dataclass
38
+ class StrategyOrder:
39
+ symbol: str
40
+ action: str # "buy" | "sell" | "target"
41
+ quantity: float = 0.0 # shares, for buy/sell
42
+ target_weight: Optional[float] = None # fraction of equity, for "target"
43
+
44
+
45
+ @dataclass
46
+ class Portfolio:
47
+ cash: float
48
+ positions: Dict[str, float] = field(default_factory=dict)
49
+
50
+ def market_value(self, prices: Dict[str, float]) -> float:
51
+ return sum(qty * prices.get(s, 0.0) for s, qty in self.positions.items())
52
+
53
+ def equity(self, prices: Dict[str, float]) -> float:
54
+ return self.cash + self.market_value(prices)
55
+
56
+
57
+ class Context:
58
+ """Read-only view handed to ``Strategy.on_bar`` each step."""
59
+
60
+ def __init__(self, date: str, bars: Dict[str, Bar],
61
+ history: Dict[str, List[Bar]], portfolio: Portfolio):
62
+ self.date = date
63
+ self.bars = bars
64
+ self.history = history
65
+ self.portfolio = portfolio
66
+
67
+ def price(self, symbol: str) -> float:
68
+ b = self.bars.get(symbol)
69
+ return b.close if b else 0.0
70
+
71
+ def position(self, symbol: str) -> float:
72
+ return self.portfolio.positions.get(symbol, 0.0)
73
+
74
+ def closes(self, symbol: str, n: int | None = None) -> List[float]:
75
+ hist = [b.close for b in self.history.get(symbol, [])]
76
+ return hist[-n:] if n else hist
77
+
78
+ def equity(self) -> float:
79
+ return self.portfolio.equity({s: self.price(s) for s in self.bars})
80
+
81
+
82
+ class Strategy(ABC):
83
+ """Backtest/live strategy. ``on_bar`` is called on each bar's close."""
84
+
85
+ name: str = "strategy"
86
+
87
+ def on_bar(self, ctx: Context) -> List[StrategyOrder]: # pragma: no cover - abstract
88
+ raise NotImplementedError
89
+
90
+
91
+ @dataclass
92
+ class BacktestResult:
93
+ strategy: str
94
+ symbols: List[str]
95
+ starting_cash: float
96
+ equity_curve: List[Dict[str, Any]] # [{date, equity}]
97
+ trades: List[Dict[str, Any]]
98
+ metrics: Dict[str, Any]
99
+ benchmark: Dict[str, Any]
100
+
101
+
102
+ def _metrics(equity_curve: List[Dict[str, Any]], trades: List[Dict[str, Any]],
103
+ periods: Optional[int] = None) -> Dict[str, Any]:
104
+ """Headline statistics for a run.
105
+
106
+ `periods` is the caller's own periods-per-year when they gave one, and then
107
+ behaves exactly as it always did. Left out, the span comes from the equity
108
+ curve's dates (see performance_stats), so a year of weekly bars and a year
109
+ of daily bars both annualize to a year. A curve whose dates cannot be read
110
+ falls back to 252, the old behaviour.
111
+ """
112
+ eq = [pt["equity"] for pt in equity_curve]
113
+ if len(eq) < 2 or eq[0] <= 0:
114
+ return {"total_return": 0.0, "annual_return": 0.0, "sharpe": 0.0,
115
+ "max_drawdown": 0.0, "n_trades": len(trades), "win_rate": 0.0}
116
+ rets = [eq[i] / eq[i - 1] - 1 for i in range(1, len(eq)) if eq[i - 1] > 0]
117
+ total = eq[-1] / eq[0] - 1
118
+ n = len(eq)
119
+ years = stats.span_years(equity_curve[0].get("date"), equity_curve[-1].get("date"))
120
+ if periods is not None:
121
+ sharpe_periods = periods
122
+ annual = -1.0 if total <= -1 else (1 + total) ** (periods / n) - 1
123
+ elif years is not None:
124
+ sharpe_periods = len(rets) / years
125
+ annual = stats.annualized_return(total, years)
126
+ else:
127
+ sharpe_periods = stats.FALLBACK_PERIODS_PER_YEAR
128
+ annual = -1.0 if total <= -1 else (1 + total) ** (sharpe_periods / n) - 1
129
+ sells = [t for t in trades if t["side"] == "sell"]
130
+ wins = [t for t in sells if t.get("realized_pnl", 0) > 0]
131
+ return {
132
+ "total_return": round(total, 6),
133
+ "annual_return": round(annual, 6),
134
+ "sharpe": round(stats.sharpe(rets, sharpe_periods), 4),
135
+ "max_drawdown": round(stats.max_drawdown(eq), 6),
136
+ "n_trades": len(trades),
137
+ "win_rate": round(len(wins) / len(sells), 4) if sells else 0.0,
138
+ }
139
+
140
+
141
+ class BacktestEngine:
142
+ def __init__(self, *, starting_cash: float = 100_000.0,
143
+ commission: float = 0.0005, slippage: float = 0.0005,
144
+ periods_per_year: Optional[int] = None):
145
+ self.starting_cash = float(starting_cash)
146
+ self.commission = float(commission)
147
+ self.slippage = float(slippage)
148
+ # None: read it from the data's dates. A number: the caller knows their data.
149
+ self.periods_per_year = None if periods_per_year is None else int(periods_per_year)
150
+
151
+ def run(self, data: Dict[str, List[Bar]], strategy: Strategy) -> BacktestResult:
152
+ symbols = list(data.keys())
153
+ by_date: Dict[str, Dict[str, Bar]] = {
154
+ s: {b.date: b for b in data[s]} for s in symbols
155
+ }
156
+ all_dates = sorted({b.date for bars in data.values() for b in bars})
157
+
158
+ cash = self.starting_cash
159
+ positions: Dict[str, float] = {s: 0.0 for s in symbols}
160
+ cost_basis: Dict[str, float] = {s: 0.0 for s in symbols} # avg cost
161
+ history: Dict[str, List[Bar]] = {s: [] for s in symbols}
162
+ last_close: Dict[str, float] = {s: 0.0 for s in symbols}
163
+ pending: List[StrategyOrder] = [] # buy/sell orders queued for next open
164
+ equity_curve: List[Dict[str, Any]] = []
165
+ trades: List[Dict[str, Any]] = []
166
+
167
+ for date in all_dates:
168
+ cur: Dict[str, Bar] = {}
169
+ for s in symbols:
170
+ b = by_date[s].get(date)
171
+ if b is not None:
172
+ cur[s] = b
173
+ history[s].append(b)
174
+ last_close[s] = b.close
175
+
176
+ # 1) Fill yesterday's orders at today's open (cost + slippage).
177
+ for order in pending:
178
+ b = cur.get(order.symbol)
179
+ if b is None or order.quantity <= 0:
180
+ continue
181
+ side = order.action
182
+ fill = b.open * (1 + self.slippage) if side == "buy" else b.open * (1 - self.slippage)
183
+ qty = order.quantity
184
+ if side == "buy":
185
+ gross = fill * qty
186
+ fee = gross * self.commission
187
+ if gross + fee > cash: # cap to affordable size
188
+ qty = max(0.0, (cash) / (fill * (1 + self.commission)))
189
+ gross = fill * qty
190
+ fee = gross * self.commission
191
+ if qty <= 0:
192
+ continue
193
+ prev_qty = positions[order.symbol]
194
+ new_qty = prev_qty + qty
195
+ cost_basis[order.symbol] = (
196
+ (cost_basis[order.symbol] * prev_qty + fill * qty) / new_qty
197
+ if new_qty > 0 else 0.0
198
+ )
199
+ positions[order.symbol] = new_qty
200
+ cash -= gross + fee
201
+ trades.append({"date": date, "symbol": order.symbol, "side": "buy",
202
+ "qty": round(qty, 6), "price": round(fill, 6),
203
+ "fee": round(fee, 6)})
204
+ else: # sell
205
+ qty = min(qty, positions[order.symbol])
206
+ if qty <= 0:
207
+ continue
208
+ gross = fill * qty
209
+ fee = gross * self.commission
210
+ realized = (fill - cost_basis[order.symbol]) * qty - fee
211
+ positions[order.symbol] -= qty
212
+ cash += gross - fee
213
+ trades.append({"date": date, "symbol": order.symbol, "side": "sell",
214
+ "qty": round(qty, 6), "price": round(fill, 6),
215
+ "fee": round(fee, 6), "realized_pnl": round(realized, 6)})
216
+ pending = []
217
+
218
+ # 2) Mark-to-market at today's close; record equity.
219
+ prices = {s: last_close[s] for s in symbols}
220
+ equity = cash + sum(positions[s] * prices[s] for s in symbols)
221
+ equity_curve.append({"date": date, "equity": round(equity, 4)})
222
+
223
+ # 3) Strategy decides on today's close → queue orders for next open.
224
+ ctx = Context(date, cur, history, Portfolio(cash, dict(positions)))
225
+ try:
226
+ orders = strategy.on_bar(ctx) or []
227
+ except Exception:
228
+ orders = []
229
+ for o in orders:
230
+ pending.append(self._normalize(o, equity, prices, positions))
231
+
232
+ metrics = _metrics(equity_curve, trades, self.periods_per_year)
233
+ benchmark = self._buy_hold(data, all_dates)
234
+ return BacktestResult(
235
+ strategy=getattr(strategy, "name", "strategy"),
236
+ symbols=symbols, starting_cash=self.starting_cash,
237
+ equity_curve=equity_curve, trades=trades,
238
+ metrics=metrics, benchmark=benchmark,
239
+ )
240
+
241
+ def _normalize(self, o: StrategyOrder, equity: float,
242
+ prices: Dict[str, float], positions: Dict[str, float]) -> StrategyOrder:
243
+ """Convert a target-weight order into a concrete buy/sell quantity."""
244
+ if o.action != "target" or o.target_weight is None:
245
+ return o
246
+ px = prices.get(o.symbol, 0.0)
247
+ if px <= 0:
248
+ return StrategyOrder(o.symbol, "buy", 0.0)
249
+ target_shares = (o.target_weight * equity) / px
250
+ delta = target_shares - positions.get(o.symbol, 0.0)
251
+ if delta >= 0:
252
+ return StrategyOrder(o.symbol, "buy", round(delta, 6))
253
+ return StrategyOrder(o.symbol, "sell", round(-delta, 6))
254
+
255
+ def _buy_hold(self, data: Dict[str, List[Bar]], all_dates: List[str]) -> Dict[str, Any]:
256
+ """Equal-weight buy-and-hold benchmark over the same window."""
257
+ symbols = [s for s in data if data[s]]
258
+ if not symbols or len(all_dates) < 2:
259
+ return {"total_return": 0.0}
260
+ firsts, lasts = {}, {}
261
+ for s in symbols:
262
+ bars = data[s]
263
+ firsts[s] = bars[0].close
264
+ lasts[s] = bars[-1].close
265
+ rets = [(lasts[s] / firsts[s] - 1) for s in symbols if firsts[s] > 0]
266
+ return {"total_return": round(sum(rets) / len(rets), 6) if rets else 0.0}
267
+
268
+
269
+ # ── Backtest <-> live parity bridge ────────────────────────────────────────────
270
+
271
+ # Strategies only simulate fills here; broker execution belongs to the host.
272
+
273
+ class BuyHoldStrategy(Strategy):
274
+ name = "buy_hold"
275
+
276
+ def __init__(self, weight: float = 1.0):
277
+ self.weight = weight
278
+ self._entered: set[str] = set()
279
+
280
+ def on_bar(self, ctx: Context) -> List[StrategyOrder]:
281
+ orders = []
282
+ per = self.weight / max(1, len(ctx.bars))
283
+ for s in ctx.bars:
284
+ if s not in self._entered:
285
+ orders.append(StrategyOrder(s, "target", target_weight=per))
286
+ self._entered.add(s)
287
+ return orders
288
+
289
+
290
+ class SmaCrossStrategy(Strategy):
291
+ name = "sma_cross"
292
+
293
+ def __init__(self, fast: int = 20, slow: int = 60, weight: float = 0.95):
294
+ self.fast, self.slow, self.weight = fast, slow, weight
295
+
296
+ def on_bar(self, ctx: Context) -> List[StrategyOrder]:
297
+ orders = []
298
+ per = self.weight / max(1, len(ctx.bars))
299
+ for s in ctx.bars:
300
+ closes = ctx.closes(s)
301
+ if len(closes) < self.slow:
302
+ continue
303
+ fast_ma = sum(closes[-self.fast:]) / self.fast
304
+ slow_ma = sum(closes[-self.slow:]) / self.slow
305
+ held = ctx.position(s) > 0
306
+ if fast_ma > slow_ma and not held:
307
+ orders.append(StrategyOrder(s, "target", target_weight=per))
308
+ elif fast_ma <= slow_ma and held:
309
+ orders.append(StrategyOrder(s, "target", target_weight=0.0))
310
+ return orders
311
+
312
+
313
+ _STRATEGIES: Dict[str, Callable[..., Strategy]] = {
314
+ "buy_hold": BuyHoldStrategy,
315
+ "sma_cross": SmaCrossStrategy,
316
+ }
317
+
318
+
319
+ def get_strategy(name: str, **kwargs: Any) -> Strategy:
320
+ cls = _STRATEGIES.get(str(name).lower())
321
+ if not cls:
322
+ raise ValueError(f"unknown strategy: {name} (have: {', '.join(_STRATEGIES)})")
323
+ return cls(**kwargs)
324
+
325
+
@@ -0,0 +1,101 @@
1
+ """Performance statistics, from the data's own calendar.
2
+
3
+ There were two backtest calculators in this package, and they disagreed. The
4
+ engine annualized as (1 + total) ** (252 / bars) - 1, which is right only when
5
+ a year holds 252 bars. Run on a calendar year of daily bars for a market that
6
+ trades every day it reported a 10.5% return as 7.1% a year, and on a year of
7
+ weekly bars it reported 59%. The report module annualized by calendar span but
8
+ still scaled volatility and Sharpe by sqrt(252). Neither could be right for a
9
+ 24/7 market, for weekly bars, or for an intraday run, and nothing tested the
10
+ numbers, because the only check was the output of the same code.
11
+
12
+ The statistics here read the span from the dates themselves, so one rule holds
13
+ for every bar frequency:
14
+
15
+ years = (last date - first date) / 365.25
16
+ annualized return = (1 + total) ** (1 / years) - 1
17
+ periods per year = observations / years
18
+ Sharpe = mean / sample-std * sqrt(periods per year)
19
+
20
+ An explicit periods-per-year is still honoured: someone who passes 365 knows
21
+ their data. Dates that cannot be read fall back to 252, the previous behaviour,
22
+ which keeps synthetic series ("1", "2", "3") working. There is a Go port of
23
+ this arithmetic (go/runtime/quant) checked against the fixtures this module
24
+ generates; change both together.
25
+ """
26
+ from __future__ import annotations
27
+
28
+ import math
29
+ from datetime import date
30
+ from typing import Optional, Sequence
31
+
32
+ #: What the engine assumed for every series, and what an undatable one still gets.
33
+ FALLBACK_PERIODS_PER_YEAR = 252
34
+
35
+ DAYS_PER_YEAR = 365.25
36
+
37
+ #: A span shorter than one trading day would compound a result hundreds of
38
+ #: times over. The report module already clamped here; the engine now does too.
39
+ MIN_YEARS = 1.0 / FALLBACK_PERIODS_PER_YEAR
40
+
41
+
42
+ def parse_day(text: object) -> Optional[date]:
43
+ """The calendar day of an ISO timestamp or date, or None when it is not one."""
44
+ try:
45
+ return date.fromisoformat(str(text)[:10])
46
+ except ValueError:
47
+ return None
48
+
49
+
50
+ def span_years(first: object, last: object) -> Optional[float]:
51
+ """Years between two dates, or None when either is unreadable or the span is not forward.
52
+
53
+ Clamped to MIN_YEARS from below so a one-day span cannot compound into nonsense.
54
+ """
55
+ a, b = parse_day(first), parse_day(last)
56
+ if a is None or b is None or b <= a:
57
+ return None
58
+ return max((b - a).days / DAYS_PER_YEAR, MIN_YEARS)
59
+
60
+
61
+ def annualized_return(total_return: float, years: float) -> float:
62
+ """The constant yearly rate that compounds to `total_return` over `years`."""
63
+ if total_return <= -1.0:
64
+ return -1.0
65
+ return (1.0 + total_return) ** (1.0 / years) - 1.0
66
+
67
+
68
+ def stddev(values: Sequence[float]) -> float:
69
+ """Sample standard deviation (n - 1); 0 for fewer than two values."""
70
+ if len(values) < 2:
71
+ return 0.0
72
+ mean = sum(values) / len(values)
73
+ variance = sum((v - mean) ** 2 for v in values) / (len(values) - 1)
74
+ return math.sqrt(max(variance, 0.0))
75
+
76
+
77
+ def sharpe(returns: Sequence[float], periods_per_year: float) -> float:
78
+ """Annualized mean over sample standard deviation; 0 when there is no spread."""
79
+ if len(returns) < 2:
80
+ return 0.0
81
+ std = stddev(returns)
82
+ if std <= 0:
83
+ return 0.0
84
+ return (sum(returns) / len(returns)) / std * math.sqrt(periods_per_year)
85
+
86
+
87
+ def max_drawdown(equity: Sequence[float]) -> float:
88
+ """The worst peak-to-trough fall, as a negative fraction (0 when never below a peak)."""
89
+ peak = equity[0] if equity else 0.0
90
+ worst = 0.0
91
+ for value in equity:
92
+ peak = max(peak, value)
93
+ if peak > 0:
94
+ worst = min(worst, value / peak - 1.0)
95
+ return worst
96
+
97
+
98
+ def periods_per_year_from_dates(n_returns: int, first: object, last: object) -> Optional[float]:
99
+ """How many observations a year this series holds, or None when its dates cannot say."""
100
+ years = span_years(first, last)
101
+ return None if years is None else n_returns / years
@@ -0,0 +1,75 @@
1
+ """Backtest compatibility API and host-specific data/broker adapters.
2
+
3
+ The pure simulation and strategy implementation is owned by financial-service
4
+ and pinned in finance-core.lock.json. This module retains existing imports,
5
+ data loading and order-intent conversion; it does not execute broker orders.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import List
11
+
12
+ from ._finance_core.backtest_engine import (
13
+ Bar,
14
+ BacktestEngine,
15
+ BacktestResult,
16
+ BuyHoldStrategy,
17
+ Context,
18
+ Portfolio,
19
+ SmaCrossStrategy,
20
+ Strategy,
21
+ StrategyOrder,
22
+ get_strategy,
23
+ stats,
24
+ _metrics,
25
+ _STRATEGIES,
26
+ )
27
+
28
+ __all__ = [
29
+ "Bar",
30
+ "BacktestEngine",
31
+ "BacktestResult",
32
+ "BuyHoldStrategy",
33
+ "Context",
34
+ "Portfolio",
35
+ "SmaCrossStrategy",
36
+ "Strategy",
37
+ "StrategyOrder",
38
+ "get_strategy",
39
+ "load_bars",
40
+ "strategy_order_to_intent",
41
+ ]
42
+
43
+
44
+ def strategy_order_to_intent(order: StrategyOrder, *, price: float | None = None, source: str = "strategy"):
45
+ """Convert a StrategyOrder into a broker OrderIntent so the SAME strategy can
46
+ drive live trading through the preview -> risk -> (auto)execute pipeline."""
47
+ from aria_code.brokers.trading import OrderIntent
48
+
49
+ if order.action == "target":
50
+ return OrderIntent(symbol=order.symbol, side="buy", target_weight=order.target_weight, source=source)
51
+ return OrderIntent(symbol=order.symbol, side=order.action, quantity=order.quantity, price=price, source=source)
52
+
53
+
54
+ def load_bars(symbol: str, days: int = 365, interval: str = "1d") -> List[Bar]:
55
+ """Pull OHLC history via DataService and adapt to Bar objects (for real runs)."""
56
+ from aria_code.data_service import DataService
57
+
58
+ res = DataService().history(symbol, days=days, interval=interval)
59
+ rows = (res.data or {}).get("data") or []
60
+ out: List[Bar] = []
61
+ for r in rows:
62
+ try:
63
+ out.append(
64
+ Bar(
65
+ date=str(r.get("date"))[:10],
66
+ open=float(r.get("open", 0) or 0),
67
+ high=float(r.get("high", 0) or 0),
68
+ low=float(r.get("low", 0) or 0),
69
+ close=float(r.get("close", 0) or 0),
70
+ volume=float(r.get("volume", 0) or 0),
71
+ )
72
+ )
73
+ except (TypeError, ValueError):
74
+ continue
75
+ return out