Bot & Automation
Market AI
/root/hermes-projects/Market 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)}\``,
`Max Position: \`${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} 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)}\``,
`Max Position: \`${params.maxPosition}\``,
`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} 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);
}