An AI-powered swing trading and financial market analysis agent for Vietnamese stocks. Provides technical indicators, fundamental analysis, portfolio management, and real-time market data via Telegram integration.
Bull Vision Agent provides 15 stock market analysis tools with basic definitions but significant gaps in schema documentation and parameter rigor. Tool names follow verb_noun patterns well (get_*, screen_*), and descriptions exist for all tools, but most descriptions lack actionable detail about when to use each tool vs. similar ones. Critical issue: input schemas are visible in the evaluation data but the actual source code provided is incomplete (cuts off mid-function in tools.py). From what is visible, tools like get_stock_context and get_price_board have documented parameters with types and descriptions, but many tools (e.g., get_all_symbols, get_fund_listings, get_sjc_gold_price) have empty input objects with no documented constraints. Output schemas are not documented anywhere in the provided source. Error handling exists (try/except blocks with logging) but does not guide LLM recovery or categorize error types. No tool annotations (readOnlyHint, destructiveHint, idempotentHint) are present. Parameters lack constraints (enums, min/max) in most cases, e.g., 'period' in get_balance_sheet accepts 'year' or 'quarter' as enum in schema but this constraint language is clear; however, 'industry' in get_stocks_by_industry has no enum constraint despite accepting 'one of the supported industries'. Descriptions are functional but brief (avg ~80 chars) and do not explain when to choose one lookup tool over another (e.g., get_company_overview vs. get_balance_sheet vs. get_income_statement).
Get a list of all available stock symbols on the Vietnamese market.
Get the balance sheet for a company.
Get the cash flow statement for a company.
Get detailed company overview information for a given symbol.
Get financial ratios for a company.
Get a list of all available mutual funds on the Vietnamese market.
Get the income statement for a company.
Output schemas not documented. Tool descriptions state what they return (e.g., 'dict containing: price, 52w_high, ...') but no formal schema is provided for the LLM to understand structure during planning. This forces the LLM to infer field names and types, risking misuse of returned data.
Ambiguous lookup tools without clear differentiation. get_company_overview, get_balance_sheet, get_income_statement, and get_financial_ratios all fetch company financial data. Descriptions do not explain when to use each instead of the others, forcing the LLM to reason about which to call first or try multiple tools.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 66 | <=2025-11-25 | v2 |
| 2026-03-09 | D | 50 | - | v1 |
Get intraday tick data for a specific stock symbol.
Get real-time data for market indices.
Get real-time price board for a list of ticker symbols.
Get the current SJC gold price.
Get technical and fundamental context for a stock ticker. Fetches stock data using vnstock and calculates technical indicators including RSI and MACD. Used to analyze stocks for swing trading opportunities.
Get a formatted list of all stock symbols in a specific industry (must be one of the supported industries).
Get VCB exchange rates for a specific date.
Screen stocks based on custom parameters.
Unconstrained parameter 'industry' in get_stocks_by_industry. Description states 'must be one of the supported industries' but provides no enum list. LLM cannot discover valid values without a discovery tool or hardcoded knowledge. Common pattern: require a separate list_industries tool or provide enum constraint.
Minimal input validation guidance. Parameter 'symbol' in get_stock_context expects a ticker (e.g., 'VCB') but description does not specify format, length, or case sensitivity. LLM may pass invalid formats like 'vcb' (lowercase) or 'VCB-HOSE' and receive cryptic API errors without recovery hints.
No error recovery guidance. Code contains try/except blocks that catch exceptions and log errors, but error messages are not structured to guide the LLM. A cryptic exception like 'vnstock.exception.DataNotFound' returns no hint about what the LLM should try next (e.g., 'Try get_all_symbols() to verify ticker is valid').
Empty input schemas for simple discovery tools. get_all_symbols, get_fund_listings, and get_sjc_gold_price accept no parameters (Input: {}). While correct, these tools are not discoverable, the LLM must know to call them. Consider adding descriptions that guide when to call each discovery tool, or batch them into a single 'list_asset_classes' tool.
Unclear parameter semantics for 'params' in screen_stocks. Accepts an arbitrary object with description 'Screening parameters, e.g. {"exchangeName": "HOSE,HNX,UPCOM"}'. No schema constraints or full list of valid keys. LLM cannot construct valid queries without trial-and-error or documentation lookup.
No tool annotations. Tools lack readOnlyHint (all 15 are read-only) or destructiveHint markers. MCP 2026-07-28 spec supports tool annotations to signal intent, their absence prevents clients from enforcing execution policies (e.g., preventing read-only tools from being cached incorrectly).