Files
xau-ai-trading-bot/web-dashboard/src/components/dashboard/equity-chart.tsx
T
buckybonezandClaude Opus 4.6 82eca84230 feat: apply #28B smart breakeven + #31B H1 EMA20 filter, add backtests #26-#32
Live trading optimizations (cumulative: $2,807 net, 81.8% WR, Sharpe 3.97):
- #28B: Smart breakeven locks profit at entry + 0.5x ATR instead of fixed $2
- #31B: H1 Price vs EMA20 filter — BUY only when H1 bullish, SELL only when bearish

Backtests #26-#32 (7 scripts testing sell improvement, regime-aware entry,
confluence scoring, dynamic RR, multi-TF H1, and ML exit optimizer).
Winners: #28B (+$229), #31B (+$343). Failed: #26, #27, #29, #30, #32.

Also includes: web dashboard redesign, Docker setup, startup scripts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 10:33:24 +07:00

89 lines
3.1 KiB
TypeScript

"use client";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { AreaChart, Area, XAxis, YAxis, ResponsiveContainer, Tooltip } from "recharts";
import { Wallet } from "lucide-react";
interface EquityChartProps {
equityData: number[];
balanceData: number[];
}
export function EquityChart({ equityData, balanceData }: EquityChartProps) {
const chartData = equityData.map((equity, i) => ({
index: i,
equity,
balance: balanceData[i] || equity,
}));
return (
<Card className="glass">
<CardHeader>
<CardTitle className="text-[11px] font-medium text-muted-foreground flex items-center gap-1.5 uppercase tracking-wider">
<Wallet className="h-3.5 w-3.5" />
Equity vs Balance (2H)
{equityData.length > 0 && (
<span className="ml-auto text-xs font-number text-success">
${equityData[equityData.length - 1]?.toFixed(2)}
</span>
)}
</CardTitle>
</CardHeader>
<CardContent>
<div className="h-[100px] w-full">
{equityData.length > 1 ? (
<ResponsiveContainer width="100%" height="100%">
<AreaChart data={chartData}>
<XAxis dataKey="index" hide />
<YAxis domain={["auto", "auto"]} hide />
<Tooltip
contentStyle={{
backgroundColor: "var(--color-card)",
border: "1px solid var(--color-border)",
borderRadius: "6px",
fontSize: "11px",
fontFamily: "var(--font-mono)",
}}
labelStyle={{ display: "none" }}
formatter={(value: number, name: string) => [
`$${value.toFixed(2)}`,
name === "equity" ? "Equity" : "Balance",
]}
/>
<defs>
<linearGradient id="equityGradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#22c55e" stopOpacity={0.2} />
<stop offset="95%" stopColor="#22c55e" stopOpacity={0} />
</linearGradient>
</defs>
<Area
type="monotone"
dataKey="balance"
stroke="#555"
strokeWidth={1}
strokeDasharray="4 4"
fill="none"
/>
<Area
type="monotone"
dataKey="equity"
stroke="#22c55e"
strokeWidth={1.5}
fill="url(#equityGradient)"
/>
</AreaChart>
</ResponsiveContainer>
) : (
<div className="h-full flex items-center justify-center text-muted-foreground/50">
<div className="text-center space-y-1">
<Wallet className="h-5 w-5 mx-auto opacity-30" />
<p className="text-xs">Collecting data...</p>
</div>
</div>
)}
</div>
</CardContent>
</Card>
);
}