aria-code 0.52.0__py3-none-any.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 (478) hide show
  1. aria_code/__init__.py +42 -0
  2. aria_code/_version.py +20 -0
  3. aria_code/adk_apps/__init__.py +1 -0
  4. aria_code/adk_apps/aria_code_review/__init__.py +1 -0
  5. aria_code/adk_apps/aria_code_review/agent.py +32 -0
  6. aria_code/adk_apps/aria_research/__init__.py +1 -0
  7. aria_code/adk_apps/aria_research/agent.py +31 -0
  8. aria_code/agents/__init__.py +34 -0
  9. aria_code/agents/base.py +318 -0
  10. aria_code/agents/code_review.py +200 -0
  11. aria_code/agents/deep/__init__.py +37 -0
  12. aria_code/agents/deep/calibration_loop.py +144 -0
  13. aria_code/agents/deep/critic.py +125 -0
  14. aria_code/agents/deep/deepen.py +193 -0
  15. aria_code/agents/deep/models.py +149 -0
  16. aria_code/agents/deep/pipeline.py +164 -0
  17. aria_code/agents/deep/quant_fusion.py +192 -0
  18. aria_code/agents/deep/themes.py +95 -0
  19. aria_code/agents/deep/tiers.py +106 -0
  20. aria_code/agents/engineering/__init__.py +14 -0
  21. aria_code/agents/engineering/coder.py +222 -0
  22. aria_code/agents/engineering/tester.py +145 -0
  23. aria_code/agents/financial/__init__.py +21 -0
  24. aria_code/agents/financial/cashflow_burn.py +119 -0
  25. aria_code/agents/financial/catalyst.py +279 -0
  26. aria_code/agents/financial/corporate_finance.py +175 -0
  27. aria_code/agents/financial/debate.py +224 -0
  28. aria_code/agents/financial/earnings.py +303 -0
  29. aria_code/agents/financial/fundamental.py +191 -0
  30. aria_code/agents/financial/macro.py +99 -0
  31. aria_code/agents/financial/news.py +207 -0
  32. aria_code/agents/financial/risk.py +165 -0
  33. aria_code/agents/financial/sector.py +279 -0
  34. aria_code/agents/financial/strategist.py +121 -0
  35. aria_code/agents/financial/stripe_revenue.py +127 -0
  36. aria_code/agents/financial/synthesis.py +274 -0
  37. aria_code/agents/financial/technical.py +258 -0
  38. aria_code/agents/orchestrator.py +44 -0
  39. aria_code/agents/portfolio_agent.py +363 -0
  40. aria_code/agents/realty/__init__.py +62 -0
  41. aria_code/agents/realty/asset_diagnosis.py +152 -0
  42. aria_code/agents/realty/business_match.py +166 -0
  43. aria_code/agents/realty/cashflow_verify.py +209 -0
  44. aria_code/agents/realty/contract_rules.py +210 -0
  45. aria_code/agents/realty/energy_anomaly.py +189 -0
  46. aria_code/agents/realty/exit_settlement.py +208 -0
  47. aria_code/agents/realty/fulfillment_risk.py +206 -0
  48. aria_code/agents/realty/ops_optimize.py +160 -0
  49. aria_code/agents/realty/revenue_share.py +215 -0
  50. aria_code/agents/registry.py +158 -0
  51. aria_code/agents/signal_scheme.py +111 -0
  52. aria_code/agents/sports/__init__.py +0 -0
  53. aria_code/agents/sports/football_agent.py +197 -0
  54. aria_code/agents/supervisor.py +113 -0
  55. aria_code/agents/team.py +492 -0
  56. aria_code/agents/warehouse/__init__.py +25 -0
  57. aria_code/agents/warehouse/contracts.py +26 -0
  58. aria_code/agents/warehouse/dashboard.py +155 -0
  59. aria_code/agents/warehouse/fulfillment_leadtime.py +95 -0
  60. aria_code/agents/warehouse/inbound_exceptions.py +25 -0
  61. aria_code/agents/warehouse/inventory_health.py +24 -0
  62. aria_code/agents/warehouse/local_run.py +71 -0
  63. aria_code/agents/warehouse/local_snapshot.py +132 -0
  64. aria_code/agents/warehouse/logistics_cost.py +84 -0
  65. aria_code/agents/warehouse/logistics_sync.py +21 -0
  66. aria_code/agents/warehouse/workflow.py +31 -0
  67. aria_code/aliyun_data_client.py +4 -0
  68. aria_code/apps/README.md +12 -0
  69. aria_code/apps/__init__.py +2 -0
  70. aria_code/apps/channels/README.md +15 -0
  71. aria_code/apps/channels/__init__.py +17 -0
  72. aria_code/apps/channels/intake.py +92 -0
  73. aria_code/apps/channels/registry.py +95 -0
  74. aria_code/apps/channels/tradingview.py +94 -0
  75. aria_code/apps/cli/README.md +13 -0
  76. aria_code/apps/cli/__init__.py +2 -0
  77. aria_code/apps/cli/_optional.py +120 -0
  78. aria_code/apps/cli/bootstrap.py +145 -0
  79. aria_code/apps/cli/broker_render.py +206 -0
  80. aria_code/apps/cli/codegen_paths.py +29 -0
  81. aria_code/apps/cli/commands/__init__.py +16 -0
  82. aria_code/apps/cli/commands/_business_render.py +78 -0
  83. aria_code/apps/cli/commands/_ui.py +71 -0
  84. aria_code/apps/cli/commands/analysis_cmds.py +369 -0
  85. aria_code/apps/cli/commands/ashare_prediction_cmds.py +327 -0
  86. aria_code/apps/cli/commands/auth_cmds.py +239 -0
  87. aria_code/apps/cli/commands/backtest_cmds.py +2543 -0
  88. aria_code/apps/cli/commands/broker_cmds.py +1234 -0
  89. aria_code/apps/cli/commands/business_workflow_cmds.py +319 -0
  90. aria_code/apps/cli/commands/canvas_cmds.py +77 -0
  91. aria_code/apps/cli/commands/catalog.py +87 -0
  92. aria_code/apps/cli/commands/core_cmds.py +2520 -0
  93. aria_code/apps/cli/commands/data_cmds.py +457 -0
  94. aria_code/apps/cli/commands/diagnostic_cmds.py +230 -0
  95. aria_code/apps/cli/commands/diagnostic_ops_cmds.py +813 -0
  96. aria_code/apps/cli/commands/file_cmds.py +312 -0
  97. aria_code/apps/cli/commands/finance_service_cmds.py +60 -0
  98. aria_code/apps/cli/commands/fx_commodity_cmds.py +123 -0
  99. aria_code/apps/cli/commands/market.py +434 -0
  100. aria_code/apps/cli/commands/market_cmds.py +1381 -0
  101. aria_code/apps/cli/commands/market_context.py +425 -0
  102. aria_code/apps/cli/commands/market_render.py +7 -0
  103. aria_code/apps/cli/commands/model_cmds.py +2153 -0
  104. aria_code/apps/cli/commands/ops_cmds.py +721 -0
  105. aria_code/apps/cli/commands/orchestrator_cmds.py +179 -0
  106. aria_code/apps/cli/commands/pdf_export_cmds.py +125 -0
  107. aria_code/apps/cli/commands/portfolio_cmds.py +1278 -0
  108. aria_code/apps/cli/commands/report.py +437 -0
  109. aria_code/apps/cli/commands/scaffold_templates.py +617 -0
  110. aria_code/apps/cli/commands/session_cmds.py +236 -0
  111. aria_code/apps/cli/commands/session_ux_cmds.py +359 -0
  112. aria_code/apps/cli/commands/team.py +669 -0
  113. aria_code/apps/cli/commands/team_render.py +8 -0
  114. aria_code/apps/cli/commands/ui_cmds.py +401 -0
  115. aria_code/apps/cli/commands/warehouse_cmds.py +79 -0
  116. aria_code/apps/cli/commands/workflow_cmds.py +480 -0
  117. aria_code/apps/cli/commands/workspace_cmds.py +1494 -0
  118. aria_code/apps/cli/config_paths.py +73 -0
  119. aria_code/apps/cli/config_store.py +78 -0
  120. aria_code/apps/cli/constants.py +88 -0
  121. aria_code/apps/cli/context.py +34 -0
  122. aria_code/apps/cli/deterministic.py +191 -0
  123. aria_code/apps/cli/direct.py +48 -0
  124. aria_code/apps/cli/finance_service_catalog.py +111 -0
  125. aria_code/apps/cli/football_reports.py +231 -0
  126. aria_code/apps/cli/github_app_auth.py +135 -0
  127. aria_code/apps/cli/google_login.py +196 -0
  128. aria_code/apps/cli/handlers/__init__.py +11 -0
  129. aria_code/apps/cli/handlers/broker_handlers.py +122 -0
  130. aria_code/apps/cli/handlers/chart_handlers.py +1309 -0
  131. aria_code/apps/cli/handlers/market_handlers.py +2513 -0
  132. aria_code/apps/cli/handlers/realty_handlers.py +114 -0
  133. aria_code/apps/cli/handlers/sports_handlers.py +22 -0
  134. aria_code/apps/cli/handlers/strategy_advice.py +82 -0
  135. aria_code/apps/cli/helpers.py +302 -0
  136. aria_code/apps/cli/hooks.py +180 -0
  137. aria_code/apps/cli/i18n.py +297 -0
  138. aria_code/apps/cli/intent.py +136 -0
  139. aria_code/apps/cli/intent_router.py +276 -0
  140. aria_code/apps/cli/intent_signals.py +344 -0
  141. aria_code/apps/cli/lifecycle_hooks.py +48 -0
  142. aria_code/apps/cli/local_tool_schemas.py +536 -0
  143. aria_code/apps/cli/main.py +29 -0
  144. aria_code/apps/cli/market_metadata.py +135 -0
  145. aria_code/apps/cli/market_universe.py +487 -0
  146. aria_code/apps/cli/message_processing.py +310 -0
  147. aria_code/apps/cli/model_catalog.py +620 -0
  148. aria_code/apps/cli/pdf_report.py +977 -0
  149. aria_code/apps/cli/plan_mode.py +139 -0
  150. aria_code/apps/cli/plotly_html.py +15 -0
  151. aria_code/apps/cli/prediction_feedback.py +202 -0
  152. aria_code/apps/cli/preflight.py +502 -0
  153. aria_code/apps/cli/project_aria.py +60 -0
  154. aria_code/apps/cli/prompt_assembly.py +59 -0
  155. aria_code/apps/cli/prompts/__init__.py +0 -0
  156. aria_code/apps/cli/prompts/coding.py +53 -0
  157. aria_code/apps/cli/prompts/select.py +142 -0
  158. aria_code/apps/cli/prompts/system_prompts.py +552 -0
  159. aria_code/apps/cli/prompts/ui.py +436 -0
  160. aria_code/apps/cli/provider_endpoints.py +237 -0
  161. aria_code/apps/cli/provider_keys.py +73 -0
  162. aria_code/apps/cli/providers/__init__.py +1 -0
  163. aria_code/apps/cli/providers/base.py +521 -0
  164. aria_code/apps/cli/providers/chat_routing.py +128 -0
  165. aria_code/apps/cli/providers/collaboration.py +98 -0
  166. aria_code/apps/cli/providers/llm/__init__.py +1 -0
  167. aria_code/apps/cli/providers/llm/offline_responses.py +68 -0
  168. aria_code/apps/cli/providers/llm/ollama_stream.py +1594 -0
  169. aria_code/apps/cli/providers/llm/response_cache.py +60 -0
  170. aria_code/apps/cli/providers/llm/sse_stream.py +257 -0
  171. aria_code/apps/cli/providers/runtime_bridge.py +353 -0
  172. aria_code/apps/cli/providers/vertexai_stream.py +316 -0
  173. aria_code/apps/cli/runtime_consumer.py +657 -0
  174. aria_code/apps/cli/sandbox.py +32 -0
  175. aria_code/apps/cli/session_export.py +120 -0
  176. aria_code/apps/cli/session_jsonl.py +208 -0
  177. aria_code/apps/cli/session_store.py +112 -0
  178. aria_code/apps/cli/skills_catalog.py +273 -0
  179. aria_code/apps/cli/todo_tracker.py +190 -0
  180. aria_code/apps/cli/tool_executor.py +823 -0
  181. aria_code/apps/cli/tool_registry.py +34 -0
  182. aria_code/apps/cli/tool_scope.py +106 -0
  183. aria_code/apps/cli/tools/__init__.py +40 -0
  184. aria_code/apps/cli/tools/context.py +46 -0
  185. aria_code/apps/cli/tools/file_tools.py +180 -0
  186. aria_code/apps/cli/tools/market_tools.py +620 -0
  187. aria_code/apps/cli/tools/notebook_tools.py +111 -0
  188. aria_code/apps/cli/tools/system_tools.py +726 -0
  189. aria_code/apps/cli/tools/write_tools.py +845 -0
  190. aria_code/apps/cli/tradingview_bridge.py +529 -0
  191. aria_code/apps/cli/turn_planning.py +137 -0
  192. aria_code/apps/cli/update_check.py +153 -0
  193. aria_code/apps/cli/utils/__init__.py +0 -0
  194. aria_code/apps/cli/utils/market_detect.py +1597 -0
  195. aria_code/apps/daemon/README.md +14 -0
  196. aria_code/apps/vscode/README.md +115 -0
  197. aria_code/apps/vscode/package.json +70 -0
  198. aria_code/aria_cli.py +6743 -0
  199. aria_code/aria_daemon.py +1398 -0
  200. aria_code/aria_feishu_bot.py +1423 -0
  201. aria_code/aria_mcp_server.py +7 -0
  202. aria_code/aria_relay_client.py +4 -0
  203. aria_code/aria_relay_server.py +490 -0
  204. aria_code/aria_telegram_bot.py +202 -0
  205. aria_code/ariarc.py +385 -0
  206. aria_code/artifacts.py +581 -0
  207. aria_code/backtest_engine.py +4 -0
  208. aria_code/backtest_report.py +4 -0
  209. aria_code/brokers/__init__.py +78 -0
  210. aria_code/brokers/automation.py +193 -0
  211. aria_code/brokers/base.py +231 -0
  212. aria_code/brokers/capabilities.py +264 -0
  213. aria_code/brokers/cn/__init__.py +10 -0
  214. aria_code/brokers/cn/easytrader_broker.py +193 -0
  215. aria_code/brokers/cn/futu_broker.py +194 -0
  216. aria_code/brokers/cn/longbridge_broker.py +190 -0
  217. aria_code/brokers/cn/tiger_broker.py +196 -0
  218. aria_code/brokers/cn/xtquant_broker.py +225 -0
  219. aria_code/brokers/config.py +414 -0
  220. aria_code/brokers/intl/__init__.py +5 -0
  221. aria_code/brokers/intl/alpaca_broker.py +183 -0
  222. aria_code/brokers/intl/ibkr_broker.py +215 -0
  223. aria_code/brokers/intl/trading212_broker.py +183 -0
  224. aria_code/brokers/intl/webull_broker.py +156 -0
  225. aria_code/brokers/paper_broker.py +266 -0
  226. aria_code/brokers/planning.py +296 -0
  227. aria_code/brokers/registry.py +213 -0
  228. aria_code/brokers/trading.py +267 -0
  229. aria_code/canva_client.py +4 -0
  230. aria_code/change_store.py +127 -0
  231. aria_code/clients/__init__.py +0 -0
  232. aria_code/clients/aliyun_data_client.py +660 -0
  233. aria_code/clients/aria_relay_client.py +182 -0
  234. aria_code/clients/canva_client.py +284 -0
  235. aria_code/clients/figma_client.py +100 -0
  236. aria_code/clients/football_data_client.py +1671 -0
  237. aria_code/clients/kling_video_client.py +182 -0
  238. aria_code/clients/market_data_client.py +1976 -0
  239. aria_code/clients/openai_image_client.py +242 -0
  240. aria_code/clients/runway_video_client.py +157 -0
  241. aria_code/clients/warehouse_erp_client.py +105 -0
  242. aria_code/cloud_memory.py +181 -0
  243. aria_code/command_safety.py +19 -0
  244. aria_code/computer_use_tools.py +4 -0
  245. aria_code/dashboard_generator.py +579 -0
  246. aria_code/data_analysis_tools.py +4 -0
  247. aria_code/data_cleaner.py +483 -0
  248. aria_code/data_service.py +513 -0
  249. aria_code/datasources/__init__.py +23 -0
  250. aria_code/datasources/base.py +166 -0
  251. aria_code/datasources/router.py +253 -0
  252. aria_code/datasources/sources/__init__.py +15 -0
  253. aria_code/datasources/sources/akshare_source.py +269 -0
  254. aria_code/datasources/sources/alpha_vantage_source.py +203 -0
  255. aria_code/datasources/sources/edgar_source.py +219 -0
  256. aria_code/datasources/sources/finnhub_source.py +198 -0
  257. aria_code/datasources/sources/fred_source.py +223 -0
  258. aria_code/datasources/sources/tushare_source.py +143 -0
  259. aria_code/datasources/sources/web_scraper_source.py +278 -0
  260. aria_code/datasources/sources/world_bank_source.py +206 -0
  261. aria_code/datasources/sources/yfinance_source.py +152 -0
  262. aria_code/demo_player.py +207 -0
  263. aria_code/doctor.py +813 -0
  264. aria_code/domain/__init__.py +0 -0
  265. aria_code/domain/backtest_engine.py +354 -0
  266. aria_code/domain/backtest_report.py +472 -0
  267. aria_code/domain/finance_formulas.py +389 -0
  268. aria_code/domain/portfolio_ledger.py +307 -0
  269. aria_code/domain/strategy_vault.py +421 -0
  270. aria_code/evals/__init__.py +37 -0
  271. aria_code/evals/harness.py +598 -0
  272. aria_code/evals/runner.py +238 -0
  273. aria_code/external_agent_runner.py +115 -0
  274. aria_code/figma_client.py +4 -0
  275. aria_code/file_analysis_tools.py +4 -0
  276. aria_code/finance_formulas.py +4 -0
  277. aria_code/football_data_client.py +4 -0
  278. aria_code/image_gen_tools.py +4 -0
  279. aria_code/intent_classifier.py +386 -0
  280. aria_code/kling_video_client.py +4 -0
  281. aria_code/licensing.py +151 -0
  282. aria_code/local_finance_tools.py +4 -0
  283. aria_code/local_image_provider.py +4 -0
  284. aria_code/local_llm_provider.py +4 -0
  285. aria_code/macro_tools.py +4 -0
  286. aria_code/markdown_pdf.py +289 -0
  287. aria_code/market_data_client.py +4 -0
  288. aria_code/mcp_client.py +639 -0
  289. aria_code/memory_manager.py +246 -0
  290. aria_code/model_capability.py +486 -0
  291. aria_code/notification_tools.py +4 -0
  292. aria_code/openai_image_client.py +4 -0
  293. aria_code/packages/__init__.py +23 -0
  294. aria_code/packages/adk_bridge/__init__.py +11 -0
  295. aria_code/packages/adk_bridge/code_review_tools.py +49 -0
  296. aria_code/packages/adk_bridge/market_tools.py +125 -0
  297. aria_code/packages/aria_agents/__init__.py +5 -0
  298. aria_code/packages/aria_agents/manifest.py +78 -0
  299. aria_code/packages/aria_core/__init__.py +34 -0
  300. aria_code/packages/aria_core/architecture.py +269 -0
  301. aria_code/packages/aria_core/export.py +147 -0
  302. aria_code/packages/aria_core/manifest.py +65 -0
  303. aria_code/packages/aria_core/paths.py +57 -0
  304. aria_code/packages/aria_core/secure_file.py +68 -0
  305. aria_code/packages/aria_infra/__init__.py +15 -0
  306. aria_code/packages/aria_infra/arthera.py +52 -0
  307. aria_code/packages/aria_infra/doctor.py +246 -0
  308. aria_code/packages/aria_infra/product.py +40 -0
  309. aria_code/packages/aria_mcp/__init__.py +25 -0
  310. aria_code/packages/aria_mcp/bridge.py +201 -0
  311. aria_code/packages/aria_mcp/circuit.py +82 -0
  312. aria_code/packages/aria_mcp/config.py +111 -0
  313. aria_code/packages/aria_mcp/installer.py +95 -0
  314. aria_code/packages/aria_mcp/server.py +1550 -0
  315. aria_code/packages/aria_mcp/tools.py +81 -0
  316. aria_code/packages/aria_sdk/__init__.py +19 -0
  317. aria_code/packages/aria_sdk/client.py +396 -0
  318. aria_code/packages/aria_sdk/providers.py +70 -0
  319. aria_code/packages/aria_sdk/streaming.py +79 -0
  320. aria_code/packages/aria_sdk/types.py +86 -0
  321. aria_code/packages/aria_services/__init__.py +92 -0
  322. aria_code/packages/aria_services/cache.py +60 -0
  323. aria_code/packages/aria_services/context.py +356 -0
  324. aria_code/packages/aria_services/context_checkpoints.py +157 -0
  325. aria_code/packages/aria_services/data.py +11 -0
  326. aria_code/packages/aria_services/provider_health.py +268 -0
  327. aria_code/packages/aria_services/references.py +247 -0
  328. aria_code/packages/aria_services/registry.py +249 -0
  329. aria_code/packages/aria_services/research_protocol.py +57 -0
  330. aria_code/packages/aria_services/research_quality.py +186 -0
  331. aria_code/packages/aria_services/settings.py +157 -0
  332. aria_code/packages/aria_services/usage.py +151 -0
  333. aria_code/packages/aria_skills/__init__.py +46 -0
  334. aria_code/packages/aria_skills/catalog.py +149 -0
  335. aria_code/packages/aria_skills/loader.py +455 -0
  336. aria_code/packages/aria_skills/registry.py +84 -0
  337. aria_code/packages/aria_tools/__init__.py +5 -0
  338. aria_code/packages/aria_tools/financial/__init__.py +8 -0
  339. aria_code/packages/aria_tools/financial/_paths.py +130 -0
  340. aria_code/packages/aria_tools/financial/compliance.py +31 -0
  341. aria_code/packages/aria_tools/financial/factors.py +33 -0
  342. aria_code/packages/aria_tools/financial/risk_tools.py +33 -0
  343. aria_code/packages/aria_tools/financial/strategy.py +31 -0
  344. aria_code/packages/aria_tools/registry.py +128 -0
  345. aria_code/packages/quant_engine/__init__.py +34 -0
  346. aria_code/packages/quant_engine/_namespace.py +62 -0
  347. aria_code/packages/quant_engine/backtest/__init__.py +14 -0
  348. aria_code/packages/quant_engine/backtest/core.py +53 -0
  349. aria_code/packages/quant_engine/backtest/engine.py +96 -0
  350. aria_code/packages/quant_engine/portfolio/__init__.py +13 -0
  351. aria_code/packages/quant_engine/portfolio/optimizer.py +85 -0
  352. aria_code/packages/quant_engine/sports/__init__.py +80 -0
  353. aria_code/packages/quant_engine/sports/calibrator.py +354 -0
  354. aria_code/packages/quant_engine/sports/dixon_coles.py +234 -0
  355. aria_code/packages/quant_engine/sports/elo.py +300 -0
  356. aria_code/packages/quant_engine/sports/form.py +188 -0
  357. aria_code/packages/quant_engine/sports/h2h.py +195 -0
  358. aria_code/packages/quant_engine/sports/ml_model.py +377 -0
  359. aria_code/packages/quant_engine/sports/predictor.py +312 -0
  360. aria_code/packages/quant_engine/sports/tracker.py +665 -0
  361. aria_code/packages/quant_engine/stochastic/__init__.py +35 -0
  362. aria_code/packages/quant_engine/stochastic/gbm_enhanced.py +195 -0
  363. aria_code/packages/quant_engine/stochastic/ito_calculus.py +477 -0
  364. aria_code/packages/quant_engine/stochastic/kelly_criterion.py +181 -0
  365. aria_code/packages/quant_engine/stochastic/monte_carlo_advanced.py +95 -0
  366. aria_code/packages/quant_engine/stochastic/options_pricing.py +576 -0
  367. aria_code/packages/quant_engine/stochastic/stochastic_processes.py +90 -0
  368. aria_code/packs/__init__.py +85 -0
  369. aria_code/packs/base.py +168 -0
  370. aria_code/packs/finance/__init__.py +250 -0
  371. aria_code/packs/logistics/__init__.py +169 -0
  372. aria_code/packs/payments/__init__.py +139 -0
  373. aria_code/packs/realty/__init__.py +190 -0
  374. aria_code/packs/registry.py +202 -0
  375. aria_code/packs/rules.py +90 -0
  376. aria_code/plan_utils.py +194 -0
  377. aria_code/plugin_loader.py +328 -0
  378. aria_code/portfolio_ledger.py +4 -0
  379. aria_code/preview_server.py +449 -0
  380. aria_code/privacy/__init__.py +5 -0
  381. aria_code/privacy/feedback.py +123 -0
  382. aria_code/project_review.py +278 -0
  383. aria_code/project_review_api.py +235 -0
  384. aria_code/project_review_server.py +18 -0
  385. aria_code/project_tools.py +4 -0
  386. aria_code/providers/__init__.py +30 -0
  387. aria_code/providers/llm/__init__.py +19 -0
  388. aria_code/providers/llm/anthropic.py +184 -0
  389. aria_code/providers/llm/autoconfig.py +213 -0
  390. aria_code/providers/llm/base.py +139 -0
  391. aria_code/providers/llm/custom.py +158 -0
  392. aria_code/providers/llm/ollama.py +129 -0
  393. aria_code/providers/llm/openai_compat.py +313 -0
  394. aria_code/providers/llm/registry.py +444 -0
  395. aria_code/providers/local_image_provider.py +202 -0
  396. aria_code/providers/local_llm_provider.py +589 -0
  397. aria_code/realty_data_tools.py +4 -0
  398. aria_code/report_exporters.py +150 -0
  399. aria_code/report_generator.py +1764 -0
  400. aria_code/runtime/__init__.py +169 -0
  401. aria_code/runtime/acceptance.py +481 -0
  402. aria_code/runtime/agent_loop.py +1520 -0
  403. aria_code/runtime/approval.py +57 -0
  404. aria_code/runtime/budget.py +232 -0
  405. aria_code/runtime/checkpoints.py +432 -0
  406. aria_code/runtime/crash_report.py +174 -0
  407. aria_code/runtime/events.py +113 -0
  408. aria_code/runtime/gateway.py +150 -0
  409. aria_code/runtime/lsp.py +484 -0
  410. aria_code/runtime/orchestrator.py +55 -0
  411. aria_code/runtime/repo_map.py +700 -0
  412. aria_code/runtime/run_state.py +127 -0
  413. aria_code/runtime/run_store.py +450 -0
  414. aria_code/runtime/self_healing.py +422 -0
  415. aria_code/runtime/subagent.py +547 -0
  416. aria_code/runtime/task_ledger.py +86 -0
  417. aria_code/runtime/task_orchestrator.py +90 -0
  418. aria_code/runtime/tool_executor.py +217 -0
  419. aria_code/runtime/tool_policy.py +107 -0
  420. aria_code/runtime/worktrees.py +215 -0
  421. aria_code/runway_video_client.py +4 -0
  422. aria_code/safety/__init__.py +23 -0
  423. aria_code/safety/permissions.py +306 -0
  424. aria_code/safety/service.py +102 -0
  425. aria_code/setup_wizard.py +673 -0
  426. aria_code/spreadsheet_tools.py +4 -0
  427. aria_code/strategy_vault.py +4 -0
  428. aria_code/tools/__init__.py +0 -0
  429. aria_code/tools/artifact_tools.py +252 -0
  430. aria_code/tools/broker_tools.py +92 -0
  431. aria_code/tools/build_quant_engine.py +97 -0
  432. aria_code/tools/code_audit_tools.py +192 -0
  433. aria_code/tools/computer_use_tools.py +504 -0
  434. aria_code/tools/data_analysis_tools.py +809 -0
  435. aria_code/tools/enterprise_finance_tools.py +156 -0
  436. aria_code/tools/extended_tools.py +240 -0
  437. aria_code/tools/file_analysis_tools.py +885 -0
  438. aria_code/tools/image_gen_tools.py +114 -0
  439. aria_code/tools/local_finance_tools.py +3417 -0
  440. aria_code/tools/logistics_tools.py +135 -0
  441. aria_code/tools/macro_tools.py +369 -0
  442. aria_code/tools/notification_tools.py +249 -0
  443. aria_code/tools/project_tools.py +525 -0
  444. aria_code/tools/realty_data_tools.py +659 -0
  445. aria_code/tools/spreadsheet_tools.py +388 -0
  446. aria_code/tools/stripe_tools.py +115 -0
  447. aria_code/ui/__init__.py +105 -0
  448. aria_code/ui/banner.py +508 -0
  449. aria_code/ui/completer.py +501 -0
  450. aria_code/ui/console.py +281 -0
  451. aria_code/ui/image_render.py +243 -0
  452. aria_code/ui/input_box.py +488 -0
  453. aria_code/ui/picker.py +201 -0
  454. aria_code/ui/render/__init__.py +11 -0
  455. aria_code/ui/render/finance.py +1705 -0
  456. aria_code/ui/render/market.py +225 -0
  457. aria_code/ui/render/output.py +775 -0
  458. aria_code/ui/render/responsive.py +75 -0
  459. aria_code/ui/render/team.py +354 -0
  460. aria_code/ui/robot.py +235 -0
  461. aria_code/ui/startup_dashboard.py +109 -0
  462. aria_code/utils/vscode_uri.py +37 -0
  463. aria_code/video_analysis.py +147 -0
  464. aria_code/video_editor.py +271 -0
  465. aria_code/workspace/__init__.py +6 -0
  466. aria_code/workspace/files.py +193 -0
  467. aria_code/workspace/verify.py +113 -0
  468. aria_code/workspace_changes.py +199 -0
  469. aria_code/workspace_context.py +233 -0
  470. aria_code/workspace_service.py +196 -0
  471. aria_code/workspace_tools.py +150 -0
  472. aria_code-0.52.0.dist-info/METADATA +237 -0
  473. aria_code-0.52.0.dist-info/RECORD +478 -0
  474. aria_code-0.52.0.dist-info/WHEEL +5 -0
  475. aria_code-0.52.0.dist-info/entry_points.txt +3 -0
  476. aria_code-0.52.0.dist-info/licenses/LICENSE +201 -0
  477. aria_code-0.52.0.dist-info/licenses/NOTICE +49 -0
  478. aria_code-0.52.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,193 @@
1
+ """Controlled auto-execution for strategy / alert-driven trading.
2
+
3
+ OFF BY DEFAULT. An order auto-executes only when EVERY gate passes:
4
+
5
+ 1. Global kill-switch off — ARIA_DRY_RUN not set (brokers.trading.global_dry_run)
6
+ 2. Automation enabled — automation.enabled=true (per-broker opt-in)
7
+ 3. Risk/exec passed — preview.can_execute is True (no execution_blockers;
8
+ covers read_only / live-without-allow_live_trade)
9
+ 4. Direction/symbol allow — within allowed_sides / allowed_symbols
10
+ 5. Value & rate limits — max_order_value, max_orders_per_day,
11
+ max_orders_per_symbol_per_day
12
+
13
+ Otherwise the order is LEFT AS A DRAFT (the existing semi-auto behaviour) and the
14
+ skip is audited. Every decision — execute or skip — is written to the trade audit
15
+ log so there is a full paper trail.
16
+
17
+ This module never lowers an existing guard: it ADDS gates on top of the normal
18
+ preview → risk → confirm pipeline (auto-execution simply supplies the confirm).
19
+ """
20
+
21
+ from __future__ import annotations
22
+
23
+ import json
24
+ import time
25
+ from dataclasses import dataclass, field
26
+ from datetime import datetime, timezone
27
+ from typing import Any, Dict, List, Optional
28
+
29
+ from .trading import (
30
+ TRADE_AUDIT_PATH,
31
+ _audit,
32
+ execute_order_preview,
33
+ global_dry_run,
34
+ load_order_preview,
35
+ )
36
+
37
+
38
+ @dataclass(frozen=True)
39
+ class AutoExecutePolicy:
40
+ """Per-broker automation policy. Disabled unless explicitly turned on."""
41
+ enabled: bool = False
42
+ max_order_value: float = 0.0 # 0 = no extra cap beyond risk rules
43
+ max_orders_per_day: int = 10
44
+ max_orders_per_symbol_per_day: int = 3
45
+ allowed_sides: tuple[str, ...] = ("buy", "sell")
46
+ allowed_symbols: tuple[str, ...] = () # empty = all symbols allowed
47
+
48
+ @classmethod
49
+ def from_config(cls, config: Dict[str, Any] | None) -> "AutoExecutePolicy":
50
+ auto = ((config or {}).get("automation") or {})
51
+ if not isinstance(auto, dict):
52
+ return cls()
53
+ sides = auto.get("allowed_sides") or ["buy", "sell"]
54
+ syms = auto.get("allowed_symbols") or []
55
+ return cls(
56
+ enabled=bool(auto.get("enabled", False)),
57
+ max_order_value=float(auto.get("max_order_value", 0.0) or 0.0),
58
+ max_orders_per_day=int(auto.get("max_orders_per_day", 10) or 0),
59
+ max_orders_per_symbol_per_day=int(auto.get("max_orders_per_symbol_per_day", 3) or 0),
60
+ allowed_sides=tuple(str(s).lower() for s in sides),
61
+ allowed_symbols=tuple(str(s).upper() for s in syms),
62
+ )
63
+
64
+
65
+ @dataclass
66
+ class AutoExecuteDecision:
67
+ allowed: bool
68
+ reasons: List[str] = field(default_factory=list)
69
+
70
+
71
+ def _order_from_preview(preview: Dict[str, Any]) -> Dict[str, Any]:
72
+ return ((preview.get("order_plan") or {}).get("estimated_order") or {})
73
+
74
+
75
+ def _order_value(order: Dict[str, Any]) -> float:
76
+ for key in ("value", "notional", "amount"):
77
+ try:
78
+ v = float(order.get(key) or 0)
79
+ if v > 0:
80
+ return v
81
+ except (TypeError, ValueError):
82
+ pass
83
+ try:
84
+ return float(order.get("price") or 0) * float(order.get("quantity") or 0)
85
+ except (TypeError, ValueError):
86
+ return 0.0
87
+
88
+
89
+ def evaluate_auto_execute(
90
+ preview: Dict[str, Any],
91
+ policy: AutoExecutePolicy,
92
+ *,
93
+ dry_run: bool,
94
+ executed_today: int = 0,
95
+ executed_today_symbol: int = 0,
96
+ ) -> AutoExecuteDecision:
97
+ """Pure gate evaluation. Returns allowed=True only if ALL gates pass."""
98
+ reasons: List[str] = []
99
+ if dry_run:
100
+ reasons.append("ARIA_DRY_RUN 全局冻结,禁止自动执行")
101
+ if not policy.enabled:
102
+ reasons.append("自动执行未开启 (automation.enabled=false)")
103
+ if not preview.get("can_execute"):
104
+ blockers = preview.get("execution_blockers") or []
105
+ reasons.append("风控/执行未通过: " + ("; ".join(str(b) for b in blockers[:3]) or "can_execute=false"))
106
+
107
+ order = _order_from_preview(preview)
108
+ side = str(order.get("side") or preview.get("side") or "").lower()
109
+ sym = str(order.get("symbol") or preview.get("symbol") or "").upper()
110
+
111
+ if policy.allowed_sides and side and side not in policy.allowed_sides:
112
+ reasons.append(f"方向 {side} 不在允许列表 {list(policy.allowed_sides)}")
113
+ if policy.allowed_symbols and sym and sym not in policy.allowed_symbols:
114
+ reasons.append(f"标的 {sym} 不在自动交易白名单")
115
+
116
+ val = _order_value(order)
117
+ if policy.max_order_value and val > policy.max_order_value:
118
+ reasons.append(f"单笔金额 {val:.2f} 超过上限 {policy.max_order_value:.2f}")
119
+ if policy.max_orders_per_day and executed_today >= policy.max_orders_per_day:
120
+ reasons.append(f"已达当日自动单上限 {policy.max_orders_per_day}")
121
+ if policy.max_orders_per_symbol_per_day and executed_today_symbol >= policy.max_orders_per_symbol_per_day:
122
+ reasons.append(f"{sym} 已达当日自动单上限 {policy.max_orders_per_symbol_per_day}")
123
+
124
+ return AutoExecuteDecision(allowed=(not reasons), reasons=reasons)
125
+
126
+
127
+ def _count_auto_executed_today(broker_id: str, symbol: Optional[str] = None) -> int:
128
+ """Count successful auto-executions today (from the trade audit log)."""
129
+ if not TRADE_AUDIT_PATH.exists():
130
+ return 0
131
+ today = datetime.now(timezone.utc).date()
132
+ sym = (symbol or "").upper()
133
+ n = 0
134
+ try:
135
+ for line in TRADE_AUDIT_PATH.read_text(encoding="utf-8").splitlines():
136
+ try:
137
+ row = json.loads(line)
138
+ except Exception:
139
+ continue
140
+ if row.get("event") != "auto_execute" or not row.get("success"):
141
+ continue
142
+ if broker_id and row.get("broker_id") != broker_id:
143
+ continue
144
+ if sym and str(row.get("symbol") or "").upper() != sym:
145
+ continue
146
+ ts = row.get("ts")
147
+ if ts and datetime.fromtimestamp(int(ts), tz=timezone.utc).date() != today:
148
+ continue
149
+ n += 1
150
+ except Exception:
151
+ return n
152
+ return n
153
+
154
+
155
+ def run_auto_execute(
156
+ broker: Any,
157
+ preview_id: str,
158
+ policy: Optional[AutoExecutePolicy] = None,
159
+ ) -> Dict[str, Any]:
160
+ """Auto-execute a preview iff all gates pass; otherwise leave it as a draft.
161
+
162
+ Returns a dict with ``auto_executed`` / ``skipped`` and the gate ``reasons``.
163
+ """
164
+ preview = load_order_preview(preview_id)
165
+ if not preview:
166
+ return {"success": False, "error": f"preview not found: {preview_id}"}
167
+
168
+ if policy is None:
169
+ policy = AutoExecutePolicy.from_config(getattr(broker, "config", {}) or {})
170
+
171
+ broker_id = getattr(broker, "broker_id", "")
172
+ symbol = str(preview.get("symbol") or _order_from_preview(preview).get("symbol") or "")
173
+ decision = evaluate_auto_execute(
174
+ preview, policy,
175
+ dry_run=global_dry_run(),
176
+ executed_today=_count_auto_executed_today(broker_id),
177
+ executed_today_symbol=_count_auto_executed_today(broker_id, symbol),
178
+ )
179
+
180
+ if not decision.allowed:
181
+ _audit({"event": "auto_execute_skipped", "preview_id": preview_id,
182
+ "broker_id": broker_id, "symbol": symbol.upper(),
183
+ "reasons": decision.reasons, "auto": True})
184
+ return {"success": False, "auto_executed": False, "skipped": True,
185
+ "reasons": decision.reasons, "preview_id": preview_id}
186
+
187
+ result = execute_order_preview(broker, preview_id, confirmed=True)
188
+ success = bool(result.get("success"))
189
+ _audit({"event": "auto_execute", "preview_id": preview_id,
190
+ "broker_id": broker_id, "symbol": symbol.upper(),
191
+ "success": success, "auto": True})
192
+ result["auto_executed"] = success
193
+ return result
@@ -0,0 +1,231 @@
1
+ """
2
+ brokers/base.py — 券商接入统一接口
3
+ ====================================
4
+ 所有券商适配器继承 BrokerBase,对外暴露统一 schema,
5
+ 上层代码不关心底层是 XTQuant / IBKR / Alpaca / 富途 / 老虎。
6
+
7
+ 数据类:
8
+ AccountInfo 账户资金汇总
9
+ Position 持仓明细
10
+ Order 订单记录
11
+ OrderResult 下单结果
12
+ PortfolioSummary 持仓组合摘要
13
+
14
+ 抽象接口:
15
+ connect() 建立连接
16
+ disconnect() 断开连接
17
+ account_info() 账户资金
18
+ positions() 当前持仓
19
+ orders(status) 历史/活跃订单
20
+ place_order(...) 下单(需用户二次确认,不在此层执行)
21
+ cancel_order(id) 撤单
22
+ """
23
+
24
+ from __future__ import annotations
25
+
26
+ from abc import ABC, abstractmethod
27
+ from dataclasses import dataclass, field
28
+ from typing import Any, Dict, List, Optional
29
+
30
+
31
+ # ── 统一数据 Schema ────────────────────────────────────────────────────────────
32
+
33
+ @dataclass
34
+ class AccountInfo:
35
+ broker_id: str # 配置中的 id 字段
36
+ broker_type: str # xtquant / ibkr / alpaca …
37
+ label: str # 用户自定义别名
38
+ account_id: str # 账户号(脱敏后展示末4位)
39
+ currency: str = "CNY"
40
+ total_assets: float = 0.0 # 总资产
41
+ cash: float = 0.0 # 可用现金
42
+ market_value: float = 0.0 # 持仓市值
43
+ frozen: float = 0.0 # 冻结资金
44
+ pnl_today: float = 0.0 # 当日盈亏
45
+ pnl_total: float = 0.0 # 累计盈亏
46
+ pnl_pct: float = 0.0 # 持仓收益率(%)
47
+ risk_level: str = "" # low / medium / high
48
+ extra: Dict[str, Any] = field(default_factory=dict)
49
+
50
+ @property
51
+ def masked_account(self) -> str:
52
+ return f"****{self.account_id[-4:]}" if len(self.account_id) > 4 else "****"
53
+
54
+
55
+ @dataclass
56
+ class Position:
57
+ symbol: str
58
+ name: str = ""
59
+ quantity: float = 0.0 # 持仓数量(股/手)
60
+ available_qty: float = 0.0 # 可卖数量
61
+ cost_price: float = 0.0 # 持仓均价
62
+ current_price: float = 0.0 # 最新价
63
+ market_value: float = 0.0 # 市值
64
+ pnl: float = 0.0 # 盈亏金额
65
+ pnl_pct: float = 0.0 # 盈亏比例(%)
66
+ currency: str = "CNY"
67
+ market: str = "" # a_share / us / hk / crypto
68
+ extra: Dict[str, Any] = field(default_factory=dict)
69
+
70
+
71
+ @dataclass
72
+ class Order:
73
+ order_id: str
74
+ symbol: str
75
+ name: str = ""
76
+ side: str = "" # buy / sell
77
+ order_type: str = "" # limit / market / stop
78
+ quantity: float = 0.0
79
+ filled_qty: float = 0.0
80
+ price: float = 0.0 # 委托价
81
+ avg_price: float = 0.0 # 成交均价
82
+ status: str = "" # open / filled / cancelled / partial
83
+ created_at: str = ""
84
+ updated_at: str = ""
85
+ currency: str = "CNY"
86
+ extra: Dict[str, Any] = field(default_factory=dict)
87
+
88
+
89
+ @dataclass
90
+ class OrderResult:
91
+ success: bool
92
+ order_id: str = ""
93
+ message: str = ""
94
+ broker_id: str = ""
95
+
96
+
97
+ @dataclass
98
+ class PortfolioSummary:
99
+ broker_id: str
100
+ positions: List[Position] = field(default_factory=list)
101
+ total_assets: float = 0.0
102
+ total_market_value: float = 0.0
103
+ cash: float = 0.0
104
+ total_pnl: float = 0.0
105
+ total_pnl_pct: float = 0.0
106
+ top_holding: Optional[Position] = None
107
+ currency: str = "CNY"
108
+
109
+
110
+ # ── 抽象基类 ───────────────────────────────────────────────────────────────────
111
+
112
+ class BrokerBase(ABC):
113
+ """所有券商适配器的抽象基类。"""
114
+
115
+ broker_type: str = "base" # 子类覆盖: xtquant / ibkr / alpaca …
116
+ broker_name: str = "券商" # 展示名称
117
+ market: str = "CN" # CN / US / HK / GLOBAL
118
+ read_only: bool = False # True = 只支持查询,不支持下单
119
+
120
+ def __init__(self, broker_id: str, config: Dict[str, Any]):
121
+ self.broker_id = broker_id
122
+ self.config = config
123
+ self.label = config.get("label", broker_id)
124
+ self._connected = False
125
+
126
+ # ── 连接管理 ──────────────────────────────────────────────────────────────
127
+
128
+ @abstractmethod
129
+ def connect(self) -> bool:
130
+ """建立连接。返回 True 表示成功。"""
131
+
132
+ def disconnect(self) -> None:
133
+ """断开连接(默认空实现,子类可覆盖)。"""
134
+ self._connected = False
135
+
136
+ @property
137
+ def is_connected(self) -> bool:
138
+ return self._connected
139
+
140
+ # ── 健康检查 / 自动重连 ────────────────────────────────────────────────────
141
+
142
+ def ping(self) -> bool:
143
+ """轻量存活探测。默认信任连接标志;拥有实时 socket/API 的子类**应覆盖**
144
+ 此方法做真实探测(如 ib.isConnected()、富途 context keepalive),
145
+ 以便检测到静默断开的连接并触发重连。"""
146
+ return self._connected
147
+
148
+ def ensure_connected(self, retries: int = 1) -> bool:
149
+ """确保连接可用,断开则自动重连。返回 True 表示可用。
150
+
151
+ 长驻场景(daemon)应在每次券商操作前调用:FutuOpenD / IB Gateway /
152
+ websocket 掉线时透明重连,而不是静默失败到下一次调用才报错。"""
153
+ if self._connected and self.ping():
154
+ return True
155
+ self._connected = False
156
+ for _ in range(max(1, retries + 1)):
157
+ try:
158
+ if self.connect():
159
+ return True
160
+ except Exception:
161
+ pass
162
+ return False
163
+
164
+ # ── 账户查询 ──────────────────────────────────────────────────────────────
165
+
166
+ @abstractmethod
167
+ def account_info(self) -> AccountInfo:
168
+ """返回账户资金汇总。"""
169
+
170
+ @abstractmethod
171
+ def positions(self) -> List[Position]:
172
+ """返回当前持仓列表。"""
173
+
174
+ @abstractmethod
175
+ def orders(self, status: str = "all", limit: int = 50) -> List[Order]:
176
+ """
177
+ 返回订单列表。
178
+ status: "open" | "filled" | "cancelled" | "all"
179
+ """
180
+
181
+ # ── 交易操作(需上层二次确认后才调用)──────────────────────────────────────
182
+
183
+ def place_order(
184
+ self,
185
+ symbol: str,
186
+ side: str, # "buy" | "sell"
187
+ quantity: float,
188
+ order_type: str = "limit",
189
+ price: float = 0.0,
190
+ **kwargs: Any,
191
+ ) -> OrderResult:
192
+ """
193
+ 下单接口。默认返回不支持,子类覆盖。
194
+ ⚠️ 此方法只应在用户明确确认后被调用。
195
+ """
196
+ if self.read_only:
197
+ return OrderResult(success=False, message=f"{self.broker_name} 为只读模式,不支持下单")
198
+ return OrderResult(success=False, message="此券商暂不支持程序化下单")
199
+
200
+ def cancel_order(self, order_id: str) -> bool:
201
+ """撤单。返回 True 表示成功。"""
202
+ return False
203
+
204
+ # ── 工具方法 ─────────────────────────────────────────────────────────────
205
+
206
+ def portfolio_summary(self) -> PortfolioSummary:
207
+ """构建持仓摘要(默认实现,子类可覆盖)。"""
208
+ try:
209
+ acct = self.account_info()
210
+ pos = self.positions()
211
+ top = max(pos, key=lambda p: abs(p.market_value), default=None) if pos else None
212
+ total_pnl = sum(p.pnl for p in pos)
213
+ total_mv = sum(p.market_value for p in pos)
214
+ pnl_pct = (total_pnl / (total_mv - total_pnl) * 100) if (total_mv - total_pnl) > 0 else 0.0
215
+ return PortfolioSummary(
216
+ broker_id=self.broker_id,
217
+ positions=pos,
218
+ total_assets=acct.total_assets,
219
+ total_market_value=acct.market_value,
220
+ cash=acct.cash,
221
+ total_pnl=total_pnl,
222
+ total_pnl_pct=pnl_pct,
223
+ top_holding=top,
224
+ currency=acct.currency,
225
+ )
226
+ except Exception as e:
227
+ return PortfolioSummary(broker_id=self.broker_id)
228
+
229
+ def __repr__(self) -> str:
230
+ status = "connected" if self._connected else "disconnected"
231
+ return f"<{self.__class__.__name__} id={self.broker_id!r} {status}>"
@@ -0,0 +1,264 @@
1
+ """Broker capability catalog and setup playbooks.
2
+
3
+ This module is intentionally UI-free so CLI, daemon, docs, and tests can share
4
+ one source of truth for supported broker connectors.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from dataclasses import dataclass
10
+ from importlib.util import find_spec
11
+ from typing import Iterable
12
+
13
+
14
+ @dataclass(frozen=True)
15
+ class BrokerCapability:
16
+ broker_type: str
17
+ display_name: str
18
+ markets: tuple[str, ...]
19
+ sdk_module: str
20
+ pip_package: str
21
+ credential_fields: tuple[str, ...]
22
+ local_runtime: str
23
+ read_capabilities: tuple[str, ...]
24
+ trade_capability: str
25
+ safety_notes: tuple[str, ...]
26
+ setup_steps: tuple[str, ...]
27
+
28
+ @property
29
+ def can_trade(self) -> bool:
30
+ return self.trade_capability not in ("read_only", "unsupported")
31
+
32
+
33
+ _BROKER_CAPABILITIES: tuple[BrokerCapability, ...] = (
34
+ BrokerCapability(
35
+ broker_type="paper",
36
+ display_name="Aria 本地仿盘账户",
37
+ markets=("美股", "港股", "A股", "加密货币"),
38
+ sdk_module="json",
39
+ pip_package="builtin",
40
+ credential_fields=("starting_cash", "currency"),
41
+ local_runtime="不需要真实券商或本地网关;订单写入本地 paper ledger。",
42
+ read_capabilities=("account", "positions", "orders"),
43
+ trade_capability="paper_trade",
44
+ safety_notes=("仿盘成交不触达真实市场。", "仍使用同一套风控、预览、确认和审计流程。"),
45
+ setup_steps=(
46
+ "运行 /paper start 100000 USD 创建本地仿盘账户。",
47
+ "运行 /broker connect paper_main 连接仿盘账户。",
48
+ "使用 /trade preview AAPL buy 10 190 生成订单预览,再 /trade confirm <preview_id>。",
49
+ ),
50
+ ),
51
+ BrokerCapability(
52
+ broker_type="xtquant",
53
+ display_name="迅投 XTQuant / QMT",
54
+ markets=("A股",),
55
+ sdk_module="xtquant",
56
+ pip_package="xtquant",
57
+ credential_fields=("account_id",),
58
+ local_runtime="QMT 量化终端需已登录并保持运行;主要面向 Windows。",
59
+ read_capabilities=("account", "positions", "orders"),
60
+ trade_capability="live_trade",
61
+ safety_notes=("实盘交易必须由 /broker_order 二次确认后执行。", "依赖包通常由券商提供,pip 可能不可直接安装。"),
62
+ setup_steps=(
63
+ "安装并登录券商 QMT/XTQuant 客户端。",
64
+ "运行 /broker add xtquant 填写 account_id。",
65
+ "运行 /broker connect <id>,再用 /account 与 /positions 验证。",
66
+ ),
67
+ ),
68
+ BrokerCapability(
69
+ broker_type="easytrader",
70
+ display_name="EasyTrader",
71
+ markets=("A股",),
72
+ sdk_module="easytrader",
73
+ pip_package="easytrader",
74
+ credential_fields=("broker_name", "exe_path"),
75
+ local_runtime="券商桌面交易客户端需已登录;主要面向 Windows。",
76
+ read_capabilities=("account", "positions", "orders"),
77
+ trade_capability="live_trade",
78
+ safety_notes=("属于客户端自动化路径,稳定性取决于券商客户端界面。",),
79
+ setup_steps=(
80
+ "安装并登录同花顺/通达信/华泰/国君等交易客户端。",
81
+ "运行 /broker add easytrader 填写 broker_name 与 exe_path。",
82
+ "先用 /account 只读校验,再启用交易。",
83
+ ),
84
+ ),
85
+ BrokerCapability(
86
+ broker_type="futu",
87
+ display_name="富途牛牛 OpenAPI",
88
+ markets=("港股", "美股", "A股"),
89
+ sdk_module="futu",
90
+ pip_package="futu-api",
91
+ credential_fields=("host", "port", "market"),
92
+ local_runtime="FutuOpenD 需在本机或局域网运行,默认 127.0.0.1:11111。",
93
+ read_capabilities=("account", "positions", "orders"),
94
+ trade_capability="live_trade",
95
+ safety_notes=("OpenD 的交易解锁、市场权限和账户类型会影响可用能力。",),
96
+ setup_steps=(
97
+ "安装 futu-api 并启动 FutuOpenD。",
98
+ "运行 /broker add futu 填写 host、port、market。",
99
+ "运行 /broker connect <id> 后检查 /positions 与 /orders。",
100
+ ),
101
+ ),
102
+ BrokerCapability(
103
+ broker_type="tiger",
104
+ display_name="老虎证券 OpenAPI",
105
+ markets=("美股", "港股", "A股"),
106
+ sdk_module="tigeropen",
107
+ pip_package="tigeropen",
108
+ credential_fields=("tiger_id", "private_key_path", "account"),
109
+ local_runtime="不需要本地网关,但需要开发者账号、账户号和 RSA 私钥。",
110
+ read_capabilities=("account", "positions", "orders"),
111
+ trade_capability="live_trade",
112
+ safety_notes=("私钥文件必须保存在本机,不要写入对话或日志。",),
113
+ setup_steps=(
114
+ "在老虎开放平台注册应用并保存 RSA 私钥。",
115
+ "运行 /broker add tiger 填写 tiger_id、account、private_key_path。",
116
+ "用 /broker doctor 检查依赖与字段,再 /broker connect <id>。",
117
+ ),
118
+ ),
119
+ BrokerCapability(
120
+ broker_type="longbridge",
121
+ display_name="长桥证券 OpenAPI",
122
+ markets=("港股", "美股", "A股"),
123
+ sdk_module="longbridge",
124
+ pip_package="longbridge",
125
+ credential_fields=("app_key", "app_secret", "access_token"),
126
+ local_runtime="不需要本地网关;需要长桥 OpenAPI App Key/Secret/Token。",
127
+ read_capabilities=("account", "positions", "orders"),
128
+ trade_capability="live_trade",
129
+ safety_notes=("Token 建议只保存在 brokers.json 或环境变量,不进入提示词。",),
130
+ setup_steps=(
131
+ "在长桥 OpenAPI 开发者中心创建应用。",
132
+ "运行 /broker add longbridge 填写 App Key、Secret、Access Token。",
133
+ "连接后使用 /account、/positions 校验账户数据。",
134
+ ),
135
+ ),
136
+ BrokerCapability(
137
+ broker_type="ibkr",
138
+ display_name="Interactive Brokers",
139
+ markets=("全球市场",),
140
+ sdk_module="ib_insync",
141
+ pip_package="ib_insync",
142
+ credential_fields=("host", "port", "client_id"),
143
+ local_runtime="TWS 或 IB Gateway 需已登录并开启 Socket API。",
144
+ read_capabilities=("account", "positions", "orders"),
145
+ trade_capability="live_trade",
146
+ safety_notes=("模拟端口通常为 7497/4002,实盘端口通常为 7496/4001。",),
147
+ setup_steps=(
148
+ "启动 TWS 或 IB Gateway,并启用 API Socket。",
149
+ "运行 /broker add ibkr 填写 host、port、client_id。",
150
+ "建议先连模拟盘,再切实盘端口。",
151
+ ),
152
+ ),
153
+ BrokerCapability(
154
+ broker_type="alpaca",
155
+ display_name="Alpaca Markets",
156
+ markets=("美股", "加密货币"),
157
+ sdk_module="alpaca",
158
+ pip_package="alpaca-py",
159
+ credential_fields=("api_key", "api_secret", "paper"),
160
+ local_runtime="不需要本地网关;支持 paper=true 模拟盘。",
161
+ read_capabilities=("account", "positions", "orders"),
162
+ trade_capability="paper_or_live_trade",
163
+ safety_notes=("默认建议使用 paper=true;实盘需确认账户权限。",),
164
+ setup_steps=(
165
+ "在 Alpaca 控制台生成 API Key/Secret。",
166
+ "运行 /broker add alpaca,优先选择 paper=true。",
167
+ "用 /broker connect <id> 与 /account 验证模拟盘。",
168
+ ),
169
+ ),
170
+ BrokerCapability(
171
+ broker_type="webull",
172
+ display_name="Webull",
173
+ markets=("美股",),
174
+ sdk_module="webull",
175
+ pip_package="webull",
176
+ credential_fields=("username", "password", "device_id"),
177
+ local_runtime="不需要本地网关;当前适配器默认只读。",
178
+ read_capabilities=("account", "positions", "orders"),
179
+ trade_capability="read_only",
180
+ safety_notes=("非官方 API,默认不开放程序化下单。",),
181
+ setup_steps=(
182
+ "安装 webull SDK 并准备登录凭证。",
183
+ "运行 /broker add webull。",
184
+ "仅用于 /account、/positions、/orders 只读查询。",
185
+ ),
186
+ ),
187
+ )
188
+
189
+
190
+ def list_broker_capabilities() -> tuple[BrokerCapability, ...]:
191
+ return _BROKER_CAPABILITIES
192
+
193
+
194
+ def get_broker_capability(broker_type: str) -> BrokerCapability | None:
195
+ normalized = str(broker_type or "").strip().lower()
196
+ for spec in _BROKER_CAPABILITIES:
197
+ if spec.broker_type == normalized:
198
+ return spec
199
+ return None
200
+
201
+
202
+ def broker_dependency_state(spec: BrokerCapability) -> dict[str, object]:
203
+ installed = bool(find_spec(spec.sdk_module))
204
+ return {
205
+ "broker_type": spec.broker_type,
206
+ "module": spec.sdk_module,
207
+ "package": spec.pip_package,
208
+ "installed": installed,
209
+ "install_hint": f"/install {spec.pip_package}" if not installed else "",
210
+ }
211
+
212
+
213
+ def broker_connection_plan(broker_type: str) -> tuple[str, ...]:
214
+ spec = get_broker_capability(broker_type)
215
+ if not spec:
216
+ return (
217
+ "运行 /broker guide 查看支持的券商类型。",
218
+ "选择券商后运行 /broker add <type>。",
219
+ )
220
+ dep = broker_dependency_state(spec)
221
+ first = (
222
+ f"依赖已安装: {spec.sdk_module}"
223
+ if dep["installed"]
224
+ else f"安装依赖: /install {spec.pip_package}"
225
+ )
226
+ return (first, *spec.setup_steps, "常用服务: /account, /positions, /orders, /risk, /report")
227
+
228
+
229
+ def broker_service_playbook() -> tuple[dict[str, str], ...]:
230
+ """Return user-facing broker-to-service usage flows."""
231
+
232
+ return (
233
+ {
234
+ "service": "账户与持仓",
235
+ "commands": "/broker connect <id> → /account → /positions → /orders",
236
+ "used_by": "LLM broker_query 工具、持仓风险分析、组合报告",
237
+ "guardrail": "只读查询,不触发交易",
238
+ },
239
+ {
240
+ "service": "策略到交易计划",
241
+ "commands": "/backtest → /signal → broker_order",
242
+ "used_by": "QuantEngine 信号、回测结果、Kelly/仓位测算",
243
+ "guardrail": "下单前必须展示订单计划并等待用户确认",
244
+ },
245
+ {
246
+ "service": "TradingView 告警联动",
247
+ "commands": "TradingView alert → Aria daemon webhook → 分析/通知/订单草案",
248
+ "used_by": "/tv、/daemon、webhook、通知渠道",
249
+ "guardrail": "Webhook 默认只生成分析和订单草案,不自动实盘下单",
250
+ },
251
+ {
252
+ "service": "报告与审计",
253
+ "commands": "/report, /dashboard, /export",
254
+ "used_by": "账户快照、持仓、行情、信号、风控、交易计划",
255
+ "guardrail": "报告落本地 artifacts;敏感字段脱敏",
256
+ },
257
+ )
258
+
259
+
260
+ def filter_capabilities(names: Iterable[str]) -> tuple[BrokerCapability, ...]:
261
+ wanted = {str(name).strip().lower() for name in names if str(name).strip()}
262
+ if not wanted:
263
+ return list_broker_capabilities()
264
+ return tuple(spec for spec in _BROKER_CAPABILITIES if spec.broker_type in wanted)