backtest work

This commit is contained in:
Boki 2025-07-03 11:04:33 -04:00
parent 143e2e1678
commit 55b4ca78c9
6 changed files with 427 additions and 129 deletions

View file

@ -11,6 +11,16 @@ export interface ChartData {
volume?: number;
}
export interface TradeMarker {
time: number;
position: 'aboveBar' | 'belowBar';
color: string;
shape: 'arrowUp' | 'arrowDown';
text: string;
id?: string;
price?: number;
}
export interface ChartProps {
data: ChartData[];
height?: number;
@ -23,6 +33,7 @@ export interface ChartProps {
color?: string;
lineWidth?: number;
}>;
tradeMarkers?: TradeMarker[];
className?: string;
}
@ -33,6 +44,7 @@ export function Chart({
showVolume = true,
theme = 'dark',
overlayData = [],
tradeMarkers = [],
className = '',
}: ChartProps) {
const chartContainerRef = useRef<HTMLDivElement>(null);
@ -94,16 +106,18 @@ export function Chart({
chartRef.current = chart;
// Filter and validate data
// Filter, validate and sort data
const validateAndFilterData = (rawData: any[]) => {
const seen = new Set<number>();
return rawData.filter((item, index) => {
if (seen.has(item.time)) {
return false;
}
seen.add(item.time);
return true;
});
return rawData
.filter((item, index) => {
if (seen.has(item.time)) {
return false;
}
seen.add(item.time);
return true;
})
.sort((a, b) => a.time - b.time); // Ensure ascending time order
};
// Create main series
@ -193,7 +207,8 @@ export function Chart({
}
// Filter out duplicate timestamps and ensure ascending order
const uniqueData = overlay.data.reduce((acc: any[], curr) => {
const sortedData = [...overlay.data].sort((a, b) => a.time - b.time);
const uniqueData = sortedData.reduce((acc: any[], curr) => {
if (!acc.length || curr.time > acc[acc.length - 1].time) {
acc.push(curr);
}
@ -203,6 +218,22 @@ export function Chart({
overlaySeriesRef.current.set(overlay.name, series);
});
// Add trade markers
if (tradeMarkers.length > 0 && mainSeriesRef.current) {
// Sort markers by time to ensure they're in ascending order
const sortedMarkers = [...tradeMarkers].sort((a, b) => a.time - b.time);
const markers: LightweightCharts.SeriesMarker<LightweightCharts.Time>[] = sortedMarkers.map(marker => ({
time: marker.time as LightweightCharts.Time,
position: marker.position,
color: marker.color,
shape: marker.shape as LightweightCharts.SeriesMarkerShape,
text: marker.text,
id: marker.id,
size: 1
}));
mainSeriesRef.current.setMarkers(markers);
}
// Fit content with a slight delay to ensure all series are loaded
setTimeout(() => {
chart.timeScale().fitContent();
@ -251,7 +282,7 @@ export function Chart({
chart.remove();
}
};
}, [data, height, type, showVolume, theme, overlayData]);
}, [data, height, type, showVolume, theme, overlayData, tradeMarkers]);
return (
<div className={`relative ${className}`}>