This commit is contained in:
qq564020069
2026-07-14 21:36:10 +08:00
parent 4cf76ce51f
commit 939da46a01
7 changed files with 90 additions and 42 deletions
+1
View File
@@ -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
+2 -2
View File
@@ -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"
+6
View File
@@ -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).
+50
View File
@@ -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
+2 -24
View File
@@ -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"
}
]
}
"sessions": []
}
+28 -15
View File
@@ -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) {
+1 -1
View File
@@ -566,6 +566,6 @@
</div>
<script src="/static/bg.js?v=1"></script>
<script src="/static/app.js?v=59"></script>
<script src="/static/app.js?v=60"></script>
</body>
</html>