From c7786946afd0c035ee99c7fb307f3b5e688731e2 Mon Sep 17 00:00:00 2001 From: aaron <> Date: Thu, 14 May 2026 11:21:21 +0800 Subject: [PATCH] update --- .env.example | 2 +- README_DOCKER.md | 4 +-- app/__init__.py | 2 +- app/cli.py | 4 +-- app/core/opportunity_lifecycle.py | 2 +- app/db/analytics.py | 34 +++++++++++++++++-- app/db/auth_db.py | 12 +++---- app/services/altcoin_confirm.py | 2 +- app/services/altcoin_screener.py | 2 +- app/services/price_tracker.py | 2 +- app/services/review_engine.py | 2 +- app/web/routes_recommendations.py | 4 +-- app/web/web_server.py | 4 +-- static/admin.html | 2 +- static/app.html | 2 +- static/auth.html | 8 ++--- static/base.html | 11 +++--- static/index.html | 12 +++---- static/iteration.html | 4 +-- static/pipeline.html | 23 +++++++++---- static/referral.html | 4 +-- static/sentiment.html | 2 +- static/strategy.html | 2 +- static/subscription.html | 6 ++-- static/watchlist.html | 2 +- tests/test_pipeline_runs_api.py | 50 ++++++++++++++++++++++++++++ tests/test_user_subscription_auth.py | 4 +-- 27 files changed, 147 insertions(+), 61 deletions(-) diff --git a/.env.example b/.env.example index d6fc577..17e468a 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,4 @@ -# AlphaX Docker 环境变量示例 +# AlphaX Agent | Crypto Docker 环境变量示例 # 复制为 .env 后再按需填写:cp .env.example .env # Web 服务端口由 docker-compose 映射为宿主机 8191 -> 容器 8190。 diff --git a/README_DOCKER.md b/README_DOCKER.md index dd5921e..f337fe0 100644 --- a/README_DOCKER.md +++ b/README_DOCKER.md @@ -1,4 +1,4 @@ -# AlphaX Docker 化副本 +# AlphaX Agent | Crypto Docker 化副本 这是从当前运行中的 `/home/ubuntu/quant_monitor/altcoin` 复制出来的独立 Docker 化副本,目录: @@ -8,7 +8,7 @@ ## 重要原则 -- 这个目录是副本,不影响当前正在运行的 AlphaX。 +- 这个目录是副本,不影响当前正在运行的 AlphaX Agent | Crypto。 - 默认 `docker-compose.yml` 将 Web 暴露到宿主机 `8191`,避免占用当前线上 `8190`。 - 调度器默认 `ALPHAX_SCHEDULER_DRY_RUN=1`,第一次启动不会真的跑筛选/确认/跟踪任务。 - SQLite 数据挂载在 `./data/altcoin_monitor.db`,容器内路径为 `/app/data/altcoin_monitor.db`。 diff --git a/app/__init__.py b/app/__init__.py index a48d373..54e724f 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1 +1 @@ -"""Application package for AlphaX.""" +"""Application package for AlphaX Agent | Crypto.""" diff --git a/app/cli.py b/app/cli.py index 2d09c80..161846a 100644 --- a/app/cli.py +++ b/app/cli.py @@ -1,4 +1,4 @@ -"""Unified CLI entrypoint for AlphaX jobs.""" +"""Unified CLI entrypoint for AlphaX Agent | Crypto jobs.""" import argparse @@ -6,7 +6,7 @@ from app.services import altcoin_confirm, altcoin_screener, event_driven_screene def build_parser(): - parser = argparse.ArgumentParser(description="AlphaX unified CLI") + parser = argparse.ArgumentParser(description="AlphaX Agent | Crypto unified CLI") subparsers = parser.add_subparsers(dest="command", required=True) screener = subparsers.add_parser("screener", help="运行粗筛/细筛") diff --git a/app/core/opportunity_lifecycle.py b/app/core/opportunity_lifecycle.py index 65089bc..411c07f 100644 --- a/app/core/opportunity_lifecycle.py +++ b/app/core/opportunity_lifecycle.py @@ -26,7 +26,7 @@ DEFAULT_ENTRY_GATE = { -# AlphaX 统一状态机:所有展示/统计/推送都应消费这些派生状态,不再各自解释 status/action_status。 +# AlphaX Agent | Crypto 统一状态机:所有展示/统计/推送都应消费这些派生状态,不再各自解释 status/action_status。 TERMINAL_STATUSES = {"hit_tp1", "hit_tp2", "stopped_out", "expired", "archived", "invalid"} EXIT_ACTIONS = {"止损", "衰减", "反转", "放弃"} PROFIT_ACTIONS = {"止盈1", "止盈2", "跟踪止盈"} diff --git a/app/db/analytics.py b/app/db/analytics.py index fa549b2..ef12eae 100644 --- a/app/db/analytics.py +++ b/app/db/analytics.py @@ -1024,18 +1024,31 @@ def _pipeline_summary_for_run(run, related): } -def get_pipeline_runs(limit=30, hours=24): +def get_pipeline_runs(limit=30, hours=24, offset=0): """按粗筛任务批次聚合推荐链路日志。""" try: limit = max(1, min(int(limit or 30), 100)) except Exception: limit = 30 + try: + offset = max(0, int(offset or 0)) + except Exception: + offset = 0 try: hours = max(1, min(int(hours or 24), 24 * 30)) except Exception: hours = 24 conn = get_conn() + total_count = conn.execute( + """ + SELECT COUNT(*) + FROM cron_run_log + WHERE job_name = '粗筛' + AND julianday(?) - julianday(started_at) <= ? + """, + (datetime.now().isoformat(), hours / 24.0), + ).fetchone()[0] run_rows = conn.execute( """ SELECT * FROM cron_run_log @@ -1043,8 +1056,9 @@ def get_pipeline_runs(limit=30, hours=24): AND julianday(?) - julianday(started_at) <= ? ORDER BY started_at DESC, id DESC LIMIT ? + OFFSET ? """, - (datetime.now().isoformat(), hours / 24.0, limit), + (datetime.now().isoformat(), hours / 24.0, limit, offset), ).fetchall() runs = [] @@ -1069,7 +1083,21 @@ def get_pipeline_runs(limit=30, hours=24): } kpi["recommendation_rate"] = round(kpi["recommendations"] / kpi["fine_qualified"] * 100, 1) if kpi["fine_qualified"] else 0 kpi["performance_hit_rate"] = round(kpi["perf_success"] / (kpi["perf_success"] + kpi["perf_failed"]) * 100, 1) if (kpi["perf_success"] + kpi["perf_failed"]) else 0 - return {"kpi": kpi, "runs": runs} + total_pages = (total_count + limit - 1) // limit if total_count else 0 + current_page = (offset // limit) + 1 if total_count else 0 + return { + "kpi": kpi, + "runs": runs, + "pagination": { + "hours": hours, + "limit": limit, + "offset": offset, + "total_count": total_count, + "total_pages": total_pages, + "page": current_page, + "has_more": offset + limit < total_count, + }, + } def get_pipeline_run_detail(run_id): diff --git a/app/db/auth_db.py b/app/db/auth_db.py index f627898..7b9c003 100644 --- a/app/db/auth_db.py +++ b/app/db/auth_db.py @@ -47,13 +47,13 @@ def send_verification_email(to_email: str, code: str) -> bool: sender = os.getenv("ASTOCK_SMTP_SENDER", username).strip() msg = EmailMessage() - msg["Subject"] = "AlphaX 邮箱验证码" + msg["Subject"] = "AlphaX Agent | Crypto 邮箱验证码" msg["From"] = sender msg["To"] = to_email msg.set_content( - f"AlphaX 邮箱验证码:{code}\n\n" + f"AlphaX Agent | Crypto 邮箱验证码:{code}\n\n" f"AI Market Intelligence.\n" - f"验证码 {VERIFY_CODE_MINUTES} 分钟内有效,用于完成 AlphaX 注册或登录验证。\n" + f"验证码 {VERIFY_CODE_MINUTES} 分钟内有效,用于完成 AlphaX Agent | Crypto 注册或登录验证。\n" f"如果不是你本人操作,请忽略本邮件。" ) msg.add_alternative( @@ -65,12 +65,12 @@ def send_verification_email(to_email: str, code: str) -> bool: