import { DataTable } from '@/components/ui'; import type { ColumnDef } from '@tanstack/react-table'; import React from 'react'; interface PortfolioItem { symbol: string; quantity: number; avgPrice: number; currentPrice: number; value: number; change: number; changePercent: number; // Additional columns for stress testing volume: number; marketCap: number; pe: number; pb: number; roe: number; debt: number; revenue: number; earnings: number; dividend: number; beta: number; rsi: number; macd: number; sma20: number; sma50: number; sma200: number; support: number; resistance: number; volatility: number; sharpe: number; alpha: number; correlation: number; sector: string; industry: string; country: string; exchange: string; currency: string; lastUpdate: string; analyst1: string; analyst2: string; analyst3: string; rating1: number; rating2: number; rating3: number; target1: number; target2: number; target3: number; risk: string; esg: number; } export function PortfolioTable() { // Generate 100,000 rows of sample data const data: PortfolioItem[] = React.useMemo(() => { const symbols = [ 'AAPL', 'GOOGL', 'MSFT', 'TSLA', 'AMZN', 'META', 'NFLX', 'NVDA', 'AMD', 'INTC', 'CRM', 'ORCL', 'IBM', 'CSCO', 'UBER', 'LYFT', 'SNAP', 'TWTR', 'SPOT', 'SQ', ]; const sectors = [ 'Technology', 'Healthcare', 'Finance', 'Energy', 'Consumer', 'Industrial', 'Materials', 'Utilities', 'Real Estate', 'Telecom', ]; const industries = [ 'Software', 'Hardware', 'Biotech', 'Banking', 'Oil & Gas', 'Retail', 'Manufacturing', 'Mining', 'Utilities', 'REITs', ]; const countries = [ 'USA', 'Canada', 'UK', 'Germany', 'Japan', 'China', 'India', 'Brazil', 'Australia', 'France', ]; const exchanges = ['NYSE', 'NASDAQ', 'LSE', 'TSX', 'Nikkei', 'SSE', 'BSE', 'ASX', 'Euronext']; const currencies = ['USD', 'CAD', 'GBP', 'EUR', 'JPY', 'CNY', 'INR', 'BRL', 'AUD']; const analysts = [ 'Goldman Sachs', 'Morgan Stanley', 'JPMorgan', 'Bank of America', 'Wells Fargo', 'Credit Suisse', 'Deutsche Bank', 'Barclays', 'UBS', 'Citigroup', ]; const risks = ['Low', 'Medium', 'High', 'Very High']; return Array.from({ length: 100000 }, (_, i) => { const basePrice = 50 + Math.random() * 500; const change = (Math.random() - 0.5) * 20; const quantity = Math.floor(Math.random() * 1000) + 1; return { symbol: `${symbols[i % symbols.length]}${Math.floor(i / symbols.length)}`, quantity, avgPrice: basePrice, currentPrice: basePrice + change, value: (basePrice + change) * quantity, change: change * quantity, changePercent: (change / basePrice) * 100, volume: Math.floor(Math.random() * 10000000), marketCap: Math.floor(Math.random() * 1000000000000), pe: Math.random() * 50 + 5, pb: Math.random() * 10 + 0.5, roe: Math.random() * 30 + 5, debt: Math.random() * 50, revenue: Math.floor(Math.random() * 100000000000), earnings: Math.floor(Math.random() * 10000000000), dividend: Math.random() * 5, beta: Math.random() * 3 + 0.5, rsi: Math.random() * 100, macd: (Math.random() - 0.5) * 10, sma20: basePrice + (Math.random() - 0.5) * 10, sma50: basePrice + (Math.random() - 0.5) * 20, sma200: basePrice + (Math.random() - 0.5) * 50, support: basePrice - Math.random() * 20, resistance: basePrice + Math.random() * 20, volatility: Math.random() * 100, sharpe: Math.random() * 3, alpha: (Math.random() - 0.5) * 20, correlation: (Math.random() - 0.5) * 2, sector: sectors[Math.floor(Math.random() * sectors.length)] || 'Technology', industry: industries[Math.floor(Math.random() * industries.length)] || 'Software', country: countries[Math.floor(Math.random() * countries.length)] || 'USA', exchange: exchanges[Math.floor(Math.random() * exchanges.length)] || 'NYSE', currency: currencies[Math.floor(Math.random() * currencies.length)] || 'USD', lastUpdate: new Date(Date.now() - Math.random() * 86400000).toISOString(), analyst1: analysts[Math.floor(Math.random() * analysts.length)] || 'Goldman Sachs', analyst2: analysts[Math.floor(Math.random() * analysts.length)] || 'Morgan Stanley', analyst3: analysts[Math.floor(Math.random() * analysts.length)] || 'JPMorgan', rating1: Math.random() * 5 + 1, rating2: Math.random() * 5 + 1, rating3: Math.random() * 5 + 1, target1: basePrice + (Math.random() - 0.3) * 50, target2: basePrice + (Math.random() - 0.3) * 50, target3: basePrice + (Math.random() - 0.3) * 50, risk: risks[Math.floor(Math.random() * risks.length)] || 'Medium', esg: Math.random() * 100, }; }); }, []); const columns: ColumnDef[] = [ { id: 'symbol', header: 'Symbol', accessorKey: 'symbol', size: 120, cell: ({ getValue }) => ( {getValue() as string} ), }, { id: 'quantity', header: 'Quantity', accessorKey: 'quantity', size: 100, cell: ({ getValue }) => ( {(getValue() as number).toLocaleString()} ), }, { id: 'avgPrice', header: 'Avg Price', accessorKey: 'avgPrice', size: 120, cell: ({ getValue }) => ( ${(getValue() as number).toFixed(2)} ), }, { id: 'currentPrice', header: 'Current Price', accessorKey: 'currentPrice', size: 120, cell: ({ getValue }) => ( ${(getValue() as number).toFixed(2)} ), }, { id: 'value', header: 'Value', accessorKey: 'value', size: 120, cell: ({ getValue }) => ( ${(getValue() as number).toLocaleString()} ), }, { id: 'change', header: 'P&L', accessorKey: 'change', size: 120, cell: ({ getValue }) => { const value = getValue() as number; const isPositive = value >= 0; return ( {isPositive ? '+' : ''}${value.toLocaleString()} ); }, }, { id: 'changePercent', header: 'P&L %', accessorKey: 'changePercent', size: 100, cell: ({ getValue }) => { const value = getValue() as number; const isPositive = value >= 0; return ( {isPositive ? '+' : ''} {value.toFixed(2)}% ); }, }, { id: 'volume', header: 'Volume', accessorKey: 'volume', size: 120, cell: ({ getValue }) => ( {(getValue() as number).toLocaleString()} ), }, { id: 'marketCap', header: 'Market Cap', accessorKey: 'marketCap', size: 120, cell: ({ getValue }) => { const value = getValue() as number; if (value >= 1e12) {return ${(value / 1e12).toFixed(2)}T;} if (value >= 1e9) {return ${(value / 1e9).toFixed(2)}B;} if (value >= 1e6) {return ${(value / 1e6).toFixed(2)}M;} return ${value.toLocaleString()}; }, }, { id: 'pe', header: 'P/E', accessorKey: 'pe', size: 80, cell: ({ getValue }) => ( {(getValue() as number).toFixed(2)} ), }, { id: 'pb', header: 'P/B', accessorKey: 'pb', size: 80, cell: ({ getValue }) => ( {(getValue() as number).toFixed(2)} ), }, { id: 'roe', header: 'ROE %', accessorKey: 'roe', size: 80, cell: ({ getValue }) => ( {(getValue() as number).toFixed(1)}% ), }, { id: 'debt', header: 'Debt %', accessorKey: 'debt', size: 80, cell: ({ getValue }) => ( {(getValue() as number).toFixed(1)}% ), }, { id: 'revenue', header: 'Revenue', accessorKey: 'revenue', size: 120, cell: ({ getValue }) => { const value = getValue() as number; if (value >= 1e9) {return ${(value / 1e9).toFixed(2)}B;} if (value >= 1e6) {return ${(value / 1e6).toFixed(2)}M;} return ${value.toLocaleString()}; }, }, { id: 'earnings', header: 'Earnings', accessorKey: 'earnings', size: 120, cell: ({ getValue }) => { const value = getValue() as number; if (value >= 1e9) {return ${(value / 1e9).toFixed(2)}B;} if (value >= 1e6) {return ${(value / 1e6).toFixed(2)}M;} return ${value.toLocaleString()}; }, }, { id: 'dividend', header: 'Dividend %', accessorKey: 'dividend', size: 100, cell: ({ getValue }) => { const value = getValue() as number; return {value.toFixed(2)}%; }, }, { id: 'beta', header: 'Beta', accessorKey: 'beta', size: 80, cell: ({ getValue }) => { const value = getValue() as number; const color = value > 1 ? 'text-warning' : value < 1 ? 'text-success' : 'text-text-primary'; return {value.toFixed(2)}; }, }, { id: 'rsi', header: 'RSI', accessorKey: 'rsi', size: 80, cell: ({ getValue }) => { const value = getValue() as number; const color = value > 70 ? 'text-danger' : value < 30 ? 'text-success' : 'text-text-primary'; return {value.toFixed(1)}; }, }, { id: 'macd', header: 'MACD', accessorKey: 'macd', size: 80, cell: ({ getValue }) => { const value = getValue() as number; const color = value > 0 ? 'text-success' : 'text-danger'; return {value.toFixed(2)}; }, }, { id: 'sma20', header: 'SMA 20', accessorKey: 'sma20', size: 100, cell: ({ getValue }) => ( ${(getValue() as number).toFixed(2)} ), }, { id: 'sma50', header: 'SMA 50', accessorKey: 'sma50', size: 100, cell: ({ getValue }) => ( ${(getValue() as number).toFixed(2)} ), }, { id: 'sma200', header: 'SMA 200', accessorKey: 'sma200', size: 100, cell: ({ getValue }) => ( ${(getValue() as number).toFixed(2)} ), }, { id: 'support', header: 'Support', accessorKey: 'support', size: 100, cell: ({ getValue }) => ( ${(getValue() as number).toFixed(2)} ), }, { id: 'resistance', header: 'Resistance', accessorKey: 'resistance', size: 100, cell: ({ getValue }) => ( ${(getValue() as number).toFixed(2)} ), }, { id: 'volatility', header: 'Volatility', accessorKey: 'volatility', size: 100, cell: ({ getValue }) => ( {(getValue() as number).toFixed(1)}% ), }, { id: 'sharpe', header: 'Sharpe', accessorKey: 'sharpe', size: 80, cell: ({ getValue }) => ( {(getValue() as number).toFixed(2)} ), }, { id: 'alpha', header: 'Alpha', accessorKey: 'alpha', size: 80, cell: ({ getValue }) => { const value = getValue() as number; const color = value > 0 ? 'text-success' : 'text-danger'; return {value.toFixed(2)}; }, }, { id: 'correlation', header: 'Correlation', accessorKey: 'correlation', size: 100, cell: ({ getValue }) => ( {(getValue() as number).toFixed(2)} ), }, { id: 'sector', header: 'Sector', accessorKey: 'sector', size: 150, cell: ({ getValue }) => {getValue() as string}, }, { id: 'industry', header: 'Industry', accessorKey: 'industry', size: 150, cell: ({ getValue }) => {getValue() as string}, }, { id: 'country', header: 'Country', accessorKey: 'country', size: 100, cell: ({ getValue }) => {getValue() as string}, }, { id: 'exchange', header: 'Exchange', accessorKey: 'exchange', size: 100, cell: ({ getValue }) => {getValue() as string}, }, { id: 'currency', header: 'Currency', accessorKey: 'currency', size: 80, cell: ({ getValue }) => ( {getValue() as string} ), }, { id: 'lastUpdate', header: 'Last Update', accessorKey: 'lastUpdate', size: 150, cell: ({ getValue }) => ( {new Date(getValue() as string).toLocaleString()} ), }, { id: 'analyst1', header: 'Analyst 1', accessorKey: 'analyst1', size: 120, cell: ({ getValue }) => ( {getValue() as string} ), }, { id: 'analyst2', header: 'Analyst 2', accessorKey: 'analyst2', size: 120, cell: ({ getValue }) => ( {getValue() as string} ), }, { id: 'analyst3', header: 'Analyst 3', accessorKey: 'analyst3', size: 120, cell: ({ getValue }) => ( {getValue() as string} ), }, { id: 'rating1', header: 'Rating 1', accessorKey: 'rating1', size: 80, cell: ({ getValue }) => { const value = getValue() as number; const color = value >= 4 ? 'text-success' : value >= 3 ? 'text-warning' : 'text-danger'; return {value.toFixed(1)}; }, }, { id: 'rating2', header: 'Rating 2', accessorKey: 'rating2', size: 80, cell: ({ getValue }) => { const value = getValue() as number; const color = value >= 4 ? 'text-success' : value >= 3 ? 'text-warning' : 'text-danger'; return {value.toFixed(1)}; }, }, { id: 'rating3', header: 'Rating 3', accessorKey: 'rating3', size: 80, cell: ({ getValue }) => { const value = getValue() as number; const color = value >= 4 ? 'text-success' : value >= 3 ? 'text-warning' : 'text-danger'; return {value.toFixed(1)}; }, }, { id: 'target1', header: 'Target 1', accessorKey: 'target1', size: 100, cell: ({ getValue }) => ( ${(getValue() as number).toFixed(2)} ), }, { id: 'target2', header: 'Target 2', accessorKey: 'target2', size: 100, cell: ({ getValue }) => ( ${(getValue() as number).toFixed(2)} ), }, { id: 'target3', header: 'Target 3', accessorKey: 'target3', size: 100, cell: ({ getValue }) => ( ${(getValue() as number).toFixed(2)} ), }, { id: 'risk', header: 'Risk Level', accessorKey: 'risk', size: 100, cell: ({ getValue }) => { const value = getValue() as string; const color = value === 'Low' ? 'text-success' : value === 'Medium' ? 'text-warning' : 'text-danger'; return {value}; }, }, { id: 'esg', header: 'ESG Score', accessorKey: 'esg', size: 100, cell: ({ getValue }) => { const value = getValue() as number; const color = value >= 70 ? 'text-success' : value >= 40 ? 'text-warning' : 'text-danger'; return {value.toFixed(0)}; }, }, ]; return ( {/* Handle row click */}} className="border border-border rounded-lg" /> ); }