Spaces:
Paused
Paused
File size: 32,301 Bytes
81d5a2e 981a2a2 81d5a2e 0006899 81d5a2e 981a2a2 0006899 981a2a2 81d5a2e 0006899 81d5a2e 981a2a2 0006899 81d5a2e 0006899 981a2a2 81d5a2e 0006899 81d5a2e 0006899 81d5a2e 0006899 81d5a2e 0006899 81d5a2e 981a2a2 81d5a2e 0006899 981a2a2 81d5a2e 0006899 981a2a2 81d5a2e 0006899 81d5a2e 981a2a2 0006899 981a2a2 81d5a2e 981a2a2 0006899 981a2a2 0006899 981a2a2 fbfdf21 981a2a2 0006899 981a2a2 0006899 981a2a2 0006899 981a2a2 0006899 81d5a2e 981a2a2 81d5a2e 0006899 81d5a2e 981a2a2 0006899 981a2a2 81d5a2e 0006899 981a2a2 0006899 981a2a2 81d5a2e 981a2a2 0006899 81d5a2e 981a2a2 0006899 81d5a2e 981a2a2 81d5a2e 981a2a2 81d5a2e 981a2a2 0006899 81d5a2e 981a2a2 81d5a2e 981a2a2 81d5a2e 981a2a2 81d5a2e 981a2a2 0006899 981a2a2 81d5a2e fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 0006899 981a2a2 0006899 981a2a2 0006899 981a2a2 81d5a2e 981a2a2 81d5a2e 0006899 981a2a2 0006899 981a2a2 0006899 981a2a2 81d5a2e 981a2a2 81d5a2e 0006899 981a2a2 0006899 981a2a2 0006899 981a2a2 81d5a2e 981a2a2 81d5a2e 0006899 981a2a2 81d5a2e 981a2a2 81d5a2e 981a2a2 81d5a2e 981a2a2 81d5a2e 981a2a2 81d5a2e 981a2a2 81d5a2e 0006899 81d5a2e 0006899 981a2a2 81d5a2e 0006899 981a2a2 81d5a2e 981a2a2 81d5a2e 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 fbfdf21 981a2a2 81d5a2e 981a2a2 0006899 81d5a2e 981a2a2 81d5a2e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 | <!DOCTYPE html>
<html lang="en" class="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SOLANA // QUANT • Autonomous Hedge Fund</title>
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
darkMode: 'class',
theme: {
extend: {
fontFamily: {
sans: ['Inter', 'system-ui', '-apple-system', 'sans-serif'],
mono: ['JetBrains Mono', 'ui-monospace', 'monospace']
},
colors: {
sol: {
purple: '#9945FF',
green: '#14F195',
},
zinc: {
850: '#1c1c22',
900: '#111115',
925: '#0c0c0f',
950: '#060608',
}
}
}
}
}
</script>
<!-- Google Fonts: Inter & JetBrains Mono -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
<!-- Lucide Icons -->
<script src="https://unpkg.com/lucide@latest"></script>
<style>
body {
background-color: #060608;
color: #fafafa;
font-feature-settings: "cv02", "cv03", "cv04", "cv11";
-webkit-font-smoothing: antialiased;
}
::selection {
background: #14F195;
color: #000000;
}
.custom-scroll::-webkit-scrollbar {
width: 5px;
height: 5px;
}
.custom-scroll::-webkit-scrollbar-track {
background: transparent;
}
.custom-scroll::-webkit-scrollbar-thumb {
background: #27272a;
border-radius: 9999px;
}
.custom-scroll::-webkit-scrollbar-thumb:hover {
background: #3f3f46;
}
</style>
</head>
<body class="min-h-screen flex flex-col font-sans selection:bg-sol-green selection:text-black">
<!-- Top Minimalist Bar -->
<header class="border-b border-zinc-800/80 bg-zinc-950/90 backdrop-blur-md sticky top-0 z-50">
<div class="max-w-7xl mx-auto px-4 sm:px-6 h-16 flex items-center justify-between">
<!-- Brand & Status -->
<div class="flex items-center space-x-4">
<a href="/" class="flex items-center space-x-2 group">
<div class="w-7 h-7 rounded-lg bg-gradient-to-tr from-sol-purple to-sol-green p-[1px] flex items-center justify-center shadow-lg shadow-sol-green/10">
<div class="w-full h-full bg-zinc-950 rounded-[7px] flex items-center justify-center font-mono font-black text-xs text-sol-green">
◎
</div>
</div>
<div>
<div class="font-extrabold text-sm sm:text-base tracking-tight uppercase text-white">
SOLANA <span class="text-zinc-500 font-normal">//</span> QUANT
</div>
<div class="text-[10px] font-mono text-zinc-500 -mt-0.5">Autonomous Hedge Fund</div>
</div>
</a>
<div class="hidden sm:flex items-center space-x-2 pl-3 border-l border-zinc-800 text-xs font-mono">
<span class="inline-flex items-center gap-1.5 px-2 py-0.5 rounded-full bg-sol-green/10 text-sol-green text-[11px] font-semibold">
<span class="w-1.5 h-1.5 rounded-full bg-sol-green animate-pulse"></span>
ACTIVE
</span>
<span class="text-zinc-500 text-[11px]">Qwen2.5-0.5B (Local CPU)</span>
</div>
</div>
<!-- Navigation Tabs (Segmented Control) -->
<nav class="flex items-center p-1 rounded-lg bg-zinc-900 border border-zinc-800 text-xs font-medium">
<button onclick="switchTab('overview')" id="btn-tab-overview" class="px-3 py-1.5 rounded-md bg-white text-zinc-950 font-bold transition">
Overview
</button>
<button onclick="switchTab('ai')" id="btn-tab-ai" class="px-3 py-1.5 rounded-md text-zinc-400 hover:text-white transition">
AI Copilot
</button>
<button onclick="switchTab('arbitrage')" id="btn-tab-arbitrage" class="px-3 py-1.5 rounded-md text-zinc-400 hover:text-white transition">
DEX Spreads
</button>
<button onclick="switchTab('blotter')" id="btn-tab-blotter" class="px-3 py-1.5 rounded-md text-zinc-400 hover:text-white transition">
Blotter
</button>
<button onclick="switchTab('storage')" id="btn-tab-storage" class="px-3 py-1.5 rounded-md text-zinc-400 hover:text-white transition">
Storage
</button>
</nav>
<!-- External Links -->
<div class="hidden md:flex items-center space-x-3 text-xs font-mono">
<a href="/docs" target="_blank" class="text-zinc-400 hover:text-white transition">
/docs
</a>
<a href="https://huggingface.co/spaces/arudradey/agent-loop" target="_blank" class="px-3 py-1.5 rounded-lg border border-zinc-700 bg-zinc-900 hover:bg-zinc-800 text-zinc-200 font-semibold transition flex items-center space-x-1">
<span>HF Space</span>
<i data-lucide="arrow-up-right" class="w-3.5 h-3.5"></i>
</a>
</div>
</div>
</header>
<!-- Live Ticker Strip -->
<div class="border-b border-zinc-800/60 bg-zinc-950/60 px-4 py-2 text-xs font-mono overflow-x-auto whitespace-nowrap custom-scroll">
<div class="max-w-7xl mx-auto flex items-center justify-between gap-6 text-[11px]">
<div class="flex items-center space-x-6">
<span class="flex items-center space-x-1.5">
<span class="text-zinc-500 font-semibold">SOL/USD:</span>
<span id="ticker-sol" class="text-white font-bold">$148.50</span>
<span class="text-sol-green font-semibold">+4.8%</span>
</span>
<span class="flex items-center space-x-1.5">
<span class="text-zinc-500 font-semibold">JUP/USD:</span>
<span id="ticker-jup" class="text-white font-bold">$0.985</span>
<span class="text-sol-green font-semibold">+2.1%</span>
</span>
<span class="flex items-center space-x-1.5">
<span class="text-zinc-500 font-semibold">RAY/USD:</span>
<span id="ticker-ray" class="text-white font-bold">$2.15</span>
<span class="text-sol-green font-semibold">+6.4%</span>
</span>
<span class="flex items-center space-x-1.5">
<span class="text-zinc-500 font-semibold">WIF/USD:</span>
<span id="ticker-wif" class="text-white font-bold">$1.84</span>
<span class="text-red-400 font-semibold">-1.2%</span>
</span>
</div>
<div class="text-zinc-500 hidden sm:block">
Jupiter Aggregator v6 • Raydium CPMM • Orca Whirlpools
</div>
</div>
</div>
<!-- Main Container -->
<main class="flex-1 max-w-7xl w-full mx-auto p-4 sm:p-6 lg:p-8">
<!-- ============================================================= -->
<!-- TAB 1: OVERVIEW & POSITIONS -->
<!-- ============================================================= -->
<div id="tab-overview" class="space-y-6">
<!-- Bold AUM & Performance Metrics -->
<div class="grid grid-cols-2 lg:grid-cols-4 gap-4">
<div class="p-5 rounded-2xl border border-zinc-800 bg-zinc-925/80">
<div class="text-[11px] font-mono uppercase tracking-wider text-zinc-500">Total Fund AUM</div>
<div id="stat-aum" class="text-2xl sm:text-3xl font-black font-mono tracking-tight text-white mt-1">$14,250,000</div>
<div class="text-xs font-mono text-sol-green mt-1">+$482,150 (+3.49% 24h)</div>
</div>
<div class="p-5 rounded-2xl border border-zinc-800 bg-zinc-925/80">
<div class="text-[11px] font-mono uppercase tracking-wider text-zinc-500">Solana Exposure</div>
<div id="stat-sol-exposure" class="text-2xl sm:text-3xl font-black font-mono tracking-tight text-white mt-1">56.5%</div>
<div class="text-xs font-mono text-zinc-400 mt-1">54,200 SOL ($8.04M)</div>
</div>
<div class="p-5 rounded-2xl border border-zinc-800 bg-zinc-925/80">
<div class="text-[11px] font-mono uppercase tracking-wider text-zinc-500">Sharpe Ratio</div>
<div class="text-2xl sm:text-3xl font-black font-mono tracking-tight text-white mt-1">3.42</div>
<div class="text-xs font-mono text-zinc-400 mt-1">Max Drawdown: 4.1%</div>
</div>
<div class="p-5 rounded-2xl border border-zinc-800 bg-zinc-925/80">
<div class="text-[11px] font-mono uppercase tracking-wider text-zinc-500">AI Quant Engine</div>
<div class="text-2xl sm:text-3xl font-black font-mono tracking-tight text-sol-green mt-1">0.5B CPU</div>
<div class="text-xs font-mono text-zinc-400 mt-1">Sub-second inference</div>
</div>
</div>
<!-- Two Column Layout: Positions & Quick Trade -->
<div class="grid grid-cols-1 lg:grid-cols-12 gap-6 items-start">
<!-- Left: Asset Allocation Table (8 Cols) -->
<div class="lg:col-span-8 rounded-2xl border border-zinc-800 bg-zinc-925/50 p-6 space-y-4 shadow-xl">
<div class="flex items-center justify-between border-b border-zinc-800 pb-3">
<h2 class="text-xs font-mono font-bold tracking-wider uppercase text-zinc-200 flex items-center space-x-2">
<i data-lucide="pie-chart" class="w-4 h-4 text-sol-purple"></i>
<span>Active Portfolio Positions</span>
</h2>
<span class="text-xs font-mono text-zinc-500">Auto-Rebalance: <strong class="text-sol-green">ON</strong></span>
</div>
<div class="rounded-xl border border-zinc-800/80 overflow-hidden font-mono text-xs">
<div class="grid grid-cols-12 bg-zinc-950 p-3 text-zinc-500 font-semibold border-b border-zinc-800">
<span class="col-span-4">ASSET</span>
<span class="col-span-3 text-right">HOLDINGS</span>
<span class="col-span-3 text-right">VALUE (USDC)</span>
<span class="col-span-2 text-right">WEIGHT</span>
</div>
<div id="positions-table" class="divide-y divide-zinc-900 bg-zinc-925/40">
<!-- Rendered via JS -->
</div>
</div>
</div>
<!-- Right: Instant Order Dispatch (4 Cols) -->
<div class="lg:col-span-4 rounded-2xl border border-zinc-800 bg-zinc-925/50 p-6 space-y-4 shadow-xl">
<div class="flex items-center justify-between border-b border-zinc-800 pb-3">
<h2 class="text-xs font-mono font-bold tracking-wider uppercase text-zinc-200 flex items-center space-x-2">
<i data-lucide="zap" class="w-4 h-4 text-sol-green"></i>
<span>Instant DEX Order</span>
</h2>
<span class="text-[10px] font-mono px-2 py-0.5 rounded bg-zinc-900 border border-zinc-800 text-zinc-400">JUPITER v6</span>
</div>
<div class="space-y-3 font-mono text-xs">
<div>
<label class="block text-zinc-500 mb-1">Asset</label>
<select id="trade-symbol" class="w-full bg-zinc-950 border border-zinc-800 rounded-lg p-2 text-white font-bold focus:outline-none">
<option value="SOL">SOL (Solana)</option>
<option value="JUP">JUP (Jupiter)</option>
<option value="RAY">RAY (Raydium)</option>
<option value="WIF">WIF (dogwifhat)</option>
</select>
</div>
<div>
<label class="block text-zinc-500 mb-1">Side</label>
<div class="grid grid-cols-2 gap-2">
<button onclick="setTradeSide('BUY')" id="btn-side-buy" class="py-1.5 rounded-lg border font-bold text-xs bg-sol-green/10 text-sol-green border-sol-green/30">BUY</button>
<button onclick="setTradeSide('SELL')" id="btn-side-sell" class="py-1.5 rounded-lg border border-zinc-800 bg-zinc-900 text-zinc-400 hover:text-white font-bold text-xs">SELL</button>
</div>
</div>
<div>
<label class="block text-zinc-500 mb-1">Notional Size (USDC)</label>
<input id="trade-amount" type="number" value="100000" class="w-full bg-zinc-950 border border-zinc-800 rounded-lg p-2 text-white font-bold focus:outline-none">
</div>
<div class="pt-2">
<button onclick="submitTradeOrder()" id="btn-submit-order" class="w-full py-2.5 rounded-lg bg-white hover:bg-zinc-200 text-black font-extrabold text-xs uppercase tracking-wider transition flex items-center justify-center space-x-2">
<span>Dispatch To Solana</span>
</button>
</div>
</div>
</div>
</div>
</div>
<!-- ============================================================= -->
<!-- TAB 2: LOCAL SMALL AI QUANT COPILOT -->
<!-- ============================================================= -->
<div id="tab-ai" class="space-y-6 hidden">
<div class="rounded-2xl border border-zinc-800 bg-zinc-925/80 p-6 sm:p-8 space-y-6 shadow-2xl">
<div class="flex flex-col sm:flex-row sm:items-center justify-between gap-3">
<div>
<div class="flex items-center space-x-2">
<span class="px-2 py-0.5 rounded text-[10px] font-mono font-bold bg-white text-black uppercase">Qwen2.5-0.5B-Instruct</span>
<span class="px-2 py-0.5 rounded text-[10px] font-mono font-bold bg-sol-green/10 text-sol-green border border-sol-green/20 uppercase">494M Params • Local CPU</span>
</div>
<h1 class="text-2xl sm:text-3xl font-black tracking-tight text-white uppercase mt-2">
SolQuant Autonomous Copilot
</h1>
<p class="text-xs sm:text-sm text-zinc-400 mt-1">
High-frequency on-chain trading signals, Raydium/Orca arbitrage analysis, and portfolio risk management generated directly on CPU in milliseconds.
</p>
</div>
<div class="text-right font-mono text-xs text-zinc-500">
<div>Engine: <span class="text-white font-bold">PyTorch SIMD</span></div>
<div>Latency: <span class="text-sol-green font-bold">< 15ms TTFT</span></div>
</div>
</div>
<!-- Presets -->
<div class="flex flex-wrap gap-2 text-xs font-mono">
<span class="text-zinc-500 self-center">Presets:</span>
<button onclick="setAiPrompt('sol_momentum')" class="px-2.5 py-1 rounded-md bg-zinc-900 hover:bg-zinc-800 border border-zinc-800 text-zinc-300 transition">
$SOL Momentum & Sizing
</button>
<button onclick="setAiPrompt('arb_scan')" class="px-2.5 py-1 rounded-md bg-zinc-900 hover:bg-zinc-800 border border-zinc-800 text-zinc-300 transition">
Raydium vs Orca Arbitrage
</button>
<button onclick="setAiPrompt('rebalance')" class="px-2.5 py-1 rounded-md bg-zinc-900 hover:bg-zinc-800 border border-zinc-800 text-zinc-300 transition">
Portfolio Rebalancing
</button>
</div>
<!-- Prompt Textarea -->
<div class="relative">
<textarea id="ai-prompt" rows="3" class="w-full rounded-xl bg-zinc-950 border border-zinc-800 focus:border-zinc-500 focus:ring-1 focus:ring-zinc-500 p-4 text-sm font-medium text-white placeholder-zinc-600 focus:outline-none transition resize-none custom-scroll leading-relaxed" placeholder="Ask SolQuant AI for portfolio signals, arbitrage strategies, or risk sizing...">Analyze current SOL/USDC momentum, calculate 24h risk-adjusted sizing, and recommend optimal slippage bounds for Raydium liquidity pools.</textarea>
</div>
<!-- Trigger Button -->
<div class="flex items-center justify-between pt-1 font-mono text-xs">
<span class="text-zinc-500">Zero external API dependencies • runs 100% locally</span>
<button onclick="queryQuantAi()" id="btn-run-ai" class="px-6 py-2.5 rounded-lg bg-white hover:bg-zinc-200 text-black font-extrabold text-xs uppercase tracking-wider transition flex items-center space-x-2 shadow-lg active:scale-95">
<i data-lucide="zap" class="w-4 h-4 fill-black"></i>
<span>Run Analysis</span>
</button>
</div>
</div>
<!-- Real-Time AI Stream Output -->
<div class="rounded-2xl border border-zinc-800 bg-zinc-925/50 p-6 space-y-4 shadow-xl">
<div class="flex items-center justify-between border-b border-zinc-800 pb-3">
<div class="flex items-center space-x-2 text-xs font-mono font-bold text-zinc-200 uppercase">
<i data-lucide="cpu" class="w-4 h-4 text-sol-green"></i>
<span>Live Quant Intelligence Output</span>
</div>
<button onclick="copyAiOutput()" id="btn-copy-ai" class="text-[11px] font-mono px-2 py-1 rounded bg-zinc-900 border border-zinc-800 text-zinc-400 hover:text-white transition">
COPY
</button>
</div>
<pre id="ai-output-box" class="p-4 rounded-xl bg-zinc-950 border border-zinc-900 text-zinc-200 font-mono text-xs whitespace-pre-wrap leading-relaxed min-h-[220px] max-h-[480px] overflow-y-auto custom-scroll">
Enter an objective above and click "Run Analysis" to receive real-time quant alpha.
</pre>
</div>
</div>
<!-- ============================================================= -->
<!-- TAB 3: DEX ARBITRAGE SPREADS -->
<!-- ============================================================= -->
<div id="tab-arbitrage" class="space-y-6 hidden">
<div class="rounded-2xl border border-zinc-800 bg-zinc-925/50 p-6 space-y-4 shadow-xl">
<div class="flex items-center justify-between border-b border-zinc-800 pb-3">
<h2 class="text-xs font-mono font-bold tracking-wider uppercase text-zinc-200 flex items-center space-x-2">
<i data-lucide="refresh-ccw" class="w-4 h-4 text-sol-green"></i>
<span>Cross-DEX Arbitrage Opportunities</span>
</h2>
<span class="text-xs font-mono text-zinc-500">Scan Interval: <strong class="text-white">100ms</strong></span>
</div>
<div id="arb-cards-container" class="grid grid-cols-1 md:grid-cols-3 gap-4">
<!-- Rendered via JS -->
</div>
</div>
</div>
<!-- ============================================================= -->
<!-- TAB 4: TRADE BLOTTER (Persistent Bucket Log) -->
<!-- ============================================================= -->
<div id="tab-blotter" class="space-y-6 hidden">
<div class="rounded-2xl border border-zinc-800 bg-zinc-925/50 p-6 space-y-4 shadow-xl">
<div class="flex items-center justify-between border-b border-zinc-800 pb-3">
<h2 class="text-xs font-mono font-bold tracking-wider uppercase text-zinc-200 flex items-center space-x-2">
<i data-lucide="list" class="w-4 h-4 text-sol-purple"></i>
<span>On-Chain Trade Execution Blotter</span>
</h2>
<span class="text-xs font-mono text-zinc-500">Saved to <strong class="text-zinc-300">/data/trades/trades.json</strong></span>
</div>
<div class="rounded-xl border border-zinc-800/80 overflow-hidden font-mono text-xs">
<div class="grid grid-cols-12 bg-zinc-950 p-3 text-zinc-500 font-semibold border-b border-zinc-800">
<span class="col-span-3">TX ID</span>
<span class="col-span-2">PAIR</span>
<span class="col-span-2">SIDE</span>
<span class="col-span-3 text-right">NOTIONAL (USDC)</span>
<span class="col-span-2 text-right">STATUS</span>
</div>
<div id="blotter-table" class="divide-y divide-zinc-900 bg-zinc-925/40">
<!-- Rendered via JS -->
</div>
</div>
</div>
</div>
<!-- ============================================================= -->
<!-- TAB 5: STORAGE BUCKET EXPLORER (/data) -->
<!-- ============================================================= -->
<div id="tab-storage" class="space-y-6 hidden">
<div class="rounded-2xl border border-zinc-800 bg-zinc-925/50 p-6 space-y-4 shadow-xl">
<div class="flex items-center justify-between border-b border-zinc-800 pb-3">
<h2 class="text-xs font-mono font-bold tracking-wider uppercase text-zinc-200 flex items-center space-x-2">
<i data-lucide="hard-drive" class="w-4 h-4 text-sol-green"></i>
<span>Persistent Bucket Storage Status</span>
</h2>
<span class="text-xs font-mono text-zinc-400">Volume: <strong class="text-white">/data</strong></span>
</div>
<div id="storage-status-box" class="p-4 rounded-xl bg-zinc-950 border border-zinc-900 text-zinc-300 font-mono text-xs space-y-2">
<div>Bucket <strong class="text-white">arudradey/agent-loop-storage</strong> is active and clean.</div>
<div class="text-zinc-500">All trade logs and hedge fund parameters persist across restarts.</div>
</div>
</div>
</div>
</main>
<!-- Clean Minimalist Footer -->
<footer class="border-t border-zinc-800/80 bg-zinc-950 text-zinc-500 text-xs py-5">
<div class="max-w-7xl mx-auto px-4 sm:px-6 flex flex-col sm:flex-row items-center justify-between gap-3 font-mono">
<div>
SOLANA QUANT HEDGE FUND • Qwen2.5-0.5B CPU Engine • arudradey/agent-loop
</div>
<div class="flex items-center space-x-4">
<span>Volume: <strong class="text-zinc-300">/data</strong></span>
<a href="/docs" class="text-sol-green hover:underline">API Docs</a>
</div>
</div>
</footer>
<!-- Application Logic Scripts -->
<script>
let activeTradeSide = 'BUY';
function initIcons() {
lucide.createIcons();
}
function switchTab(tabId) {
const tabs = ['overview', 'ai', 'arbitrage', 'blotter', 'storage'];
tabs.forEach(t => {
const pane = document.getElementById('tab-' + t);
const btn = document.getElementById('btn-tab-' + t);
if (t === tabId) {
pane.classList.remove('hidden');
btn.className = 'px-3 py-1.5 rounded-md bg-white text-zinc-950 font-bold transition';
} else {
pane.classList.add('hidden');
btn.className = 'px-3 py-1.5 rounded-md text-zinc-400 hover:text-white transition';
}
});
if (tabId === 'overview') fetchMarket();
if (tabId === 'arbitrage') fetchMarket();
if (tabId === 'blotter') fetchTrades();
initIcons();
}
function setTradeSide(side) {
activeTradeSide = side;
const buyBtn = document.getElementById('btn-side-buy');
const sellBtn = document.getElementById('btn-side-sell');
if (side === 'BUY') {
buyBtn.className = 'py-1.5 rounded-lg border font-bold text-xs bg-sol-green/10 text-sol-green border-sol-green/30';
sellBtn.className = 'py-1.5 rounded-lg border border-zinc-800 bg-zinc-900 text-zinc-400 hover:text-white font-bold text-xs';
} else {
sellBtn.className = 'py-1.5 rounded-lg border font-bold text-xs bg-red-500/10 text-red-400 border-red-500/30';
buyBtn.className = 'py-1.5 rounded-lg border border-zinc-800 bg-zinc-900 text-zinc-400 hover:text-white font-bold text-xs';
}
}
function setAiPrompt(type) {
const p = document.getElementById('ai-prompt');
if (type === 'sol_momentum') {
p.value = "Analyze current SOL/USDC momentum, calculate 24h risk-adjusted sizing, and recommend optimal slippage bounds for Raydium liquidity pools.";
} else if (type === 'arb_scan') {
p.value = "Scan Raydium CPMM vs Orca Whirlpools for flash loan cross-DEX arbitrage spreads and calculate net yield.";
} else if (type === 'rebalance') {
p.value = "Simulate portfolio rebalancing: maintain 60% SOL, 15% JUP, 10% RAY, and 15% USDC cash buffers to minimize drawdown.";
}
}
async function fetchMarket() {
try {
const res = await fetch('/api/market');
const data = await res.json();
// Ticker
if (data.prices) {
document.getElementById('ticker-sol').textContent = '$' + data.prices.SOL;
document.getElementById('ticker-jup').textContent = '$' + data.prices.JUP;
document.getElementById('ticker-ray').textContent = '$' + data.prices.RAY;
document.getElementById('ticker-wif').textContent = '$' + data.prices.WIF;
}
// Positions
if (data.portfolio && data.portfolio.positions) {
const container = document.getElementById('positions-table');
container.innerHTML = '';
data.portfolio.positions.forEach(pos => {
const row = document.createElement('div');
row.className = 'grid grid-cols-12 p-3 items-center hover:bg-zinc-900/60 transition';
row.innerHTML = `
<div class="col-span-4 flex items-center space-x-2 font-bold text-white">
<span class="w-2 h-2 rounded-full ${pos.symbol === 'SOL' ? 'bg-sol-green' : 'bg-sol-purple'}"></span>
<span>${pos.symbol}</span>
<span class="text-zinc-500 font-normal">(${pos.name})</span>
</div>
<div class="col-span-3 text-right text-zinc-300 font-semibold">${pos.amount.toLocaleString()}</div>
<div class="col-span-3 text-right text-white font-bold">$${pos.value_usdc.toLocaleString()}</div>
<div class="col-span-2 text-right text-sol-green font-bold">${pos.allocation}%</div>
`;
container.appendChild(row);
});
}
// Arbitrage Cards
if (data.arbitrage_opportunities) {
const arbCont = document.getElementById('arb-cards-container');
arbCont.innerHTML = '';
data.arbitrage_opportunities.forEach(arb => {
const card = document.createElement('div');
card.className = 'p-4 rounded-xl border border-zinc-800 bg-zinc-950 space-y-2 font-mono';
card.innerHTML = `
<div class="flex items-center justify-between text-xs font-bold">
<span class="text-white">${arb.pair}</span>
<span class="px-2 py-0.5 rounded text-[10px] bg-sol-green/10 text-sol-green border border-sol-green/20">+${arb.spread_pct}% SPREAD</span>
</div>
<div class="text-[11px] text-zinc-400 space-y-1">
<div>Route: <span class="text-white">${arb.buy_venue} → ${arb.sell_venue}</span></div>
<div>Estimated Profit: <span class="text-sol-green font-bold">${arb.net_profit_est}</span></div>
</div>
`;
arbCont.appendChild(card);
});
}
} catch (err) {
console.error(err);
}
}
async function fetchTrades() {
try {
const res = await fetch('/api/trades');
const data = await res.json();
const container = document.getElementById('blotter-table');
container.innerHTML = '';
if (!data.trades || data.trades.length === 0) {
container.innerHTML = '<div class="p-6 text-center text-zinc-600">No trades executed yet.</div>';
return;
}
data.trades.forEach(t => {
const row = document.createElement('div');
row.className = 'grid grid-cols-12 p-3 items-center hover:bg-zinc-900/60 transition';
const sideColor = t.side === 'BUY' ? 'text-sol-green' : 'text-red-400';
row.innerHTML = `
<div class="col-span-3 text-zinc-400 font-bold">${t.trade_id}</div>
<div class="col-span-2 text-white font-bold">${t.symbol}/USDC</div>
<div class="col-span-2 ${sideColor} font-extrabold">${t.side}</div>
<div class="col-span-3 text-right text-white font-bold">$${t.amount_usdc.toLocaleString()}</div>
<div class="col-span-2 text-right text-sol-green font-bold text-[10px]">CONFIRMED</div>
`;
container.appendChild(row);
});
} catch (e) {
console.error(e);
}
}
async function submitTradeOrder() {
const sym = document.getElementById('trade-symbol').value;
const amt = parseFloat(document.getElementById('trade-amount').value);
if (!amt || amt <= 0) return;
const btn = document.getElementById('btn-submit-order');
btn.disabled = true;
btn.textContent = 'EXECUTING ON JUPITER...';
try {
const res = await fetch('/api/trades/execute', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ symbol: sym, side: activeTradeSide, amount_usdc: amt })
});
const data = await res.json();
btn.textContent = 'ORDER CONFIRMED!';
setTimeout(() => {
btn.disabled = false;
btn.textContent = 'DISPATCH TO SOLANA';
}, 1200);
fetchMarket();
} catch (err) {
alert(err.message);
btn.disabled = false;
btn.textContent = 'DISPATCH TO SOLANA';
}
}
async function queryQuantAi() {
const prompt = document.getElementById('ai-prompt').value.trim();
if (!prompt) return;
const btn = document.getElementById('btn-run-ai');
btn.disabled = true;
btn.className = "px-6 py-2.5 rounded-lg bg-zinc-700 text-zinc-400 font-extrabold text-xs uppercase tracking-wider transition flex items-center space-x-2 cursor-not-allowed";
btn.innerHTML = '<i data-lucide="loader-2" class="w-4 h-4 animate-spin"></i><span>Analyzing...</span>';
initIcons();
const outBox = document.getElementById('ai-output-box');
outBox.textContent = '';
try {
const res = await fetch('/api/ai/analyze', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ prompt: prompt, max_tokens: 256 })
});
const reader = res.body.getReader();
const decoder = new TextDecoder('utf-8');
let buffer = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const parts = buffer.split('\n\n');
buffer = parts.pop();
for (const p of parts) {
if (!p.trim()) continue;
let eventType = '';
let payload = '';
for (const line of p.split('\n')) {
if (line.startsWith('event: ')) eventType = line.substring(7).trim();
if (line.startsWith('data: ')) payload = line.substring(6).trim();
}
if (payload) {
const data = JSON.parse(payload);
if (eventType === 'token' && data.token) {
outBox.textContent += data.token;
outBox.scrollTop = outBox.scrollHeight;
}
}
}
}
} catch (err) {
outBox.textContent += '\n[Inference Error: ' + err.message + ']';
} finally {
btn.disabled = false;
btn.className = "px-6 py-2.5 rounded-lg bg-white hover:bg-zinc-200 text-black font-extrabold text-xs uppercase tracking-wider transition flex items-center space-x-2 shadow-lg active:scale-95";
btn.innerHTML = '<i data-lucide="zap" class="w-4 h-4 fill-black"></i><span>Run Analysis</span>';
initIcons();
}
}
function copyAiOutput() {
const text = document.getElementById('ai-output-box').textContent;
navigator.clipboard.writeText(text).then(() => {
const btn = document.getElementById('btn-copy-ai');
btn.textContent = 'COPIED';
setTimeout(() => { btn.textContent = 'COPY'; }, 1800);
});
}
window.addEventListener('DOMContentLoaded', () => {
initIcons();
fetchMarket();
});
</script>
</body>
</html>
|