Yan Wang commited on
Commit
4115887
·
1 Parent(s): 36b100b

remove normalization and raw prices button

Browse files
Files changed (1) hide show
  1. src/App_New.tsx +13 -43
src/App_New.tsx CHANGED
@@ -12,7 +12,7 @@ import {
12
  } from "./api";
13
 
14
  type SeriesPoint = { date: string; close: number[] };
15
- type ViewMode = "daily" | "intraday";
16
 
17
  const START_DAY = 7;
18
 
@@ -59,6 +59,7 @@ function generateFakeJSON(maxLen = 500): DataDict {
59
  const sigma = 0.15 + Math.random() * 0.35;
60
  const series: SeriesPoint[] = [];
61
  for (let i = 0; i < dates.length; i++) {
 
62
  const mins = 200 + Math.floor(Math.random() * 100);
63
  const intraday: number[] = [];
64
  let p = price;
@@ -103,9 +104,6 @@ export default function App() {
103
  const [viewMode, setViewMode] = useState<ViewMode>("daily");
104
  const [intradayDayIdx, setIntradayDayIdx] = useState<number | null>(null);
105
 
106
- // NEW: global normalize toggle
107
- const [normalize, setNormalize] = useState<boolean>(true);
108
-
109
  /* ---------- localStorage keys ---------- */
110
  const LS_DATASET_KEY = "annot_dataset_meta";
111
  const LS_DATA_PREFIX = (id: string) => `annot_dataset_${id}`;
@@ -276,7 +274,7 @@ export default function App() {
276
  /* ---------- computed ---------- */
277
  const isFinal = windowLen >= maxDays || selections.length >= maxSteps;
278
 
279
- // Daily
280
  const windowData = useMemo(() => {
281
  if (!dates.length || windowLen < 2) return [] as any[];
282
  const sliceDates = dates.slice(0, windowLen);
@@ -284,18 +282,14 @@ export default function App() {
284
  const row: Record<string, any> = { date };
285
  assets.forEach((a) => {
286
  const base = rawData[a]?.[0] ? latestClose(rawData[a][0]) : 1;
287
- const val = rawData[a]?.[idx] ? latestClose(rawData[a][idx]) : (normalize ? base : null);
288
- if (normalize) {
289
- row[a] = base ? (val as number) / base : 1; // normalize to day 0
290
- } else {
291
- row[a] = typeof val === "number" ? val : null; // raw price
292
- }
293
  });
294
  return row;
295
  });
296
- }, [assets, dates, windowLen, rawData, normalize]);
297
 
298
- // Intraday (single day)
299
  const visibleDates = useMemo(() => dates.slice(0, Math.max(0, windowLen)), [dates, windowLen]);
300
  const activeIntradayIdx = intradayDayIdx ?? Math.min(windowLen - 1, dates.length - 1);
301
  const intradayData = useMemo(() => {
@@ -312,16 +306,12 @@ export default function App() {
312
  assets.forEach(a => {
313
  const arr = rawData[a]?.[activeIntradayIdx]?.close ?? [];
314
  const val = arr[i];
315
- if (normalize) {
316
- row[a] = typeof val === "number" ? (dayFirstPrice[a] ? val / dayFirstPrice[a] : null) : null; // normalized to first tick
317
- } else {
318
- row[a] = typeof val === "number" ? val : null; // raw price
319
- }
320
  });
321
  rows.push(row);
322
  }
323
  return rows;
324
- }, [assets, rawData, dates.length, activeIntradayIdx, normalize]);
325
 
326
  function realizedNextDayReturn(asset: string) {
327
  const t = windowLen - 1;
@@ -450,7 +440,7 @@ export default function App() {
450
  useEffect(() => {
451
  function onKey(e: KeyboardEvent) {
452
  const tag = (e.target && (e.target as HTMLElement).tagName) || "";
453
- if (tag === "INPUT" || "TEXTAREA") return;
454
  const idx = parseInt((e as any).key, 10) - 1;
455
  if (!Number.isNaN(idx) && idx >= 0 && idx < assets.length) setSelectedAsset(assets[idx]);
456
  if ((e as any).key === "Enter" && Boolean(selectedAsset) && windowLen < maxDays) confirmSelection();
@@ -485,20 +475,12 @@ export default function App() {
485
  </div>
486
  );
487
 
488
- // Tooltip 格式化:normalized 用“×”,raw 用价格两位小数
489
- function tooltipFormatter(value: any, name: any) {
490
- if (normalize) {
491
- return [Number.isFinite(value) ? `${Number(value).toFixed(4)}×` : value, aliasMap[name] || name];
492
- }
493
- return [Number.isFinite(value) ? Number(value).toFixed(2) : value, aliasMap[name] || name];
494
- }
495
-
496
  return (
497
  <div className="p-6 bg-gray-50 min-h-screen flex flex-col gap-6">
498
  <div className="flex flex-wrap justify-between items-center gap-3">
499
  <div className="flex items-center gap-2">
500
  <h1 className="text-xl font-semibold">Asset Choice Simulation</h1>
501
- <span className="text-[10px] ml-2 px-1.5 py-0.5 rounded bg-amber-200 text-amber-900">BUILD_TAG: 2025-10-29</span>
502
  <span className="text-xs text-gray-500">Dataset: {datasetName || datasetId}</span>
503
  <span className="text-xs text-gray-500">User: {userId.slice(0,8)}…</span>
504
  <span className="text-xs text-gray-500">Day {windowLen} / {maxDays}</span>
@@ -513,15 +495,6 @@ export default function App() {
513
  <button className={`text-xs px-3 py-1.5 ${viewMode==="intraday" ? "bg-gray-900 text-white" : "bg-white text-gray-700 hover:bg-gray-50"}`} onClick={()=>setViewMode("intraday")}>Intraday (1 day)</button>
514
  </div>
515
 
516
- {/* NEW: Normalize/Raw toggle */}
517
- <button
518
- className="text-xs px-3 py-1.5 rounded-xl border border-gray-200 hover:bg-gray-50"
519
- onClick={() => setNormalize(v => !v)}
520
- title="Toggle normalized ratio vs raw price"
521
- >
522
- {normalize ? "Normalized" : "Raw Price"}
523
- </button>
524
-
525
  <button onClick={exportLog} className="text-sm px-3 py-1.5 rounded-xl bg-gray-900 text-white hover:bg-black">Export My Log</button>
526
  </div>
527
  </div>
@@ -540,9 +513,6 @@ export default function App() {
540
  </button>
541
  ))}
542
  {assets.length>0 && <span className="text-xs text-gray-500 ml-1">Hotkeys: 1..{assets.length}, Enter confirm</span>}
543
- <span className="text-[10px] px-2 py-0.5 rounded bg-black/60 text-white">
544
- {normalize ? "Viewing: Normalized (×)" : "Viewing: Raw Price"}
545
- </span>
546
  </div>
547
 
548
  <div className="h-80 relative">
@@ -552,7 +522,7 @@ export default function App() {
552
  <CartesianGrid strokeDasharray="3 3" />
553
  <XAxis dataKey="idx" tick={{ fontSize: 10 }} />
554
  <YAxis domain={["auto", "auto"]} tick={{ fontSize: 10 }} />
555
- <Tooltip contentStyle={{ fontSize: 12 }} formatter={tooltipFormatter as any} />
556
  <Legend onClick={(o: any) => setSelectedAsset(o.value)} wrapperStyle={{ cursor: "pointer" }} formatter={(v: any) => aliasMap[v] || v} />
557
  {assets.map((a, i) => (
558
  <Line
@@ -577,7 +547,7 @@ export default function App() {
577
  <CartesianGrid strokeDasharray="3 3" />
578
  <XAxis dataKey="date" tick={{ fontSize: 10 }} />
579
  <YAxis domain={["auto", "auto"]} tick={{ fontSize: 10 }} />
580
- <Tooltip contentStyle={{ fontSize: 12 }} formatter={tooltipFormatter as any} />
581
  <Legend onClick={(o: any) => setSelectedAsset(o.value)} wrapperStyle={{ cursor: "pointer" }} formatter={(v: any) => aliasMap[v] || v} />
582
  {assets.map((a, i) => (
583
  <Line
 
12
  } from "./api";
13
 
14
  type SeriesPoint = { date: string; close: number[] };
15
+ type ViewMode = "daily" | "intraday"; // 移除 multi
16
 
17
  const START_DAY = 7;
18
 
 
59
  const sigma = 0.15 + Math.random() * 0.35;
60
  const series: SeriesPoint[] = [];
61
  for (let i = 0; i < dates.length; i++) {
62
+ // Fake minute series (varying length)
63
  const mins = 200 + Math.floor(Math.random() * 100);
64
  const intraday: number[] = [];
65
  let p = price;
 
104
  const [viewMode, setViewMode] = useState<ViewMode>("daily");
105
  const [intradayDayIdx, setIntradayDayIdx] = useState<number | null>(null);
106
 
 
 
 
107
  /* ---------- localStorage keys ---------- */
108
  const LS_DATASET_KEY = "annot_dataset_meta";
109
  const LS_DATA_PREFIX = (id: string) => `annot_dataset_${id}`;
 
274
  /* ---------- computed ---------- */
275
  const isFinal = windowLen >= maxDays || selections.length >= maxSteps;
276
 
277
+ // Daily (normalized to day 0)
278
  const windowData = useMemo(() => {
279
  if (!dates.length || windowLen < 2) return [] as any[];
280
  const sliceDates = dates.slice(0, windowLen);
 
282
  const row: Record<string, any> = { date };
283
  assets.forEach((a) => {
284
  const base = rawData[a]?.[0] ? latestClose(rawData[a][0]) : 1;
285
+ const val = rawData[a]?.[idx] ? latestClose(rawData[a][idx]) : base;
286
+ row[a] = base ? val / base : 1;
 
 
 
 
287
  });
288
  return row;
289
  });
290
+ }, [assets, dates, windowLen, rawData]);
291
 
292
+ // Intraday (single day, normalized to first tick of the day)
293
  const visibleDates = useMemo(() => dates.slice(0, Math.max(0, windowLen)), [dates, windowLen]);
294
  const activeIntradayIdx = intradayDayIdx ?? Math.min(windowLen - 1, dates.length - 1);
295
  const intradayData = useMemo(() => {
 
306
  assets.forEach(a => {
307
  const arr = rawData[a]?.[activeIntradayIdx]?.close ?? [];
308
  const val = arr[i];
309
+ row[a] = typeof val === "number" ? (dayFirstPrice[a] ? val / dayFirstPrice[a] : null) : null;
 
 
 
 
310
  });
311
  rows.push(row);
312
  }
313
  return rows;
314
+ }, [assets, rawData, dates.length, activeIntradayIdx]);
315
 
316
  function realizedNextDayReturn(asset: string) {
317
  const t = windowLen - 1;
 
440
  useEffect(() => {
441
  function onKey(e: KeyboardEvent) {
442
  const tag = (e.target && (e.target as HTMLElement).tagName) || "";
443
+ if (tag === "INPUT" || tag === "TEXTAREA") return;
444
  const idx = parseInt((e as any).key, 10) - 1;
445
  if (!Number.isNaN(idx) && idx >= 0 && idx < assets.length) setSelectedAsset(assets[idx]);
446
  if ((e as any).key === "Enter" && Boolean(selectedAsset) && windowLen < maxDays) confirmSelection();
 
475
  </div>
476
  );
477
 
 
 
 
 
 
 
 
 
478
  return (
479
  <div className="p-6 bg-gray-50 min-h-screen flex flex-col gap-6">
480
  <div className="flex flex-wrap justify-between items-center gap-3">
481
  <div className="flex items-center gap-2">
482
  <h1 className="text-xl font-semibold">Asset Choice Simulation</h1>
483
+ <span className="text-[10px] ml-2 px-1.5 py-0.5 rounded bg-amber-200 text-amber-900">BUILD_TAG: 2025-10-28</span>
484
  <span className="text-xs text-gray-500">Dataset: {datasetName || datasetId}</span>
485
  <span className="text-xs text-gray-500">User: {userId.slice(0,8)}…</span>
486
  <span className="text-xs text-gray-500">Day {windowLen} / {maxDays}</span>
 
495
  <button className={`text-xs px-3 py-1.5 ${viewMode==="intraday" ? "bg-gray-900 text-white" : "bg-white text-gray-700 hover:bg-gray-50"}`} onClick={()=>setViewMode("intraday")}>Intraday (1 day)</button>
496
  </div>
497
 
 
 
 
 
 
 
 
 
 
498
  <button onClick={exportLog} className="text-sm px-3 py-1.5 rounded-xl bg-gray-900 text-white hover:bg-black">Export My Log</button>
499
  </div>
500
  </div>
 
513
  </button>
514
  ))}
515
  {assets.length>0 && <span className="text-xs text-gray-500 ml-1">Hotkeys: 1..{assets.length}, Enter confirm</span>}
 
 
 
516
  </div>
517
 
518
  <div className="h-80 relative">
 
522
  <CartesianGrid strokeDasharray="3 3" />
523
  <XAxis dataKey="idx" tick={{ fontSize: 10 }} />
524
  <YAxis domain={["auto", "auto"]} tick={{ fontSize: 10 }} />
525
+ <Tooltip contentStyle={{ fontSize: 12 }} formatter={(v: any, n: any) => [v, aliasMap[n] || n]} />
526
  <Legend onClick={(o: any) => setSelectedAsset(o.value)} wrapperStyle={{ cursor: "pointer" }} formatter={(v: any) => aliasMap[v] || v} />
527
  {assets.map((a, i) => (
528
  <Line
 
547
  <CartesianGrid strokeDasharray="3 3" />
548
  <XAxis dataKey="date" tick={{ fontSize: 10 }} />
549
  <YAxis domain={["auto", "auto"]} tick={{ fontSize: 10 }} />
550
+ <Tooltip contentStyle={{ fontSize: 12 }} formatter={(v: any, n: any) => [v, aliasMap[n] || n]} />
551
  <Legend onClick={(o: any) => setSelectedAsset(o.value)} wrapperStyle={{ cursor: "pointer" }} formatter={(v: any) => aliasMap[v] || v} />
552
  {assets.map((a, i) => (
553
  <Line