/* global React, apiFetch */ function MonthlyPreview({ account }) { const [data,setData]=React.useState(null); const [error,setError]=React.useState(""); React.useEffect(()=>{ let alive=true; setData(null); setError(""); if (!account || account.server !== "OctaFX-Demo") return ()=>{alive=false;}; const load=()=>apiFetch(`/monthly/${encodeURIComponent(account.id)}`).then(value=>{ if(alive){setData(value);setError("");} }).catch(()=>{if(alive)setError("Monthly observations are temporarily unavailable.");}); load(); const timer=setInterval(load,60000); return ()=>{alive=false;clearInterval(timer);}; },[account && account.id,account && account.server]); if(!account || account.server!=="OctaFX-Demo") return null; const row=data && data.latest; const money=v=>Number.isFinite(v)?v.toLocaleString(undefined,{style:"currency",currency:"USD",maximumFractionDigits:2}):"—"; const unavailable=!row || row.status==="inputs_unavailable"; return
Experimental long/cash strategy. This monitor uses your actual demo balance and equity. It records sizing observations; it does not place orders or simulate profits.
{error &&{error}
} {data && data.stale &&Observations are stale or pending. Do not treat this as a current trading signal.
} {!data && !error &&Loading observations…
} {row && <>{unavailable?"Waiting for valid inputs":row.sizing_status==="below_minimum"?"Below minimum trade size — skip":"Size is representable — execution still disabled"}
{!unavailable &&Signal: {row.status==="signal_cash"?"Cash":row.status==="target_long"||row.status==="below_minimum"?"Long indication":row.status.replaceAll("_"," ")} · Rounded target: {Number(row.target_lots||0).toFixed(2)} lots
}Observed: {new Date(row.captured_at).toLocaleString()}
Report date: {row.report_date?new Date(row.report_date).toLocaleDateString():"—"}
Risk is fixed at a 5% annual volatility target, capped at unlevered exposure. Lots round down; a small account is never rounded up or given an artificial balance.
Historical results are promising, not proof of a winning strategy. Monthly execution timing and holding costs still need verification. Your currently selected bot runs separately from this monitor.