| {h} | ))}||||
|---|---|---|---|---|
| {t.time} |
|
{t.entry} | = 0 ? "text-emerald-400" : "text-red-400"}`}> {parseFloat(t.pnl) >= 0 ? "+" : ""}${t.pnl} |
|
import { useState, useEffect, useRef } from "react"; import { LineChart, Line, XAxis, YAxis, Tooltip, ResponsiveContainer, ReferenceLine } from "recharts"; // ─── Simulated live data (replace with real MT5 API/websocket in production) ─── function useSimulatedBot(strategy, params) { const [log, setLog] = useState([]); const [trades, setTrades] = useState([]); const [price, setPrice] = useState(1.08542); const [priceHistory, setPriceHistory] = useState(() => Array.from({ length: 60 }, (_, i) => ({ t: i, price: 1.0854 + (Math.random() - 0.5) * 0.003, })) ); const [equity, setEquity] = useState(10000); const [running, setRunning] = useState(false); const tickRef = useRef(0); useEffect(() => { if (!running) return; const id = setInterval(() => { tickRef.current++; const t = tickRef.current; // Simulate price walk setPrice((p) => { const next = +(p + (Math.random() - 0.499) * 0.0003).toFixed(5); setPriceHistory((h) => [...h.slice(-99), { t, price: next }]); return next; }); // Occasionally fire a signal if (t % 8 === 0) { const side = Math.random() > 0.5 ? "BUY" : "SELL"; const entry = price; const pnl = (Math.random() - 0.45) * 30; const trade = { id: t, time: new Date().toLocaleTimeString(), side, entry: entry.toFixed(5), pnl: pnl.toFixed(2), status: pnl > 0 ? "WIN" : "LOSS", }; setTrades((prev) => [trade, ...prev].slice(0, 30)); setEquity((e) => +(e + pnl).toFixed(2)); setLog((l) => [ `[${trade.time}] Signal: ${side} @ ${entry.toFixed(5)} → P&L: $${pnl.toFixed(2)}`, ...l, ].slice(0, 100) ); } }, 800); return () => clearInterval(id); }, [running, price]); return { log, trades, price, priceHistory, equity, running, setRunning }; } // ─── Components ─────────────────────────────────────────────────────────────── const STRATEGIES = ["MA_CROSSOVER", "RSI", "BOLLINGER", "MACD"]; const defaultParams = { MA_CROSSOVER: { fast_ma: 10, slow_ma: 50 }, RSI: { rsi_period: 14, rsi_overbought: 70, rsi_oversold: 30 }, BOLLINGER: { bb_period: 20, bb_std: 2.0 }, MACD: { macd_fast: 12, macd_slow: 26, macd_signal: 9 }, }; function Badge({ children, color }) { const colors = { green: "bg-emerald-500/20 text-emerald-400 border-emerald-500/30", red: "bg-red-500/20 text-red-400 border-red-500/30", blue: "bg-sky-500/20 text-sky-400 border-sky-500/30", yellow: "bg-amber-500/20 text-amber-400 border-amber-500/30", }; return ( {children} ); } function StatCard({ label, value, sub, color = "white" }) { const textColor = { white: "text-white", green: "text-emerald-400", red: "text-red-400" }[color]; return (
MetaTrader 5 · Live Trading Dashboard
| {h} | ))}||||
|---|---|---|---|---|
| {t.time} |
|
{t.entry} | = 0 ? "text-emerald-400" : "text-red-400"}`}> {parseFloat(t.pnl) >= 0 ? "+" : ""}${t.pnl} |
|