feat: implement authentic 7-page storybook matching real-world QuantIQ features and architecture
Browse files- frontend/src/pages/LandingPage.tsx +141 -47
frontend/src/pages/LandingPage.tsx
CHANGED
|
@@ -100,7 +100,7 @@ export default function LandingPage({ onGoogleLogin, googleClientId, onAuthSucce
|
|
| 100 |
|
| 101 |
const handleNextPage = () => {
|
| 102 |
playPageTurnSound();
|
| 103 |
-
setBookPage(prev => Math.min(prev + 1,
|
| 104 |
};
|
| 105 |
|
| 106 |
const handlePrevPage = () => {
|
|
@@ -1380,38 +1380,48 @@ export default function LandingPage({ onGoogleLogin, googleClientId, onAuthSucce
|
|
| 1380 |
<div className="flex flex-col h-full justify-between">
|
| 1381 |
<div>
|
| 1382 |
<h3 className="ink-heading text-center mb-1">Index</h3>
|
| 1383 |
-
<div className="w-16 h-0.5 bg-[#8c2020]/20 mx-auto mb-
|
| 1384 |
|
| 1385 |
-
<div className="flex flex-col gap-
|
| 1386 |
<div className="flex justify-between items-baseline">
|
| 1387 |
<span className="font-semibold">Prologue: Genesis</span>
|
| 1388 |
<span className="flex-grow border-b border-dotted border-[#8c2020]/30 mx-2"></span>
|
| 1389 |
<span>Page I</span>
|
| 1390 |
</div>
|
| 1391 |
<div className="flex justify-between items-baseline">
|
| 1392 |
-
<span className="font-semibold">
|
| 1393 |
<span className="flex-grow border-b border-dotted border-[#8c2020]/30 mx-2"></span>
|
| 1394 |
<span>Page II</span>
|
| 1395 |
</div>
|
| 1396 |
<div className="flex justify-between items-baseline">
|
| 1397 |
-
<span className="font-semibold">
|
| 1398 |
<span className="flex-grow border-b border-dotted border-[#8c2020]/30 mx-2"></span>
|
| 1399 |
<span>Page III</span>
|
| 1400 |
</div>
|
| 1401 |
<div className="flex justify-between items-baseline">
|
| 1402 |
-
<span className="font-semibold">
|
| 1403 |
<span className="flex-grow border-b border-dotted border-[#8c2020]/30 mx-2"></span>
|
| 1404 |
<span>Page IV</span>
|
| 1405 |
</div>
|
| 1406 |
<div className="flex justify-between items-baseline">
|
| 1407 |
-
<span className="font-semibold">
|
| 1408 |
<span className="flex-grow border-b border-dotted border-[#8c2020]/30 mx-2"></span>
|
| 1409 |
<span>Page V</span>
|
| 1410 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1411 |
</div>
|
| 1412 |
</div>
|
| 1413 |
|
| 1414 |
-
<div className="text-center italic text-[#8c2020]/75 text-[11px] pb-
|
| 1415 |
"Every great strategy begins with a single line in the registry."
|
| 1416 |
</div>
|
| 1417 |
</div>
|
|
@@ -1420,15 +1430,15 @@ export default function LandingPage({ onGoogleLogin, googleClientId, onAuthSucce
|
|
| 1420 |
{/* PAGE 2: CHAPTER I */}
|
| 1421 |
{bookPage === 2 && (
|
| 1422 |
<>
|
| 1423 |
-
<h3 className="ink-heading">Chapter I: The
|
| 1424 |
<p className="ink-paragraph">
|
| 1425 |
-
In quantitative
|
| 1426 |
</p>
|
| 1427 |
<p className="ink-paragraph">
|
| 1428 |
-
|
| 1429 |
</p>
|
| 1430 |
-
<p className="ink-paragraph
|
| 1431 |
-
|
| 1432 |
</p>
|
| 1433 |
</>
|
| 1434 |
)}
|
|
@@ -1436,12 +1446,15 @@ export default function LandingPage({ onGoogleLogin, googleClientId, onAuthSucce
|
|
| 1436 |
{/* PAGE 3: CHAPTER II */}
|
| 1437 |
{bookPage === 3 && (
|
| 1438 |
<>
|
| 1439 |
-
<h3 className="ink-heading">Chapter II:
|
| 1440 |
<p className="ink-paragraph">
|
| 1441 |
-
|
| 1442 |
</p>
|
| 1443 |
<p className="ink-paragraph">
|
| 1444 |
-
|
|
|
|
|
|
|
|
|
|
| 1445 |
</p>
|
| 1446 |
</>
|
| 1447 |
)}
|
|
@@ -1449,15 +1462,15 @@ export default function LandingPage({ onGoogleLogin, googleClientId, onAuthSucce
|
|
| 1449 |
{/* PAGE 4: CHAPTER III */}
|
| 1450 |
{bookPage === 4 && (
|
| 1451 |
<>
|
| 1452 |
-
<h3 className="ink-heading">Chapter III:
|
| 1453 |
<p className="ink-paragraph">
|
| 1454 |
-
|
| 1455 |
</p>
|
| 1456 |
<p className="ink-paragraph">
|
| 1457 |
-
|
| 1458 |
</p>
|
| 1459 |
-
<p className="ink-paragraph
|
| 1460 |
-
|
| 1461 |
</p>
|
| 1462 |
</>
|
| 1463 |
)}
|
|
@@ -1465,15 +1478,47 @@ export default function LandingPage({ onGoogleLogin, googleClientId, onAuthSucce
|
|
| 1465 |
{/* PAGE 5: CHAPTER IV */}
|
| 1466 |
{bookPage === 5 && (
|
| 1467 |
<>
|
| 1468 |
-
<h3 className="ink-heading">Chapter IV:
|
| 1469 |
<p className="ink-paragraph">
|
| 1470 |
-
|
| 1471 |
</p>
|
| 1472 |
<p className="ink-paragraph">
|
| 1473 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1474 |
</p>
|
| 1475 |
<p className="ink-paragraph">
|
| 1476 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1477 |
</p>
|
| 1478 |
</>
|
| 1479 |
)}
|
|
@@ -1486,66 +1531,115 @@ export default function LandingPage({ onGoogleLogin, googleClientId, onAuthSucce
|
|
| 1486 |
<>
|
| 1487 |
<h4 className="ink-subheading">Prologue: Genesis</h4>
|
| 1488 |
<p className="ink-paragraph">
|
| 1489 |
-
|
|
|
|
|
|
|
|
|
|
| 1490 |
</p>
|
| 1491 |
<p className="ink-paragraph">
|
| 1492 |
-
|
| 1493 |
</p>
|
| 1494 |
</>
|
| 1495 |
)}
|
| 1496 |
|
| 1497 |
-
{/* PAGE 2: ACHIEVEMENTS */}
|
| 1498 |
{bookPage === 2 && (
|
| 1499 |
<>
|
| 1500 |
<h4 className="ink-subheading">Completed Achievements</h4>
|
| 1501 |
<div className="ink-bullet-list">
|
| 1502 |
<div className="ink-bullet-item">
|
| 1503 |
<span className="ink-bullet-bullet">β¦</span>
|
| 1504 |
-
<span><strong>
|
| 1505 |
</div>
|
| 1506 |
<div className="ink-bullet-item">
|
| 1507 |
<span className="ink-bullet-bullet">β¦</span>
|
| 1508 |
-
<span><strong>
|
| 1509 |
</div>
|
| 1510 |
<div className="ink-bullet-item">
|
| 1511 |
<span className="ink-bullet-bullet">β¦</span>
|
| 1512 |
-
<span><strong>
|
| 1513 |
</div>
|
| 1514 |
<div className="ink-bullet-item">
|
| 1515 |
<span className="ink-bullet-bullet">β¦</span>
|
| 1516 |
-
<span><strong>
|
| 1517 |
</div>
|
| 1518 |
</div>
|
| 1519 |
</>
|
| 1520 |
)}
|
| 1521 |
|
| 1522 |
-
{/* PAGE 3:
|
| 1523 |
{bookPage === 3 && (
|
| 1524 |
<>
|
| 1525 |
-
<h4 className="ink-subheading">
|
| 1526 |
<div className="ink-bullet-list">
|
| 1527 |
<div className="ink-bullet-item">
|
| 1528 |
-
<span className="ink-bullet-bullet">
|
| 1529 |
-
<span><strong>
|
| 1530 |
</div>
|
| 1531 |
<div className="ink-bullet-item">
|
| 1532 |
-
<span className="ink-bullet-bullet">
|
| 1533 |
-
<span><strong>
|
| 1534 |
</div>
|
| 1535 |
<div className="ink-bullet-item">
|
| 1536 |
-
<span className="ink-bullet-bullet">
|
| 1537 |
-
<span><strong>
|
| 1538 |
</div>
|
| 1539 |
<div className="ink-bullet-item">
|
| 1540 |
-
<span className="ink-bullet-bullet">
|
| 1541 |
-
<span><strong>
|
| 1542 |
</div>
|
| 1543 |
</div>
|
| 1544 |
</>
|
| 1545 |
)}
|
| 1546 |
|
| 1547 |
-
{/* PAGE 4:
|
| 1548 |
{bookPage === 4 && (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1549 |
<div className="blueprint-container">
|
| 1550 |
<div className="blueprint-grid-nodes">
|
| 1551 |
{/* Row 1: Frontend */}
|
|
@@ -1653,8 +1747,8 @@ export default function LandingPage({ onGoogleLogin, googleClientId, onAuthSucce
|
|
| 1653 |
</div>
|
| 1654 |
)}
|
| 1655 |
|
| 1656 |
-
{/* PAGE
|
| 1657 |
-
{bookPage ===
|
| 1658 |
<div className="flex flex-col h-full justify-between">
|
| 1659 |
<form onSubmit={handleBookContactSubmit} className="ink-form">
|
| 1660 |
{bookFormError && (
|
|
@@ -1742,9 +1836,9 @@ export default function LandingPage({ onGoogleLogin, googleClientId, onAuthSucce
|
|
| 1742 |
)}
|
| 1743 |
{/* Page indicator */}
|
| 1744 |
<span className="book-page-indicator">
|
| 1745 |
-
{['β I β', 'β II β', 'β III β', 'β IV β', 'β V β'][bookPage - 1]}
|
| 1746 |
</span>
|
| 1747 |
-
{bookPage <
|
| 1748 |
<button className="book-page-turn-btn next-btn" onClick={handleNextPage}>
|
| 1749 |
Next Chapter <ArrowRight size={16} />
|
| 1750 |
</button>
|
|
|
|
| 100 |
|
| 101 |
const handleNextPage = () => {
|
| 102 |
playPageTurnSound();
|
| 103 |
+
setBookPage(prev => Math.min(prev + 1, 7));
|
| 104 |
};
|
| 105 |
|
| 106 |
const handlePrevPage = () => {
|
|
|
|
| 1380 |
<div className="flex flex-col h-full justify-between">
|
| 1381 |
<div>
|
| 1382 |
<h3 className="ink-heading text-center mb-1">Index</h3>
|
| 1383 |
+
<div className="w-16 h-0.5 bg-[#8c2020]/20 mx-auto mb-5"></div>
|
| 1384 |
|
| 1385 |
+
<div className="flex flex-col gap-2.5 font-serif text-[12px] text-[#2c1d11] px-2">
|
| 1386 |
<div className="flex justify-between items-baseline">
|
| 1387 |
<span className="font-semibold">Prologue: Genesis</span>
|
| 1388 |
<span className="flex-grow border-b border-dotted border-[#8c2020]/30 mx-2"></span>
|
| 1389 |
<span>Page I</span>
|
| 1390 |
</div>
|
| 1391 |
<div className="flex justify-between items-baseline">
|
| 1392 |
+
<span className="font-semibold">Ch. I: The Redpanda Pipeline</span>
|
| 1393 |
<span className="flex-grow border-b border-dotted border-[#8c2020]/30 mx-2"></span>
|
| 1394 |
<span>Page II</span>
|
| 1395 |
</div>
|
| 1396 |
<div className="flex justify-between items-baseline">
|
| 1397 |
+
<span className="font-semibold">Ch. II: On-Device ONNX ML</span>
|
| 1398 |
<span className="flex-grow border-b border-dotted border-[#8c2020]/30 mx-2"></span>
|
| 1399 |
<span>Page III</span>
|
| 1400 |
</div>
|
| 1401 |
<div className="flex justify-between items-baseline">
|
| 1402 |
+
<span className="font-semibold">Ch. III: ReAct AI Analyst</span>
|
| 1403 |
<span className="flex-grow border-b border-dotted border-[#8c2020]/30 mx-2"></span>
|
| 1404 |
<span>Page IV</span>
|
| 1405 |
</div>
|
| 1406 |
<div className="flex justify-between items-baseline">
|
| 1407 |
+
<span className="font-semibold">Ch. IV: Context-Aware Chat</span>
|
| 1408 |
<span className="flex-grow border-b border-dotted border-[#8c2020]/30 mx-2"></span>
|
| 1409 |
<span>Page V</span>
|
| 1410 |
</div>
|
| 1411 |
+
<div className="flex justify-between items-baseline">
|
| 1412 |
+
<span className="font-semibold">Ch. V: MLOps Loop & Scale</span>
|
| 1413 |
+
<span className="flex-grow border-b border-dotted border-[#8c2020]/30 mx-2"></span>
|
| 1414 |
+
<span>Page VI</span>
|
| 1415 |
+
</div>
|
| 1416 |
+
<div className="flex justify-between items-baseline">
|
| 1417 |
+
<span className="font-semibold">Epilogue: Developer's Ledger</span>
|
| 1418 |
+
<span className="flex-grow border-b border-dotted border-[#8c2020]/30 mx-2"></span>
|
| 1419 |
+
<span>Page VII</span>
|
| 1420 |
+
</div>
|
| 1421 |
</div>
|
| 1422 |
</div>
|
| 1423 |
|
| 1424 |
+
<div className="text-center italic text-[#8c2020]/75 text-[11px] pb-4" style={{ fontFamily: "'EB Garamond', serif" }}>
|
| 1425 |
"Every great strategy begins with a single line in the registry."
|
| 1426 |
</div>
|
| 1427 |
</div>
|
|
|
|
| 1430 |
{/* PAGE 2: CHAPTER I */}
|
| 1431 |
{bookPage === 2 && (
|
| 1432 |
<>
|
| 1433 |
+
<h3 className="ink-heading">Chapter I: The Redpanda Pipeline</h3>
|
| 1434 |
<p className="ink-paragraph">
|
| 1435 |
+
In quantitative trading, latency is measured in losses. Our pipeline ingests real-time stock price ticks from Yahoo Finance every 5 seconds.
|
| 1436 |
</p>
|
| 1437 |
<p className="ink-paragraph">
|
| 1438 |
+
These ticks are published as JSON messages via an asynchronous Kafka-compatible Redpanda broker (`stock-ticks` topic). The backend consumer pulls the feed, and connected client browsers receive live tick updates instantly over WebSockets.
|
| 1439 |
</p>
|
| 1440 |
+
<p className="ink-paragraph">
|
| 1441 |
+
To keep storage fees low and optimize queries, an ingestion worker aggregates ticks in-memory and flushes 1-minute OHLCV candles to our NeonDB.
|
| 1442 |
</p>
|
| 1443 |
</>
|
| 1444 |
)}
|
|
|
|
| 1446 |
{/* PAGE 3: CHAPTER II */}
|
| 1447 |
{bookPage === 3 && (
|
| 1448 |
<>
|
| 1449 |
+
<h3 className="ink-heading">Chapter II: On-Device ONNX ML</h3>
|
| 1450 |
<p className="ink-paragraph">
|
| 1451 |
+
Rather than paying for expensive cloud GPUs or calling latency-prone prediction APIs, we built a local inference engine.
|
| 1452 |
</p>
|
| 1453 |
<p className="ink-paragraph">
|
| 1454 |
+
Using a RandomForestClassifier trained offline on two years of daily OHLCV data (utilizing technical indicator features like RSI-14, MACD, and EMA-20 ratios), we export the model to ONNX.
|
| 1455 |
+
</p>
|
| 1456 |
+
<p className="ink-paragraph font-semibold text-[#8c2020]">
|
| 1457 |
+
The model loads directly on FastAPI startup. Local CPU inference takes under 5ms, maintaining zero per-request cloud cost.
|
| 1458 |
</p>
|
| 1459 |
</>
|
| 1460 |
)}
|
|
|
|
| 1462 |
{/* PAGE 4: CHAPTER III */}
|
| 1463 |
{bookPage === 4 && (
|
| 1464 |
<>
|
| 1465 |
+
<h3 className="ink-heading">Chapter III: ReAct AI Analyst</h3>
|
| 1466 |
<p className="ink-paragraph">
|
| 1467 |
+
A standalone indicator only shows the past. To construct context-rich reports, we built a multi-step reasoning agent powered by Google Gemini 2.5 Flash.
|
| 1468 |
</p>
|
| 1469 |
<p className="ink-paragraph">
|
| 1470 |
+
The agent runs in a ReAct loop. It calls Python tools to fetch NeonDB watchlists, query indicators computed via pandas-ta, execute ONNX model predictions, and evaluate active price thresholds.
|
| 1471 |
</p>
|
| 1472 |
+
<p className="ink-paragraph">
|
| 1473 |
+
It synthesizes these elements into a structured JSON analysis report detailing entry and exit suggestions.
|
| 1474 |
</p>
|
| 1475 |
</>
|
| 1476 |
)}
|
|
|
|
| 1478 |
{/* PAGE 5: CHAPTER IV */}
|
| 1479 |
{bookPage === 5 && (
|
| 1480 |
<>
|
| 1481 |
+
<h3 className="ink-heading">Chapter IV: Context-Aware Chat</h3>
|
| 1482 |
<p className="ink-paragraph">
|
| 1483 |
+
Our co-pilot interface, the AI Advisor, uses an interactive chat component anchored to the chart.
|
| 1484 |
</p>
|
| 1485 |
<p className="ink-paragraph">
|
| 1486 |
+
On every chat turn, the system prompt is rebuilt dynamically. It takes the active stock price, user-drawn chart markers, indicators, and the ONNX score, passing them alongside the last 30 turns of conversation history.
|
| 1487 |
+
</p>
|
| 1488 |
+
<p className="ink-paragraph font-medium text-[#8c2020]">
|
| 1489 |
+
This lets the copilot verify its prior advice, preventing contradictory recommendations as you adjust entry points.
|
| 1490 |
+
</p>
|
| 1491 |
+
</>
|
| 1492 |
+
)}
|
| 1493 |
+
|
| 1494 |
+
{/* PAGE 6: CHAPTER V */}
|
| 1495 |
+
{bookPage === 6 && (
|
| 1496 |
+
<>
|
| 1497 |
+
<h3 className="ink-heading">Chapter V: MLOps Loop & Scale</h3>
|
| 1498 |
+
<p className="ink-paragraph">
|
| 1499 |
+
To ensure prediction quality over time, every generated Analyst report is logged to NeonDB.
|
| 1500 |
</p>
|
| 1501 |
<p className="ink-paragraph">
|
| 1502 |
+
A Celery beat worker fires every two minutes, queries the latest asset prices, and automatically labels predictions with actual profit and loss percentages.
|
| 1503 |
+
</p>
|
| 1504 |
+
<p className="ink-paragraph">
|
| 1505 |
+
Similarly, when a user locks in custom targets, both the User and AI configurations are tracked in `strategy_logs` for performance comparison.
|
| 1506 |
+
</p>
|
| 1507 |
+
</>
|
| 1508 |
+
)}
|
| 1509 |
+
|
| 1510 |
+
{/* PAGE 7: EPILOGUE */}
|
| 1511 |
+
{bookPage === 7 && (
|
| 1512 |
+
<>
|
| 1513 |
+
<h3 className="ink-heading">Epilogue: Developer's Ledger</h3>
|
| 1514 |
+
<p className="ink-paragraph">
|
| 1515 |
+
Thank you for studying the story of QuantIQ. This platform is actively designed and maintained by Karan Shelar.
|
| 1516 |
+
</p>
|
| 1517 |
+
<p className="ink-paragraph">
|
| 1518 |
+
If you have questions about our pipeline, want to collaborate on quantitative models, or have design inquiries, drop a message in the ledger.
|
| 1519 |
+
</p>
|
| 1520 |
+
<p className="ink-paragraph font-serif italic text-sm mt-4 text-[#8c2020]">
|
| 1521 |
+
"Every tick is a story, and every strategy a chapter in code."
|
| 1522 |
</p>
|
| 1523 |
</>
|
| 1524 |
)}
|
|
|
|
| 1531 |
<>
|
| 1532 |
<h4 className="ink-subheading">Prologue: Genesis</h4>
|
| 1533 |
<p className="ink-paragraph">
|
| 1534 |
+
QuantIQ is an AI-powered decision intelligence platform for retail investors.
|
| 1535 |
+
</p>
|
| 1536 |
+
<p className="ink-paragraph">
|
| 1537 |
+
Instead of forcing users to switch between charts, news portals, screeners, and general-purpose chatbots, QuantIQ unifies live market feeds, historical technical indicators, local machine learning models, and AI reasoning.
|
| 1538 |
</p>
|
| 1539 |
<p className="ink-paragraph">
|
| 1540 |
+
The goal is to reduce research time and provide transparent, data-backed insights to help users make more informed trading decisions.
|
| 1541 |
</p>
|
| 1542 |
</>
|
| 1543 |
)}
|
| 1544 |
|
| 1545 |
+
{/* PAGE 2: PIPELINE ACHIEVEMENTS */}
|
| 1546 |
{bookPage === 2 && (
|
| 1547 |
<>
|
| 1548 |
<h4 className="ink-subheading">Completed Achievements</h4>
|
| 1549 |
<div className="ink-bullet-list">
|
| 1550 |
<div className="ink-bullet-item">
|
| 1551 |
<span className="ink-bullet-bullet">β¦</span>
|
| 1552 |
+
<span><strong>yfinance Tick Ingestion</strong>: Asynchronous polling worker consuming tickers every 5 seconds.</span>
|
| 1553 |
</div>
|
| 1554 |
<div className="ink-bullet-item">
|
| 1555 |
<span className="ink-bullet-bullet">β¦</span>
|
| 1556 |
+
<span><strong>Redpanda Cloud Pub/Sub</strong>: Kafka-compatible partition brokers serving message retention on disk.</span>
|
| 1557 |
</div>
|
| 1558 |
<div className="ink-bullet-item">
|
| 1559 |
<span className="ink-bullet-bullet">β¦</span>
|
| 1560 |
+
<span><strong>NeonDB Serverless DB</strong>: Cloud Postgres managing user session credentials, watches, and strategy logs.</span>
|
| 1561 |
</div>
|
| 1562 |
<div className="ink-bullet-item">
|
| 1563 |
<span className="ink-bullet-bullet">β¦</span>
|
| 1564 |
+
<span><strong>Gmail Transactional SMTP</strong>: Price alert threshold dispatches mailed straight to inboxes.</span>
|
| 1565 |
</div>
|
| 1566 |
</div>
|
| 1567 |
</>
|
| 1568 |
)}
|
| 1569 |
|
| 1570 |
+
{/* PAGE 3: ONNX & REACT TOOLS */}
|
| 1571 |
{bookPage === 3 && (
|
| 1572 |
<>
|
| 1573 |
+
<h4 className="ink-subheading">ML & ReAct Agent Setup</h4>
|
| 1574 |
<div className="ink-bullet-list">
|
| 1575 |
<div className="ink-bullet-item">
|
| 1576 |
+
<span className="ink-bullet-bullet">β¦</span>
|
| 1577 |
+
<span><strong>Random Forest model</strong>: Trained on historical Open/High/Low/Close/Volume vectors.</span>
|
| 1578 |
</div>
|
| 1579 |
<div className="ink-bullet-item">
|
| 1580 |
+
<span className="ink-bullet-bullet">β¦</span>
|
| 1581 |
+
<span><strong>ONNX Runtime execution</strong>: In-process local inference running under 5 milliseconds.</span>
|
| 1582 |
</div>
|
| 1583 |
<div className="ink-bullet-item">
|
| 1584 |
+
<span className="ink-bullet-bullet">β¦</span>
|
| 1585 |
+
<span><strong>ReAct reasoning loops</strong>: Google Gemini 2.5 Flash executing typed tools.</span>
|
| 1586 |
</div>
|
| 1587 |
<div className="ink-bullet-item">
|
| 1588 |
+
<span className="ink-bullet-bullet">β¦</span>
|
| 1589 |
+
<span><strong>Structured JSON schema</strong>: Clean validations via Pydantic model response constraints.</span>
|
| 1590 |
</div>
|
| 1591 |
</div>
|
| 1592 |
</>
|
| 1593 |
)}
|
| 1594 |
|
| 1595 |
+
{/* PAGE 4: ADVISOR FEATURES */}
|
| 1596 |
{bookPage === 4 && (
|
| 1597 |
+
<>
|
| 1598 |
+
<h4 className="ink-subheading">Advisor Capabilities</h4>
|
| 1599 |
+
<div className="ink-bullet-list">
|
| 1600 |
+
<div className="ink-bullet-item">
|
| 1601 |
+
<span className="ink-bullet-bullet">β¦</span>
|
| 1602 |
+
<span><strong>TradingView Lightweight Charts</strong>: Candle charting with GPU-accelerated canvas.</span>
|
| 1603 |
+
</div>
|
| 1604 |
+
<div className="ink-bullet-item">
|
| 1605 |
+
<span className="ink-bullet-bullet">β¦</span>
|
| 1606 |
+
<span><strong>Custom marker synchronization</strong>: Chart markers passed into AI chat prompt contexts.</span>
|
| 1607 |
+
</div>
|
| 1608 |
+
<div className="ink-bullet-item">
|
| 1609 |
+
<span className="ink-bullet-bullet">β¦</span>
|
| 1610 |
+
<span><strong>Historical Memory tracking</strong>: Chat history context of 30 turns saved to prevent contradictions.</span>
|
| 1611 |
+
</div>
|
| 1612 |
+
<div className="ink-bullet-item">
|
| 1613 |
+
<span className="ink-bullet-bullet">β¦</span>
|
| 1614 |
+
<span><strong>Watchlist tape metrics</strong>: Real-time ticker tapes showing active predictions.</span>
|
| 1615 |
+
</div>
|
| 1616 |
+
</div>
|
| 1617 |
+
</>
|
| 1618 |
+
)}
|
| 1619 |
+
|
| 1620 |
+
{/* PAGE 5: MLOPS AND SCALING */}
|
| 1621 |
+
{bookPage === 5 && (
|
| 1622 |
+
<>
|
| 1623 |
+
<h4 className="ink-subheading">MLOps, Observability & Pricing</h4>
|
| 1624 |
+
<div className="ink-bullet-list">
|
| 1625 |
+
<div className="ink-bullet-item">
|
| 1626 |
+
<span className="ink-bullet-bullet">β¦</span>
|
| 1627 |
+
<span><strong>Celery periodic beat</strong>: Automated backfill outcomes running every two minutes.</span>
|
| 1628 |
+
</div>
|
| 1629 |
+
<div className="ink-bullet-item">
|
| 1630 |
+
<span className="ink-bullet-bullet">β¦</span>
|
| 1631 |
+
<span><strong>Prometheus auto-instrumentation</strong>: Endpoints scraped directly by Grafana Cloud.</span>
|
| 1632 |
+
</div>
|
| 1633 |
+
<div className="ink-bullet-item">
|
| 1634 |
+
<span className="ink-bullet-bullet">β¦</span>
|
| 1635 |
+
<span><strong>Razorpay credit tiers</strong>: Webhook payments with secure HMAC server checks.</span>
|
| 1636 |
+
</div>
|
| 1637 |
+
</div>
|
| 1638 |
+
</>
|
| 1639 |
+
)}
|
| 1640 |
+
|
| 1641 |
+
{/* PAGE 6: INTERACTIVE BLUEPRINT */}
|
| 1642 |
+
{bookPage === 6 && (
|
| 1643 |
<div className="blueprint-container">
|
| 1644 |
<div className="blueprint-grid-nodes">
|
| 1645 |
{/* Row 1: Frontend */}
|
|
|
|
| 1747 |
</div>
|
| 1748 |
)}
|
| 1749 |
|
| 1750 |
+
{/* PAGE 7: LEDGER CONTACT FORM */}
|
| 1751 |
+
{bookPage === 7 && (
|
| 1752 |
<div className="flex flex-col h-full justify-between">
|
| 1753 |
<form onSubmit={handleBookContactSubmit} className="ink-form">
|
| 1754 |
{bookFormError && (
|
|
|
|
| 1836 |
)}
|
| 1837 |
{/* Page indicator */}
|
| 1838 |
<span className="book-page-indicator">
|
| 1839 |
+
{['β I β', 'β II β', 'β III β', 'β IV β', 'β V β', 'β VI β', 'β VII β'][bookPage - 1]}
|
| 1840 |
</span>
|
| 1841 |
+
{bookPage < 7 && (
|
| 1842 |
<button className="book-page-turn-btn next-btn" onClick={handleNextPage}>
|
| 1843 |
Next Chapter <ArrowRight size={16} />
|
| 1844 |
</button>
|