export default function ForexOpenClawDashboard() {
const overview = {
botStatus: "Running",
mt5: "Connected",
provider: "Anthropic",
openPositions: 4,
balance: 10342.18,
equity: 10196.42,
drawdownPct: 1.41,
latestSignal: "BUY EURUSDm",
lastUpdate: "2026-03-21 10:25",
};
const signals = [
{
symbol: "EURUSDm",
bias: "BUY",
score: 82,
regime: "TREND",
entry: "1.0842 - 1.0848",
rsiH1: 58,
rsiM15: 34,
adx: 27,
atr: 0.00086,
note: "H1 bullish, M15 pullback",
},
{
symbol: "USDJPYm",
bias: "SELL",
score: 74,
regime: "TREND",
entry: "148.20 - 148.35",
rsiH1: 43,
rsiM15: 67,
adx: 29,
atr: 0.118,
note: "Sell pullback in downtrend",
},
{
symbol: "XAUUSDm",
bias: "NO TRADE",
score: 49,
regime: "RANGE",
entry: "Wait",
rsiH1: 51,
rsiM15: 53,
adx: 18,
atr: 7.2,
note: "Range, no edge",
},
];
const positions = [
{ ticket: 120381, symbol: "EURUSDm", side: "BUY", lot: 0.1, pnl: 24.8, opened: "09:12" },
{ ticket: 120382, symbol: "EURUSDm", side: "BUY", lot: 0.2, pnl: -12.4, opened: "09:35" },
{ ticket: 120410, symbol: "USDJPYm", side: "SELL", lot: 0.1, pnl: 31.2, opened: "10:01" },
{ ticket: 120425, symbol: "GBPUSDm", side: "BUY", lot: 0.1, pnl: -5.6, opened: "10:14" },
];
const riskChecks = [
{ name: "Daily Loss Limit", value: "Pass", detail: "-1.41% / max 3.00%" },
{ name: "Symbol Exposure", value: "Pass", detail: "EURUSDm 0.3 / max 0.5 lot" },
{ name: "Basket Layers", value: "Warn", detail: "EURUSDm 2 / max 3 layers" },
{ name: "Spread Filter", value: "Pass", detail: "All symbols within threshold" },
{ name: "Kill Switch", value: "Off", detail: "No emergency lock" },
];
const logs = [
"10:25 Analyze EURUSDm -> BUY score 82",
"10:24 Risk check EURUSDm BUY 0.1 -> approved",
"10:24 Execute EURUSDm BUY 0.1 -> queued",
"10:12 Analyze XAUUSDm -> NO TRADE score 49",
"10:07 MT5 heartbeat OK",
];
const StatCard = ({ title, value, sub }) => (
{title}
{value}
{sub ?
{sub}
: null}
);
const Pill = ({ children, tone = "slate" }) => {
const tones = {
green: "bg-green-100 text-green-700",
red: "bg-red-100 text-red-700",
amber: "bg-amber-100 text-amber-700",
blue: "bg-blue-100 text-blue-700",
slate: "bg-slate-100 text-slate-700",
};
return (
{children}
);
};
const toneForBias = (bias) => {
if (bias === "BUY") return "green";
if (bias === "SELL") return "red";
return "amber";
};
const toneForRisk = (value) => {
if (value === "Pass") return "green";
if (value === "Warn") return "amber";
if (value === "Off") return "slate";
return "red";
};
const pnlTone = (pnl) => (pnl >= 0 ? "text-green-600" : "text-red-600");
return (
OpenClaw + Forex Copilot
Dashboard v1
Giám sát bot, tín hiệu, risk và lệnh mở trong một màn hình.
Bot {overview.botStatus}
MT5 {overview.mt5}
LLM {overview.provider}
Updated {overview.lastUpdate}
Latest Signals
Rule-based core, OpenClaw orchestration
| Symbol |
Bias |
Score |
Regime |
Entry |
RSI H1/M15 |
ADX |
ATR |
{signals.map((row) => (
| {row.symbol} |
{row.bias} |
{row.score} |
{row.regime} |
{row.entry} |
{row.rsiH1} / {row.rsiM15} |
{row.adx} |
{row.atr} |
))}
{signals.map((row) => (
))}
{riskChecks.map((item) => (
))}
Open Positions
{positions.length} tickets
| Ticket |
Symbol |
Side |
Lot |
PnL |
Opened |
{positions.map((p) => (
| #{p.ticket} |
{p.symbol} |
{p.side} |
{p.lot} |
{p.pnl >= 0 ? `+$${p.pnl}` : `-$${Math.abs(p.pnl)}`} |
{p.opened} |
))}
{logs.map((line, idx) => (
{line}
))}
Nút v1 cần thêm sau: Kill Switch, Refresh Signal, Pause New Entries, Export Report.
);
}