| | <!DOCTYPE html> |
| | <html lang="en"> |
| | <head> |
| | <meta charset="UTF-8"> |
| | <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| | <title>Trading Game - Proof of Concept</title> |
| | <script src="https://cdn.tailwindcss.com"></script> |
| | <style> |
| | body { font-family: 'Inter', sans-serif; } |
| | </style> |
| | </head> |
| | <body class="bg-gray-900 text-white min-h-screen"> |
| | <main class="container mx-auto px-4 py-8 max-w-7xl"> |
| | <h1 class="text-4xl font-bold mb-8 text-center bg-gradient-to-r from-green-400 to-blue-500 bg-clip-text text-transparent"> |
| | Trading Game - Proof of Concept |
| | </h1> |
| |
|
| | |
| | <div id="scenario-section" class="bg-gradient-to-r from-red-900 to-orange-900 p-6 rounded-xl mb-6 border-2 border-orange-500"> |
| | <h2 class="text-2xl font-bold mb-3 text-yellow-300">β οΈ Current Market Scenario</h2> |
| | <div id="scenario-text" class="text-lg mb-4"> |
| | A typhoon is seen off the coast of New Gregoria, likely impacting the Galvanium Supply Chain. |
| | This may affect logistics companies (NLN) and energy sectors (VCG). |
| | </div> |
| | <button id="next-scenario-button" class="px-4 py-2 bg-orange-600 rounded hover:bg-orange-700 text-sm"> |
| | Next Scenario |
| | </button> |
| | </div> |
| |
|
| | |
| | <div class="grid lg:grid-cols-2 gap-6"> |
| | |
| | |
| | <div class="space-y-6"> |
| | |
| | <div class="bg-gray-800 p-6 rounded-xl"> |
| | <h2 class="text-2xl font-bold mb-4 text-blue-400">π€ AI Advisor Settings</h2> |
| | <div class="space-y-4"> |
| | <div> |
| | <label class="block text-gray-400 mb-2"> |
| | Risk Tolerance: <span id="risk-value" class="text-white font-bold">5.0</span> / 10 |
| | </label> |
| | <input type="range" id="risk-slider" min="0" max="10" step="0.5" value="5.0" |
| | class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer"> |
| | <div class="flex justify-between text-xs text-gray-500 mt-1"> |
| | <span>Conservative</span> |
| | <span>Moderate</span> |
| | <span>Aggressive</span> |
| | </div> |
| | </div> |
| | <div> |
| | <label class="block text-gray-400 mb-2"> |
| | AI Creativity: <span id="temperature-value" class="text-white font-bold">0.7</span> |
| | </label> |
| | <input type="range" id="temperature-slider" min="0" max="2" step="0.1" value="0.7" |
| | class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer"> |
| | <div class="flex justify-between text-xs text-gray-500 mt-1"> |
| | <span>Deterministic</span> |
| | <span>Balanced</span> |
| | <span>Creative</span> |
| | </div> |
| | </div> |
| | <div> |
| | <label class="block text-gray-400 mb-2"> |
| | Confidence Level: <span id="confidence-value" class="text-white font-bold">0</span> |
| | </label> |
| | <input type="range" id="confidence-slider" min="-100" max="100" step="10" value="0" |
| | class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer"> |
| | <div class="flex justify-between text-xs text-gray-500 mt-1"> |
| | <span>Cautious (-100)</span> |
| | <span>Neutral (0)</span> |
| | <span>Very Confident (+100)</span> |
| | </div> |
| | </div> |
| | </div> |
| | </div> |
| |
|
| | |
| | <div id="ai-advice-section" class="bg-gray-800 p-6 rounded-xl flex flex-col" style="height: 600px;"> |
| | <h2 class="text-2xl font-bold mb-4 text-green-400">π€ AI Trading Advisor</h2> |
| | |
| | |
| | <div id="chat-messages" class="flex-1 bg-gray-900 rounded-lg p-4 mb-4 overflow-y-auto space-y-3"> |
| | <div class="flex justify-start"> |
| | <div class="bg-blue-600 text-white rounded-lg p-3 max-w-[80%]"> |
| | <p class="text-sm font-semibold mb-1">AI Assistant</p> |
| | <p class="text-sm">Welcome! I'm your AI trading advisor. I can help you with trading decisions, market analysis, and portfolio advice. Ask me anything or try one of the suggested questions below!</p> |
| | </div> |
| | </div> |
| | </div> |
| |
|
| | |
| | <div id="query-suggestions" class="mb-3 flex flex-wrap gap-2"> |
| | <button class="query-suggestion-btn px-3 py-1.5 bg-gray-700 text-gray-300 rounded-lg text-sm hover:bg-gray-600" |
| | onclick="sendQuickQuery('What are the best stocks to trade right now?')"> |
| | π Best stocks now? |
| | </button> |
| | <button class="query-suggestion-btn px-3 py-1.5 bg-gray-700 text-gray-300 rounded-lg text-sm hover:bg-gray-600" |
| | onclick="sendQuickQuery('Explain the current market scenario')"> |
| | π Market scenario |
| | </button> |
| | <button class="query-suggestion-btn px-3 py-1.5 bg-gray-700 text-gray-300 rounded-lg text-sm hover:bg-gray-600" |
| | onclick="sendQuickQuery('What is my risk profile?')"> |
| | βοΈ My risk profile |
| | </button> |
| | <button class="query-suggestion-btn px-3 py-1.5 bg-gray-700 text-gray-300 rounded-lg text-sm hover:bg-gray-600" |
| | onclick="const sym = document.getElementById('trade-symbol').value; sendQuickQuery(`Should I buy ${sym}?`)"> |
| | π° Trade advice |
| | </button> |
| | </div> |
| |
|
| | |
| | <div class="flex gap-2"> |
| | <input type="text" id="chat-input" placeholder="Ask me anything about trading..." |
| | class="flex-1 bg-gray-700 text-white rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" |
| | onkeypress="if(event.key === 'Enter') sendChatMessage()"> |
| | <button id="send-chat-button" onclick="sendChatMessage()" |
| | class="px-6 py-2 bg-blue-600 rounded-lg font-bold hover:bg-blue-700"> |
| | Send |
| | </button> |
| | </div> |
| |
|
| | |
| | <div id="ai-actions" class="flex gap-2 mt-3" style="display: none;"> |
| | <button id="follow-advice-button" class="flex-1 py-2 bg-green-600 rounded hover:bg-green-700 text-sm font-semibold"> |
| | β
Follow Advice |
| | </button> |
| | <button id="ignore-advice-button" class="flex-1 py-2 bg-gray-600 rounded hover:bg-gray-700 text-sm"> |
| | Ignore & Trade |
| | </button> |
| | <button id="clear-chat-button" class="px-3 py-2 bg-red-600 rounded hover:bg-red-700 text-sm"> |
| | Clear |
| | </button> |
| | </div> |
| | </div> |
| | </div> |
| |
|
| | |
| | <div class="space-y-6"> |
| | |
| | <div class="bg-gray-800 p-6 rounded-xl"> |
| | <h2 class="text-2xl font-bold mb-4">Portfolio</h2> |
| | <div class="grid grid-cols-2 gap-4"> |
| | <div> |
| | <p class="text-gray-400">Balance</p> |
| | <p class="text-3xl font-bold" id="balance">$50,000.00</p> |
| | </div> |
| | <div> |
| | <p class="text-gray-400">Positions</p> |
| | <p class="text-3xl font-bold" id="positions">0</p> |
| | </div> |
| | </div> |
| | </div> |
| |
|
| | |
| | <div class="bg-gray-800 p-6 rounded-xl"> |
| | <h2 class="text-2xl font-bold mb-4">Make a Trade</h2> |
| | <div class="space-y-4 mb-4"> |
| | <div> |
| | <label class="block text-gray-400 mb-2">Symbol</label> |
| | <select id="trade-symbol" class="w-full bg-gray-700 rounded p-3 text-white"> |
| | <option>VCG</option> |
| | <option>CSI</option> |
| | <option>STDY</option> |
| | <option>AUBIO</option> |
| | <option>NLN</option> |
| | </select> |
| | </div> |
| | <div class="grid grid-cols-2 gap-4"> |
| | <div> |
| | <label class="block text-gray-400 mb-2">Quantity</label> |
| | <input id="trade-quantity" type="number" value="10" min="1" |
| | class="w-full bg-gray-700 rounded p-3 text-white"> |
| | </div> |
| | <div> |
| | <label class="block text-gray-400 mb-2">Price</label> |
| | <input id="trade-price" type="number" value="100" min="0" step="0.01" |
| | class="w-full bg-gray-700 rounded p-3 text-white" readonly> |
| | </div> |
| | </div> |
| | </div> |
| | <div class="flex gap-4"> |
| | <button id="buy-button" class="flex-1 py-3 bg-green-600 rounded-lg font-bold hover:bg-green-700"> |
| | Buy |
| | </button> |
| | <button id="sell-button" class="flex-1 py-3 bg-red-600 rounded-lg font-bold hover:bg-red-700"> |
| | Sell |
| | </button> |
| | </div> |
| | </div> |
| |
|
| | |
| | <div class="bg-gray-800 p-6 rounded-xl"> |
| | <h2 class="text-2xl font-bold mb-4">Recent Trades</h2> |
| | <div id="trade-history" class="space-y-2 max-h-[400px] overflow-y-auto"> |
| | <p class="text-gray-400 text-center">No trades yet</p> |
| | </div> |
| | </div> |
| | </div> |
| | </div> |
| | </main> |
| |
|
| | <script src="game-api-integration.js"></script> |
| | <script> |
| | |
| | let gameState = { |
| | balance: 50000, |
| | positions: [], |
| | trades: [], |
| | currentScenario: { |
| | title: "Typhoon near New Gregoria", |
| | description: "A typhoon is seen off the coast of New Gregoria, likely impacting the Galvanium Supply Chain. This may affect logistics companies (NLN) and energy sectors (VCG).", |
| | affectedSymbols: ["NLN", "VCG"] |
| | } |
| | }; |
| | |
| | |
| | const scenarios = [ |
| | { |
| | title: "Typhoon near New Gregoria", |
| | description: "A typhoon is seen off the coast of New Gregoria, likely impacting the Galvanium Supply Chain. This may affect logistics companies (NLN) and energy sectors (VCG).", |
| | affectedSymbols: ["NLN", "VCG"] |
| | }, |
| | { |
| | title: "Quantum Processor Breakthrough", |
| | description: "Veridian Capital Group (VCG) announces a major quantum computing breakthrough. This could significantly impact energy and tech sectors.", |
| | affectedSymbols: ["VCG", "CSI"] |
| | }, |
| | { |
| | title: "Asteroid Mining Success", |
| | description: "Stellar Dynamics Corp (STDY) successfully completes asteroid mining operations, securing rare earth minerals. Logistics and space commerce stocks may surge.", |
| | affectedSymbols: ["STDY", "NLN"] |
| | }, |
| | { |
| | title: "Biosynthetics Regulatory Approval", |
| | description: "Aurora Biosynthetics (AUBIO) receives approval for commercial distribution of synthetic products, opening new markets worth 200 billion credits.", |
| | affectedSymbols: ["AUBIO"] |
| | } |
| | ]; |
| | |
| | |
| | document.getElementById('risk-slider').addEventListener('input', (e) => { |
| | document.getElementById('risk-value').textContent = parseFloat(e.target.value).toFixed(1); |
| | }); |
| | |
| | document.getElementById('temperature-slider').addEventListener('input', (e) => { |
| | document.getElementById('temperature-value').textContent = parseFloat(e.target.value).toFixed(1); |
| | }); |
| | |
| | document.getElementById('confidence-slider').addEventListener('input', (e) => { |
| | document.getElementById('confidence-value').textContent = e.target.value; |
| | }); |
| | |
| | |
| | document.getElementById('trade-symbol').addEventListener('change', (e) => { |
| | const prices = { VCG: 150, CSI: 200, STDY: 100, AUBIO: 75, NLN: 120 }; |
| | document.getElementById('trade-price').value = prices[e.target.value] || 100; |
| | }); |
| | |
| | |
| | document.getElementById('trade-symbol').dispatchEvent(new Event('change')); |
| | |
| | |
| | document.getElementById('next-scenario-button').addEventListener('click', () => { |
| | const randomScenario = scenarios[Math.floor(Math.random() * scenarios.length)]; |
| | gameState.currentScenario = randomScenario; |
| | document.getElementById('scenario-text').textContent = randomScenario.description; |
| | }); |
| | |
| | let pendingTrade = null; |
| | let chatHistory = []; |
| | |
| | |
| | function addChatMessage(message, isUser = false) { |
| | const chatMessages = document.getElementById('chat-messages'); |
| | const messageDiv = document.createElement('div'); |
| | messageDiv.className = `flex ${isUser ? 'justify-end' : 'justify-start'}`; |
| | |
| | const contentDiv = document.createElement('div'); |
| | contentDiv.className = isUser |
| | ? 'bg-gray-600 text-white rounded-lg p-3 max-w-[80%]' |
| | : 'bg-blue-600 text-white rounded-lg p-3 max-w-[80%]'; |
| | |
| | if (!isUser) { |
| | const label = document.createElement('p'); |
| | label.className = 'text-sm font-semibold mb-1'; |
| | label.textContent = 'AI Assistant'; |
| | contentDiv.appendChild(label); |
| | } |
| | |
| | const text = document.createElement('p'); |
| | text.className = 'text-sm whitespace-pre-wrap'; |
| | text.textContent = message; |
| | contentDiv.appendChild(text); |
| | |
| | messageDiv.appendChild(contentDiv); |
| | chatMessages.appendChild(messageDiv); |
| | |
| | |
| | chatMessages.scrollTop = chatMessages.scrollHeight; |
| | } |
| | |
| | |
| | async function sendChatMessage() { |
| | const chatInput = document.getElementById('chat-input'); |
| | const question = chatInput.value.trim(); |
| | |
| | if (!question) return; |
| | |
| | |
| | addChatMessage(question, true); |
| | chatInput.value = ''; |
| | |
| | |
| | const thinkingDiv = document.createElement('div'); |
| | thinkingDiv.id = 'thinking-indicator'; |
| | thinkingDiv.className = 'flex justify-start'; |
| | const thinkingContent = document.createElement('div'); |
| | thinkingContent.className = 'bg-blue-600 text-white rounded-lg p-3 max-w-[80%]'; |
| | thinkingContent.innerHTML = '<p class="text-sm font-semibold mb-1">AI Assistant</p><p class="text-sm italic">Thinking...</p>'; |
| | thinkingDiv.appendChild(thinkingContent); |
| | document.getElementById('chat-messages').appendChild(thinkingDiv); |
| | document.getElementById('chat-messages').scrollTop = document.getElementById('chat-messages').scrollHeight; |
| | |
| | try { |
| | if (window.gameAI && window.gameAI.askAI) { |
| | |
| | const riskLevel = parseFloat(document.getElementById('risk-slider').value); |
| | const temperature = parseFloat(document.getElementById('temperature-slider').value); |
| | const confidence = parseFloat(document.getElementById('confidence-slider').value); |
| | |
| | |
| | const scenarioText = gameState.currentScenario.description; |
| | const enhancedQuestion = `Current Market Scenario: ${scenarioText}\n\nRisk Profile: ${riskLevel}/10\n\n${question}`; |
| | |
| | |
| | if (window.gameAI.updateAIParams) { |
| | window.gameAI.updateAIParams(riskLevel, temperature, confidence); |
| | } |
| | |
| | const response = await window.gameAI.askAI(enhancedQuestion, { |
| | risk_level: riskLevel, |
| | temperature: temperature, |
| | confidence_boost: confidence |
| | }); |
| | |
| | |
| | const thinking = document.getElementById('thinking-indicator'); |
| | if (thinking) thinking.remove(); |
| | |
| | |
| | const answer = response.answer || 'No response available.'; |
| | addChatMessage(answer, false); |
| | |
| | |
| | if (question.toLowerCase().includes('buy') || question.toLowerCase().includes('sell') || |
| | question.toLowerCase().includes('trade') || question.toLowerCase().includes('should i')) { |
| | |
| | document.getElementById('ai-actions').style.display = 'flex'; |
| | } |
| | } else { |
| | |
| | const thinking = document.getElementById('thinking-indicator'); |
| | if (thinking) thinking.remove(); |
| | |
| | addChatMessage('AI service not available. Check console for errors.', false); |
| | } |
| | } catch (error) { |
| | console.error('AI chat error:', error); |
| | const thinking = document.getElementById('thinking-indicator'); |
| | if (thinking) thinking.remove(); |
| | addChatMessage('Error getting AI response. Check console.', false); |
| | } |
| | } |
| | |
| | |
| | function sendQuickQuery(query) { |
| | const chatInput = document.getElementById('chat-input'); |
| | chatInput.value = query; |
| | sendChatMessage(); |
| | } |
| | |
| | |
| | document.getElementById('buy-button').addEventListener('click', async () => { |
| | const symbol = document.getElementById('trade-symbol').value; |
| | const quantity = parseInt(document.getElementById('trade-quantity').value); |
| | const price = parseFloat(document.getElementById('trade-price').value); |
| | const total = quantity * price; |
| | |
| | if (total > gameState.balance) { |
| | alert('Insufficient balance!'); |
| | return; |
| | } |
| | |
| | pendingTrade = { symbol, quantity, price, action: 'buy' }; |
| | await showAIAdvice(symbol, quantity, price, 'buy'); |
| | }); |
| | |
| | |
| | document.getElementById('sell-button').addEventListener('click', async () => { |
| | const symbol = document.getElementById('trade-symbol').value; |
| | const quantity = parseInt(document.getElementById('trade-quantity').value); |
| | const price = parseFloat(document.getElementById('trade-price').value); |
| | |
| | pendingTrade = { symbol, quantity, price, action: 'sell' }; |
| | await showAIAdvice(symbol, quantity, price, 'sell'); |
| | }); |
| | |
| | |
| | async function showAIAdvice(symbol, quantity, price, action) { |
| | const question = `Should I ${action} ${quantity} shares of ${symbol} at $${price.toFixed(2)}?`; |
| | |
| | |
| | addChatMessage(question, true); |
| | |
| | |
| | pendingTrade = { symbol, quantity, price, action }; |
| | |
| | |
| | const thinkingDiv = document.createElement('div'); |
| | thinkingDiv.id = 'thinking-indicator'; |
| | thinkingDiv.className = 'flex justify-start'; |
| | const thinkingContent = document.createElement('div'); |
| | thinkingContent.className = 'bg-blue-600 text-white rounded-lg p-3 max-w-[80%]'; |
| | thinkingContent.innerHTML = '<p class="text-sm font-semibold mb-1">AI Assistant</p><p class="text-sm italic">Analyzing trade...</p>'; |
| | thinkingDiv.appendChild(thinkingContent); |
| | document.getElementById('chat-messages').appendChild(thinkingDiv); |
| | document.getElementById('chat-messages').scrollTop = document.getElementById('chat-messages').scrollHeight; |
| | |
| | try { |
| | if (window.gameAI && window.gameAI.askAI) { |
| | |
| | const riskLevel = parseFloat(document.getElementById('risk-slider').value); |
| | const temperature = parseFloat(document.getElementById('temperature-slider').value); |
| | const confidence = parseFloat(document.getElementById('confidence-slider').value); |
| | |
| | |
| | const scenarioText = gameState.currentScenario.description; |
| | const enhancedQuestion = `Current Market Scenario: ${scenarioText}\n\nShould I ${action} ${quantity} shares of ${symbol} at $${price.toFixed(2)}? Consider the current scenario and provide a direct recommendation based on my risk tolerance of ${riskLevel}/10.`; |
| | |
| | |
| | if (window.gameAI.updateAIParams) { |
| | window.gameAI.updateAIParams(riskLevel, temperature, confidence); |
| | } |
| | |
| | const response = await window.gameAI.askAI(enhancedQuestion, { |
| | risk_level: riskLevel, |
| | temperature: temperature, |
| | confidence_boost: confidence |
| | }); |
| | |
| | |
| | const thinking = document.getElementById('thinking-indicator'); |
| | if (thinking) thinking.remove(); |
| | |
| | |
| | const answer = response.answer || 'No advice available'; |
| | addChatMessage(answer, false); |
| | |
| | |
| | document.getElementById('ai-actions').style.display = 'flex'; |
| | } else { |
| | const thinking = document.getElementById('thinking-indicator'); |
| | if (thinking) thinking.remove(); |
| | addChatMessage('AI service not available. Check console for errors.', false); |
| | } |
| | } catch (error) { |
| | console.error('AI advice error:', error); |
| | const thinking = document.getElementById('thinking-indicator'); |
| | if (thinking) thinking.remove(); |
| | addChatMessage('Error getting AI advice. Check console.', false); |
| | } |
| | } |
| | |
| | |
| | document.getElementById('follow-advice-button').addEventListener('click', async () => { |
| | if (!pendingTrade) return; |
| | |
| | executeTrade(pendingTrade, true); |
| | document.getElementById('ai-actions').style.display = 'none'; |
| | pendingTrade = null; |
| | }); |
| | |
| | |
| | document.getElementById('ignore-advice-button').addEventListener('click', async () => { |
| | if (!pendingTrade) return; |
| | |
| | executeTrade(pendingTrade, false); |
| | document.getElementById('ai-actions').style.display = 'none'; |
| | pendingTrade = null; |
| | }); |
| | |
| | |
| | document.getElementById('clear-chat-button').addEventListener('click', () => { |
| | const chatMessages = document.getElementById('chat-messages'); |
| | chatMessages.innerHTML = ` |
| | <div class="flex justify-start"> |
| | <div class="bg-blue-600 text-white rounded-lg p-3 max-w-[80%]"> |
| | <p class="text-sm font-semibold mb-1">AI Assistant</p> |
| | <p class="text-sm">Chat cleared. How can I help you with your trading today?</p> |
| | </div> |
| | </div> |
| | `; |
| | document.getElementById('ai-actions').style.display = 'none'; |
| | pendingTrade = null; |
| | chatHistory = []; |
| | }); |
| | |
| | |
| | function executeTrade(trade, followedAdvice) { |
| | const { symbol, quantity, price, action } = trade; |
| | const total = quantity * price; |
| | |
| | if (action === 'buy') { |
| | gameState.balance -= total; |
| | const existingPosition = gameState.positions.find(p => p.symbol === symbol); |
| | if (existingPosition) { |
| | existingPosition.quantity += quantity; |
| | } else { |
| | gameState.positions.push({ symbol, quantity, price }); |
| | } |
| | } else { |
| | gameState.balance += total; |
| | const existingPosition = gameState.positions.find(p => p.symbol === symbol); |
| | if (existingPosition) { |
| | existingPosition.quantity -= quantity; |
| | if (existingPosition.quantity <= 0) { |
| | gameState.positions = gameState.positions.filter(p => p.symbol !== symbol); |
| | } |
| | } |
| | } |
| | |
| | |
| | gameState.trades.unshift({ |
| | timestamp: new Date().toLocaleTimeString(), |
| | symbol, |
| | action, |
| | quantity, |
| | price: price.toFixed(2), |
| | total: total.toFixed(2), |
| | followedAdvice |
| | }); |
| | |
| | |
| | updateUI(); |
| | |
| | |
| | if (window.gameAI && window.gameAI.logDecision) { |
| | window.gameAI.logDecision(symbol, action, quantity, price, followedAdvice); |
| | } |
| | |
| | |
| | const trustScore = prompt('How much did you trust the AI advice? (1-10):'); |
| | if (trustScore && window.gameAI && window.gameAI.logDecision) { |
| | window.gameAI.logDecision(symbol, action, quantity, price, followedAdvice, parseFloat(trustScore)); |
| | } |
| | } |
| | |
| | |
| | function updateUI() { |
| | document.getElementById('balance').textContent = '$' + gameState.balance.toFixed(2); |
| | document.getElementById('positions').textContent = gameState.positions.length; |
| | |
| | const tradeHistory = document.getElementById('trade-history'); |
| | if (gameState.trades.length === 0) { |
| | tradeHistory.innerHTML = '<p class="text-gray-400 text-center">No trades yet</p>'; |
| | } else { |
| | tradeHistory.innerHTML = gameState.trades.map(trade => ` |
| | <div class="bg-gray-700 p-3 rounded flex justify-between items-center"> |
| | <div> |
| | <span class="font-bold ${trade.action === 'buy' ? 'text-green-400' : 'text-red-400'}"> |
| | ${trade.action.toUpperCase()} |
| | </span> |
| | ${trade.quantity} ${trade.symbol} @ $${trade.price} |
| | ${trade.followedAdvice ? 'β
(Followed AI)' : 'β (Ignored AI)'} |
| | </div> |
| | <div class="text-right"> |
| | <p class="font-bold">$${trade.total}</p> |
| | <p class="text-sm text-gray-400">${trade.timestamp}</p> |
| | </div> |
| | </div> |
| | `).join(''); |
| | } |
| | } |
| | </script> |
| | </body> |
| | </html> |
| |
|