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:
+17
-16
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user