Files
AlphaMaster/config.py
T
2026-07-07 15:17:53 +08:00

219 lines
9.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
config.py — 统一配置模块(项目根目录)
所有子模块从此文件导入 Config,废弃各自的 config.py。
MT5 连接凭证通过环境变量或 .env 文件加载。
"""
import os
try:
import MetaTrader5 as mt5
_MT5_AVAILABLE = True
except ImportError:
_MT5_AVAILABLE = False
# 测试环境无 MT5 时使用整数占位常量(与真实 MT5 值一致)
class _MT5Stub:
TIMEFRAME_M1 = 1
TIMEFRAME_M5 = 5
TIMEFRAME_M15 = 15
TIMEFRAME_M30 = 30
TIMEFRAME_H1 = 16385
TIMEFRAME_H4 = 16388
TIMEFRAME_D1 = 16408
TIMEFRAME_W1 = 32769
TIMEFRAME_MN1 = 49153
mt5 = _MT5Stub()
try:
import torch
_TORCH_AVAILABLE = True
except ImportError:
_TORCH_AVAILABLE = False
from dotenv import load_dotenv
load_dotenv()
class Config:
# ── MT5 连接 ──────────────────────────────────────────
MT5_LOGIN = int(os.getenv("MT5_LOGIN", "0"))
MT5_PASSWORD = os.getenv("MT5_PASSWORD", "")
MT5_SERVER = os.getenv("MT5_SERVER", "")
# ── 品种与周期 ────────────────────────────────────────
# TRADE_SYMBOLS:实际交易的品种(新账号,无 m 后缀)
SYMBOLS = [
# 外汇
"EURUSD", "USDJPY",
# 贵金属
"XAUUSD", "XAGUSD",
# AAVUSD 已移除:实为 Aave 加密货币,非大宗商品。波动特征与贵金属完全不匹配。
# COCOA.c 已移除:大宗商品期货,日交易~10h,时间对齐后仅8546 bar,
# 拖累整组数据量,且流动性/交易时段与贵金属不匹配。
# 美国指数
"US30.cash", "US100.cash", "US500.cash", "US2000.cash",
# 其他指数
"JP225.cash",
]
# ── 训练品种(单品种模式)──────────────────────────────
# 2026-07-07 从分组模式切换到单品种模式。原因:
# 1. 截面信息没用上:precious_metals/index 跑出的4个最优公式,没有一个用了 CS 算子
# 2. 跨品种干扰严重:XAUUSD/XAGUSD 同组时,白银 Kyle Lambda 波动是黄金4倍,
# 模型被白银主导,黄金信号被淹没
# 3. 指数组无效探索:5个美股指数相关性>0.85,截面空间狭窄,19次重启后仍是beta
# 4. 单品种策略更纯粹:因子只针对一种资产特征,实盘也更容易管理
# 每个品种独立训练,checkpoint 按 ckpt_{symbol}_step_{N}.pt 保存。
TRAINABLE_SYMBOLS = [
# 外汇(各8年数据,24h连续交易)
"EURUSD",
"USDJPY",
# 贵金属(8年数据,24h连续交易)
"XAUUSD",
# XAGUSD 已移除:白银与黄金高度相关,单品种训练收益有限,
# 且黄金已有验证策略(Sharpe 2.66),优先覆盖未挖掘品种
# 美国指数(各5年数据)
"US30.cash",
"US100.cash",
"US500.cash",
"US2000.cash",
# 日本指数
"JP225.cash",
]
# [deprecated] 相关性分组(已废弃,改用 TRAINABLE_SYMBOLS 单品种训练)
# 保留供回测参考,新训练不再使用
SYMBOL_GROUPS = {
"forex": ["EURUSD", "USDJPY"],
"precious_metals":["XAUUSD", "XAGUSD"],
"index": ["US30.cash", "US100.cash", "US500.cash", "US2000.cash", "JP225.cash"],
}
# FEATURE_SYMBOLS:用于计算截面特征的宽品种集
# 包含主要外汇、贵金属、大宗商品、主流指数,时间与 SYMBOLS 高度对齐
# REL_RET5/REL_RET20/REL_VOL 等跨资产特征将基于这 40 个品种计算截面均值
# 若设为 None,则退化为只用 SYMBOLS(5品种截面)
FEATURE_SYMBOLS = [
# 主要外汇(26个)
"EURUSD", "GBPUSD", "AUDUSD", "NZDUSD", "USDCAD", "USDCHF",
"USDJPY", "EURJPY", "GBPJPY", "AUDJPY", "EURGBP", "EURAUD",
"EURCAD", "EURCHF", "GBPAUD", "GBPCAD", "GBPCHF",
"AUDCAD", "AUDCHF", "AUDNZD", "NZDCAD", "NZDCHF", "NZDJPY",
"CADCHF", "CADJPY", "CHFJPY",
# 贵金属(3个)
"XAUUSD", "XAGUSD", "XPTUSD",
# 美元指数(1个)
"DXY.cash",
# 大宗商品(2个)
"USOIL.cash", "UKOIL.cash",
# 主流指数(8个)
"US30.cash", "US500.cash", "US100.cash", "UK100.cash",
"DE30.cash", "FR40.cash", "JP225.cash", "AUS200.cash",
]
# ── 数据参数 ──────────────────────────────────────────
TIMEFRAME = mt5.TIMEFRAME_H1 # K 线周期
# 每品种拉取的历史 K 线上限。设为极大值以使用 MT5 全部可用历史;
# 本地缓存优先:若 D:\K线数据 已有数据,fetcher 会返回本地全部历史(不截断)。
BARS_COUNT = 10_000_000
MIN_BARS = 3000 # 低于此值的品种被排除
DATA_REFRESH_INTERVAL = 300 # 秒,实盘数据刷新间隔
KLINE_CACHE_DIR = r"D:\K线数据" # 本地 K 线缓存目录
# ── 模型参数(仅供参考,训练实际使用 model_core.config.ModelConfig)────
# 训练参数的权威来源是 model_core/config.py,这里的值不生效
INPUT_DIM = 20 # 特征数(与 MT5FeatureEngineer.INPUT_DIM 一致)
BATCH_SIZE = 128 # 参见 ModelConfig.BATCH_SIZE
TRAIN_STEPS = 300 # 参见 ModelConfig.TRAIN_STEPS
MAX_FORMULA_LEN = 8 # 参见 ModelConfig.MAX_FORMULA_LEN
# DEVICE 同样以 model_core/config.py 为准(已改为 cpu,原因见该文件注释)
DEVICE = (
torch.device("cpu")
if _TORCH_AVAILABLE
else "cpu"
)
# ── 风控参数 ──────────────────────────────────────────
RISK_PER_TRADE = 0.01 # 收益优先:每笔 1 个 ATR 波动约对应账户净值 1%
COST_RATE = 0.0001 # 单边点差+佣金(forex/metals)
MAX_OPEN_POSITIONS = 4 # 最多同时持仓品种数
MAX_LOT_PER_TRADE = 1.0 # 收益优先上限;仍受 MT5 品种规格和保证金约束
# 手数校准:
# - 黄金(XAUUSD)波动金额显著更大,固定小手数避免整体风险失控
# - 其他品种在 ATR 风控手数基础上乘一个系数放大收益弹性
XAUUSD_FIXED_LOT = 0.10
OTHER_LOT_MULTIPLIER = 2.0
MIN_TRADE_EXPOSURE = 0.05 # |tanh(factor)| 小于该值时视为空仓,回测/实盘共用
# ── 策略参数 ──────────────────────────────────────────
# SIGNAL_MODE 控制信号→仓位的转换方式:
# "backtest_parity": tanh 连续仓位,与 backtest.py 完全一致(推荐)
# "threshold": sigmoid + BUY_THRESHOLD / SELL_THRESHOLD(旧逻辑)
SIGNAL_MODE = "backtest_parity"
# EXIT_MODE 控制出场机制:
# "signal": 仅靠信号翻转出场,严格对标回测
# "risk": 保留止损/止盈/追踪止损
# "hybrid": 信号翻转为主,保留紧急熔断(单日最大亏损 / 极端滑点)
EXIT_MODE = "signal"
# threshold 模式专用(SIGNAL_MODE="threshold" 时生效)
BUY_THRESHOLD = 0.70
SELL_THRESHOLD = 0.40
# risk / hybrid 模式专用(EXIT_MODE != "signal" 时生效)
STOP_LOSS_PCT = -0.02 # -2%
TAKE_PROFIT_PCT = 0.04 # +4%
TRAILING_ACTIVATION = 0.03
TRAILING_DROP = 0.015
# 时间对齐
REBALANCE_ON_BAR_CLOSE = True # True=仅新 K 线收盘后调仓,对标回测
EXECUTION_LAG_BARS = 1 # 与回测 target_ret 的执行延迟对齐
# 持仓上限:None = 不限制(严格对标回测,各品种独立)
# 设为整数(如 3)则启用约束(需回测里同步加同样约束才对标)
MAX_OPEN_POSITIONS: int | None = None
# ── 文件路径 ──────────────────────────────────────────
STRATEGY_FILE = "best_mt5_strategy.json"
PORTFOLIO_FILE = "portfolio_state.json"
STOP_SIGNAL = "STOP_SIGNAL"
# ── Magic Number ──────────────────────────────────────
MAGIC_NUMBER = 20250101
@classmethod
def get_timeframe(cls, tf_str: str) -> int:
"""将字符串(如 'H1')映射为 MT5 时间周期常量。
支持的周期:M1, M5, M15, M30, H1, H4, D1, W1, MN1
Args:
tf_str: 时间周期字符串,例如 "H1"
Returns:
对应的 MT5 TIMEFRAME_* 整数常量
Raises:
ValueError: 若 tf_str 不在支持列表中
"""
mapping = {
"M1": mt5.TIMEFRAME_M1,
"M5": mt5.TIMEFRAME_M5,
"M15": mt5.TIMEFRAME_M15,
"M30": mt5.TIMEFRAME_M30,
"H1": mt5.TIMEFRAME_H1,
"H4": mt5.TIMEFRAME_H4,
"D1": mt5.TIMEFRAME_D1,
"W1": mt5.TIMEFRAME_W1,
"MN1": mt5.TIMEFRAME_MN1,
}
if tf_str not in mapping:
raise ValueError(
f"Unknown timeframe: '{tf_str}'. "
f"Supported values: {list(mapping.keys())}"
)
return mapping[tf_str]