Skip to main content
Glama
dun999

FinSight

analyze_report

Analyze investment portfolios with comprehensive risk assessment, diversification scoring, stress testing, and rebalancing recommendations to optimize performance and manage exposure.

Instructions

Full report — all 8 modules in one call: risk + rebalance + diversification + stress_test (10 scenarios) + var_cvar + factor_exposure + correlation + market_regime. Includes ExecutiveSummary: overall score (0-100), grade (A-F), key strengths, key risks, top recommendations. Most cost-effective option for comprehensive analysis. Costs $0.10 USDC.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
holdingsYes
profileNoRisk profile — affects rebalance targets and scoring. Default: balanced.
benchmarkReturnNoAnnual benchmark return for Sharpe calculation, e.g. 0.08 = 8%. Default: 0.08.
riskFreeRateNoAnnual risk-free rate for Sortino and VaR excess return, e.g. 0.05 = 5%. Default: 0.05.
rebalanceMethodNoPortfolio construction method for rebalance recommendations. Default: profile.
marketIndicatorsNoOptional macro indicators — improves market regime detection confidence to HIGH when 3+ provided.

Implementation Reference

  • The handler for the '/analyze/report' endpoint, which maps to the "analyze_report" tool/feature. It validates the request, handles payment, checks for cached results, and calls generateFullReport.
    app.post('/analyze/report', validate, charge('0.05'), async (c) => {
      try {
        const portfolio = c.get('portfolio')
    
        // Cache: return previously computed result for identical portfolios (30s TTL).
        // Uses stableJSON() instead of JSON.stringify() to ensure key order in the
        // input object does not produce different cache keys for identical portfolios.
        if (c.env.CACHE) {
          const keyBytes = await crypto.subtle.digest(
            'SHA-256',
            new TextEncoder().encode(stableJSON(portfolio)),
          )
          const cacheKey = 'report:' + Array.from(new Uint8Array(keyBytes))
            .map((b) => b.toString(16).padStart(2, '0'))
            .join('')
    
          const cached = await c.env.CACHE.get(cacheKey).catch(() => null)
          if (cached) {
            c.res.headers.set('X-Cache', 'HIT')
            return c.json({ ...JSON.parse(cached), ...{ warnings: c.get('warnings') ?? [], request_id: c.get('requestId') ?? 'unknown' } })
          }
    
          const result = generateFullReport(portfolio, c.get('returnSeries'))
          await c.env.CACHE.put(cacheKey, JSON.stringify(result), { expirationTtl: 30 }).catch(() => undefined)
          c.res.headers.set('X-Cache', 'MISS')
          return c.json(withMeta(c, result))
        }
    
        return c.json(withMeta(c, generateFullReport(portfolio, c.get('returnSeries'))))
      } catch (err) {
        console.error(err)
        return internalError(c)
      }
    })
  • The core implementation logic for generating the full report, which aggregates data from various other analyze modules.
    export function generateFullReport(
      portfolio: Portfolio,
      returnSeries?: Record<string, number[]>,
    ): FullReport {
      const risk            = analyzeRisk(portfolio, returnSeries)
      const rebalance       = analyzeRebalance(portfolio)
      const diversification = analyzeDiversification(portfolio)
      const stressTest      = analyzeStressTest(portfolio, returnSeries)
      const varCvar         = analyzeVaR(portfolio)
      const factorExposure  = analyzeFactorExposure(portfolio, returnSeries)
      const correlation     = analyzeCorrelation(portfolio, returnSeries)
      const marketRegime    = analyzeMarketRegime(portfolio)
      const executiveSummary = computeExecutiveSummary(
        risk, diversification, correlation, factorExposure, stressTest, portfolio,
      )
    
      return {
        risk,
        rebalance,
        diversification,
        stressTest,
        varCvar,
        factorExposure,
        correlation,
        marketRegime,
        executiveSummary,
        generatedAt: new Date().toISOString(),
        version: '3.1.0',
      }
    }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dun999/finsight-mpp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server