diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 1cc0864..435c20e 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -3,7 +3,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import OptionsFlowPanel from '@/components/dashboard/OptionsFlowPanel'; import ScannerPanel from '@/components/dashboard/ScannerPanel'; import BacktestPanel from '@/components/dashboard/BacktestPanel'; -import PerformanceTrackingPanel from '@/components/dashboard/PerformanceTrackingPanel'; +import MethodologyModal from '@/components/modals/MethodologyModal'; import ReversalAlerts from '@/components/alerts/ReversalAlerts'; import ConvergenceAlerts from '@/components/alerts/ConvergenceAlerts'; import MarketScreenerPanel from '@/components/dashboard/MarketScreenerPanel'; @@ -11,11 +11,13 @@ import StockDetailPanel from '@/components/dashboard/StockDetailPanel'; export default function App() { const [selectedSymbol, setSelectedSymbol] = useState(null); + const [isMethodologyOpen, setIsMethodologyOpen] = useState(false); return (
+ setIsMethodologyOpen(false)} /> {/* Header */}
@@ -23,14 +25,20 @@ export default function App() {

- ๐Ÿš€ Institutional Flow Platform + FactorLab: Transparent Market Research

- Real-time options flow ยท Tape analysis ยท Pro-grade signals + We show you the facts fast โ€” and we tell you what we've tested and what we haven't.

-
+ +
Market Status
RTH โ€ข LIVE
@@ -79,11 +87,6 @@ export default function App() { - - {/* Bottom: Performance Tracking */} -
- -
); diff --git a/frontend/src/components/dashboard/MarketScreenerPanel.jsx b/frontend/src/components/dashboard/MarketScreenerPanel.jsx index f61beda..89f9535 100644 --- a/frontend/src/components/dashboard/MarketScreenerPanel.jsx +++ b/frontend/src/components/dashboard/MarketScreenerPanel.jsx @@ -56,33 +56,47 @@ function ScoreRing({ score, color }) { // โ”€โ”€โ”€ Factor Profile Component โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ function pctBar(pct) { - if (pct == null) return No data; - const filled = Math.round(pct / 10); - const empty = 10 - filled; + if (pct == null) return Missing; + + let colorClass = 'bg-yellow-500'; // middle 50% + if (pct >= 75) colorClass = 'bg-emerald-500'; // top 25% + else if (pct < 25) colorClass = 'bg-red-500'; // bottom 25% + return ( - - {'โ–ˆ'.repeat(filled)} - {'โ–‘'.repeat(empty)} - +
+
+
); } function FactorProfileCard({ profile, onSelect }) { + // Check for incomplete data + const isIncomplete = profile.value == null || profile.quality == null || profile.lowVol == null || profile.momentum == null; + return (
onSelect?.(profile.ticker)} - className="group bg-slate-900 border border-slate-700/50 rounded-xl p-4 cursor-pointer - hover:bg-slate-800 hover:border-blue-500/50 transition-all duration-150 - hover:shadow-lg active:scale-[0.99] relative" - title={profile._disclaimer} + className={`group bg-slate-900 border rounded-xl p-4 cursor-pointer transition-all duration-150 relative ${ + isIncomplete ? 'border-orange-900/50 hover:border-orange-500/50' : 'border-slate-700/50 hover:border-blue-500/50 hover:shadow-lg' + }`} >
{profile.ticker} - - Factor Profile (vs. Universe) - + + {isIncomplete ? ( + + โš ๏ธ INCOMPLETE DATA + + ) : ( + + Factor Profile + + )}
@@ -193,6 +207,7 @@ export default function MarketScreenerPanel({ onSelectSymbol }) { const [leaderboard, setLeaderboard] = useState(null); const [loading, setLoading] = useState(true); const [lastUpdated, setLastUpdated] = useState(null); + const [sortConfig, setSortConfig] = useState({ key: 'composite', direction: 'desc' }); const fetchData = useCallback(async () => { try { @@ -221,9 +236,13 @@ export default function MarketScreenerPanel({ onSelectSymbol }) { return () => clearInterval(interval); }, [fetchData]); - // Sort profiles by composite percentile desc + // Sort profiles based on config const profiles = screenerData?.profiles || []; - const sortedProfiles = [...profiles].sort((a, b) => (b.composite || 0) - (a.composite || 0)); + const sortedProfiles = [...profiles].sort((a, b) => { + const aVal = a[sortConfig.key] || 0; + const bVal = b[sortConfig.key] || 0; + return sortConfig.direction === 'desc' ? bVal - aVal : aVal - bVal; + }); return (
@@ -254,8 +273,23 @@ export default function MarketScreenerPanel({ onSelectSymbol }) {
- {/* Search */} -
+ {/* Search and Sort */} +
+ + onSelectSymbol?.(sym)} onClear={() => {}} @@ -272,8 +306,13 @@ export default function MarketScreenerPanel({ onSelectSymbol }) { {/* โ”€โ”€โ”€ Factor Grid โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */}
-
-

Descriptive only. Shows where each stock ranks against its peers across four foundational factors based on current data. We have not validated that these ranks predict forward returns. We will only upgrade these to "predictive" signals after they pass rigorous out-of-sample holdout validation.

+
+ ๐Ÿ’ก +

+ This is a research starting point, not a buy list. High rank = "worth a closer look," not "will go up." + Think Zillow for stocks: it shows you the facts fast โ€” you still do the homework and decide. + We will only upgrade these to "predictive" signals after they pass rigorous out-of-sample holdout validation. +

diff --git a/frontend/src/components/dashboard/OptionsFlowPanel.jsx b/frontend/src/components/dashboard/OptionsFlowPanel.jsx index e35283e..bb3a17f 100644 --- a/frontend/src/components/dashboard/OptionsFlowPanel.jsx +++ b/frontend/src/components/dashboard/OptionsFlowPanel.jsx @@ -1471,6 +1471,15 @@ export default function OptionsFlowPanel() { return (
+ {/* Descriptive Disclaimer */} +
+ โš ๏ธ +

+ Descriptive Only. Options flow imbalance is shown strictly for market context and sentiment analysis. + The "Smart Money" thesis has not been validated out-of-sample as a predictive signal by our engine. Do not treat flow as a buy/sell signal. +

+
+ {/* Header with Date and Quick Actions */}
diff --git a/frontend/src/components/modals/MethodologyModal.jsx b/frontend/src/components/modals/MethodologyModal.jsx new file mode 100644 index 0000000..97d31b0 --- /dev/null +++ b/frontend/src/components/modals/MethodologyModal.jsx @@ -0,0 +1,91 @@ +import { Info, X } from 'lucide-react'; +import { Button } from '@/components/ui/button'; + +export default function MethodologyModal({ isOpen, onClose }) { + if (!isOpen) return null; + + return ( +
+
e.stopPropagation()} + > +
+
+ +

+ Our Methodology: Why We Don't Sell Predictions +

+
+ +
+ +
+
+

The Out-of-Sample Reality

+

+ Most platforms show you backtests that work perfectly. We're showing you ours that didn't โ€” because that's how you know our descriptive tools are honest. +

+

+ We built a highly sophisticated predictive scoring engine based on technical indicators and options flow. We optimized it, tuned the hyperparameters, and achieved a 63% win rate in-sample. + Then, we tested it honestly. We ran a strict out-of-sample forward test on unseen data. +

+ +
+ + + + + + + + + + + + + + + + + + + + +
Test GroupExpectancy (R-Multiple)Hit Rate
Random Control (Coin Flip)+0.027R49.2%
Top-Graded "A" Signals+0.019R48.5%
+
+ +

+ The Result: The edge completely vanished. The highly-engineered signals failed to beat a random coin flip. So we stopped selling them. +

+
+ +
+

The FactorLab Approach

+

+ Instead of black-box predictions, we built the FactorLab. This is a purely descriptive lens. +

+

+ We take the Top 50 liquid stocks and ETFs, ingest their raw fundamentals and technicals, and mathematically rank them across four academic factors: + Value, + Quality, + Low-Volatility, and + Momentum. +

+

+ When you see a stock is in the 95th percentile for Quality, it is a mathematical fact about its balance sheet relative to its peers. It is not a buy recommendation. Think of this tool like Zillow for stocks: we show you the facts fast, but you still do the homework and make the decision. +

+
+
+ +
+ +
+
+
+ ); +}