fix: LTTB downsampling crashes on string timestamps + abs→Math.abs

- _lttb_downsample: equity curve timestamps are ISO strings,
  not numeric. Rewrote to use array indices for triangle area
  instead of trying to multiply string * float.
- Fixed IndexError from reusing 'a' variable incorrectly
- Also fixed earlier: abs(dd) → Math.abs(dd) in vbt.html
This commit is contained in:
ramseshk
2026-08-07 15:26:42 +08:00
parent 870df57051
commit 9ee13a45bb
+17 -16
View File
@@ -586,27 +586,28 @@ def _lttb_downsample(points: list[dict], target: int) -> list[dict]:
return points
bucket_size = (n - 2) / (target - 2)
result = [points[0]]
a = 0
a = 0 # index of last point in result (within original points array)
for i in range(target - 2):
avg_x_start = int((i + 0) * bucket_size) + 1
avg_x_end = int((i + 1) * bucket_size) + 1
avg_range = points[avg_x_start:avg_x_end]
avg_x = sum(p.get("t", 0) if isinstance(p.get("t"), (int, float)) else 0 for p in avg_range) / max(len(avg_range), 1)
avg_y = sum(p["v"] for p in avg_range) / max(len(avg_range), 1)
range_offs = int((i + 1) * bucket_size) + 1
range_to = int((i + 2) * bucket_size) + 1
max_area = -1.0
avg_start = int((i + 0) * bucket_size) + 1
avg_end = int((i + 1) * bucket_size) + 1
avg_range = points[avg_start:avg_end]
avg_y = sum(p["v"] for p in avg_range) / max(len(avg_range), 1)
avg_x = int((avg_start + avg_end - 1) / 2)
range_offs = int((i + 1) * bucket_size) + 1
range_to = int((i + 2) * bucket_size) + 1
max_area = -1.0
next_pt = range_offs
for j in range(range_offs, min(range_to + 1, n)):
pa = result[a]
pa = points[a]
pc = points[j]
area = abs((pa.get("t", 0) if isinstance(pa.get("t"), (int, float)) else a) * (pc["v"] - avg_y) +
pc.get("t", 0) * (avg_y - pa["v"]) +
avg_x * (pa["v"] - pc["v"])) * 0.5
area = abs((a - j) * (pc["v"] - avg_y) +
(j - avg_x) * (avg_y - pa["v"]) +
(avg_x - a) * (pa["v"] - pc["v"])) * 0.5
if area > max_area:
max_area = area
next_a = j
result.append(points[next_a])
a = next_a
next_pt = j
result.append(points[next_pt])
a = next_pt
result.append(points[-1])
return result