// === ГЛОБАЛЬНЫЕ ДАННЫЕ === let currentPair = 'EURUSD'; let currentTimeframe = '15'; let tradingWidget = null; // === НОВОСТИ (учебные данные) === const newsData = [ { id: 1, title: 'Решение по процентной ставке ФРС (США)', impact: 'high', currency: 'USD', time: '14:00', actual: '', forecast: '5.50%', previous: '5.50%' }, { id: 2, title: 'Инфляция CPI (Еврозона)', impact: 'high', currency: 'EUR', time: '12:00', actual: '2.4%', forecast: '2.3%', previous: '2.6%' }, { id: 3, title: 'ВВП Великобритании (квартал)', impact: 'high', currency: 'GBP', time: '09:30', actual: '0.2%', forecast: '0.2%', previous: '0.1%' }, { id: 4, title: 'Запасы сырой нефти (США)', impact: 'medium', currency: 'USD', time: '17:30', actual: '-2.5M', forecast: '-1.0M', previous: '+1.2M' }, { id: 5, title: 'Индекс потребительских настроений (США)', impact: 'medium', currency: 'USD', time: '16:00', actual: '69.5', forecast: '68.0', previous: '67.9' }, { id: 6, title: 'Розничные продажи (Япония)', impact: 'low', currency: 'JPY', time: '08:30', actual: '1.8%', forecast: '1.5%', previous: '1.2%' }, { id: 7, title: 'Индекс деловой активности PMI (Германия)', impact: 'medium', currency: 'EUR', time: '11:00', actual: '47.5', forecast: '48.0', previous: '47.8' }, { id: 8, title: 'Заявки на пособие по безработице (США)', impact: 'medium', currency: 'USD', time: '15:30', actual: '220K', forecast: '215K', previous: '218K' }, { id: 9, title: 'Баланс торгового счёта (Китай)', impact: 'high', currency: 'CNY', time: '05:00', actual: '+75.0B', forecast: '+70.0B', previous: '+68.5B' }, { id: 10, title: 'Индекс цен на недвижимость (Швейцария)', impact: 'low', currency: 'CHF', time: '10:00', actual: '0.3%', forecast: '0.2%', previous: '0.1%' } ]; // === СИГНАЛЫ (учебные) === const signalsData = [ { pair: 'EUR/USD', direction: 'buy', entry: 1.0850, sl: 1.0830, tp: 1.0890, rsi: 35, ma: 'Bullish', time: '10:45' }, { pair: 'GBP/USD', direction: 'sell', entry: 1.2680, sl: 1.2710, tp: 1.2620, rsi: 68, ma: 'Bearish', time: '10:30' }, { pair: 'USD/JPY', direction: 'hold', entry: 149.50, sl: 149.20, tp: 150.10, rsi: 52, ma: 'Neutral', time: '10:15' }, { pair: 'XAU/USD', direction: 'buy', entry: 2035.00, sl: 2025.00, tp: 2055.00, rsi: 42, ma: 'Bullish', time: '09:50' }, { pair: 'BTC/USD', direction: 'sell', entry: 42500, sl: 43200, tp: 41100, rsi: 72, ma: 'Bearish', time: '09:20' } ]; // === ИНИЦИАЛИЗАЦИЯ === document.addEventListener('DOMContentLoaded', () => { initTabs(); initCharts(); initCalculator(); initNews(); initSignals(); }); // === ВКЛАДКИ === function initTabs() { const tabs = document.querySelectorAll('.tab'); const contents = document.querySelectorAll('.tab-content'); tabs.forEach(tab => { tab.addEventListener('click', () => { const target = tab.dataset.tab; tabs.forEach(t => t.classList.remove('active')); contents.forEach(c => c.classList.remove('active')); tab.classList.add('active'); document.getElementById(target).classList.add('active'); // Перерисовать график если перешли на вкладку if (target === 'charts' && tradingWidget) { loadWidget(currentPair, currentTimeframe); } }); }); } // === ГРАФИКИ (TradingView) === function initCharts() { const pairBtns = document.querySelectorAll('.pair-btn'); const tfBtns = document.querySelectorAll('.tf-btn'); // Загрузить первый график loadWidget('EURUSD', '15'); pairBtns.forEach(btn => { btn.addEventListener('click', () => { pairBtns.forEach(b => b.classList.remove('active')); btn.classList.add('active'); currentPair = btn.dataset.pair; loadWidget(currentPair, currentTimeframe); }); }); tfBtns.forEach(btn => { btn.addEventListener('click', () => { tfBtns.forEach(b => b.classList.remove('active')); btn.classList.add('active'); currentTimeframe = btn.dataset.tf; loadWidget(currentPair, currentTimeframe); }); }); } function loadWidget(pair, timeframe) { const container = document.getElementById('tradingview-widget'); container.innerHTML = ''; const intervalMap = { '1': '1', '5': '5', '15': '15', '60': '60', 'D': 'D' }; const symbolMap = { 'EURUSD': 'FX:EURUSD', 'GBPUSD': 'FX:GBPUSD', 'USDJPY': 'FX:USDJPY', 'XAUUSD': 'OANDA:XAUUSD', 'BTCUSD': 'COINBASE:BTCUSD' }; tradingWidget = new TradingView.widget({ width: '100%', height: 500, symbol: symbolMap[pair] || 'FX:EURUSD', interval: intervalMap[timeframe] || '15', timezone: 'Asia/Almaty', theme: 'dark', style: '1', locale: 'ru', toolbar_bg: '#f1f3f6', enable_publishing: false, allow_symbol_change: true, container_id: 'tradingview-widget', hide_side_toolbar: false, details: true, hotlist: true, calendar: true, withdateranges: true, range: '1D' }); } // === КАЛЬКУЛЯТОР === function initCalculator() { const calcBtn = document.getElementById('calculate-btn'); calcBtn.addEventListener('click', calculateRisk); } function calculateRisk() { const deposit = parseFloat(document.getElementById('deposit').value) || 100; const riskPercent = parseFloat(document.getElementById('risk-percent').value) || 2; const pair = document.getElementById('pair-select').value; const entryPrice = parseFloat(document.getElementById('entry-price').value); const stopLoss = parseFloat(document.getElementById('stop-loss').value); // Риск в долларах const riskAmount = deposit * (riskPercent / 100); document.getElementById('risk-amount').textContent = '$' + riskAmount.toFixed(2); // Расчёт лота (упрощённо для стандарта) let pipValue = 10; // Стандартный лот для EUR/USD if (pair === 'USDJPY') pipValue = 6.7; if (pair === 'XAUUSD') pipValue = 100; if (pair === 'BTCUSD') pipValue = 1; const lotSize = stopLoss > 0 ? (riskAmount / (stopLoss * pipValue)).toFixed(2) : '0.01'; document.getElementById('lot-size').textContent = lotSize; // Тейк-профит 1:2 const tp = stopLoss * 2; document.getElementById('take-profit').textContent = '+' + tp + ' пунктов'; // Прибыль const profit = riskAmount * 2; const profitEl = document.getElementById('profit-amount'); profitEl.textContent = '+$' + profit.toFixed(2); profitEl.className = 'result-value profit'; // Соотношение document.getElementById('rr-ratio').textContent = '1:2'; } // === НОВОСТИ === function initNews() { const filters = document.querySelectorAll('.news-filter'); renderNews('all'); filters.forEach(filter => { filter.addEventListener('click', () => { filters.forEach(f => f.classList.remove('active')); filter.classList.add('active'); renderNews(filter.dataset.impact); }); }); } function renderNews(filter) { const container = document.getElementById('news-list'); const filtered = filter === 'all' ? newsData : newsData.filter(n => n.impact === filter); container.innerHTML = filtered.map(news => `
${news.impact === 'high' ? '🔴' : news.impact === 'medium' ? '🟡' : '🟢'}
${news.title}
${news.currency} • ${news.time} • Факт: ${news.actual || '—'} • Прогноз: ${news.forecast} • Пред: ${news.previous}
`).join(''); } // === СИГНАЛЫ === function initSignals() { renderSignals(); } function renderSignals() { const tbody = document.getElementById('signals-body'); tbody.innerHTML = signalsData.map(signal => ` ${signal.pair} ${getDirectionBadge(signal.direction)} ${signal.entry} ${signal.sl} ${signal.tp} ${getRSIColor(signal.rsi)} ${getMABadge(signal.ma)} ${signal.time} `).join(''); } function getDirectionBadge(dir) { const map = { 'buy': '📈 Покупка', 'sell': '📉 Продажа', 'hold': '⏸️ Флэт' }; return map[dir] || dir; } function getRSIColor(rsi) { let color = 'var(--text-primary)'; if (rsi < 30) color = 'var(--accent-green)'; if (rsi > 70) color = 'var(--accent-red)'; return `${rsi}`; } function getMABadge(ma) { const map = { 'Bullish': '▲ Бычий', 'Bearish': '▼ Медвежий', 'Neutral': '▬ Флэт' }; return map[ma] || ma; }