get_portfolio_analysis
Analyze investment portfolios to assess position values, allocation percentages, PnL, concentration risk, regime alignment, and generate rebalancing suggestions based on current market conditions.
Instructions
Get personalized portfolio analysis against current market conditions. Shows position values, allocation percentages, PnL, concentration risk, regime alignment, and specific rebalancing suggestions. Requires set_portfolio_context to be called first.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- The handler function `getPortfolioAnalysis` fetches the user's portfolio, performs a market reality check, and uses the `analyzePortfolio` service to generate the analysis.
export async function getPortfolioAnalysis(cache: CacheService): Promise<PortfolioAnalysisOutput | ErrorOutput> { const portfolio = getPortfolio(AGENT_ID); if (!portfolio || portfolio.holdings.length === 0) { return { error: true, error_source: 'get_portfolio_analysis', agent_guidance: 'No portfolio context found. Call set_portfolio_context first with your holdings array: [{asset: "bitcoin", amount: 2}, {asset: "solana", amount: 50}].', last_known_data: null, data_warnings: ['No portfolio context set for this agent.'], }; } try { // Get current market reality const reality = await getRealityCheck(cache); // Extract regime info (handle both success and error cases) let posture = 'moderate'; let regime = 'transitional'; let riskScore = 50; let opportunityScore = 50; if ('suggested_posture' in reality) { const r = reality as RealityCheckOutput; posture = r.suggested_posture; regime = typeof r.regime === 'object' && r.regime !== null ? (r.regime as unknown as Record<string, string>).regime ?? 'transitional' : 'transitional'; riskScore = r.risk_score; opportunityScore = r.opportunity_score; } const analysis = await analyzePortfolio( portfolio.holdings, posture, regime, riskScore, ); return { ...analysis, market_context: { regime, posture, risk_score: riskScore, opportunity_score: opportunityScore, }, }; } catch { return { error: true, error_source: 'get_portfolio_analysis', agent_guidance: 'Portfolio analysis temporarily unavailable. Market data sources may be down. Retry shortly.', last_known_data: null, data_warnings: ['Portfolio analysis service temporarily unavailable.'], }; } } - Interface definition for the output of `get_portfolio_analysis`.
export interface PortfolioAnalysisOutput extends PortfolioAnalysis { market_context: { regime: string; posture: string; risk_score: number; opportunity_score: number; }; } - src/index.ts:231-240 (registration)Registration and invocation logic for `get_portfolio_analysis` in the main entry point.
// ─── Tool: get_portfolio_analysis ─── server.tool( 'get_portfolio_analysis', 'Get personalized portfolio analysis against current market conditions. Shows position values, allocation percentages, PnL, concentration risk, regime alignment, and specific rebalancing suggestions. Requires set_portfolio_context to be called first.', {}, async () => { const gateError = gateTool('get_portfolio_analysis'); if (gateError) return { content: [{ type: 'text' as const, text: gateError }] }; const text = await executeAndLog('get_portfolio_analysis', {}, () => getPortfolioAnalysis(cache));