# Timeframe Filtering Feature ## Overview The timeframe filtering feature allows users to view dashboard metrics and charts for specific date ranges, providing better insights into performance over different time periods. ## User Interface ### Location - Dashboard page (DashboardV2 component) - Dropdown filter positioned at the top of the dashboard, above metrics cards ### Available Options 1. **All Time** - Shows all historical data 2. **Last 30 Days** - Shows data from the past 30 days 3. **Last 90 Days** - Shows data from the past 90 days 4. **Last 180 Days** - Shows data from the past 180 days (default for chart) 5. **Last 1 Year** - Shows data from the past 365 days 6. **Year to Date** - Shows data from January 1st of current year to today ## What Gets Filtered ### Metrics Cards (Top of Dashboard) When a timeframe is selected, the following metrics are filtered by position open date: - Total Positions count - Open Positions count - Closed Positions count - Total Realized P&L - Total Unrealized P&L - Win Rate percentage - Average Win amount - Average Loss amount - Current Balance (always shows latest) ### Balance History Chart The chart adjusts to show the requested number of days: - All Time: ~10 years (3650 days) - Last 30 Days: 30 days - Last 90 Days: 90 days - Last 180 Days: 180 days - Last 1 Year: 365 days - Year to Date: Dynamic calculation from Jan 1 to today ## Implementation Details ### Frontend #### Component: `DashboardV2.tsx` ```typescript // State management const [timeframe, setTimeframe] = useState('all'); // Convert timeframe to days for balance history const getDaysFromTimeframe = (tf: TimeframeOption): number => { switch (tf) { case 'last30days': return 30; case 'last90days': return 90; // ... etc } }; // Get date range for filtering const { startDate, endDate } = getTimeframeDates(timeframe); ``` #### API Calls 1. **Overview Stats**: - Endpoint: `GET /analytics/overview/{account_id}` - Parameters: `start_date`, `end_date` - Query key includes timeframe for proper caching 2. **Balance History**: - Endpoint: `GET /analytics/balance-history/{account_id}` - Parameters: `days` (calculated from timeframe) - Query key includes timeframe for proper caching ### Backend #### Endpoint: `analytics_v2.py` ```python @router.get("/overview/{account_id}") def get_overview( account_id: int, refresh_prices: bool = False, max_api_calls: int = 5, start_date: Optional[date] = None, # NEW end_date: Optional[date] = None, # NEW db: Session = Depends(get_db) ): # Passes dates to calculator stats = calculator.calculate_account_stats( account_id, update_prices=True, max_api_calls=max_api_calls, start_date=start_date, end_date=end_date ) ``` #### Service: `performance_calculator_v2.py` ```python def calculate_account_stats( self, account_id: int, update_prices: bool = True, max_api_calls: int = 10, start_date = None, # NEW end_date = None # NEW ) -> Dict: # Filter positions by open date query = self.db.query(Position).filter(Position.account_id == account_id) if start_date: query = query.filter(Position.open_date >= start_date) if end_date: query = query.filter(Position.open_date <= end_date) positions = query.all() # ... rest of calculation logic ``` ## Filter Logic ### Position Filtering Positions are filtered based on their `open_date`: - Only positions opened on or after `start_date` are included - Only positions opened on or before `end_date` are included - Open positions are always included if they match the date criteria ### Balance History The balance history shows account balance at end of each day: - Calculated from transactions within the specified days - Does not filter by open date, shows actual historical balances ## Caching Strategy React Query cache keys include timeframe parameters to ensure: 1. Different timeframes don't conflict in cache 2. Changing timeframes triggers new API calls 3. Cache invalidation works correctly Cache keys: - Overview: `['analytics', 'overview', accountId, startDate, endDate]` - Balance: `['analytics', 'balance-history', accountId, timeframe]` ## User Experience ### Performance - Balance history queries are fast (no market data needed) - Overview queries use cached prices by default (fast) - Users can still trigger price refresh within filtered timeframe ### Visual Feedback - Filter immediately updates both metrics and chart - Loading states handled by React Query - Stale data shown while fetching (stale-while-revalidate pattern) ## Testing Checklist - [ ] All timeframe options work correctly - [ ] Metrics update when timeframe changes - [ ] Balance history chart adjusts to show correct date range - [ ] "All Time" shows complete data - [ ] Year to Date calculation is accurate - [ ] Filter persists during price refresh - [ ] Cache invalidation works properly - [ ] UI shows loading states appropriately ## Future Enhancements Potential improvements: 1. Add custom date range picker 2. Compare multiple timeframes side-by-side 3. Save preferred timeframe in user settings 4. Add timeframe filter to Transactions table 5. Add timeframe presets for tax year, quarters 6. Export filtered data to CSV ## Related Components - `TimeframeFilter.tsx` - Reusable dropdown component - `getTimeframeDates()` - Helper function to convert timeframe to dates - `TransactionTable.tsx` - Already uses timeframe filtering ## API Reference ### GET /analytics/overview/{account_id} ``` Query Parameters: - refresh_prices: boolean (default: false) - max_api_calls: integer (default: 5) - start_date: date (optional, format: YYYY-MM-DD) - end_date: date (optional, format: YYYY-MM-DD) ``` ### GET /analytics/balance-history/{account_id} ``` Query Parameters: - days: integer (default: 30, max: 3650) ```