From 939da46a019ad701b034590aa4514a8c4ed92b4e Mon Sep 17 00:00:00 2001
From: qq564020069 <125543001+qq564020069@users.noreply.github.com>
Date: Tue, 14 Jul 2026 21:36:10 +0800
Subject: [PATCH] 0.994
---
.gitignore | 1 +
_launch_web.bat | 4 ++--
requirements.txt | 6 +++++
start_web.bat | 50 +++++++++++++++++++++++++++++++++++++++
training_time_XAUUSD.json | 26 ++------------------
web/static/app.js | 43 +++++++++++++++++++++------------
web/static/index.html | 2 +-
7 files changed, 90 insertions(+), 42 deletions(-)
create mode 100644 start_web.bat
diff --git a/.gitignore b/.gitignore
index 08de53d..38fb7b2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -81,6 +81,7 @@ portfolio_state.json
web_settings.json
ai_analysis_history.json
train_elapsed.json
+training_time_*.json
STOP_SIGNAL
train.pid
train_stdout.log
diff --git a/_launch_web.bat b/_launch_web.bat
index 0997d62..5769279 100644
--- a/_launch_web.bat
+++ b/_launch_web.bat
@@ -1,4 +1,4 @@
@echo off
+REM Compatibility wrapper — prefer start_web.bat
cd /d "%~dp0"
-python run_web.py
-pause
+call "%~dp0start_web.bat"
diff --git a/requirements.txt b/requirements.txt
index d0139c7..c6f73ae 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -27,8 +27,14 @@ tqdm>=4.66.0 # Progress bars
# Training Web UI
fastapi>=0.110.0
uvicorn[standard]>=0.27.0
+python-multipart>=0.0.9 # FastAPI UploadFile 隐含依赖
+pyarrow>=14.0.0 # pandas 读写 Parquet 必需引擎
# ===== Optional Dependencies (For experimental scripts) =====
# See requirements-optional.txt for:
# - matplotlib, seaborn (for lord/experiment.py visualization)
# - tushare (for times.py Chinese stock market data)
+#
+# Install tip (Chinese Windows): prefer
+# python -m pip install -r requirements.txt
+# over bare `pip` (avoids pip-shim GBK encoding issues).
diff --git a/start_web.bat b/start_web.bat
new file mode 100644
index 0000000..071a85a
--- /dev/null
+++ b/start_web.bat
@@ -0,0 +1,50 @@
+@echo off
+chcp 65001 >nul
+cd /d "%~dp0"
+
+REM Prefer: python -m pip ... (avoids pip-shim GBK issues on Chinese Windows)
+set HOST=127.0.0.1
+set PORT=8765
+
+echo ============================================================
+echo AlphaMaster Web Console
+echo http://%HOST%:%PORT%
+echo ============================================================
+echo.
+
+echo [1/3] Releasing port %PORT% if occupied ...
+for /f "tokens=5" %%P in ('netstat -ano ^| findstr ":%PORT% " ^| findstr LISTENING') do (
+ echo taskkill PID %%P
+ taskkill /F /PID %%P >nul 2>&1
+)
+timeout /t 1 /nobreak >nul
+
+echo [2/3] Starting uvicorn ...
+start "AlphaMaster Server" python run_web.py --host %HOST% --port %PORT%
+
+echo [3/3] Warming up APIs (torch/fastapi first import can take ~6s) ...
+set /a TRIES=0
+:wait_ready
+set /a TRIES+=1
+if %TRIES% GTR 90 goto ready_fail
+timeout /t 1 /nobreak >nul
+python -c "import urllib.request; urllib.request.urlopen('http://%HOST%:%PORT%/api/overview', timeout=2).read(); urllib.request.urlopen('http://%HOST%:%PORT%/api/ai/providers', timeout=2).read(); urllib.request.urlopen('http://%HOST%:%PORT%/api/strategies', timeout=2).read()" 2>nul
+if errorlevel 1 goto wait_ready
+
+echo.
+echo Ready. Opening browser ...
+start "" "http://%HOST%:%PORT%/"
+echo.
+echo Server window title: AlphaMaster Server
+echo Press any key to close this launcher (server keeps running)...
+pause >nul
+exit /b 0
+
+:ready_fail
+echo.
+echo ERROR: server did not become ready within ~90s.
+echo Check the "AlphaMaster Server" window for import/dependency errors.
+echo Tip: python -m pip install -r requirements.txt
+echo.
+pause
+exit /b 1
diff --git a/training_time_XAUUSD.json b/training_time_XAUUSD.json
index 6c42d6e..43b1452 100644
--- a/training_time_XAUUSD.json
+++ b/training_time_XAUUSD.json
@@ -1,26 +1,4 @@
{
"symbol": "XAUUSD",
- "sessions": [
- {
- "log_path": "logs/train_XAUUSD_20260713_100546.log",
- "started_at": "2026-07-13T10:05:46+00:00",
- "finished_at": "2026-07-13T12:31:26.268836+00:00",
- "seconds": 8740,
- "source": "log_backfill"
- },
- {
- "log_path": "logs/train_XAUUSD_20260713_133709.log",
- "started_at": "2026-07-13T13:37:09+00:00",
- "finished_at": "2026-07-14T03:17:27.415464+00:00",
- "seconds": 49218,
- "source": "log_backfill"
- },
- {
- "log_path": "logs/train_XAUUSD_20260714_033057.log",
- "started_at": "2026-07-14T03:30:57+00:00",
- "finished_at": "2026-07-14T07:23:03.906968+00:00",
- "seconds": 13926,
- "source": "log_backfill"
- }
- ]
-}
\ No newline at end of file
+ "sessions": []
+}
diff --git a/web/static/app.js b/web/static/app.js
index 3bb926b..35bab32 100644
--- a/web/static/app.js
+++ b/web/static/app.js
@@ -190,24 +190,37 @@ async function refreshDebugLogs() {
async function fetchJSON(path, opts = {}) {
const silent = !!opts.silent;
+ const maxRetries = opts.retries != null ? Number(opts.retries) : 5;
+ const retryDelayMs = opts.retryDelayMs != null ? Number(opts.retryDelayMs) : 2000;
const fetchOpts = { ...opts };
delete fetchOpts.silent;
- let res;
- try {
- res = await fetch(API + path, fetchOpts);
- } catch (e) {
- const msg = `网络错误 ${path}: ${e.message}`;
- await logClientError(msg, { path, silent });
- throw new Error(msg);
+ delete fetchOpts.retries;
+ delete fetchOpts.retryDelayMs;
+
+ let lastNetworkMsg = null;
+ for (let attempt = 1; attempt <= Math.max(1, maxRetries); attempt++) {
+ let res;
+ try {
+ res = await fetch(API + path, fetchOpts);
+ } catch (e) {
+ lastNetworkMsg = `网络错误 ${path}: ${e.message}`;
+ if (attempt < maxRetries) {
+ await new Promise((r) => setTimeout(r, retryDelayMs));
+ continue;
+ }
+ await logClientError(lastNetworkMsg, { path, silent, attempts: attempt });
+ throw new Error(lastNetworkMsg);
+ }
+ const data = await res.json().catch(() => ({}));
+ if (!res.ok) {
+ const msg = formatApiError(data, res.status, path);
+ await logClientError(`${path} -> ${msg}`, { path, status: res.status, silent });
+ if (!silent) await refreshDebugLogs();
+ throw new Error(msg);
+ }
+ return data;
}
- const data = await res.json().catch(() => ({}));
- if (!res.ok) {
- const msg = formatApiError(data, res.status, path);
- await logClientError(`${path} -> ${msg}`, { path, status: res.status, silent });
- if (!silent) await refreshDebugLogs();
- throw new Error(msg);
- }
- return data;
+ throw new Error(lastNetworkMsg || `网络错误 ${path}`);
}
function formatScore(v) {
diff --git a/web/static/index.html b/web/static/index.html
index 4c6db61..4687df1 100644
--- a/web/static/index.html
+++ b/web/static/index.html
@@ -566,6 +566,6 @@
-
+