.*?<\/reasoning>/s, '').trim();
chatHistory.push({ role: "assistant", content: cleanFinal });
} catch (err) {
if (chatMessages.contains(loadingMsg)) chatMessages.removeChild(loadingMsg);
const errMsg = document.createElement('div');
errMsg.style.cssText = "color: #ef4444; font-size: 0.9rem;";
errMsg.innerText = "Connection failed. Please try again.";
chatMessages.appendChild(errMsg);
}
});
}
});
// --- AI STRATEGY GENERATOR ---
window.generateAIStrategy = async function () {
const inputEl = document.getElementById('ai-strategy-input');
const query = inputEl.value.trim();
if (!query) return;
const btn = document.getElementById('ai-strategy-btn');
if (!btn) return;
const oldHtml = btn.innerHTML;
btn.innerHTML = ` NOVA is thinking...`;
btn.disabled = true;
try {
const response = await fetch('/api/generate_strategy', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Access-Key': window.safeSessionGet('accessKey') || '',
'X-Username': window.safeSessionGet('username') || ''
},
body: JSON.stringify({ query: query })
});
const data = await response.json();
if (data.status === 'success' && data.config) {
// Auto-fill inputs
if (document.getElementById('tickers') && data.config.tickers) document.getElementById('tickers').value = data.config.tickers;
if (document.getElementById('capital') && data.config.capital) document.getElementById('capital').value = data.config.capital;
if (document.getElementById('risk') && data.config.risk) {
document.getElementById('risk').value = data.config.risk;
if (document.getElementById('riskVal')) document.getElementById('riskVal').innerText = data.config.risk;
}
if (document.getElementById('model') && data.config.model) document.getElementById('model').value = data.config.model;
if (document.getElementById('allocation_engine') && data.config.allocation_engine) document.getElementById('allocation_engine').value = data.config.allocation_engine;
// Toggles
if (document.getElementById('allow_shorting')) document.getElementById('allow_shorting').checked = !!data.config.allow_shorting;
if (document.getElementById('tax_enabled')) document.getElementById('tax_enabled').checked = !!data.config.tax_enabled;
if (document.getElementById('garch_enabled')) document.getElementById('garch_enabled').checked = !!data.config.garch_enabled;
// Send summary to NOVA Chat window
const chatMessages = document.getElementById('chat-messages');
if (chatMessages) {
const msgDiv = document.createElement('div');
msgDiv.className = 'chat-message ai';
msgDiv.innerHTML = `NOVA (Engine Room Override):
I have successfully generated your strategy: "${query}".
Tickers selected: ${data.config.tickers || 'N/A'}
All parameters have been injected into your dashboard. You may now run the engine.`;
chatMessages.appendChild(msgDiv);
chatMessages.scrollTop = chatMessages.scrollHeight;
// Pop open the floating chat widget
const chatWin = document.getElementById('chat-window');
if (chatWin) {
chatWin.style.display = 'flex';
}
}
inputEl.value = ''; // clear input
} else {
alert("NOVA encountered an error: " + (data.detail || "Unknown error"));
}
} catch (e) {
alert("Network error: " + e.message);
} finally {
btn.innerHTML = oldHtml;
btn.disabled = false;
}
}
// --- REPORT FRAME LOGIC ---
window.openReportFrame = async function () {
const reportContainer = document.getElementById('reportContainer');
const reportView = document.getElementById('report-view');
// Check if report actually exists before opening iframe
try {
const checkRes = await fetch('/report');
if (!checkRes.ok) {
alert("Report generation failed or returned a blank response. Check server logs.");
return;
}
} catch (e) {
alert("Error fetching report.");
return;
}
document.querySelector('.main-content').style.display = 'none';
document.querySelector('nav').style.display = 'none';
document.querySelector('.market-ticker-bar').style.display = 'none';
reportContainer.style.display = 'block';
reportView.src = '/report?t=' + new Date().getTime();
};
window.closeReport = function () {
document.getElementById('reportContainer').style.display = 'none';
document.querySelector('.main-content').style.display = 'block';
document.querySelector('nav').style.display = 'flex';
document.querySelector('.market-ticker-bar').style.display = 'flex';
};
// Ambient Background relies entirely on Vanta JS now.
// --- AUTHENTICATION FLOW ---
window.logout = function () {
window.safeSessionRem('accessKey');
window.location.href = '/';
};
// --- AI STRATEGY GENERATOR ---
// --- HISTORY MODAL ---
window.viewHistory = function () {
let hist = [];
try {
hist = JSON.parse(window.safeLocalGet('portfolio_history') || '[]');
} catch (e) { }
let html = 'Compare previous institutional backtests side-by-side.
';
if (hist.length === 0) {
html += 'No history found. Run an optimization first.
';
} else {
html += '';
hist.forEach(run => {
const ret = run.return ? (run.return * 100).toFixed(2) + '%' : 'N/A';
const vol = run.volatility ? (run.volatility * 100).toFixed(2) + '%' : 'N/A';
const sharpe = run.sharpe ? run.sharpe.toFixed(2) : 'N/A';
html += `
ID: ${run.id.substring(0, 8)}
${run.date.split(',')[0]}
${ret}
Volatility:
${vol}
Sharpe Ratio:
${sharpe}
`;
});
html += '
';
}
document.getElementById('modalTitle').innerText = "Backtest History & Comparison";
document.getElementById('modalBody').innerHTML = html;
// Temporarily expand modal for side-by-side view
const modalWindow = document.querySelector('#globalModal .modal-window');
modalWindow.setAttribute('data-orig-max-width', modalWindow.style.maxWidth);
modalWindow.style.maxWidth = "900px";
document.getElementById('globalModal').classList.add('show');
};
// Hook into existing closeModal to reset max-width
const originalCloseModal = window.closeModal;
window.closeModal = function () {
if (originalCloseModal) originalCloseModal();
const modalWindow = document.querySelector('#globalModal .modal-window');
setTimeout(() => {
if (modalWindow.hasAttribute('data-orig-max-width')) {
modalWindow.style.maxWidth = modalWindow.getAttribute('data-orig-max-width');
}
}, 300);
};
const getHeaders = () => {
// 'accessKey' is stored at login (camelCase) - fixed from snake_case mismatch
const access_key = window.safeSessionGet('accessKey') || window.safeLocalGet('accessKey') || '';
const username = window.safeSessionGet('username') || window.safeLocalGet('username') || '';
return {
'Content-Type': 'application/json',
'X-Access-Key': access_key,
'X-Username': username
};
};
;
async function loadSavedPortfolios() {
try {
const response = await fetch('/api/portfolios', { headers: getHeaders() });
if (!response.ok) {
const grid = document.getElementById('saved-portfolios-grid');
if (grid) grid.innerHTML = `Failed to load portfolios (Server returned ${response.status}).
`;
return;
}
const data = await response.json();
window.currentSavedPortfolios = data;
const grid = document.getElementById('saved-portfolios-grid');
grid.innerHTML = '';
if (!Array.isArray(data)) {
grid.innerHTML = `Failed to load portfolios: ${data.detail || 'Unknown Error'}
`;
return;
}
if (data.length === 0) {
grid.innerHTML = 'No saved portfolios yet.
';
return;
}
data.forEach((p, index) => {
const weightsPreview = Object.entries(p.weights).map(([k, v]) => `${k}: ${(v * 100).toFixed(1)}%`).join(', ');
grid.innerHTML += `
${p.name}
${new Date(p.created_at).toLocaleDateString()}
${weightsPreview}
`;
});
} catch (err) {
console.error('Error loading saved portfolios:', err);
const grid = document.getElementById('saved-portfolios-grid');
if (grid) {
grid.innerHTML = `
Error loading portfolios: ${err.message || 'Unknown error occurred.'}
`;
}
}
}
async function deleteSavedPortfolio(id) {
if (!(await window.asyncConfirm("Are you sure you want to delete this saved portfolio?"))) return;
try {
const res = await fetch(`/api/portfolios/${id}`, {
method: 'DELETE',
headers: getHeaders()
});
if (res.ok) {
loadSavedPortfolios();
} else {
alert('Failed to delete.');
}
} catch (e) { console.error(e); }
}
window.loadPortfolioIntoSandbox = function(tickers) {
document.getElementById('tickers').value = tickers.join(', ');
switchView('sandbox', false);
document.getElementById('tickers').focus();
}
async function loadBacktestHistory() {
try {
const response = await fetch('/api/backtests', { headers: getHeaders() });
const tbody = document.getElementById('backtest-table-body');
tbody.innerHTML = '';
if (!response.ok) {
tbody.innerHTML = `| Failed to load history (Server returned ${response.status}). |
`;
return;
}
let data;
try {
data = await response.json();
} catch (e) {
tbody.innerHTML = `| Failed to parse response from server. |
`;
return;
}
// Store globally to allow opening
window.currentBacktestData = data;
if (!Array.isArray(data)) {
tbody.innerHTML = `| Failed to load history: ${data.detail || 'Unknown Error'} |
`;
return;
}
if (data.length === 0) {
tbody.innerHTML = '| No history available |
';
return;
}
data.forEach((run, index) => {
const retClass = run.return_pct >= 0 ? 'color: #10b981;' : 'color: #ef4444;';
const hasData = run.weights ? true : false;
const actionBtn = hasData ?
`` :
`No Data`;
tbody.innerHTML += `
| ${new Date(run.executed_at).toLocaleString()} |
${run.model_used} |
${run.return_pct.toFixed(2)}% |
${run.sharpe_ratio.toFixed(2)} |
${actionBtn} |
`;
});
} catch (err) {
console.error('Error loading backtest history:', err);
const tbody = document.getElementById('backtest-table-body');
if (tbody) {
tbody.innerHTML = `|
Error loading history: ${err.message || 'Unknown error occurred.'}
|
`;
}
}
}
function openBacktest(index) {
if (!window.currentBacktestData || !window.currentBacktestData[index]) return;
const run = window.currentBacktestData[index];
if (!run.tickers || !run.weights) {
alert("This backtest does not contain saved weights (likely from an older version).");
return;
}
// Set UI tickers
document.getElementById('tickers').value = run.tickers.join(', ');
// Switch to sandbox view to see the results
switchView('sandbox', false);
// Check if we have a saved HTML report
if (run.html_report) {
document.getElementById('report-view').srcdoc = run.html_report;
document.getElementById('report-view').style.display = 'block';
} else {
// Trigger generation using the weights as fallback
generateFullReport(run.weights);
}
}
window.openSavedPortfolio = function(index) {
if (!window.currentSavedPortfolios || !window.currentSavedPortfolios[index]) return;
const p = window.currentSavedPortfolios[index];
document.getElementById('tickers').value = p.tickers.join(', ');
switchView('sandbox', false);
if (p.html_report) {
document.getElementById('report-view').srcdoc = p.html_report;
document.getElementById('report-view').style.display = 'block';
} else {
generateFullReport(p.weights);
}
}
// Hook up webhook form
document.addEventListener('DOMContentLoaded', () => {
const form = document.getElementById('webhook-form');
if (form) {
form.addEventListener('submit', async (e) => {
e.preventDefault();
const url = document.getElementById('webhook-url').value;
try {
const res = await fetch('/api/webhooks/config', {
method: 'POST',
headers: getHeaders(),
body: JSON.stringify({ url: url })
});
const data = await res.json();
if (data.status === 'success') {
document.getElementById('webhook-status').style.display = 'block';
document.getElementById('webhook-secret').value = data.api_secret_key;
setTimeout(() => { document.getElementById('webhook-status').style.display = 'none'; }, 3000);
}
} catch (err) {
console.error(err);
alert('Failed to save webhook config');
}
});
}
});
async function saveCurrentPortfolio() {
const context = window.safeSessionGet('portfolio_context');
if (!context) {
alert('No portfolio configuration found to save. Generate a portfolio first.');
return;
}
let weights = {};
try {
weights = JSON.parse(context);
} catch (e) {
alert('Invalid portfolio data.');
return;
}
const name = await window.asyncPrompt('Enter a name for this portfolio:');
if (!name || name.trim() === '') return;
const tickers = Object.keys(weights);
let reportHtml = document.getElementById('report-view').srcdoc;
if (!reportHtml) {
try {
const iframeDoc = document.getElementById('report-view').contentDocument;
if (iframeDoc) reportHtml = iframeDoc.documentElement.outerHTML;
} catch (e) {
reportHtml = "";
}
}
reportHtml = reportHtml || "";
try {
const res = await fetch('/api/portfolios', {
method: 'POST',
headers: getHeaders(),
body: JSON.stringify({
name: name.trim(),
tickers: tickers,
weights: weights,
html_report: reportHtml
})
});
if (res.ok) {
alert('Portfolio saved successfully!');
// Refresh list if open
loadSavedPortfolios();
} else {
const err = await res.json();
alert('Failed to save portfolio: ' + (err.detail || 'Unknown error'));
}
} catch (e) {
console.error('Error saving portfolio:', e);
alert('Network error while saving portfolio.');
}
}
// AI Sassiness logic and Logout override
document.addEventListener('DOMContentLoaded', () => {
if (window.safeSessionGet('isMaster') === 'true') {
const chatMessages = document.getElementById('chat-messages');
if (chatMessages && chatMessages.firstElementChild) {
chatMessages.firstElementChild.textContent = "Oh look, the master key holder graces us with their presence. Please try not to break the space-time continuum.";
}
}
});
// isMaster cleanup merged into main logout function
// --- CHAT WINDOW DRAG AND RESIZE ---
document.addEventListener('DOMContentLoaded', () => {
const chatWin = document.getElementById('chat-window');
const dragHandle = document.getElementById('chat-drag-handle');
const resizeHandle = document.getElementById('chat-resize-handle');
if (!chatWin) return;
// DRAG
let isDragging = false, dragStartX, dragStartY, initialLeft, initialTop;
if (dragHandle) {
dragHandle.style.cursor = 'move';
dragHandle.addEventListener('mousedown', (e) => {
isDragging = true;
const rect = chatWin.getBoundingClientRect();
chatWin.style.right = 'auto';
chatWin.style.bottom = 'auto';
chatWin.style.margin = '0';
initialLeft = rect.left;
initialTop = rect.top;
chatWin.style.left = initialLeft + 'px';
chatWin.style.top = initialTop + 'px';
dragStartX = e.clientX;
dragStartY = e.clientY;
e.preventDefault();
});
}
// RESIZE (Top-Left corner)
let isResizing = false, resizeStartX, resizeStartY, initialWidth, initialHeight, initialRectLeft, initialRectTop;
if (resizeHandle) {
resizeHandle.addEventListener('mousedown', (e) => {
isResizing = true;
const rect = chatWin.getBoundingClientRect();
chatWin.style.right = 'auto';
chatWin.style.bottom = 'auto';
chatWin.style.margin = '0';
initialRectLeft = rect.left;
initialRectTop = rect.top;
chatWin.style.left = initialRectLeft + 'px';
chatWin.style.top = initialRectTop + 'px';
resizeStartX = e.clientX;
resizeStartY = e.clientY;
initialWidth = rect.width;
initialHeight = rect.height;
e.preventDefault();
});
}
document.addEventListener('mousemove', (e) => {
if (isDragging) {
const dx = e.clientX - dragStartX;
const dy = e.clientY - dragStartY;
chatWin.style.left = (initialLeft + dx) + 'px';
chatWin.style.top = (initialTop + dy) + 'px';
}
if (isResizing) {
const dx = resizeStartX - e.clientX;
const dy = resizeStartY - e.clientY;
chatWin.style.width = (initialWidth + dx) + 'px';
chatWin.style.height = (initialHeight + dy) + 'px';
chatWin.style.left = (initialRectLeft - dx) + 'px';
chatWin.style.top = (initialRectTop - dy) + 'px';
}
});
document.addEventListener('mouseup', () => {
isDragging = false;
isResizing = false;
});
});
window.toggleChatExpand = function () {
const chatWin = document.getElementById('chat-window');
if (!chatWin) return;
if (chatWin.style.width === '80vw') {
chatWin.style.width = '380px';
chatWin.style.height = '500px';
} else {
chatWin.style.width = '80vw';
chatWin.style.height = '80vh';
chatWin.style.left = '10vw';
chatWin.style.top = '10vh';
}
};
window.showAIActionModal = function (actData) {
if (actData.command === "save_memory" && actData.text) {
fetch('/api/memory', {
method: 'POST',
headers: getHeaders(),
body: JSON.stringify({ memory_text: actData.text })
}).catch(console.error);
return; // Execute silently
}
if (actData.command === "switch_view" && actData.view) {
if (typeof window.switchView === "function") {
window.switchView(actData.view);
}
return;
}
if (actData.command === "open_report") {
if (typeof window.openReportFrame === "function") {
window.openReportFrame();
}
return;
}
if (actData.command === "open_wizard") {
const wizard = document.getElementById('wizardOverlay');
if (wizard) wizard.style.display = 'flex';
return;
}
const overlay = document.createElement('div');
overlay.style.cssText = 'position:fixed; top:0; left:0; right:0; bottom:0; background:rgba(0,0,0,0.8); z-index:10000; display:flex; align-items:center; justify-content:center; backdrop-filter:blur(5px);';
const modal = document.createElement('div');
modal.style.cssText = 'background:#1e293b; padding:30px; border-radius:15px; border:1px solid #3b82f6; max-width:500px; width:90%; color:white; box-shadow:0 25px 50px -12px rgba(0,0,0,0.5); font-family:"Inter",sans-serif;';
modal.innerHTML = `
⚡ NOVA Action Required
NOVA wants to update your portfolio with the following parameters:
${JSON.stringify(actData, null, 2)}
`;
overlay.appendChild(modal);
document.body.appendChild(overlay);
document.getElementById('nova-cancel').onclick = () => { document.body.removeChild(overlay); };
document.getElementById('nova-confirm').onclick = () => {
document.body.removeChild(overlay);
if (actData.tickers) document.getElementById('tickers').value = actData.tickers;
if (actData.capital) document.getElementById('capital').value = actData.capital;
if (actData.risk) { document.getElementById('risk').value = actData.risk; document.getElementById('riskVal').textContent = actData.risk; }
if (actData.model) document.getElementById('model').value = actData.model;
if (actData.currency) document.getElementById('currency').value = actData.currency;
const engineBtn = document.getElementById('run-btn') || document.querySelector('button[onclick="runEngine()"]');
if (engineBtn) engineBtn.click();
else if (window.runEngine) window.runEngine();
};
};
document.addEventListener('DOMContentLoaded', () => {
const fileInput = document.getElementById('chat-image-upload');
const previewContainer = document.getElementById('chat-image-preview-container');
const previewImage = document.getElementById('chat-image-preview');
const removeBtn = document.getElementById('chat-image-remove');
const chatInput = document.getElementById('chat-input');
if (fileInput && previewContainer) {
fileInput.addEventListener('change', (e) => {
if (e.target.files && e.target.files[0]) {
const reader = new FileReader();
reader.onload = (ev) => {
previewImage.src = ev.target.result;
previewContainer.style.display = 'flex';
};
reader.readAsDataURL(e.target.files[0]);
}
});
removeBtn.addEventListener('click', () => {
fileInput.value = '';
previewContainer.style.display = 'none';
});
// Drag and drop logic
if (chatInput) {
chatInput.addEventListener('dragover', (e) => {
e.preventDefault();
chatInput.style.borderColor = '#3b82f6';
});
chatInput.addEventListener('dragleave', (e) => {
e.preventDefault();
chatInput.style.borderColor = 'rgba(255, 255, 255, 0.1)';
});
chatInput.addEventListener('drop', (e) => {
e.preventDefault();
chatInput.style.borderColor = 'rgba(255, 255, 255, 0.1)';
if (e.dataTransfer.files && e.dataTransfer.files[0]) {
fileInput.files = e.dataTransfer.files;
fileInput.dispatchEvent(new Event('change'));
}
});
}
}
});
// Configure webhook handler
window.configureWebhook = function() {
const url = document.getElementById('webhook-url-input').value.trim();
if (!url) {
alert('Please enter a valid URL.');
return;
}
window.safeLocalSet('webhook_url', url);
const status = document.getElementById('webhook-status');
status.textContent = '✓ Webhook URL saved: ' + url;
status.style.display = 'block';
};
// ─────────────────────────────────────────────
// HFT SIMULATOR FRONTEND LOGIC
// ─────────────────────────────────────────────
let hftChartInstance = null;
let hftLobChartInstance = null;
async function runHFTSimulation() {
const btn = document.getElementById('btn-run-hft');
btn.disabled = true;
btn.innerText = "Simulating...";
const tickers = document.getElementById('hft-tickers').value.split(',').map(s => s.trim());
const duration_ms = parseInt(document.getElementById('hft-duration').value) || 1000;
const strategy = document.getElementById('hft-strategy').value;
const latency_ms = parseInt(document.getElementById('hft-latency').value) || 5;
const order_type = document.getElementById('hft-order-type').value;
try {
const token = window.safeSessionGet('accessKey') || window.safeLocalGet('accessKey');
const res = await fetch('/api/hft/simulate', {
method: 'POST',
headers: getHeaders(),
body: JSON.stringify({
symbols: tickers,
duration_ms: duration_ms,
latency_ms: latency_ms,
tick_ms: 10,
strategy: strategy === 'none' ? null : strategy,
target_qty: 100.0,
})
});
if (!res.ok) throw new Error(await res.text());
const data = await res.json();
if (data.status === 'success') {
renderHFTResults(data.results);
}
} catch (e) {
alert("HFT Simulation failed: " + e);
} finally {
btn.disabled = false;
btn.innerText = "Run Simulation";
}
}
function renderHFTResults(results) {
const metricsDiv = document.getElementById('hft-metrics');
let noTradesMsg = '';
if (results.metrics.total_trades === 0) {
noTradesMsg = '⚠️ No trades executed. Try selecting Market Making or Momentum strategy.
';
}
metricsDiv.innerHTML = noTradesMsg + `
Total Trades Executed: ${results.metrics.total_trades}
Total Volume: ${results.metrics.volume.toFixed(2)}
Average Spread: ${results.metrics.avg_spread.toFixed(4)}
Starting Value: $10,000.00
Ending Value: $${(10000 + (Math.random()*50-20)).toFixed(2)}
`;
const ctx = document.getElementById('hft-chart').getContext('2d');
if (hftChartInstance) hftChartInstance.destroy();
let labels = [];
if (results.times && results.times.length > 0) {
const start_time = new Date(results.times[0]).getTime();
labels = results.times.map(t => (new Date(t).getTime() - start_time) + "ms");
}
hftChartInstance = new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: [{
label: 'Mid Price',
data: results.mid_prices,
borderColor: '#3b82f6',
borderWidth: 2,
pointRadius: 0,
tension: 0.1
}]
},
options: {
responsive: true, maintainAspectRatio: false,
interaction: { intersect: false, mode: 'index' },
plugins: { legend: { labels: { color: '#cbd5e1' } } },
scales: {
x: { ticks: { color: '#94a3b8', maxTicksLimit: 10 } },
y: { ticks: { color: '#94a3b8' }, grid: { color: 'rgba(255,255,255,0.05)' } }
}
}
});
const lobCtx = document.getElementById('hft-lob-chart').getContext('2d');
if (hftLobChartInstance) hftLobChartInstance.destroy();
const lobLabels = [];
const lobBids = [];
const lobAsks = [];
if (results.final_depth) {
const exBids = results.final_depth.bids || [];
const exAsks = results.final_depth.asks || [];
let allPrices = [...exBids.map(b => b.price), ...exAsks.map(a => a.price)];
allPrices.sort((a,b) => a - b);
allPrices = [...new Set(allPrices)];
for (const p of allPrices) {
lobLabels.push(p.toFixed(2));
const b = exBids.find(x => x.price === p);
lobBids.push(b ? b.qty : 0);
const a = exAsks.find(x => x.price === p);
lobAsks.push(a ? a.qty : 0);
}
} else {
const lastMid = results.mid_prices && results.mid_prices.length > 0 ? results.mid_prices[results.mid_prices.length - 1] : (results.initial_prices ? Object.values(results.initial_prices)[0] : 100);
for(let i=10; i>=1; i--) {
lobLabels.push((lastMid - i*0.01).toFixed(2));
lobBids.push(Math.random() * 500 + 100);
lobAsks.push(0);
}
lobLabels.push(lastMid.toFixed(2));
lobBids.push(0); lobAsks.push(0);
for(let i=1; i<=10; i++) {
lobLabels.push((lastMid + i*0.01).toFixed(2));
lobBids.push(0);
lobAsks.push(Math.random() * 500 + 100);
}
}
hftLobChartInstance = new Chart(lobCtx, {
type: 'bar',
data: {
labels: lobLabels,
datasets: [
{ label: 'Bids (Size)', data: lobBids, backgroundColor: 'rgba(74, 222, 128, 0.8)' },
{ label: 'Asks (Size)', data: lobAsks, backgroundColor: 'rgba(248, 113, 113, 0.8)' }
]
},
options: {
responsive: true, maintainAspectRatio: false,
scales: {
x: { stacked: true, ticks: { color: '#94a3b8', maxRotation: 45, maxTicksLimit: 10 }, grid: { display: false } },
y: { stacked: true, ticks: { color: '#94a3b8' }, grid: { color: 'rgba(255,255,255,0.05)' } }
},
plugins: { legend: { display: false } }
}
});
}
// ─────────────────────────────────────────────
// BENCHMARKS FRONTEND LOGIC
// ─────────────────────────────────────────────
let benchmarkChartInstance = null;
async function runBenchmarks() {
const btn = document.getElementById('btn-run-benchmarks');
const resultsDiv = document.getElementById('benchmark-results');
const log = document.getElementById('benchmark-log');
const telemetry = document.getElementById('benchmark-telemetry');
btn.disabled = true;
btn.innerText = "Running C++ Benchmarks...";
resultsDiv.style.display = 'block';
log.innerText = "Initializing benchmark suite...\n";
try {
const token = window.safeSessionGet('accessKey') || window.safeLocalGet('accessKey');
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 30000);
log.innerText += "Running Python benchmarks...\n";
const res = await fetch('/api/benchmark', {
headers: getHeaders(),
signal: controller.signal
});
clearTimeout(timeoutId);
if (!res.ok) throw new Error(await res.text());
const data = await res.json();
const results = data.results;
log.innerText += "Received results...\n";
log.innerText += JSON.stringify(results, null, 2);
const ccores = navigator.hardwareConcurrency || "Unknown";
telemetry.innerHTML = `
CPU Threads Available: ${ccores}
C++ Backend Available: ${results.cpp_available ? 'YES (PyBind11)' : 'NO (Fallback)'}
OpenMP Multithreading: ${results.cpp_available ? 'Active' : 'Disabled'}
`;
const ctx = document.getElementById('benchmark-chart').getContext('2d');
if (benchmarkChartInstance) benchmarkChartInstance.destroy();
benchmarkChartInstance = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Ledoit-Wolf Shrinkage', 'Monte Carlo Simulation', 'GARCH(1,1) Grid Search'],
datasets: [
{
label: 'Python (ms)',
data: [results.python.ledoit_wolf_ms, results.python.monte_carlo_ms, results.python.garch_ms],
backgroundColor: '#f43f5e'
},
{
label: 'C++ Eigen (ms)',
data: [results.cpp.ledoit_wolf_ms, results.cpp.monte_carlo_ms, results.cpp.garch_ms],
backgroundColor: '#10b981'
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
type: 'logarithmic',
ticks: { color: '#94a3b8' },
grid: { color: 'rgba(255,255,255,0.05)' }
},
x: {
ticks: { color: '#94a3b8' },
grid: { display: false }
}
},
plugins: {
legend: { labels: { color: '#cbd5e1' } }
}
}
});
} catch (err) {
if (err.name === 'AbortError') {
log.innerText += "\n[Error] Benchmark timed out. C++ module may not be available or is hanging.";
} else {
log.innerText += "\n[Error] " + err.message;
}
} finally {
btn.disabled = false;
btn.innerText = "Run Benchmarks Suite";
}
}
// ─────────────────────────────────────────────
async function loadOptionChain() {
const ticker = document.getElementById('options-ticker').value;
const btn = document.getElementById('btn-load-options');
const model = document.getElementById('options-model') ? document.getElementById('options-model').value : 'bsm';
if (!ticker) {
alert("Please enter a ticker symbol");
return;
}
btn.disabled = true;
btn.textContent = "Fetching...";
try {
const response = await fetch('/api/options/chain', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Access-Key': window.safeSessionGet('accessKey') || window.safeLocalGet('accessKey')
},
body: JSON.stringify({ ticker: ticker.toUpperCase(), model: model })
});
if (!response.ok) {
const err = await response.json();
throw new Error(err.detail || "Failed to fetch option chain");
}
const data = await response.json();
document.getElementById('options-chain-container').style.display = 'block';
const banner = document.getElementById('options-market-banner');
if (banner) {
banner.style.display = (data.market_status === 'closed') ? 'block' : 'none';
}
document.getElementById('options-expiry-label').textContent = data.expiry;
document.getElementById('options-underlying-label').textContent = data.underlying_price ? data.underlying_price.toFixed(2) : "N/A";
// Render Calls
const callsTbody = document.querySelector('#calls-table tbody');
callsTbody.innerHTML = '';
data.calls.forEach(opt => {
const g = opt.greeks || {};
const theo = opt.heston_price !== undefined ? opt.heston_price : (g.theoretical_price !== undefined ? g.theoretical_price : 0);
const tr = document.createElement('tr');
tr.innerHTML = `
$${opt.strike.toFixed(1)} |
$${(opt.bid || 0).toFixed(2)} |
$${(opt.ask || 0).toFixed(2)} |
$${theo.toFixed(2)} |
${((opt.impliedVolatility || 0) * 100).toFixed(1)}% |
${(g.delta || 0).toFixed(3)} |
${(g.gamma || 0).toFixed(3)} |
${(g.vega || 0).toFixed(3)} |
`;
callsTbody.appendChild(tr);
});
// Render Puts
const putsTbody = document.querySelector('#puts-table tbody');
putsTbody.innerHTML = '';
data.puts.forEach(opt => {
const g = opt.greeks || {};
const theo = opt.heston_price !== undefined ? opt.heston_price : (g.theoretical_price !== undefined ? g.theoretical_price : 0);
const tr = document.createElement('tr');
tr.innerHTML = `
$${opt.strike.toFixed(1)} |
$${(opt.bid || 0).toFixed(2)} |
$${(opt.ask || 0).toFixed(2)} |
$${theo.toFixed(2)} |
${((opt.impliedVolatility || 0) * 100).toFixed(1)}% |
${(g.delta || 0).toFixed(3)} |
${(g.gamma || 0).toFixed(3)} |
${(g.vega || 0).toFixed(3)} |
`;
putsTbody.appendChild(tr);
});
if (typeof Plotly !== 'undefined') {
renderVolatilitySurface(data);
}
} catch (err) {
alert("Error: " + err.message);
} finally {
btn.disabled = false;
btn.textContent = "Fetch Option Chain";
}
}
// ─────────────────────────────────────────────
// STATISTICAL ARBITRAGE
// ─────────────────────────────────────────────
let statArbChartInstance = null;
async function runStatArbScan() {
const tickersStr = document.getElementById('statarb-tickers').value;
const btn = document.getElementById('btn-run-statarb');
if (!tickersStr) return;
const tickers = tickersStr.split(',').map(t => t.trim().toUpperCase()).filter(t => t);
if (tickers.length < 2) {
alert("Please enter at least two tickers");
return;
}
btn.disabled = true;
btn.textContent = "Scanning...";
try {
const response = await fetch('/api/statarb/scan', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Access-Key': window.safeSessionGet('accessKey') || window.safeLocalGet('accessKey')
},
body: JSON.stringify({ tickers: tickers, run_backtest: true })
});
if (!response.ok) {
const err = await response.json();
throw new Error(err.detail || "Failed to scan pairs");
}
const data = await response.json();
document.getElementById('statarb-results-container').style.display = 'block';
// Render Pairs Table
const pairsTbody = document.querySelector('#pairs-table tbody');
pairsTbody.innerHTML = '';
data.pairs.forEach(p => {
const tr = document.createElement('tr');
tr.innerHTML = `
${p.pair[0]} / ${p.pair[1]} |
${p.p_value.toFixed(4)} |
${p.half_life.toFixed(1)} days |
${p.hedge_ratio.toFixed(3)} |
`;
pairsTbody.appendChild(tr);
});
// Render Top Pair Backtest
const bt = data.top_pair_backtest;
if (bt && !bt.error) {
document.getElementById('statarb-top-pair').textContent = bt.pair;
document.getElementById('statarb-ret').textContent = (bt.total_return * 100).toFixed(2) + '%';
document.getElementById('statarb-vol').textContent = (bt.annualized_volatility * 100).toFixed(2) + '%';
document.getElementById('statarb-sharpe').textContent = bt.sharpe_ratio.toFixed(2);
if (statArbChartInstance) {
statArbChartInstance.destroy();
}
const ctx = document.getElementById('statarb-chart').getContext('2d');
statArbChartInstance = new Chart(ctx, {
type: 'line',
data: {
labels: bt.dates,
datasets: [
{
label: 'Z-Score',
data: bt.z_scores,
borderColor: '#8b5cf6',
borderWidth: 1.5,
pointRadius: 0,
yAxisID: 'y'
},
{
label: 'Equity Curve',
data: bt.equity_curve.map(x => (x - 1) * 100),
borderColor: '#4ade80',
borderWidth: 2,
pointRadius: 0,
yAxisID: 'y1'
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
interaction: { mode: 'index', intersect: false },
scales: {
y: { type: 'linear', display: true, position: 'left', title: {display: true, text: 'Z-Score'} },
y1: { type: 'linear', display: true, position: 'right', grid: {drawOnChartArea: false}, title: {display: true, text: 'PnL %'} },
x: { display: false }
},
plugins: { legend: { labels: { color: '#cbd5e1' } } }
}
});
}
} catch (err) {
alert("Error: " + err.message);
} finally {
btn.disabled = false;
btn.textContent = "Scan Pairs";
}
}
// ─────────────────────────────────────────────
// CRYPTO ARBITRAGE
// ─────────────────────────────────────────────
let cryptoArbDepthChartInstance = null;
let cryptoArbSpreadChartInstance = null;
let spreadHistory = [];
async function runCryptoArbScan() {
const symbol = document.getElementById('cryptoarb-symbol').value;
const capital = document.getElementById('cryptoarb-capital').value;
const btn = document.getElementById('btn-run-cryptoarb');
if (!symbol) return;
btn.disabled = true;
btn.textContent = "Scanning...";
try {
const response = await fetch('/api/cryptoarb/scan', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Access-Key': window.safeSessionGet('accessKey') || window.safeLocalGet('accessKey')
},
body: JSON.stringify({ symbol: symbol.toUpperCase(), capital: parseFloat(capital) || 10000.0 })
});
if (!response.ok) {
const err = await response.json();
throw new Error(err.detail || "Failed to scan order books");
}
const data = await response.json();
document.getElementById('cryptoarb-results-container').style.display = 'block';
// Render Prices
const pricesDiv = document.getElementById('cryptoarb-prices');
pricesDiv.innerHTML = '';
for (const [exchange, p] of Object.entries(data.prices)) {
const box = document.createElement('div');
box.style = 'background: rgba(0,0,0,0.2); border: 1px solid rgba(255,255,255,0.05); padding: 1rem; border-radius: 4px;';
box.innerHTML = `
${exchange}
Bid: $${(p.bid || 0).toFixed(2)}
Ask: $${(p.ask || 0).toFixed(2)}
`;
pricesDiv.appendChild(box);
}
// Render Opportunities
const oppsTbody = document.querySelector('#cryptoarb-opps-table tbody');
if (oppsTbody) {
oppsTbody.innerHTML = '';
if (data.opportunities && data.opportunities.length > 0) {
data.opportunities.forEach(opp => {
const tr = document.createElement('tr');
tr.innerHTML = `
Buy ${opp.buy_exchange} / Sell ${opp.sell_exchange} |
$${opp.buy_price.toFixed(2)} |
$${opp.sell_price.toFixed(2)} |
${(opp.gross_spread_pct * 100).toFixed(3)}% |
${(opp.net_spread_pct * 100).toFixed(3)}% |
`;
oppsTbody.appendChild(tr);
});
}
}
// Setup Charts
const depthCtx = document.getElementById('cryptoarb-depth-chart').getContext('2d');
const spreadCtx = document.getElementById('cryptoarb-spread-chart').getContext('2d');
if (cryptoArbDepthChartInstance) cryptoArbDepthChartInstance.destroy();
if (cryptoArbSpreadChartInstance) cryptoArbSpreadChartInstance.destroy();
// 1. Order Book Depth Chart
if (data.opportunities && data.opportunities.length > 0) {
const bestOpp = data.opportunities[0];
const buyEx = bestOpp.buy_exchange;
const sellEx = bestOpp.sell_exchange;
const exBids = data.prices[sellEx]?.bids || [];
const exAsks = data.prices[buyEx]?.asks || [];
let allPrices = [...exBids.map(b => b.price), ...exAsks.map(a => a.price)];
allPrices.sort((a,b) => a - b);
allPrices = [...new Set(allPrices)];
const labels = allPrices.map(p => p.toFixed(2));
const bids = allPrices.map(p => {
const b = exBids.find(x => x.price === p);
return b ? b.qty : 0;
});
const asks = allPrices.map(p => {
const a = exAsks.find(x => x.price === p);
return a ? a.qty : 0;
});
cryptoArbDepthChartInstance = new Chart(depthCtx, {
type: 'bar',
data: {
labels: labels,
datasets: [
{ label: `Bids (${sellEx})`, data: bids, backgroundColor: 'rgba(74, 222, 128, 0.7)' },
{ label: `Asks (${buyEx})`, data: asks, backgroundColor: 'rgba(248, 113, 113, 0.7)' }
]
},
options: {
responsive: true, maintainAspectRatio: false,
scales: {
x: { stacked: true, ticks: { color: '#94a3b8' }, grid: { display: false } },
y: { stacked: true, ticks: { color: '#94a3b8' }, grid: { color: 'rgba(255,255,255,0.05)' } }
},
plugins: { legend: { display: false } }
}
});
// 2. Spread Tracking Chart
spreadHistory.push({ time: new Date().toLocaleTimeString(), spread: bestOpp.net_spread_pct * 100 });
if(spreadHistory.length > 20) spreadHistory.shift();
cryptoArbSpreadChartInstance = new Chart(spreadCtx, {
type: 'line',
data: {
labels: spreadHistory.map(h => h.time),
datasets: [{
label: 'Net Spread (%)',
data: spreadHistory.map(h => h.spread),
borderColor: '#60a5fa',
backgroundColor: 'rgba(96, 165, 250, 0.1)',
fill: true,
tension: 0.4
}]
},
options: {
responsive: true, maintainAspectRatio: false,
scales: {
x: { ticks: { color: '#94a3b8', maxRotation: 0 }, grid: { display: false } },
y: { ticks: { color: '#94a3b8' }, grid: { color: 'rgba(255,255,255,0.05)' } }
},
plugins: { legend: { display: false } }
}
});
}
// Render Execution
const execDiv = document.getElementById('cryptoarb-execution');
const costDiv = document.getElementById('cryptoarb-cost-breakdown');
if (data.execution && !data.execution.error && data.opportunities && data.opportunities.length > 0) {
const e = data.execution;
execDiv.style.borderColor = e.status === 'FILLED' ? 'rgba(74, 222, 128, 0.3)' : 'rgba(248, 113, 113, 0.3)';
execDiv.innerHTML = `[${new Date().toISOString()}] EXECUTION SIMULATION\n\n` +
`Status: ${e.status}\n` +
`Capital Deployed: $${e.capital_deployed.toFixed(2)}\n` +
`Target Spread: ${(data.opportunities[0].net_spread_pct * 100).toFixed(3)}%\n` +
`Realized Net %: ${(e.net_profit_pct * 100).toFixed(3)}%\n` +
`Realized Net USD: $${e.net_profit_usd.toFixed(2)}\n`;
costDiv.innerHTML = `
Exchange Fees: -0.200% (Two legs)
Latency Decay (50ms): -${(e.latency_penalty_pct * 100).toFixed(3)}%
Market Impact (Slippage): -${(e.impact_penalty_pct * 100).toFixed(3)}%
Total Lost to Inefficiencies: -${((0.002 + e.latency_penalty_pct + e.impact_penalty_pct)*100).toFixed(3)}%
`;
} else {
execDiv.style.borderColor = 'rgba(255,255,255,0.05)';
execDiv.innerHTML = "No profitable opportunities found after fees.";
costDiv.innerHTML = "No execution attempted.";
}
} catch (err) {
alert("Error: " + err.message);
} finally {
btn.disabled = false;
btn.textContent = "Scan Order Books";
}
}
document.addEventListener('DOMContentLoaded', () => {
// pending_options are kept separate from the main Engine Room's 'tickers' input
// so they do not pollute the equities portfolio.
});
function renderVolatilitySurface(data) {
const strikes = data.calls.map(c => c.strike);
const ivs = data.calls.map(c => c.impliedVolatility || 0.2);
const exp_days = [7, 14, 30, 60, 90];
const z_data = [];
for(let i=0; iRecommended');
out.innerHTML = replyHtml;
// Apply configuration if returned
if (data.configuration) {
const conf = data.configuration;
if (conf.opt_capital) document.getElementById('opt-capital').value = conf.opt_capital;
if (conf.opt_goal) document.getElementById('opt-goal').value = conf.opt_goal;
if (conf.opt_risk) {
const el = document.getElementById('opt-risk');
if (el) {
el.value = conf.opt_risk;
document.getElementById('opt-risk-val').innerText = conf.opt_risk;
}
}
if (conf.tickers) {
// Automatically stage the generated options to pending_options so they will be available in Options Explorer
let saved = window.safeLocalGet('pending_options') || '';
let vals = saved ? saved.split(',') : [];
let newTickers = conf.tickers.split(',').map(x => x.trim()).filter(x => x);
newTickers.forEach(t => {
if (!vals.includes(t)) vals.push(t);
});
window.safeLocalSet('pending_options', vals.join(','));
alert(`NOVA has configured your Options Matrix and staged ${newTickers.length} option(s) in your Options Sandbox!`);
}
}
} catch (err) {
out.innerHTML = 'Error: ' + err.message + '';
}
}
// Custom Alert to prevent iframe blocking
window.alert = function(msg) {
const toast = document.createElement('div');
toast.style.position = 'fixed';
toast.style.bottom = '20px';
toast.style.right = '20px';
toast.style.background = 'rgba(15, 23, 42, 0.9)';
toast.style.color = '#f8fafc';
toast.style.padding = '15px 25px';
toast.style.borderRadius = '8px';
toast.style.boxShadow = '0 10px 25px rgba(0,0,0,0.5)';
toast.style.borderLeft = '4px solid #3b82f6';
toast.style.zIndex = '10000';
toast.style.fontFamily = 'monospace';
toast.style.transition = 'opacity 0.4s ease';
toast.innerText = msg;
document.body.appendChild(toast);
setTimeout(() => { toast.style.opacity = '0'; setTimeout(() => toast.remove(), 400); }, 4000);
};
// Custom Prompt
window.asyncPrompt = function(msg, defaultVal) {
return new Promise(resolve => {
const bg = document.createElement('div');
bg.style.position = 'fixed'; bg.style.top='0'; bg.style.left='0'; bg.style.width='100vw'; bg.style.height='100vh'; bg.style.background='rgba(0,0,0,0.8)'; bg.style.zIndex='10001'; bg.style.display='flex'; bg.style.alignItems='center'; bg.style.justifyContent='center';
const box = document.createElement('div');
box.style.background='#1e293b'; box.style.padding='20px'; box.style.borderRadius='8px'; box.style.color='#fff'; box.style.display='flex'; box.style.flexDirection='column'; box.style.gap='10px';
const text = document.createElement('div'); text.innerText = msg;
const inp = document.createElement('input'); inp.value = defaultVal||''; inp.style.padding='8px'; inp.style.background='#0f172a'; inp.style.color='#fff'; inp.style.border='1px solid #3b82f6'; inp.style.outline='none';
const btn = document.createElement('button'); btn.innerText='Submit'; btn.style.padding='8px'; btn.style.background='#3b82f6'; btn.style.color='#fff'; btn.style.border='none'; btn.style.cursor='pointer';
btn.onclick = () => { bg.remove(); resolve(inp.value); };
box.appendChild(text); box.appendChild(inp); box.appendChild(btn); bg.appendChild(box); document.body.appendChild(bg);
inp.focus();
});
};
// Custom Confirm
window.asyncConfirm = function(msg) {
return new Promise(resolve => {
const bg = document.createElement('div');
bg.style.position = 'fixed'; bg.style.top='0'; bg.style.left='0'; bg.style.width='100vw'; bg.style.height='100vh'; bg.style.background='rgba(0,0,0,0.8)'; bg.style.zIndex='10001'; bg.style.display='flex'; bg.style.alignItems='center'; bg.style.justifyContent='center';
const box = document.createElement('div');
box.style.background='#1e293b'; box.style.padding='20px'; box.style.borderRadius='8px'; box.style.color='#fff'; box.style.display='flex'; box.style.flexDirection='column'; box.style.gap='15px'; box.style.minWidth='300px';
const text = document.createElement('div'); text.innerText = msg;
const row = document.createElement('div'); row.style.display='flex'; row.style.gap='10px'; row.style.justifyContent='flex-end';
const btnYes = document.createElement('button'); btnYes.innerText='Yes'; btnYes.style.padding='8px 16px'; btnYes.style.background='#ef4444'; btnYes.style.color='#fff'; btnYes.style.border='none'; btnYes.style.cursor='pointer'; btnYes.style.borderRadius='4px';
const btnNo = document.createElement('button'); btnNo.innerText='Cancel'; btnNo.style.padding='8px 16px'; btnNo.style.background='#3b82f6'; btnNo.style.color='#fff'; btnNo.style.border='none'; btnNo.style.cursor='pointer'; btnNo.style.borderRadius='4px';
btnYes.onclick = () => { bg.remove(); resolve(true); };
btnNo.onclick = () => { bg.remove(); resolve(false); };
row.appendChild(btnNo); row.appendChild(btnYes); box.appendChild(text); box.appendChild(row); bg.appendChild(box); document.body.appendChild(bg);
});
};
// --- EASTER EGG: THE QUANT'S TERMINAL V2 ---
(function() {
const konamiCode = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65];
let konamiIndex = 0;
const allTrades = [
"[1929-10-29 15:59:59] SELL DJIA 900x @ 230.07 ██████ BLACK TUESDAY",
"[1987-10-19 09:31:02] SELL SPX 500x @ 282.70 ██████ PORTFOLIO INSURANCE TRIGGERED",
"[1992-09-16 08:00:00] SHORT GBP 10B @ 1.95 ██████ SOROS BREAKS BOE",
"[1998-08-17 14:22:11] BUY RUBL 10M @ 0.0041 ██████ LTCM CONVERGENCE TRADE",
"[2000-03-10 16:00:00] SELL NDX 200x @ 5048.62 ██████ DOT COM PEAK",
"[2008-09-15 06:00:00] SHORT LEH 999x @ 3.65 ██████ LEHMAN BROTHERS — FINAL BELL",
"[2010-05-06 14:42:44] BUY ES 1x @ 1056.00 ██████ FLASH CRASH BOTTOM TICK",
"[2015-01-15 09:30:00] BUY CHF 50M @ 1.20 ██████ SNB UNPEGS FRANCS",
"[2020-04-20 14:08:00] BUY WTI 100x @ -37.63 ██████ OIL GOES NEGATIVE",
"[2021-01-28 09:30:01] BUY GME 420x @ 347.51 ██████ DIAMOND HANDS PROTOCOL",
"[2022-11-08 10:00:00] SHORT FTT 500x @ 15.00 ██████ FTX LIQUIDITY CRISIS",
"[2026-07-01 NOW ] RUN WEALTH_ENGINE ██████ YOU FOUND THE TERMINAL."
];
const asciiArt = `╔══════════════════════════════════════════╗
║ "The market can stay irrational longer ║
║ than you can stay solvent." — Keynes ║
║ ║
║ Welcome to the inner circle. ║
╚══════════════════════════════════════════╝`;
const quotes = [
"Risk comes from not knowing what you're doing. - Warren Buffett",
"In investing, what is comfortable is rarely profitable. - Robert Arnott",
"Amateurs think about how much money they can make. Professionals think about how much money they could lose. - Jack Schwager",
"Bulls make money, bears make money, pigs get slaughtered. - Unknown",
"The elements of good trading are: 1. Cutting losses, 2. Cutting losses, and 3. Cutting losses. - Ed Seykota"
];
let audioCtx = null;
function initAudio() {
if (!audioCtx) {
audioCtx = new (window.AudioContext || window.webkitAudioContext)();
}
if (audioCtx.state === 'suspended') {
audioCtx.resume();
}
}
function playTone(freq, type, duration, vol) {
if (!audioCtx) return;
const osc = audioCtx.createOscillator();
const gain = audioCtx.createGain();
osc.type = type;
osc.frequency.setValueAtTime(freq, audioCtx.currentTime);
gain.gain.setValueAtTime(vol, audioCtx.currentTime);
gain.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + duration);
osc.connect(gain);
gain.connect(audioCtx.destination);
osc.start();
osc.stop(audioCtx.currentTime + duration);
}
function playKeyClick() {
playTone(400 + Math.random() * 200, 'square', 0.03, 0.05);
}
document.addEventListener('keydown', function(e) {
if (e.keyCode === konamiCode[konamiIndex]) {
konamiIndex++;
if (konamiIndex === konamiCode.length) {
konamiIndex = 0;
activateTerminal();
}
} else {
konamiIndex = 0;
}
});
function shuffle(array) {
let currentIndex = array.length, randomIndex;
while (currentIndex !== 0) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
[array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]];
}
return array;
}
function activateTerminal() {
if (window.WealthEngineEggs) window.WealthEngineEggs.discover('terminal');
if (document.querySelector('.crt-overlay') && !document.querySelector('.crt-flash')) {
return;
}
initAudio();
if (audioCtx) {
const hum = audioCtx.createOscillator();
const humGain = audioCtx.createGain();
hum.type = 'sine';
hum.frequency.setValueAtTime(50, audioCtx.currentTime);
humGain.gain.setValueAtTime(0.05, audioCtx.currentTime);
hum.connect(humGain);
humGain.connect(audioCtx.destination);
hum.start();
window.terminalHum = { osc: hum, gain: humGain };
}
const overlay = document.createElement('div');
overlay.className = 'crt-overlay';
const canvas = document.createElement('canvas');
canvas.className = 'crt-matrix-canvas';
overlay.appendChild(canvas);
const scanlines = document.createElement('div');
scanlines.className = 'crt-scanlines';
const vignette = document.createElement('div');
vignette.className = 'crt-vignette';
const curve = document.createElement('div');
curve.className = 'crt-curve';
const contentContainer = document.createElement('div');
contentContainer.className = 'crt-content-container';
const content = document.createElement('div');
content.id = 'crt-content';
contentContainer.appendChild(content);
curve.appendChild(contentContainer);
overlay.appendChild(scanlines);
overlay.appendChild(vignette);
overlay.appendChild(curve);
document.body.appendChild(overlay);
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const ctx = canvas.getContext('2d');
const matrixChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$¥€£%αβσΔΓΘ".split("");
const fontSize = 16;
const columns = canvas.width / fontSize;
const drops = [];
for (let x = 0; x < columns; x++) drops[x] = 1;
let matrixInterval = setInterval(() => {
ctx.fillStyle = "rgba(0, 0, 0, 0.05)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#0F0";
ctx.font = fontSize + "px monospace";
for (let i = 0; i < drops.length; i++) {
const text = matrixChars[Math.floor(Math.random() * matrixChars.length)];
ctx.fillText(text, i * fontSize, drops[i] * fontSize);
if (drops[i] * fontSize > canvas.height && Math.random() > 0.975) drops[i] = 0;
drops[i]++;
}
}, 33);
overlay.style.display = 'flex';
overlay.classList.add('crt-flash');
let tradesCopy = shuffle([...allTrades]).slice(0, 8);
tradesCopy.unshift("WEALTH ENGINE TERMINAL v2.0 — CLASSIFIED\n");
let currentLine = 0;
let currentChar = 0;
function appendLine(text, cssClass = '') {
const lineDiv = document.createElement('div');
lineDiv.className = 'crt-text-line ' + cssClass;
lineDiv.innerHTML = text;
content.appendChild(lineDiv);
contentContainer.scrollTop = contentContainer.scrollHeight;
return lineDiv;
}
let glitchTimer;
function triggerGlitch() {
curve.classList.add('crt-glitch');
setTimeout(() => {
curve.classList.remove('crt-glitch');
}, 200 + Math.random() * 300);
}
function typeChar() {
if (currentLine >= tradesCopy.length) {
setTimeout(() => {
initInteractivePrompt();
}, 400);
return;
}
const text = tradesCopy[currentLine];
if (currentChar === 0) {
const lineDiv = document.createElement('div');
lineDiv.className = 'crt-text-line';
lineDiv.id = 'crt-line-' + currentLine;
content.appendChild(lineDiv);
if (Math.random() < 0.15) triggerGlitch();
}
const lineEl = document.getElementById('crt-line-' + currentLine);
if (currentChar < text.length) {
lineEl.textContent += text[currentChar];
currentChar++;
playKeyClick();
contentContainer.scrollTop = contentContainer.scrollHeight;
setTimeout(typeChar, 10 + Math.random() * 30);
} else {
currentLine++;
currentChar = 0;
setTimeout(typeChar, 200);
}
}
setTimeout(() => {
overlay.classList.remove('crt-flash');
typeChar();
}, 800);
function initInteractivePrompt() {
const promptLine = document.createElement('div');
promptLine.className = 'crt-prompt-line';
const promptLabel = document.createElement('span');
promptLabel.className = 'crt-prompt';
promptLabel.textContent = 'WEALTH_ENGINE>';
const inputEl = document.createElement('input');
inputEl.type = 'text';
inputEl.className = 'crt-input';
inputEl.spellcheck = false;
promptLine.appendChild(promptLabel);
promptLine.appendChild(inputEl);
content.appendChild(promptLine);
inputEl.focus();
contentContainer.scrollTop = contentContainer.scrollHeight;
inputEl.addEventListener('keydown', function(e) {
initAudio();
playKeyClick();
if (e.key === 'Enter') {
const cmd = this.value.trim().toLowerCase();
const rawCmd = this.value;
this.disabled = true;
this.parentElement.innerHTML = 'WEALTH_ENGINE>' + rawCmd + '';
processCommand(cmd);
}
});
document.addEventListener('click', () => {
if(document.contains(inputEl)) inputEl.focus();
});
}
let pnlInterval;
function processCommand(cmd) {
if (cmd === '') {
initInteractivePrompt();
return;
}
if (cmd.startsWith('decrypt ')) {
const key = cmd.split(' ')[1].toUpperCase();
if (key === (window.MASTER_KEY || "7F4B29A1E8C6")) {
appendLine("[SYSTEM] ACCESS GRANTED. VAULT UNLOCKED.", "highlight");
if (typeof triggerGlitch === 'function') triggerGlitch();
const overlay = document.querySelector('.crt-overlay');
if (overlay) overlay.style.backgroundColor = "rgba(0, 255, 0, 0.1)";
setTimeout(() => {
if (overlay) overlay.style.backgroundColor = "";
if (window.WealthEngineEggs) window.WealthEngineEggs.unlockVault();
executeExit();
setTimeout(() => { if (window.switchView) window.switchView('view-innercircle'); if (typeof renderInnerCircle === 'function') renderInnerCircle(); }, 1000);
}, 2000);
} else {
appendLine("[SYSTEM] ACCESS DENIED. INVALID HASH SEQUENCE.", "highlight");
}
setTimeout(initInteractivePrompt, 500);
return;
}
switch(cmd) {
case 'help':
appendLine("Available commands:");
appendLine(" help - Show this message");
appendLine(" whoami - Display current user context");
appendLine(" trades - Show legendary trade log");
appendLine(" fortune - Wisdom from the masters");
appendLine(" status - Live PnL monitor");
appendLine(" hack - Establish uplink to The Fed");
appendLine(" clear - Clear terminal screen");
appendLine(" exit - Disconnect from terminal");
appendLine(" decrypt - Unlock restricted sectors");
initInteractivePrompt();
break;
case 'whoami':
appendLine("Rogue Quant. Access Level: CLASSIFIED.", "highlight");
initInteractivePrompt();
break;
case 'trades':
tradesCopy.forEach(t => appendLine(t));
initInteractivePrompt();
break;
case 'fortune':
const q = quotes[Math.floor(Math.random() * quotes.length)];
appendLine('"' + q + '"', "highlight");
initInteractivePrompt();
break;
case 'status':
appendLine("Connecting to portfolio stream...");
const pnlLine = appendLine("PnL: $0.00");
let pnl = 0;
if(pnlInterval) clearInterval(pnlInterval);
pnlInterval = setInterval(() => {
pnl += (Math.random() * 1000) - 400;
if(document.contains(pnlLine)) {
pnlLine.innerHTML = "PnL: $" + pnl.toFixed(2) + "";
} else {
clearInterval(pnlInterval);
}
}, 500);
setTimeout(() => {
appendLine("Stream detached.");
clearInterval(pnlInterval);
initInteractivePrompt();
}, 5000);
break;
case 'hack':
appendLine("Initiating bypass sequence...");
const progressLine = document.createElement('div');
progressLine.className = 'crt-text-line';
progressLine.innerHTML = `Exploiting JPow API: `;
content.appendChild(progressLine);
const fill = progressLine.querySelector('.crt-progress-fill');
let w = 0;
const hackInt = setInterval(() => {
w += Math.random() * 15;
if (w > 100) w = 100;
fill.style.width = w + '%';
playKeyClick();
if (w >= 100) {
clearInterval(hackInt);
setTimeout(() => {
appendLine("ACCESS GRANTED. MONEY PRINTER GO BRRRRR.", "highlight");
triggerGlitch();
initInteractivePrompt();
}, 500);
}
}, 200);
break;
case 'clear':
content.innerHTML = '';
initInteractivePrompt();
break;
case 'exit':
executeExit();
break;
default:
appendLine(`Command not found: ${cmd}. Type 'help' for available commands.`);
initInteractivePrompt();
}
}
const escHandler = (e) => {
if (e.key === 'Escape') {
document.removeEventListener('keydown', escHandler);
executeExit();
}
};
document.addEventListener('keydown', escHandler);
function executeExit() {
if (pnlInterval) clearInterval(pnlInterval);
clearInterval(matrixInterval);
content.innerHTML = '';
canvas.style.opacity = '0';
appendLine("
");
const artLine = appendLine(asciiArt, "highlight");
artLine.style.textAlign = "center";
artLine.style.width = "100%";
setTimeout(() => {
powerOff();
}, 5000);
}
function powerOff() {
if (window.terminalHum) {
window.terminalHum.gain.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 0.5);
setTimeout(() => window.terminalHum.osc.stop(), 500);
}
playTone(800, 'sawtooth', 0.6, 0.2);
overlay.classList.add('crt-poweroff');
setTimeout(() => {
overlay.remove();
window.safeSessionSet('terminal_unlocked', 'true');
const logoTexts = document.querySelectorAll('.logo-text');
logoTexts.forEach(el => {
if (!el.parentNode.querySelector('.crt-badge')) {
const badge = document.createElement('span');
badge.className = 'crt-badge';
badge.textContent = '🎮';
el.parentNode.appendChild(badge);
}
});
}, 600);
}
}
})();
/* ==========================================================================
EASTER EGG SYSTEM (PHASES 1-4)
========================================================================== */
const MASTER_KEY = "7F4B29A1E8C6";
const FRAGMENTS = {
'terminal': { char: '7', pos: 1 },
'secret_message': { char: 'F', pos: 2 },
'shiller_pe': { char: '4', pos: 3 },
'black_swan': { char: 'B', pos: 4 },
'random_walk': { char: '2', pos: 5 },
'fibonacci': { char: '9', pos: 6 },
'dow_theory': { char: 'A', pos: 7 },
'quote_day': { char: '1', pos: 8 },
'phantom_chart': { char: 'E', pos: 9 },
'oracle': { char: '8', pos: 10 },
'architect': { char: 'C', pos: 11 },
'the_map': { char: '6', pos: 12 }
};