import React, { useState, useEffect } from 'react'; import { useAuth } from '../components/AuthContext'; import { getStrategyExplanation } from '../lib/StrategyExplanationService'; import { getUserTier } from '../lib/TierPolicy'; import { Play, Pause, Trash2, Activity, TrendingUp, Plus, Shield, Zap, Scale, Settings, ChevronDown, ChevronUp, Lightbulb, Cpu, Fingerprint, Target, DollarSign, Lock } from 'lucide-react'; import { StrategyWizard } from '../components/StrategyWizard'; import { BacktestRunnerPanel } from '../backtest/components/BacktestRunnerPanel'; import { useBacktestFeatureGate } from '../backtest/useBacktestFeatureGate'; import { deleteTradeProfile, fetchTradeProfiles, setTradeProfileActive } from '../lib/profileApi'; import { Button, IconButton } from '../components/ui/Primitives'; function getStrategyKindLabel(config: any) { if (config?.type === 'visual') return 'Visual Builder'; if (config?.type === 'code') return 'Code Strategy'; return 'V4.0 Core'; } const ActiveStrategyCard: React.FC<{ profile: any; botState: any; tier: string; onToggle: (p: any) => void; onEdit: (p: any) => void; onBacktest?: (p: any) => void; onDelete: (id: string) => void; isExpanded: boolean; onToggleExpand: (id: string) => void; }> = ({ profile, botState, tier, onToggle, onEdit, onBacktest, onDelete, isExpanded, onToggleExpand }) => { const config = profile.strategy_config; const isAggressive = config?.execution?.minRulePassRatio < 0.9; const isSafe = config?.execution?.minRulePassRatio >= 1.0; const strategyKindLabel = getStrategyKindLabel(config); const explanation = getStrategyExplanation(profile, botState); return (
{/* 1. Direct Status Strip */}
{/* 2. Header Area */}
{isSafe ? : isAggressive ? : }
Active Strategy {profile.is_active ? 'Running' : 'Paused'}
{onBacktest && ( } onClick={() => onBacktest(profile)} style={{ width: '38px', height: '38px', borderRadius: '10px', background: 'var(--bl-surface-highlight)', border: '1px solid var(--bl-border-subtle)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--bl-text-quiet)', cursor: 'pointer' }} className="icon-btn-hover" /> )} } onClick={() => onEdit(profile)} style={{ width: '38px', height: '38px', borderRadius: '10px', background: 'var(--bl-surface-highlight)', border: '1px solid var(--bl-border-subtle)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--bl-text-quiet)', cursor: 'pointer' }} className="icon-btn-hover" /> } onClick={() => onDelete(profile.id)} style={{ width: '38px', height: '38px', borderRadius: '10px', background: 'var(--bl-surface-highlight)', border: '1px solid var(--bl-border-subtle)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--bl-text-quiet)', cursor: 'pointer' }} className="icon-btn-hover" />
{/* 3. Identity */}

{profile.name}

{profile.symbols} {strategyKindLabel}
{/* 4. Operational DNA (Specs) */}
{[ { label: 'Allocation', value: `$${profile.allocated_capital.toLocaleString()}`, icon: , color: 'var(--bl-success)' }, { label: 'PnL (Global)', value: '$0.00', icon: , color: 'var(--bl-info-strong)' }, { label: 'Target', value: `$${config?.riskLimits?.dailyProfitTargetUsd || 0}`, icon: , color: 'var(--bl-warning)' }, { label: 'Latency', value: '5ms', icon: , color: 'var(--bl-danger)' } ].map((spec, i) => (
{spec.icon} {spec.label}
{spec.value}
))}
{/* 5. Health Diagnostic (Education Layer) */}
{/* 6. Action */}
); }; export const MyStrategiesTab: React.FC<{ botState: any; alerts?: any[]; previewAsCustomer?: boolean }> = ({ botState, alerts = [], previewAsCustomer = false }) => { const { user, profile: userProfile } = useAuth(); const [profiles, setProfiles] = useState([]); const [isLoading, setIsLoading] = useState(true); const [showWizard, setShowWizard] = useState(false); const [editingProfile, setEditingProfile] = useState(null); const [expandedExplanations, setExpandedExplanations] = useState>({}); const [backtestProfile, setBacktestProfile] = useState(null); const tier = getUserTier(userProfile); const { enabled: backtestEnabled, loading: backtestGateLoading } = useBacktestFeatureGate({ previewAsCustomer }); const fetchProfiles = async () => { if (!user) return; setIsLoading(true); const data = await fetchTradeProfiles(); setProfiles(data || []); setIsLoading(false); }; useEffect(() => { fetchProfiles(); window.addEventListener('profiles-updated', fetchProfiles); return () => window.removeEventListener('profiles-updated', fetchProfiles); }, [user]); const toggleBot = async (profile: any) => { try { await setTradeProfileActive(profile.id, !profile.is_active); fetchProfiles(); } catch { // existing UI remains silent on toggle failure } }; const deleteBot = async (id: string) => { if (!confirm('Are you sure you want to delete this strategy?')) return; try { await deleteTradeProfile(id); fetchProfiles(); } catch { // existing UI remains silent on delete failure } }; if (showWizard) { return (
{ setShowWizard(false); setEditingProfile(null); fetchProfiles(); }} />
); } return (
Strategy operations

My strategies

Monitor active profiles, review recent signals, and create new automated trading workflows.

{botState?.connected ? 'Systems online' : 'Systems disconnected'}
{/* Contextual Intelligence Row: Recent Activity + Symbol Volatility */} {(() => { const activeSymbols = [...new Set(profiles.flatMap(p => p.symbols?.split(',').map((s: string) => s.trim()) || []))]; const recentAlerts = [...alerts].reverse().slice(0, 5); const symbolVolatility = activeSymbols .filter(s => botState?.symbols?.[s]) .map(s => ({ symbol: s, change: botState.symbols[s].change24h || 0 })) .sort((a, b) => Math.abs(b.change) - Math.abs(a.change)); return (
{/* Recent Activity */}
Recent Activity
{recentAlerts.map((alert, i) => { const mins = Math.floor((Date.now() - alert.timestamp) / 60000); const timeAgo = mins < 1 ? 'just now' : mins < 60 ? `${mins}m ago` : `${Math.floor(mins / 60)}h ago`; return (
{alert.symbol} {alert.message} {timeAgo}
); })} {recentAlerts.length === 0 &&
No activity yet...
}
{/* Symbol-Specific Volatility */}
Your Markets (24h)
{symbolVolatility.map(({ symbol, change }) => (
{symbol}
= 0 ? 'var(--bl-success)' : 'var(--bl-danger)', borderRadius: '99px' }} />
= 0 ? 'var(--bl-success)' : 'var(--bl-danger)', minWidth: '55px', textAlign: 'right' }}> {change >= 0 ? '+' : ''}{change.toFixed(2)}%
))} {symbolVolatility.length === 0 &&
Deploy a strategy to see its market data
}
); })()}
{!backtestGateLoading && backtestEnabled && backtestProfile && (
s.trim()).filter(Boolean)} initialCapitalUsd={Number(backtestProfile.allocated_capital || 1000)} title={`Backtest: ${backtestProfile.name}`} onClose={() => setBacktestProfile(null)} />
)} {profiles.map(profile => ( { setEditingProfile(p); setShowWizard(true); }} onBacktest={!backtestGateLoading && backtestEnabled ? ((p) => setBacktestProfile(p)) : undefined} onDelete={deleteBot} isExpanded={!!expandedExplanations[profile.id]} onToggleExpand={(id) => setExpandedExplanations(prev => ({ ...prev, [id]: !prev[id] }))} /> ))} {profiles.length === 0 && !isLoading && (

No strategies yet

Create your first strategy to start monitoring markets and testing automated execution.

)}
); };