From e264a45bb305aba038646c9481b62c6c3561089c Mon Sep 17 00:00:00 2001 From: niuben Date: Sun, 30 Nov 2025 18:06:26 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/config/agent.yaml | 4 ++-- backend/trading/binance_futures.py | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/backend/config/agent.yaml b/backend/config/agent.yaml index ea2f70b..485640d 100644 --- a/backend/config/agent.yaml +++ b/backend/config/agent.yaml @@ -2,8 +2,8 @@ agent: # LLM Configuration - Compatible with any OpenAI API format - model_name: "deepseek-chat" # Model name (gpt-4o, claude-3-5-sonnet, deepseek-chat, qwen-plus, etc.) - base_url: "https://api.deepseek.com/v1" # API base URL (null for OpenAI, or custom like "https://api.deepseek.com/v1") + model_name: "MiniMax-M2" # Model name (gpt-4o, claude-3-5-sonnet, deepseek-chat, qwen-plus, etc.) + base_url: "https://ai.gitee.com/v1" # API base URL (null for OpenAI, or custom like "https://api.deepseek.com/v1") api_key: "${OPENAI_API_KEY}" # API key environment variable # Trading Configuration diff --git a/backend/trading/binance_futures.py b/backend/trading/binance_futures.py index 8d2f98e..97c9977 100644 --- a/backend/trading/binance_futures.py +++ b/backend/trading/binance_futures.py @@ -21,6 +21,13 @@ def __init__(self): # 创建CCXT Binance Futures实例 from config.settings import config exchange_config = config.exchange.get_ccxt_config() + + exchange_config.update({ + "proxies": { + "http": "http://127.0.0.1:7890", + "https": "http://127.0.0.1:7890", + } + }) self.exchange = ccxt.binance(exchange_config) # 设置默认类型为期货 From 575d49236eb14d40569425e3a7c79ba70d267bdd Mon Sep 17 00:00:00 2001 From: niuben Date: Sun, 7 Dec 2025 15:52:01 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/api/routes.py | 25 ++++++++++++++++- backend/config/agent.yaml | 36 ++++++++++++++++++++---- backend/config/agent_config.py | 1 + backend/services/prompt_service.py | 37 +++++++++++++++++++++---- frontend/src/app/settings/page.tsx | 20 +++++++------- frontend/src/lib/config.ts | 44 +++++++++++++++++++++++++----- frontend/src/middleware.ts | 11 ++++++-- 7 files changed, 143 insertions(+), 31 deletions(-) diff --git a/backend/api/routes.py b/backend/api/routes.py index 22cbf36..7711646 100644 --- a/backend/api/routes.py +++ b/backend/api/routes.py @@ -19,6 +19,9 @@ from trading.position_service import get_position_service from services.prompt_service import get_trading_strategy, set_trading_strategy +from functools import wraps +from fastapi import HTTPException, status + router = APIRouter() @@ -49,6 +52,19 @@ class CacheInfoResponse(BaseModel): symbol_details: Dict[str, Dict[str, Any]] +def check_control_permission(func): + """装饰器:检查控制操作权限""" + @wraps(func) + async def wrapper(*args, **kwargs): + if not config.system.allow_control_operations: + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="Control operations are disabled for security reasons. Set allow_control_operations=true in agent.yaml to enable." + ) + return await func(*args, **kwargs) + return wrapper + + @router.get("/health", response_model=HealthResponse) async def health_check(): """System health check""" @@ -182,7 +198,8 @@ async def get_system_config(): "system": { "host": config.system.host, "port": config.system.port, - "log_level": config.system.log_level + "log_level": config.system.log_level, + "allow_control_operations": config.system.allow_control_operations }, "risk": { "max_position_size_percent": config.default_risk.max_position_size_percent, @@ -370,6 +387,7 @@ class AgentStatusResponse(BaseModel): # Agent control endpoints @router.post("/agent/start", response_model=AgentControlResponse) +@check_control_permission async def start_agent(): """启动 AI Agent 调度器""" try: @@ -405,6 +423,7 @@ async def start_agent(): @router.post("/agent/stop", response_model=AgentControlResponse) +@check_control_permission async def stop_agent(): """停止 AI Agent 调度器""" try: @@ -670,6 +689,7 @@ async def get_trade_stats(days: int = 30): @router.post("/trading/history/reset") +@check_control_permission async def reset_trading_history(init_time: Optional[str] = None): """重置交易历史系统(清空所有数据并重新初始化)""" try: @@ -695,6 +715,7 @@ async def reset_trading_history(init_time: Optional[str] = None): @router.post("/trading/history/sync") +@check_control_permission async def sync_trading_history(full_sync: bool = False): """手动同步交易历史""" try: @@ -775,6 +796,7 @@ async def get_current_trading_strategy(): @router.post("/trading/strategy", response_model=TradingStrategyUpdateResponse) +@check_control_permission async def update_trading_strategy(request: TradingStrategyRequest): """更新用户自定义交易策略""" try: @@ -801,6 +823,7 @@ async def update_trading_strategy(request: TradingStrategyRequest): @router.delete("/trading/strategy", response_model=TradingStrategyUpdateResponse) +@check_control_permission async def reset_trading_strategy(): """重置交易策略为默认值(删除数据库中的自定义配置)""" try: diff --git a/backend/config/agent.yaml b/backend/config/agent.yaml index 485640d..fc5cfeb 100644 --- a/backend/config/agent.yaml +++ b/backend/config/agent.yaml @@ -20,12 +20,35 @@ agent: # 用户可配置的交易策略(会被数据库覆盖) trading_strategy: | - 1. 单一币种仓位上限为可用余额的 20% - 2. 止损止盈 - 可以用小时级 NATR 为单位,盈亏比 2:1 + 策略前提/风控设定: + - 单一币种一次建仓最大不超过 可用余额 的 20%。 + - 止损/止盈设定: 以小时级 NATR 为单位 (例如用当前 NATR * k),盈亏比设为 2:1。 + - 不要随意建仓 —— 只有当所有关键指标一致指向同一方向时 (趋势、波动性、量/成交、动能 等) 才考虑建仓。 + - 不要随意主动平仓 —— 已设置止损/止盈后,除非出现强烈趋势反转信号,否则维持持仓。 + + 入场逻辑 (开多/开空): + - 计算近期 NATR (例如过去 14 根小时线),并根据当前价格波动与 NATR 判断市场是否处于“合适波动/趋势启动”阶段。 + - 如果 NATR 显著上升 (例如突破其近期均值),说明波动性放大 → 市场可能进入大幅波动阶段,适合趋势交易或突破交易。 + - 同时确认趋势方向 (可以用趋势指标,比如均线、动量、ADX/DI/MACD 等) 和成交量/动能辅助信号 —— 只有当趋势与波动性和动量共同指向同一方向时,才考虑建仓。 + + 止损/止盈逻辑: + - 止损设置为入场价 ± (NATR * k1),止盈设置为入场价 + (方向 × NATR * k2),且 k2 ≈ 2 * k1 以符合盈亏比 2:1。 + - 随着价格移动,可以考虑将止损跟踪 (trailing stop) —— 例如用波动性停止 (类似于 “Volatility Stop / Chandelier Exit” 思路,用 NATR 或 ATR 动态调整止损), 以保护盈利。 + + 平仓/加仓规则: + - 不主动平仓,除非有强烈趋势反转信号 (例如趋势指标反转 + 波动性下降 + 动量逆转/成交量萎缩)。 + - 若价格朝有利方向运行,可考虑分批加仓 (不过总仓位仍 ≤ 可用余额 20%)。 + - 加仓/加仓前也必须满足所有指标一致 (趋势 + 波动 + 动量 + 成交量 等) 。 + + 风险控制/资金管理: + - 总仓位风险分散 —— 不把所有资金压在一个币种或一个方向上。 + - 使用 NATR 作为 “波动性滤波器 (volatility filter)” —— 若 NATR 太低 (行情太平),避免入场;若 NATR 太高 (过度波动或躁动),适当缩减仓位或等待稳定。 + - 保持冷静 / 避免情绪交易 (遵守规则,不被 FOMO 诱惑) 。 + + 记录/复盘: + - 每次入场/出场都记录 NATR 值、入场价、止损价、止盈价、成交量、趋势/动量指标值。 + - 定期统计胜率、盈亏比、最大回撤、每笔交易波动性 (NATR 倍数) 等,以评估策略表现、优化参数。 - 原则: - 1. 不要随意建仓,除非所有指标都指向一个方向,否则不要轻易下单 - 2. 不要随意主动平仓,因为已经设置了止盈止损了 - 除非有强烈的信号指示趋势已经反转,才需要平仓 # Exchange Configuration exchange: @@ -74,4 +97,5 @@ logging: system: host: "0.0.0.0" port: 8000 - max_concurrent_decisions: 1 # Prevent overlapping decisions \ No newline at end of file + max_concurrent_decisions: 1 # Prevent overlapping decisions + allow_control_operations: true # 是否允许前端控制操作(启动/停止 agent、修改策略等) \ No newline at end of file diff --git a/backend/config/agent_config.py b/backend/config/agent_config.py index 9041588..4f88bd6 100644 --- a/backend/config/agent_config.py +++ b/backend/config/agent_config.py @@ -123,6 +123,7 @@ class SystemConfig(BaseModel): port: int = 8000 log_level: str = "INFO" max_concurrent_decisions: int = 1 + allow_control_operations: bool = False # 是否允许前端控制操作 class AppConfig(BaseModel): diff --git a/backend/services/prompt_service.py b/backend/services/prompt_service.py index af5a6cc..cdd3dac 100644 --- a/backend/services/prompt_service.py +++ b/backend/services/prompt_service.py @@ -12,12 +12,39 @@ logger = logging.getLogger("AlphaTransformer") # 代码默认的交易策略 -DEFAULT_TRADING_STRATEGY = """1. 单一币种仓位上限为可用余额的 20% -2. 止损止盈 - 可以用小时级 NATR 为单位,盈亏比 2:1 +DEFAULT_TRADING_STRATEGY = """ -原则: -1. 不要随意建仓,除非所有指标都指向一个方向,否则不要轻易下单 -2. 不要随意主动平仓,因为已经设置了止盈止损了 - 除非有强烈的信号指示趋势已经反转,才需要平仓""" +策略前提/风控设定: +- 单一币种一次建仓最大不超过 可用余额 的 20%。 +- 止损/止盈设定: 以小时级 NATR 为单位 (例如用当前 NATR * k),盈亏比设为 2:1。 +- 不要随意建仓 —— 只有当所有关键指标一致指向同一方向时 (趋势、波动性、量/成交、动能 等) 才考虑建仓。 +- 不要随意主动平仓 —— 已设置止损/止盈后,除非出现强烈趋势反转信号,否则维持持仓。 + +入场逻辑 (开多/开空): +- 计算近期 NATR (例如过去 14 根小时线),并根据当前价格波动与 NATR 判断市场是否处于“合适波动/趋势启动”阶段。 +- 如果 NATR 显著上升 (例如突破其近期均值),说明波动性放大 → 市场可能进入大幅波动阶段,适合趋势交易或突破交易。 +- 同时确认趋势方向 (可以用趋势指标,比如均线、动量、ADX/DI/MACD 等) 和成交量/动能辅助信号 —— 只有当趋势与波动性和动量共同指向同一方向时,才考虑建仓。 + +止损/止盈逻辑: +- 止损设置为入场价 ± (NATR * k1),止盈设置为入场价 + (方向 × NATR * k2),且 k2 ≈ 2 * k1 以符合盈亏比 2:1。 +- 随着价格移动,可以考虑将止损跟踪 (trailing stop) —— 例如用波动性停止 (类似于 “Volatility Stop / Chandelier Exit” 思路,用 NATR 或 ATR 动态调整止损), 以保护盈利。 + +平仓/加仓规则: +- 不主动平仓,除非有强烈趋势反转信号 (例如趋势指标反转 + 波动性下降 + 动量逆转/成交量萎缩)。 +- 若价格朝有利方向运行,可考虑分批加仓 (不过总仓位仍 ≤ 可用余额 20%)。 +- 加仓/加仓前也必须满足所有指标一致 (趋势 + 波动 + 动量 + 成交量 等) 。 + +风险控制/资金管理: +- 总仓位风险分散 —— 不把所有资金压在一个币种或一个方向上。 +- 使用 NATR 作为 “波动性滤波器 (volatility filter)” —— 若 NATR 太低 (行情太平),避免入场;若 NATR 太高 (过度波动或躁动),适当缩减仓位或等待稳定。 +- 保持冷静 / 避免情绪交易 (遵守规则,不被 FOMO 诱惑) 。 + +记录/复盘: +- 每次入场/出场都记录 NATR 值、入场价、止损价、止盈价、成交量、趋势/动量指标值。 +- 定期统计胜率、盈亏比、最大回撤、每笔交易波动性 (NATR 倍数) 等,以评估策略表现、优化参数。 + + +""" # 缓存配置 _strategy_cache: Optional[str] = None diff --git a/frontend/src/app/settings/page.tsx b/frontend/src/app/settings/page.tsx index 2c619d0..722dfa6 100644 --- a/frontend/src/app/settings/page.tsx +++ b/frontend/src/app/settings/page.tsx @@ -14,6 +14,7 @@ import type { AgentStatus } from "@/lib/api"; import Toast from "@/components/Toast"; import Sidebar from "@/components/Sidebar"; import Header from "@/components/Header"; +import { isControlOperationsAllowed } from "@/lib/config"; export default function SettingsPage() { const [strategy, setStrategy] = useState(""); @@ -25,6 +26,7 @@ export default function SettingsPage() { text: string; } | null>(null); const [sidebarOpen, setSidebarOpen] = useState(false); + const [controlAllowed, setControlAllowed] = useState(false); // Bot status const [botStatus, setBotStatus] = useState({ @@ -43,6 +45,7 @@ export default function SettingsPage() { useEffect(() => { loadStrategy(); loadBotStatus(); + isControlOperationsAllowed().then(setControlAllowed); }, []); const loadStrategy = async () => { @@ -82,9 +85,8 @@ export default function SettingsPage() { await loadBotStatus(); // Reload status } catch (error) { - const fallbackMessage = `Failed to ${ - botStatus.is_running ? "stop" : "start" - } trading bot`; + const fallbackMessage = `Failed to ${botStatus.is_running ? "stop" : "start" + } trading bot`; setMessage({ type: "error", text: error instanceof Error ? error.message : fallbackMessage, @@ -204,11 +206,10 @@ export default function SettingsPage() { Trading Bot Status: {botStatus.is_running ? "RUNNING" : "STOPPED"} @@ -218,12 +219,11 @@ export default function SettingsPage() {