Skip to main content
The Wealthyhood Home screen displays a daily summary of the user’s portfolio, market data, and investment insights. All data is fetched from a single endpoint that returns historical and current portfolio information.
All routes require a bearer token with the appropriate scopes plus the x-user-id header to identify the user account.

Data sources

Prerequisites

  • Bearer token with required scopes
  • x-user-id header to identify the user

What to fetch

Use Get daily summaries to retrieve all data needed for the home screen.Returns:
  • Historical portfolio snapshots (cash, savings, holdings, total)
  • Performance metrics (returns, performers)
  • Market data (today’s markets, market summary)
  • Sentiment scores
  • Chart scaling data (maxValueDifferences)
You’ll need to generate date labels client-side using the timestamp field. See implementation notes in each component section.

Component Guide

1. Date Selector / Time Series Navigation

Purpose: Allows users to navigate through historical portfolio data by selecting different dates. Data Source:
  • Use the data array from the response
  • Filter out items where isOnlyForChartLabel is true (these entries are used for chart axis labeling in future & past data points when there is no daily summary for those dates)
Fields to Use:
  • timestamp - Unix timestamp in milliseconds for the date
  • isOnlyForChartLabel - Boolean flag to identify chart-label-only entries

2. Portfolio Value Cards

Purpose: Display four key portfolio metrics as cards that users can swipe through. Data Source:
  • portfolio object from the selected daily summary item
Fields to Use:

Total Account Value Card

  • portfolio.total.displayValue - Formatted value string (e.g., “€12,345.67”)
  • portfolio.total.value - Numeric value in cents

Holdings Card

  • portfolio.holdings.displayValue - Formatted investment value
  • portfolio.holdings.upBy - Percentage increase (if positive)
  • portfolio.holdings.downBy - Percentage decrease (if negative)

Savings Card

  • portfolio.savings.displayValue - Formatted savings value
  • portfolio.savings.dailyInterest - Daily interest earned (if applicable)
  • portfolio.savings.unrealisedMonthlyInterest - Monthly interest (if applicable)
  • portfolio.savings.estimated - Boolean indicating if interest is estimated

Cash Card

  • portfolio.cash.displayValue - Formatted cash balance
  • portfolio.cash.value - Numeric value in cents
Implementation Notes:
  • Display cards in a horizontal scrollable container
  • Show up/down indicators with appropriate colors (green for up, red for down)
  • Cards should be swipeable/scrollable
  • Default selection should be “Total” (index 0)

3. Portfolio Chart

Purpose: Visualize portfolio value trends over time with an interactive line chart. Data Source:
  • Use the entire data array from the response
  • Filter based on selected portfolio type (Total, Holdings, Savings, or Cash)
Fields to Use (depending on selected portfolio type):

For Total Account Value:

  • Iterate through all items in data array
  • Use data[].portfolio.total.chartValue - Numeric value for chart plotting
  • Use data[].timestamp - For sorting and date handling
  • Use data[].portfolio.total.displayValue - Tooltip/display value on hover
  • X-axis Labels: Generate labels from timestamp field

For Holdings:

  • data[].portfolio.holdings.chartValue
  • data[].timestamp
  • data[].portfolio.holdings.displayValue

For Savings:

  • data[].portfolio.savings.chartValue
  • data[].timestamp
  • data[].portfolio.savings.displayValue

For Cash:

  • data[].portfolio.cash.chartValue
  • data[].timestamp
  • data[].portfolio.cash.displayValue
Additional Data:
  • maxValueDifferences.total - Maximum value difference for Total (used for chart scaling)
  • maxValueDifferences.holdings - Maximum value difference for Holdings
  • maxValueDifferences.savings - Maximum value difference for Savings
  • maxValueDifferences.cash - Maximum value difference for Cash
Implementation Notes:
  • Chart should update when user selects a different portfolio card type
  • Chart should highlight the currently selected date
  • Use maxValueDifferences to properly scale the Y-axis
  • Chart should be interactive, allowing users to tap/click on data points to select that date
  • Chart Label Handling: For items where isOnlyForChartLabel is true, generate labels from timestamp for x-axis display
  • Filter out chart-label-only points when allowing date selection, but include them in chart rendering for proper axis labels

4. Top Movers (Best & Worst Performers)

Purpose: Display the best and worst performing assets in the user’s portfolio. Data Source:
  • performers object from the selected daily summary item
Important: The performers field may be undefined. Always check if performers exists before accessing its properties.
Fields to Use:

Best Performers Section

  • performers.best - Array of top performing assets
    • Each item contains:
      • value - Formatted value string
      • upBy - Percentage increase
      • weight - Portfolio weight percentage
      • assetId - Asset identifier for navigation

Worst Performers Section

  • performers.worst - Array of worst performing assets
    • Each item contains:
      • value - Formatted value string
      • downBy - Percentage decrease
      • weight - Portfolio weight percentage
      • assetId - Asset identifier for navigation
Additional Data:
  • performers.all - Complete list of all performers (used for “See All” functionality)
  • seeAllTopPerformersEnabled - Boolean indicating if “See All” button should be enabled
Implementation Notes:
  • Only show this section if performers exists and has data
  • Display best performers in green/positive styling
  • Display worst performers in red/negative styling
  • Show “See All” button if performers.all is not empty and seeAllTopPerformersEnabled is true
  • Hide the entire section if performers is null/undefined or both arrays are empty

5. Today’s Markets

Purpose: Display a scrolling ticker of market indices and their daily performance. Data Source:
  • todayMarkets array from the selected daily summary item
Fields to Use:
  • todayMarkets[] - Array of market items
    • Each item contains:
      • label - Market/index name (e.g., “FTSE 100”, “S&P 500”)
      • returns.upBy - Percentage increase (if positive)
      • returns.downBy - Percentage decrease (if negative)
Implementation Notes:
  • Display as a horizontally scrolling ticker/marquee
  • Auto-scroll continuously if multiple markets are present
  • Show green/positive styling for upBy, red/negative styling for downBy
  • Hide the section if todayMarkets is null or empty
  • Pause auto-scroll on user interaction, resume after a delay

6. Sentiment Score

Purpose: Display a comprehensive sentiment score gauge showing overall portfolio sentiment and breakdowns. Data Source:
  • sentimentScore object from the selected daily summary item
Fields to Use:

Overall Sentiment

  • sentimentScore.total.score - Overall sentiment score (integer, typically 0-100)
  • sentimentScore.total.label - Score label: “optimal”, “suboptimal”, or “underperforming”

News Sentiment

  • sentimentScore.news.score - News-based sentiment score (if available)
  • sentimentScore.news.label - Score label

Analyst Sentiment

  • sentimentScore.analyst.score - Analyst-based sentiment score (if available)
  • sentimentScore.analyst.label - Score label

Price Momentum

  • sentimentScore.priceMomentum.score - Price momentum score (if enabled)
  • sentimentScore.priceMomentum.label - Score label
Implementation Notes:
  • Display as a gauge/chart visualization
  • Use color coding based on label:
    • “optimal” - Green
    • “suboptimal” - Yellow/Orange
    • “underperforming” - Red
  • Show breakdown sections for News, Analyst, and Price Momentum (only if they exist)
  • Price Momentum section should only be shown if priceMomentum exists
  • Hide the entire section if sentimentScore is null

7. Market Summary

Purpose: Display a daily market summary with overview text and detailed sections. Data Source:
  • marketSummary object from the selected daily summary item
Fields to Use:

Overview Section

  • marketSummary.overview - Main summary text (displayed on home screen)

Detailed Sections (for full view)

  • marketSummary.sections[] - Array of detailed sections
    • Each section contains:
      • tag - Section category/tag
      • title - Section title
      • content - Section content text
      • assetId - Related asset ID (if applicable)
      • tickerSymbol - Ticker symbol (if applicable)
      • assetReturns.upBy - Asset return percentage (if positive)
      • assetReturns.downBy - Asset return percentage (if negative)
Implementation Notes:
  • Display overview text on the home screen
  • Show “Read more” button/link if marketSummary.sections exists and has items
  • Navigate to full market summary view when “Read more” is clicked
  • Hide the section if marketSummary is null

8. Uninvested State

Purpose: Show a special state when the user hasn’t made any investments yet. Data Source:
  • isUninvested boolean from the selected daily summary item
Fields to Use:
  • isUninvested - Boolean flag indicating if user has no investments
Implementation Notes:
  • When isUninvested is true:
    • Hide or blur portfolio value cards
    • Hide chart
    • Hide top movers section
    • Show call-to-action buttons for first investment
    • Display encouraging message about starting to invest
  • When isUninvested is false, show all normal components

Data Flow

  1. Initial Load:
    • Fetch data from GET /daily-summaries endpoint with x-user-id header
    • Filter data array to remove items where isOnlyForChartLabel is true
    • Select the most recent date (last item in filtered array) as default
    • Render all components using data from the selected date
  2. Date Selection:
    • When user selects a different date from the date selector
    • Update all components with data from the newly selected daily summary item
    • Update chart highlight to show selected date
    • Maintain selected portfolio card type (Total/Holdings/Savings/Cash)
  3. Portfolio Card Selection:
    • When user selects a different portfolio card (Total/Holdings/Savings/Cash)
    • Update chart to show data for the selected portfolio type
    • Use corresponding maxValueDifferences value for chart scaling
    • Update chart data points using the appropriate portfolio.*.chartValue fields
  4. Refresh:
    • Re-fetch from GET /daily-summaries endpoint
    • Update all components with fresh data
    • Maintain current date and portfolio card selection if still valid

Error Handling

  • If the API request fails, display an appropriate error message
  • If data array is empty or null, show an empty state
  • If specific fields are missing (e.g., portfolio, performers), hide the corresponding components gracefully
  • Handle cases where historical data might be incomplete
  • Always check if optional fields exist before accessing nested properties (especially performers, sentimentScore, todayMarkets, marketSummary)

Performance Considerations

  • The data array may contain many items (potentially weeks or months of data)
  • Consider pagination or limiting the number of data points if the array becomes very large
  • Cache the response appropriately to avoid unnecessary API calls
  • Filter isOnlyForChartLabel items early to reduce processing overhead
  • Use maxValueDifferences values to optimize chart rendering
  • Generate date labels efficiently using cached formatters

Example: Complete Fetch Implementation

const BASE = 'https://api.wealthyhood.com';

async function fetchHomeScreen({ token, userId }) {
  const headers = {
    'Authorization': `Bearer ${token}`,
    'x-user-id': userId,
    'Accept': 'application/json'
  };

  const response = await fetch(`${BASE}/daily-summaries`, { headers });
  
  if (!response.ok) {
    throw new Error(`Failed to fetch daily summaries: ${response.status}`);
  }

  const data = await response.json();
  
  // Filter out chart-label-only entries for date selector
  const selectableDates = data.data.filter(
    item => !('isOnlyForChartLabel' in item && item.isOnlyForChartLabel)
  );
  
  // Get most recent date (last item)
  const selectedDate = selectableDates[selectableDates.length - 1];
  
  // Generate date labels client-side
  const formatDateLabel = (timestamp) => {
    const date = new Date(timestamp);
    const today = new Date();
    const isToday = date.toDateString() === today.toDateString();
    
    if (isToday) return 'Today';
    
    return date.toLocaleDateString('en-GB', { 
      day: 'numeric', 
      month: 'short' 
    });
  };
  
  return {
    ...data,
    selectableDates: selectableDates.map(item => ({
      ...item,
      dateLabel: formatDateLabel(item.timestamp)
    })),
    selectedDate: {
      ...selectedDate,
      dateLabel: formatDateLabel(selectedDate.timestamp)
    }
  };
}
Implement a client-side date formatting utility that handles:
  • Locale-specific formatting
  • Relative dates (“Today”, “Yesterday”)
  • Consistent formatting across all components
  • Timezone handling
Always check if performers exists before accessing its properties, as it may be undefined even when other data is present.

See also