Bot & Automation

Treding Forex Ai

/root/hermes-projects/Treding Forex Ai

src/bot/ui/formatters.ts text
import { RISK_DISCLAIMER } from "../../constants/risk";
import type {
  BrokerExecutionStatus,
  ExecutedTrade,
  TradingRuntimeMode
} from "../../domain/types";

export function formatWelcome(botName: string): string {
  return [
    `🤖 *${botName}*`,
    "",
    "Asisten AI Trading & Analisis Pasar Forex/Gold/Crypto Anda.",
    "Gunakan menu interaktif di bawah atau ketik pertanyaan langsung untuk analisis instan.",
    "",
    RISK_DISCLAIMER
  ].join("\n");
}

export interface MarketAnalysisParams {
  symbolLabel: string;
  currentPrice: number;
  action: string;
  trendM1: string;
  trendM5: string;
  trendM15: string;
  trendH1: string;
  spreadPoints: number;
  volatility: string;
}

export function formatMarketAnalysis(params: MarketAnalysisParams): string {
  return [
    "📊 *MARKET ANALYSIS*",
    "",
    `Market: *${params.symbolLabel}*`,
    `Harga Sekarang: \`${formatNumber(params.currentPrice)}\``,
    `Signal: *${params.action}*`,
    `Trend M1: \`${params.trendM1}\``,
    `Trend M5: \`${params.trendM5}\``,
    `Trend M15: \`${params.trendM15}\``,
    `Trend H1: \`${params.trendH1}\``,
    `Spread: \`${params.spreadPoints} points\``,
    `Volatilitas: *${params.volatility}*`,
    "",
    RISK_DISCLAIMER
  ].join("\n");
}

export interface AutoTradingDashboardParams {
  isEnabled: boolean;
  accountMode?: string;
  marketSymbol?: string;
  strategy?: string;
  lot?: number;
}

export function formatAutoTradingDashboard(params: AutoTradingDashboardParams): string {
  const statusStr = params.isEnabled ? "🟢 ON" : "🔴 OFF";
  return [
    "🤖 *AUTO TRADING CENTER*",
    "",
    `Status: *${statusStr}*`,
    `Account Mode: *${params.accountMode || "Belum dipilih"}*`,
    `Market: *${params.marketSymbol || "Belum dipilih"}*`,
    `Strategy: *${params.strategy || "Belum dipilih"}*`,
    `Lot: *${params.lot !== undefined ? params.lot.toFixed(2) : "Belum diatur"}*`,
    "",
    "ℹ️ Gunakan menu setup di bawah untuk mengonfigurasi dan mengaktifkan robot."
  ].join("\n");
}

export interface RiskManagementSetupParams {
  lot: number;
  maxPosition: number;
  targetProfitPips: number;
  stopLossPips: number;
  dailyLossLimitPercent: number;
  cooldownSeconds: number;
  maxSpreadPips: number;
}

export function formatSetupRisk(params: RiskManagementSetupParams): string {
  return [
    "⚙️ *Risk Management*",
    "",
    `Lot: \`${params.lot.toFixed(2)}\``,
    `Jumlah Entry Bersamaan: \`${params.maxPosition}\``,
    `Target Profit: \`${params.targetProfitPips} Pips\` (wajib diatur)`,
    `Stop Loss: \`${params.stopLossPips} Pips\` (wajib aktif)`,
    `Daily Loss Limit: \`${params.dailyLossLimitPercent}%\` (wajib aktif)`,
    `Cooldown: \`${params.cooldownSeconds === 0 ? "langsung re-entry" : `${params.cooldownSeconds} detik`}\` (aktif)`,
    `Max Spread: \`${params.maxSpreadPips} Pips\` (aktif)`,
    "",
    "ℹ️ Klik tombol di bawah untuk mengubah parameter atau klik Lanjutkan."
  ].join("\n");
}

export interface ReviewSetupParams {
  accountMode: string;
  marketSymbol: string;
  strategy: string;
  lot: number;
  maxPosition: number;
  targetProfitPips: number;
  stopLossPips: number;
  dailyLossLimitPercent: number;
  maxSpreadPips: number;
  cooldownSeconds: number;
}

export function formatSetupReview(params: ReviewSetupParams): string {
  return [
    "🤖 *AUTO TRADING REVIEW*",
    "",
    `Account: *${params.accountMode}*`,
    `Market: *${params.marketSymbol}*`,
    `Strategy: *${params.strategy}*`,
    `Lot: \`${params.lot.toFixed(2)}\``,
    `Jumlah Entry Bersamaan: \`${params.maxPosition}\``,
    `Reward:Risk: \`${(params.targetProfitPips / params.stopLossPips).toFixed(2)}\``,
    `Target Profit: \`Aktif (${params.targetProfitPips} pips)\``,
    `Stop Loss: \`Aktif (${params.stopLossPips} pips)\``,
    `Daily Loss Limit: \`Aktif (${params.dailyLossLimitPercent}%)\``,
    `Spread Filter: \`Aktif (${params.maxSpreadPips} pips)\``,
    `Cooldown: \`Aktif (${params.cooldownSeconds === 0 ? "langsung re-entry" : `${params.cooldownSeconds} detik`})\``,
    "",
    "⚠️ Pastikan Anda sudah mengerti risiko sebelum menjalankan robot."
  ].join("\n");
}

export function formatRealConfirmation(): string {
  return [
    "⚠️ *REAL ACCOUNT CONFIRMATION*",
    "",
    "Robot akan menjalankan transaksi di akun *REAL* (Uang Sungguhan).",
    "",
    "Pastikan semua parameter risiko dan lot size sudah Anda verifikasi dengan benar.",
    "",
    "Apakah Anda yakin ingin memulai?"
  ].join("\n");
}

export function formatTradeExecuted(trade: ExecutedTrade): string {
  const status =
    trade.broker === "real"
      ? "Status: order dikirim ke akun MT5 real."
      : trade.broker === "mt5_demo"
        ? "Status: order dikirim ke akun MT5 demo."
        : "Status: dry-run/paper, belum mengirim order ke MT5.";

  return [
    trade.broker === "paper" || trade.broker === "dry_run" ? "Paper trade executed" : "MT5 trade executed",
    "",
    `Order ID: ${trade.brokerOrderId}`,
    `Market: ${trade.symbolCode}`,
    `Action: ${trade.action}`,
    `Entry: ${formatNumber(trade.entry)}`,
    `Stop Loss: ${formatNumber(trade.stopLoss)}`,
    `Take Profit 1: ${formatNumber(trade.takeProfit1)}`,
    `Lot size: ${trade.positionSizing.lotSize}`,
    "",
    status
  ].join("\n");
}

export function formatSettings(params: {
  runtimeMode: TradingRuntimeMode;
  enableRealTrading: boolean;
  accountBalance: number;
  riskPerTradePercent: number;
  maxDailyLossPercent: number;
  maxOpenTrades: number;
  maxLotPerOrder: number;
  marketDataProvider: string;
  brokerProvider: string;
  autoTradingEnabled: boolean;
  brokerStatus?: BrokerExecutionStatus;
}): string {
  const lines = [
    "Settings",
    "",
    `Runtime mode: ${params.runtimeMode}`,
    `Real trading enabled: ${params.enableRealTrading}`,
    `Market data provider: ${params.marketDataProvider}`,
    `Broker provider: ${params.brokerProvider}`,
    `Auto trading enabled: ${params.autoTradingEnabled}`,
    `Account balance: ${params.accountBalance}`,
    `Risk per trade: ${params.riskPerTradePercent}%`,
    `Max daily loss: ${params.maxDailyLossPercent}%`,
    `Max open trades: ${params.maxOpenTrades}`,
    `Max lot per order: ${params.maxLotPerOrder}`
  ];

  if (params.brokerStatus) {
    lines.push(
      "",
      `Bridge connected: ${params.brokerStatus.connected}`,
      `Bridge account mode: ${params.brokerStatus.currentMode}`,
      `Demo execution gate: ${params.brokerStatus.allowDemoTrading}`,
      `Realtime execution gate: ${params.brokerStatus.allowRealTrading}`,
      `Bridge detail: ${params.brokerStatus.detail}`
    );
  }

  lines.push(
    "",
    params.enableRealTrading
      ? "Warning: real trading aktif. Pastikan broker adapter sudah diaudit."
      : "Real trading masih terkunci. Semua order berjalan sebagai paper trade."
  );

  return lines.join("\n");
}

export function formatWatchlist(symbols: string[]): string {
  if (symbols.length === 0) {
    return "Watchlist masih kosong. Tambahkan pair dari signal card.";
  }

  return ["Watchlist", "", ...symbols.map((symbol) => `- ${symbol}`)].join("\n");
}

export function formatHelp(): string {
  return [
    "💡 *AI Trading Bot Help*",
    "",
    "Command Menu Utama:",
    "• /start - Membuka menu navigasi utama.",
    "• /auto - Membuka Dashboard Auto Trading.",
    "• /watchlist - Melihat instrumen dalam daftar pantau.",
    "• /settings - Memeriksa konfigurasi manajemen risiko.",
    "",
    "Contoh Pertanyaan Bebas:",
    "• `XAUUSD sekarang arah mana?`",
    "• `EURUSD buy atau sell?`",
    "• `GBPUSD scalping`"
  ].join("\n");
}

export function formatAutoTradingStatus(status: string): string {
  return [
    "⚡ Auto Trading Status",
    "",
    status
  ].join("\n");
}

function formatNumber(value: number): string {
  return Number.isInteger(value) ? String(value) : value.toFixed(value >= 100 ? 2 : 5);
}