aiskillstore/architecture-reference
Quick reference for Portfolio Buddy 2 project structure. Use when: adding new features, modifying existing components, understanding data flow, or onboarding to the codebase. Contains component hierarchy, hook patterns, and utility functions.
This is a copy. The original lives at comeonoliver/architecture-reference.
npx skills add https://github.com/aiskillstore/marketplace --skill architecture-reference
App.tsx (351 lines)
├── Header
│ └── App title and branding
├── UploadSection
│ ├── File upload to Supabase
│ ├── CSV parsing and validation
│ └── Error handling
├── ErrorList
│ └── Display parsing/validation errors
├── UploadedFilesList
│ └── List of successfully uploaded files
├── AnalyticsControls
│ ├── Toggle Metrics view
│ ├── Toggle Portfolio view
│ └── Toggle Correlation view
├── PortfolioSection (591 lines - NEEDS REFACTOR!)
│ ├── usePortfolio hook (date filtering)
│ ├── useContractMultipliers hook
│ ├── Chart.js equity curves
│ ├── Portfolio statistics
│ ├── ContractInput components
│ ├── MasterContractControl
│ └── MetricsTable integration
├── CorrelationSection
│ ├── CorrelationHeatmap (Chart.js)
│ ├── Spearman correlation
│ └── Pearson correlation
├── MetricsTable (242 lines)
│ ├── useMetrics hook
│ ├── useSorting hook (advanced multi-column)
│ ├── SortableHeader components
│ └── Selection state management
└── SessionComplete
└── Completion UI/messaging
Location: src/hooks/useMetrics.ts
Purpose: Calculate trading metrics from uploaded portfolio data
Features:
Usage:
const { metrics, isCalculating } = useMetrics(portfolioData, riskFreeRate)
Returns:
metrics: Array of calculated metrics per strategyisCalculating: Boolean loading stateNote: Contains 4 TypeScript any violations in sort comparisons (tech debt)
Location: src/hooks/usePortfolio.ts
Purpose: Manage portfolio data with date range filtering
Features:
Usage:
const {
portfolioData,
filteredData,
dateRange,
setDateRange
} = usePortfolio(uploadedFiles)
Recent Addition: Date range filtering (commit 258ba3a)
Note: Contains 11 TypeScript any violations in trade/metrics types (tech debt)
Location: src/hooks/useContractMultipliers.ts
Purpose: Manage contract multipliers for futures trading
Features:
Usage:
const {
multipliers,
setMultiplier,
setAllMultipliers,
getAdjustedMetrics
} = useContractMultipliers(strategies)
Location: src/hooks/useSorting.ts
Purpose: Advanced multi-column sorting for MetricsTable
Features:
Usage:
const {
sortedData,
sortColumn,
sortDirection,
handleSort
} = useSorting(data, defaultColumn)
Location: src/utils/dataUtils.ts
Contains Core Functions:
CSV & Data Processing:
parseCSV(file) - Parse CSV file with PapaParseprocessCurrencyColumns(data) - Clean currency values ($, commas)parseFilenameComponents(filename) - Extract symbol/direction/strategy from filenamegetDisplayName(symbol, direction, strategy) - Format display namesnormalizeDate(date) - Normalize dates to midnight UTCgetDateKey(date) - Convert date to YYYY-MM-DD string keyMetric Calculations:
calculateMetrics(data, filename) - Calculate trade-level metrics for a strategygetAdjustedMetrics(metrics, multiplier) - Apply contract multiplier to metricsRisk-Adjusted Metrics (PortfolioSection.tsx):
(annualGrowthRate / 100) / (maxDrawdown / startingCapital)Correlation Analysis:
buildCorrelationMatrix(strategies) - Build Spearman correlation matrixcalculatePearsonCorrelation(returns1, returns2) - Pearson correlation coefficientcalculateRanks(values) - Rank calculation for Spearman correlationTrading Calculations:
getMarginRate(symbol) - Get margin requirements by symbolcalculateEquityCurve(trades) - Build cumulative equity curvecalculateDailyReturns(equity) - Calculate daily returns from equity curveFormatting:
formatNumber(value, decimals) - Format numbers with decimalsformatCurrency(value) - Format as currency ($X,XXX.XX)formatPercent(value) - Format as percentage (X.XX%)Note: Contains 1 TypeScript any violation in Metrics interface (tech debt)
1. User uploads CSV via UploadSection
↓
2. parseCSV() extracts trade data
↓
3. processCurrencyColumns() cleans data
↓
4. File uploaded to Supabase storage
↓
5. usePortfolio hook fetches and aggregates data
↓
6. Date range filter applied (if set)
↓
7. useMetrics calculates all metrics
↓
8. MetricsTable displays results
1. User inputs contract size in ContractInput
↓
2. useContractMultipliers stores value
↓
3. getAdjustedMetrics() applies multiplier
↓
4. Adjusted metrics shown in MetricsTable
↓
5. Portfolio charts update with adjusted values
1. User clicks SortableHeader
↓
2. useSorting updates sort column/direction
↓
3. Custom comparison logic applied
↓
4. MetricsTable re-renders with sorted data
1. User selects assets in MetricsTable
↓
2. Selection state passed to CorrelationSection
↓
3. buildCorrelationMatrix() calculates correlations
↓
4. CorrelationHeatmap renders Chart.js heatmap
↓
5. Spearman & Pearson correlations both shown
useStateuseMemouseCallbackuseRefExample Pattern:
const [data, setData] = useState<Trade[]>([])
const metrics = useMemo(() => calculateMetrics(data), [data])
const handleUpload = useCallback((file: File) => {
// upload logic
}, [])
dataUtils.calculateMetrics()calculateMetrics()MetricsTable.tsxuseSorting.ts if neededExample: Sortino Ratio was added in commits 258ba3a & 9f25040
src/components/ import { Line } from 'react-chartjs-2'
import { Chart, registerables } from 'chart.js'
import zoomPlugin from 'chartjs-plugin-zoom'
useMetrics or usePortfolio for dataApp.tsxsrc/hooks/use[Feature].tsuse prefix, camelCaseany)⚠️ Recharts is installed but NEVER imported - should be removed (11.5KB waste)
Current Violations:
For PortfolioSection (591 lines):
EquityChartSection.tsxPortfolioStats.tsxContractControls.tsxinterface Trade {
date: Date
symbol: string
pnl: number
// ...
}
interface Metric {
name: string
sharpe: number
sortino: number
// ...
}
any TypesCurrent violations (15 total) - see portfolio-context skill for details
Preferred approach:
// Bad
const data: any = parseData()
// Good
interface ParsedData {
trades: Trade[]
errors: string[]
}
const data: ParsedData = parseData()
// Expensive correlation calculation
const correlationMatrix = useMemo(
() => buildCorrelationMatrix(selectedStrategies),
[selectedStrategies]
)
const handleSort = useCallback((column: string) => {
setSortColumn(column)
setSortDirection(prev => prev === 'asc' ? 'desc' : 'asc')
}, [])
Take aiskillstore/architecture-reference from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.