const { Bot } = require("grammy"); // Токен из .env (не хардкодить!) const bot = new Bot(process.env.BOT_TOKEN || "7891234567:AAF_z8kN3xQ5vR9mP2wL7tY4uH6jK1sD0cB"); // === БАЗА ДАННЫХ ПОЛЬЗОВАТЕЛЕЙ === let users = new Set(); // === СИГНАЛЫ И НОВОСТИ === const signals = [ { pair: 'EUR/USD', dir: '📈', type: 'Покупка', entry: 1.0850, sl: 1.0830, tp: 1.0890, time: '10:45' }, { pair: 'GBP/USD', dir: '📉', type: 'Продажа', entry: 1.2680, sl: 1.2710, tp: 1.2620, time: '10:30' }, { pair: 'XAU/USD', dir: '📈', type: 'Покупка', entry: 2035, sl: 2025, tp: 2055, time: '09:50' }, { pair: 'BTC/USD', dir: '📉', type: 'Продажа', entry: 42500, sl: 43200, tp: 41100, time: '09:20' } ]; const news = [ { title: '🔴 Решение по ставке ФРС (США)', time: '14:00', impact: 'Важно' }, { title: '🔴 Инфляция CPI (Еврозона)', time: '12:00', impact: 'Важно' }, { title: '🟡 ВВП Великобритании', time: '09:30', impact: 'Средне' }, { title: '🟢 Розничные продажи (Япония)', time: '08:30', impact: 'Слабо' } ]; const candles = [ { name: '🔨 Молот (Hammer)', type: 'Бычий разворот', desc: 'Появляется после нисходящего тренда. Длинная нижняя тень.' }, { name: '☄️ Падающая звезда', type: 'Медвежий разворот', desc: 'Длинная верхняя тень, отскок от сопротивления.' }, { name: '📈 Бычье поглощение', type: 'Бычий разворот', desc: 'Зелёная свеча перекрывает предыдущую красную.' }, { name: '📉 Медвежье поглощение', type: 'Медвежий разворот', desc: 'Красная свеча перекрывает предыдущую зелёную.' }, { name: '➕ Доджи (Doji)', type: 'Неопределённость', desc: 'Цена открытия = цена закрытия.' }, { name: '🌅 Утренняя звезда', type: 'Бычий разворот', desc: '3 свечи: красная, маленькая, зелёная.' }, { name: '🌆 Вечерняя звезда', type: 'Медвежий разворот', desc: '3 свечи: зелёная, маленькая, красная.' } ]; // === КОМАНДЫ === bot.command("start", async (ctx) => { users.add(ctx.from.id); await ctx.reply( `👋 Привет, ${ctx.from.first_name}! 📊 *Forex Assistant Bot* — твой помощник в торговле 💰 Стартовый капитал: $100 📈 Графики, сигналы, новости, свечи *Команды:* /signals — текущие сигналы /news — важные новости /candles — справочник свечей /risk — калькулятор риска /help — помощь ⚠️ Это обучающий бот. Реальные деньги — только через брокера.`, { parse_mode: "Markdown" } ); }); bot.command("help", async (ctx) => { await ctx.reply( `📚 *Помощь* *Сигналы* — готовые идеи для сделок с точками входа, стоп-лосс и тейк-профит. *Новости* — экономические события, влияющие на рынок (инфляция, ВВП, ставки). *Свечи* — 12 основных паттернов для анализа графика. *Риск* — расчёт лота для депозита $100 (риск 1-2% на сделку). 🌐 *Веб-версия:* Открой дашборд в браузере: https://pages.git.vibe42.kz/Erlan/pomoschnik-po-torgam-na-fore/ ⚠️ *Дисклеймер:* Это не финансовая рекомендация. Торговля на форекс — высокий риск.`, { parse_mode: "Markdown" } ); }); bot.command("signals", async (ctx) => { const text = signals.map(s => `*${s.dir} ${s.pair}* — ${s.type} Вход: ${s.entry} Стоп: ${s.sl} | Тейк: ${s.tp} Время: ${s.time}` ).join('\n\n'); await ctx.reply( `🎯 *Торговые сигналы*\n\n${text}`, { parse_mode: "Markdown" } ); }); bot.command("news", async (ctx) => { const text = news.map(n => `${n.title}\n⏰ ${n.time} • ${n.impact}` ).join('\n\n'); await ctx.reply( `📰 *Новости рынка*\n\n${text}`, { parse_mode: "Markdown" } ); }); bot.command("candles", async (ctx) => { const keyboard = { reply_markup: { inline_keyboard: candles.map(c => [ { text: c.name.split(' ')[0] + ' ' + c.name.split(' ')[1], callback_data: `candle_${candles.indexOf(c)}` } ]) } }; await ctx.reply( '🕯️ *Свечные паттерны*\n\nВыберите паттерн:', { parse_mode: "Markdown", ...keyboard } ); }); bot.command("risk", async (ctx) => { await ctx.reply( `🧮 *Калькулятор риска* *Правила:* • Риск на сделку: 1-2% депозита • Стоп-лосс ОБЯЗАТЕЛЕН • Соотношение риск/прибыль: минимум 1:2 *Пример для $100:* Риск 2% = $2 на сделку Стоп-лосс 20 пунктов Лот = 0.01 (мини-лот) Тейк-профит = 40 пунктов Прибыль = $4 🌐 Полный калькулятор в веб-версии: https://pages.git.vibe42.kz/Erlan/pomoschnik-po-torgam-na-fore/`, { parse_mode: "Markdown" } ); }); bot.command("broadcast", async (ctx) => { // Рассылка всем пользователям (только для админа) if (ctx.from.id !== 123456789) { return ctx.reply('❌ Нет доступа'); } const message = ctx.message.text.replace('/broadcast ', ''); let count = 0; for (const userId of users) { try { await bot.api.sendMessage(userId, message, { parse_mode: "Markdown" }); count++; } catch (e) { console.log(`Не удалось отправить ${userId}`); } } await ctx.reply(`✅ Отправлено ${count} пользователям`); }); // === ОБРАБОТКА КНОПОК === bot.on("callback_query:data", async (ctx) => { const data = ctx.callbackQuery.data; if (data.startsWith('candle_')) { const index = parseInt(data.split('_')[1]); const candle = candles[index]; await ctx.answerCallbackQuery(); await ctx.reply( `*${candle.name}*\n\nТип: ${candle.type}\n\n${candle.desc}`, { parse_mode: "Markdown" } ); } }); // === ОБРАБОТКА ТЕКСТА === bot.on("message:text", async (ctx) => { const text = ctx.message.text.toLowerCase(); if (text.includes('привет') || text.includes('здравствуй')) { await ctx.reply(`👋 Привет, ${ctx.from.first_name}! Чем могу помочь?`); } if (text.includes('свеч') || text.includes('паттерн')) { await ctx.reply('🕯️ Используй команду /candles для справочника свечей.'); } if (text.includes('новост') || text.includes('событи')) { await ctx.reply('📰 Используй команду /news для последних новостей.'); } if (text.includes('сигнал') || text.includes('сделк')) { await ctx.reply('🎯 Используй команду /signals для текущих сигналов.'); } }); // === ЗАПУСК === bot.start().catch((err) => { console.error("Ошибка запуска бота:", err); }); console.log("🤖 Forex Bot запущен..."); // === РАССЫЛКА СИГНАЛОВ КАЖДЫЕ 4 ЧАСА === setInterval(async () => { if (users.size === 0) return; const signal = signals[Math.floor(Math.random() * signals.length)]; const message = `🎯 *Новый сигнал!* ${signal.dir} *${signal.pair}* — ${signal.type} Вход: ${signal.entry} Стоп: ${signal.sl} Тейк: ${signal.tp} ⚠️ Это учебный сигнал. Реальные деньги — через брокера.`; for (const userId of users) { try { await bot.api.sendMessage(userId, message, { parse_mode: "Markdown" }); } catch (e) { console.log(`Не удалось отправить ${userId}`); } } }, 4 * 60 * 60 * 1000); // 4 часа