From 56325113b3f7f5dd5b2962b1d73c634487324db0 Mon Sep 17 00:00:00 2001 From: Le Date: Sat, 4 Jul 2026 09:31:48 +0700 Subject: [PATCH] Show all UI times in GMT+7 and unify the timeframe list across the app MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every displayed timestamp previously relied on either the viewer's browser-local timezone (toLocaleString/toLocaleDateString/toLocaleTimeString) or raw UTC ISO-string slicing (.slice(0,10)/.slice(5,16)) — both wrong for a Vietnam-based system, and the string-slicing approach could show the wrong calendar date entirely near the UTC/GMT+7 day boundary. Added frontend/src/utils/dateTime.ts with formatVN* helpers that explicitly render in Asia/Ho_Chi_Minh regardless of the viewer's machine, and applied them across AdminPage, OrderPanel's live clock, SignalPanel, ProfilePage, AuditLogPage, and BacktestPage (including the new walk-forward fold/history dates) — 10 display sites total. Also consolidated the timeframe list (15m/30m/1h/4h/1d/1w/1M), which had drifted into 4 different copies across BacktestPage, ProfilePage, ChartToolbar, and AlertsPage, into a single frontend/src/utils/timeframes.ts source of truth. Extended Walk-Forward's timeframe options from 1h/4h to 1h/4h/1d, and fixed a latent backend bug where backtest_engine.py's tf_minutes map was missing "1d", silently defaulting to 30 minutes for any daily-timeframe backtest. Co-Authored-By: Claude Sonnet 5 --- backend/app/services/backtest_engine.py | 2 +- backend/app/services/walk_forward.py | 2 +- frontend/src/features/admin/AdminPage.tsx | 3 +- frontend/src/features/alerts/AlertsPage.tsx | 7 +-- .../src/features/backtest/BacktestPage.tsx | 29 ++++++---- .../src/features/dashboard/ChartToolbar.tsx | 3 +- .../src/features/dashboard/OrderPanel.tsx | 7 ++- .../src/features/dashboard/SignalPanel.tsx | 3 +- frontend/src/features/profile/ProfilePage.tsx | 12 ++-- frontend/src/pages/AuditLogPage.tsx | 8 +-- frontend/src/utils/dateTime.ts | 56 +++++++++++++++++++ frontend/src/utils/timeframes.ts | 5 ++ theo_doi_trading-portal_v7.md | 15 +++-- 13 files changed, 113 insertions(+), 39 deletions(-) create mode 100644 frontend/src/utils/dateTime.ts create mode 100644 frontend/src/utils/timeframes.ts diff --git a/backend/app/services/backtest_engine.py b/backend/app/services/backtest_engine.py index 66ae04e..22942fe 100644 --- a/backend/app/services/backtest_engine.py +++ b/backend/app/services/backtest_engine.py @@ -70,7 +70,7 @@ def _precompute_indicators(candles: list[Candle], timeframe: str) -> dict: (see `_simulate_trades`). """ # MTF config - tf_minutes = {"15m": 15, "30m": 30, "1h": 60, "4h": 240} + tf_minutes = {"15m": 15, "30m": 30, "1h": 60, "4h": 240, "1d": 1440, "1w": 10080, "1M": 43200} main_minutes = tf_minutes.get(timeframe, 30) mtf_config = [] for mtf_tf, mtf_minutes, mtf_w in [("15m", 15, 0.5), ("1h", 60, 1.5), ("4h", 240, 2.0)]: diff --git a/backend/app/services/walk_forward.py b/backend/app/services/walk_forward.py index abc88ad..aecdd36 100644 --- a/backend/app/services/walk_forward.py +++ b/backend/app/services/walk_forward.py @@ -45,7 +45,7 @@ DEFAULT_PARAM_GRID: dict[str, list[float]] = { MIN_TRADES_PER_FOLD = 5 # reject param combos too sparse to trust WARMUP_BUFFER_CANDLES = 60 # extra history fetched before each window so indicators aren't cold at window start -_TF_MINUTES = {"15m": 15, "30m": 30, "1h": 60, "4h": 240, "1d": 1440} +_TF_MINUTES = {"15m": 15, "30m": 30, "1h": 60, "4h": 240, "1d": 1440, "1w": 10080, "1M": 43200} def _fold_score(closed_trades: list[dict], min_trades: int = MIN_TRADES_PER_FOLD) -> float: diff --git a/frontend/src/features/admin/AdminPage.tsx b/frontend/src/features/admin/AdminPage.tsx index 933c7a5..b6bd032 100755 --- a/frontend/src/features/admin/AdminPage.tsx +++ b/frontend/src/features/admin/AdminPage.tsx @@ -14,6 +14,7 @@ import { adminGetHealth, } from '../api/apiService'; import type { User, Exchange } from '../../types/trading'; +import { formatVNDateOnly } from '../../utils/dateTime'; interface HealthData { status: string; @@ -472,7 +473,7 @@ export default function AdminPage() { {u.is_active ? ● Active : ● Inactive} - {u.created_at ? new Date(u.created_at).toLocaleDateString() : '-'} + {formatVNDateOnly(u.created_at)}