Problem:
- Leaderboard used ai_model-based colors (qwen=purple, other=blue)
- Performance Comparison used index-based colors (10 color pool)
- This caused color mismatch between the two components
- Same trader showed different colors in different sections
Solution:
- Create shared color utility (utils/traderColors.ts)
- Define single color pool with 10 distinct colors
- Implement unified getTraderColor function based on trader index
- Update both ComparisonChart and CompetitionPage to use shared utility
Changes:
- New file: web/src/utils/traderColors.ts (shared color logic)
- Updated: ComparisonChart.tsx (use shared utility)
- Updated: CompetitionPage.tsx (use shared utility in Leaderboard
and Head-to-Head sections)
Now traders consistently display the same color across all UI sections.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Problem:
- Multiple traders using the same AI model had duplicate colors
- Only 2 colors were available (blue for deepseek, purple for qwen)
- Made it difficult to distinguish between traders
Solution:
- Expand color pool from 2 to 10 distinct colors
- Change color assignment from ai_model-based to index-based
- Each trader now gets a unique color based on their position
- Colors cycle if there are more than 10 traders
Color pool includes: blue, purple, emerald, orange, pink, amber,
sky, violet, green, rose
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Previously, ComparisonChart was hardcoded to only fetch equity history
data for the first 2 traders, causing the 3rd and subsequent traders'
data to not be displayed on the chart.
Changes:
- Replaced multiple individual useSWR calls with single consolidated call
- Use Promise.all() to fetch all traders' equity data concurrently
- Generate dynamic cache key based on all trader IDs
- Maintain backward compatibility with existing component structure
- Update useMemo dependencies to properly track data changes
This fix allows the comparison chart to properly display any number of
competing traders, not just 2.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Root cause:
ComparisonChart was calling useSWR hooks dynamically inside a .map() loop,
which violates React's Rules of Hooks. When the traders array length changed
(e.g., from 0 to 2, or during initial load), the number of hook calls would
change between renders, triggering React Error #310.
Previous code:
```tsx
const traderHistories = traders.map((trader) => {
return useSWR(`equity-history-${trader.trader_id}`, ...); // ❌ Dynamic hooks
});
```
The eslint-disable comment on line 24 was masking this critical issue.
Fix:
- Always call exactly 2 useSWR hooks (trader1, trader2) unconditionally
- Pass null as the key when trader doesn't exist (SWR handles this gracefully)
- Build traderHistories array from these fixed hooks
- Ensures same number of hooks called on every render
This follows React's Rules of Hooks:
✅ Only call hooks at the top level
✅ Don't call hooks inside loops, conditions, or nested functions
✅ Call hooks in the same order every render
Fixes: React Error #310 (Rendered more hooks than during previous render)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major improvements:
- Replace useState+useEffect with useMemo for better performance
- Use timestamp-based grouping instead of cycle_number
- Fix data alignment issues when backend resets cycles
- Add detailed console logging for debugging
- Optimize data merging logic with Map structures
Chart updates:
- Display sequence number instead of cycle number on X-axis
- Improve tooltip to show actual time and sequence
- Better handling of multi-trader data synchronization
- More reliable data point matching across traders
Performance:
- Reduce unnecessary re-renders with useMemo
- More efficient data processing with Maps
- Better dependency tracking in hooks
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Multi-AI competition mode (Qwen vs DeepSeek)
- Binance Futures integration
- AI self-learning mechanism
- Professional web dashboard
- Complete risk management system