在配置管理中引入市场状态方案,允许在不同市场条件下快速切换策略(如熊市、牛市、正常、保守)。更新相关参数以自动覆盖止损、仓位和趋势过滤设置,增强策略灵活性。同时,前端组件更新以支持市场状态方案的展示与选择,提升用户体验。
118 lines
4.3 KiB
Python
118 lines
4.3 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
定时任务:自动识别市场行情并更新 MARKET_SCHEME(需开启 AUTO_MARKET_SCHEME_ENABLED)。
|
||
|
||
用法:
|
||
cd /path/to/auto_trade_sys && python scripts/update_market_scheme.py # 仅检测并打印
|
||
python scripts/update_market_scheme.py --apply # 若开启自动模式则更新 DB
|
||
python scripts/update_market_scheme.py --apply --force # 强制更新(忽略 AUTO 开关)
|
||
|
||
crontab 示例(每 4 小时执行):
|
||
0 */4 * * * cd /path/to/auto_trade_sys && python scripts/update_market_scheme.py --apply >> /tmp/update_market_scheme.log 2>&1
|
||
"""
|
||
import argparse
|
||
import logging
|
||
import os
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
# 项目根目录
|
||
proj = Path(__file__).resolve().parent.parent
|
||
sys.path.insert(0, str(proj / "backend"))
|
||
sys.path.insert(0, str(proj))
|
||
|
||
logging.basicConfig(
|
||
level=logging.INFO,
|
||
format="%(asctime)s [%(levelname)s] %(message)s",
|
||
datefmt="%Y-%m-%d %H:%M:%S",
|
||
)
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
def _get_auto_enabled() -> bool:
|
||
"""从 DB 读取 AUTO_MARKET_SCHEME_ENABLED,默认 False。"""
|
||
try:
|
||
from database.models import GlobalStrategyConfig
|
||
val = GlobalStrategyConfig.get_value("AUTO_MARKET_SCHEME_ENABLED", False)
|
||
if isinstance(val, bool):
|
||
return val
|
||
if isinstance(val, str):
|
||
return val.lower() in ("true", "1", "yes")
|
||
return bool(val)
|
||
except Exception as e:
|
||
logger.warning(f"读取 AUTO_MARKET_SCHEME_ENABLED 失败: {e},默认不自动更新")
|
||
return False
|
||
|
||
|
||
def _update_market_scheme(scheme: str) -> bool:
|
||
"""更新 MARKET_SCHEME 到 DB,并清除全局配置 Redis 缓存。"""
|
||
try:
|
||
from database.models import GlobalStrategyConfig
|
||
except ImportError as e:
|
||
logger.error(f"导入 GlobalStrategyConfig 失败: {e}")
|
||
return False
|
||
|
||
try:
|
||
GlobalStrategyConfig.set(
|
||
"MARKET_SCHEME",
|
||
scheme,
|
||
"string",
|
||
"strategy",
|
||
"市场方案:normal / bear / bull / conservative。由 update_market_scheme 定时任务自动更新。",
|
||
updated_by="update_market_scheme",
|
||
)
|
||
logger.info(f"已更新 MARKET_SCHEME = {scheme}")
|
||
|
||
# 清除全局配置 Redis 缓存,让 trading_system 下次读取时从 DB 获取
|
||
try:
|
||
import redis
|
||
redis_url = os.getenv("REDIS_URL", "redis://localhost:6379")
|
||
redis_use_tls = os.getenv("REDIS_USE_TLS", "False").lower() == "true"
|
||
redis_username = os.getenv("REDIS_USERNAME", None)
|
||
redis_password = os.getenv("REDIS_PASSWORD", None)
|
||
if redis_use_tls and not redis_url.startswith("rediss://"):
|
||
redis_url = redis_url.replace("redis://", "rediss://", 1)
|
||
r = redis.from_url(
|
||
redis_url,
|
||
username=redis_username,
|
||
password=redis_password,
|
||
decode_responses=True,
|
||
)
|
||
r.ping()
|
||
r.delete("global_strategy_config_v5")
|
||
logger.info("已清除全局配置 Redis 缓存")
|
||
except Exception as e:
|
||
logger.warning(f"清除 Redis 缓存失败(不影响 DB 更新): {e}")
|
||
|
||
return True
|
||
except Exception as e:
|
||
logger.error(f"更新 MARKET_SCHEME 失败: {e}", exc_info=True)
|
||
return False
|
||
|
||
|
||
def main():
|
||
parser = argparse.ArgumentParser(description="自动识别市场行情并可选更新 MARKET_SCHEME")
|
||
parser.add_argument("--apply", action="store_true", help="若开启自动模式则更新 DB")
|
||
parser.add_argument("--force", action="store_true", help="强制更新(忽略 AUTO_MARKET_SCHEME_ENABLED)")
|
||
args = parser.parse_args()
|
||
|
||
from trading_system.market_regime_detector import detect_market_regime
|
||
|
||
regime, details = detect_market_regime()
|
||
logger.info(f"市场行情识别: {regime} | 详情: {details}")
|
||
|
||
if not args.apply:
|
||
print(f"REGIME={regime} DETAILS={details}")
|
||
return 0
|
||
|
||
if not args.force and not _get_auto_enabled():
|
||
logger.info("AUTO_MARKET_SCHEME_ENABLED 未开启,跳过更新。如需强制更新请加 --force")
|
||
return 0
|
||
|
||
ok = _update_market_scheme(regime)
|
||
return 0 if ok else 1
|
||
|
||
|
||
if __name__ == "__main__":
|
||
sys.exit(main())
|