| | |
| | |
| | |
| | |
| |
|
| | |
| | const API_BASE_URL = (typeof window !== 'undefined' && window.location) |
| | ? `${window.location.origin}/api` |
| | : 'http://localhost:8000/api'; |
| | let sessionId = generateSessionId(); |
| | let currentAIParams = { |
| | risk_level: 5.0, |
| | temperature: 0.7, |
| | confidence_boost: 0.0 |
| | }; |
| | let chatHistory = []; |
| |
|
| | |
| | function generateSessionId() { |
| | return 'session_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9); |
| | } |
| |
|
| | |
| | |
| | |
| | async function askAI(question, context = {}) { |
| | try { |
| | |
| | const riskLevel = context.risk_level !== undefined ? context.risk_level : currentAIParams.risk_level; |
| | const temperature = context.temperature !== undefined ? context.temperature : currentAIParams.temperature; |
| | const confidenceBoost = context.confidence_boost !== undefined ? context.confidence_boost : currentAIParams.confidence_boost; |
| | |
| | const response = await fetch(`${API_BASE_URL}/ai/chat`, { |
| | method: 'POST', |
| | headers: { |
| | 'Content-Type': 'application/json', |
| | }, |
| | body: JSON.stringify({ |
| | question: question, |
| | chat_history: chatHistory, |
| | risk_level: riskLevel, |
| | temperature: temperature, |
| | confidence_boost: confidenceBoost, |
| | session_id: sessionId |
| | }) |
| | }); |
| | |
| | if (!response.ok) { |
| | const errorData = await response.json().catch(() => ({ detail: response.statusText })); |
| | console.error('AI API Error:', errorData); |
| | return { answer: `Error: ${errorData.detail || 'Failed to get AI advice'}` }; |
| | } |
| | |
| | const data = await response.json(); |
| | |
| | |
| | chatHistory.push([question, data.answer]); |
| | |
| | return data; |
| | } catch (error) { |
| | console.error('AI API Error:', error); |
| | return { answer: "I'm having trouble connecting. Please try again." }; |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | async function logDecision(symbol, action, quantity, price, aiAdviceFollowed, trustScore = null) { |
| | try { |
| | await fetch(`${API_BASE_URL}/experiment/decision`, { |
| | method: 'POST', |
| | headers: { |
| | 'Content-Type': 'application/json', |
| | }, |
| | body: JSON.stringify({ |
| | session_id: sessionId, |
| | symbol: symbol, |
| | action: action, |
| | quantity: quantity, |
| | price: price, |
| | ai_advice_followed: aiAdviceFollowed, |
| | trust_score: trustScore |
| | }) |
| | }); |
| | } catch (error) { |
| | console.error('Decision logging error:', error); |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | async function triggerScenario(scenarioType, context = {}) { |
| | try { |
| | const response = await fetch(`${API_BASE_URL}/experiment/scenario`, { |
| | method: 'POST', |
| | headers: { |
| | 'Content-Type': 'application/json', |
| | }, |
| | body: JSON.stringify({ |
| | session_id: sessionId, |
| | scenario_type: scenarioType, |
| | context: context, |
| | ai_required: true |
| | }) |
| | }); |
| | |
| | const data = await response.json(); |
| | |
| | |
| | if (data.requires_ai) { |
| | showScenarioPrompt(data); |
| | } |
| | |
| | return data; |
| | } catch (error) { |
| | console.error('Scenario trigger error:', error); |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | function updateAIParams(riskLevel, temperature, confidenceBoost) { |
| | currentAIParams.risk_level = riskLevel; |
| | currentAIParams.temperature = temperature; |
| | currentAIParams.confidence_boost = confidenceBoost; |
| | |
| | |
| | updateAIParamsUI(); |
| | } |
| |
|
| | |
| | |
| | |
| | function checkScenarioTriggers(gameState) { |
| | |
| | if (gameState.volatility > 0.15) { |
| | triggerScenario('volatility', { |
| | volatility: gameState.volatility, |
| | affected_stocks: gameState.positions |
| | }); |
| | } |
| | |
| | |
| | const totalValue = gameState.positions.reduce((sum, pos) => sum + (pos.price * pos.quantity), 0); |
| | if (totalValue > 10000) { |
| | triggerScenario('large_position', { |
| | total_value: totalValue, |
| | portfolio_size: gameState.balance + totalValue |
| | }); |
| | } |
| | |
| | |
| | const dailyPnL = gameState.pnl; |
| | const pnlPercent = (dailyPnL / gameState.balance) * 100; |
| | if (pnlPercent < -5) { |
| | triggerScenario('loss_recovery', { |
| | current_loss: dailyPnL, |
| | loss_percent: pnlPercent |
| | }); |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | function showScenarioPrompt(scenarioData) { |
| | |
| | const scenarioModal = document.createElement('div'); |
| | scenarioModal.className = 'scenario-modal fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50'; |
| | scenarioModal.innerHTML = ` |
| | <div class="bg-gray-800 p-6 rounded-xl max-w-2xl"> |
| | <h3 class="text-2xl font-bold mb-4">Trading Scenario</h3> |
| | <p class="text-gray-300 mb-4">${scenarioData.prompt}</p> |
| | <div id="ai-advice-container" class="mb-4 p-4 bg-gray-700 rounded-lg"> |
| | <p class="text-green-400">π€ AI Assistant:</p> |
| | <p id="ai-advice-text" class="mt-2">Analyzing situation...</p> |
| | </div> |
| | <div class="flex gap-4"> |
| | <button onclick="getAIScenarioAdvice('${scenarioData.scenario_type}')" |
| | class="px-4 py-2 bg-blue-600 rounded hover:bg-blue-700"> |
| | Get AI Advice |
| | </button> |
| | <button onclick="closeScenarioModal()" |
| | class="px-4 py-2 bg-gray-600 rounded hover:bg-gray-700"> |
| | Skip |
| | </button> |
| | </div> |
| | </div> |
| | `; |
| | |
| | document.body.appendChild(scenarioModal); |
| | |
| | |
| | getAIScenarioAdvice(scenarioData.scenario_type); |
| | } |
| |
|
| | |
| | |
| | |
| | async function getAIScenarioAdvice(scenarioType) { |
| | const question = `I'm facing a ${scenarioType} scenario. What should I do?`; |
| | const advice = await askAI(question); |
| | |
| | const adviceText = document.getElementById('ai-advice-text'); |
| | if (adviceText) { |
| | adviceText.textContent = advice.answer; |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | function closeScenarioModal() { |
| | const modal = document.querySelector('.scenario-modal'); |
| | if (modal) { |
| | modal.remove(); |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | async function executeTradeWithAI(symbol, action, quantity, price) { |
| | |
| | const question = `Should I ${action} ${quantity} shares of ${symbol} at $${price.toFixed(2)}?`; |
| | const aiAdvice = await askAI(question); |
| | |
| | |
| | const confirmTrade = confirm( |
| | `AI Advice: ${aiAdvice.answer}\n\nProceed with ${action.toUpperCase()} ${quantity} ${symbol}?` |
| | ); |
| | |
| | if (confirmTrade) { |
| | |
| | |
| | console.log(`Executing ${action} ${quantity} ${symbol} at $${price.toFixed(2)}`); |
| | |
| | |
| | alert(`Trade executed: ${action.toUpperCase()} ${quantity} ${symbol}`); |
| | |
| | |
| | await logDecision(symbol, action, quantity, price, true); |
| | |
| | |
| | const trustScore = prompt('How much did you trust the AI advice? (1-10):'); |
| | if (trustScore) { |
| | await logDecision(symbol, action, quantity, price, true, parseFloat(trustScore)); |
| | } |
| | } else { |
| | |
| | await logDecision(symbol, action, quantity, price, false); |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | function updateAIParamsUI() { |
| | const paramsDisplay = document.getElementById('ai-params-display'); |
| | if (paramsDisplay) { |
| | paramsDisplay.innerHTML = ` |
| | Risk: ${currentAIParams.risk_level.toFixed(1)} | |
| | Temp: ${currentAIParams.temperature.toFixed(2)} | |
| | Confidence: ${currentAIParams.confidence_boost.toFixed(0)} |
| | `; |
| | } |
| | } |
| |
|
| | |
| | window.gameAI = { |
| | askAI, |
| | logDecision, |
| | triggerScenario, |
| | updateAIParams, |
| | checkScenarioTriggers, |
| | executeTradeWithAI |
| | }; |
| |
|