This commit is contained in:
薇薇安 2026-01-25 16:31:37 +08:00
parent 00751298bb
commit 07d3bf4398
7 changed files with 95 additions and 25 deletions

View File

@ -390,6 +390,12 @@ async def get_global_configs(
"category": "scan",
"description": "严格成交量过滤24H Volume低于此值USD直接剔除",
},
"EXCLUDE_MAJOR_COINS": {
"value": True,
"type": "boolean",
"category": "scan",
"description": "是否排除主流币BTC、ETH、BNB等专注于山寨币。山寨币策略建议开启。",
},
"USE_TRAILING_STOP": {
"value": False,
"type": "boolean",

View File

@ -745,7 +745,6 @@ class ConfigManager:
# 涨跌幅阈值
'MIN_CHANGE_PERCENT': eff_get('MIN_CHANGE_PERCENT', 2.0),
'TOP_N_SYMBOLS': eff_get('TOP_N_SYMBOLS', 10),
# 风险控制
'STOP_LOSS_PERCENT': eff_get('STOP_LOSS_PERCENT', 0.10), # 默认10%
@ -767,8 +766,9 @@ class ConfigManager:
# 市场扫描1小时主周期
'SCAN_INTERVAL': eff_get('SCAN_INTERVAL', 3600), # 1小时
'TOP_N_SYMBOLS': eff_get('TOP_N_SYMBOLS', 10), # 每次扫描后处理的交易对数量
'MAX_SCAN_SYMBOLS': eff_get('MAX_SCAN_SYMBOLS', 500), # 扫描的最大交易对数量0表示扫描所有
'TOP_N_SYMBOLS': eff_get('TOP_N_SYMBOLS', 8), # 每次扫描后处理的交易对数量增加到8给更多选择余地
'MAX_SCAN_SYMBOLS': eff_get('MAX_SCAN_SYMBOLS', 250), # 扫描的最大交易对数量增加到250提升覆盖率到46%
'EXCLUDE_MAJOR_COINS': eff_get('EXCLUDE_MAJOR_COINS', True), # 是否排除主流币BTC、ETH、BNB等专注于山寨币
'KLINE_INTERVAL': eff_get('KLINE_INTERVAL', '1h'),
'PRIMARY_INTERVAL': eff_get('PRIMARY_INTERVAL', '1h'),
'CONFIRM_INTERVAL': eff_get('CONFIRM_INTERVAL', '4h'),

View File

@ -82,9 +82,9 @@ const ConfigPanel = () => {
USE_FIXED_RISK_SIZING: true, FIXED_RISK_PERCENT: 1.0,
USE_TRAILING_STOP: true, TRAILING_STOP_ACTIVATION: 30.0, TRAILING_STOP_PROTECT: 15.0,
MAX_POSITION_PERCENT: 1.5, MAX_TOTAL_POSITION_PERCENT: 12.0, MAX_DAILY_ENTRIES: 5,
MIN_VOLUME_24H: 30000000, MIN_VOLATILITY: 3.0, TOP_N_SYMBOLS: 5, MIN_SIGNAL_STRENGTH: 5,
SCAN_INTERVAL: 3600, SMART_ENTRY_ENABLED: true, AUTO_TRADE_ONLY_TRENDING: true,
AUTO_TRADE_ALLOW_4H_NEUTRAL: true,
MIN_VOLUME_24H: 30000000, MIN_VOLATILITY: 3.0, TOP_N_SYMBOLS: 8, MIN_SIGNAL_STRENGTH: 5,
MAX_SCAN_SYMBOLS: 250, SCAN_INTERVAL: 3600, SMART_ENTRY_ENABLED: true, AUTO_TRADE_ONLY_TRENDING: true,
AUTO_TRADE_ALLOW_4H_NEUTRAL: true, EXCLUDE_MAJOR_COINS: true,
},
},
swing: {

View File

@ -358,9 +358,10 @@ const GlobalConfig = () => {
MIN_VOLUME_24H: 30000000, // 24H3000
MIN_VOLUME_24H_STRICT: 50000000, // 5000
MIN_VOLATILITY: 3.0, // 3%
TOP_N_SYMBOLS: 5, // 5
MAX_SCAN_SYMBOLS: 150, // 150
TOP_N_SYMBOLS: 8, // 8
MAX_SCAN_SYMBOLS: 250, // 25027.6%46.0%
MIN_SIGNAL_STRENGTH: 5, // 5MACD/
EXCLUDE_MAJOR_COINS: true, // BTCETHBNB
//
PRIMARY_INTERVAL: '4h', // 4

View File

@ -565,9 +565,9 @@ class BinanceClient:
'ts': now_ms
}
# 写入 Redis 缓存TTL: 30秒
await self.redis_cache.set(cache_key, result, ttl=30)
logger.debug(f"批量获取到 {len(result)} 个交易对的24小时行情数据已缓存")
# 写入 Redis 缓存TTL: 60秒多个账户可以共用
await self.redis_cache.set(cache_key, result, ttl=60)
logger.debug(f"批量获取到 {len(result)} 个交易对的24小时行情数据已缓存 (TTL: 60秒)")
return result
except BinanceAPIException as e:
error_code = e.code if hasattr(e, 'code') else None

View File

@ -213,8 +213,9 @@ def _get_trading_config():
'MIN_POSITION_PERCENT': 0.01, # 最小仓位1%
'MIN_MARGIN_USDT': 5.0, # 最小保证金5美元
'MIN_CHANGE_PERCENT': 0.5, # 最小价格变动0.5%
'TOP_N_SYMBOLS': 5, # 只做信号最强的5个专注优质机会
'MAX_SCAN_SYMBOLS': 150, # 扫描前150个覆盖主流山寨
'TOP_N_SYMBOLS': 8, # 选择信号最强的8个给更多选择余地避免错过好机会
'MAX_SCAN_SYMBOLS': 250, # 扫描前250个增加覆盖率从27.6%提升到46.0%
'EXCLUDE_MAJOR_COINS': True, # 排除主流币BTC、ETH、BNB等专注于山寨币
'STOP_LOSS_PERCENT': 0.15, # 止损15%(山寨币波动大,止损要宽)
'TAKE_PROFIT_PERCENT': 0.60, # 止盈60%4:1盈亏比追求大赢家
'MIN_STOP_LOSS_PRICE_PCT': 0.02, # 最小止损价格变动2%

View File

@ -71,6 +71,22 @@ class MarketScanner:
symbols = all_symbols
logger.info(f"扫描所有 {len(symbols)} 个USDT交易对")
# 过滤主流币(山寨币策略应该排除主流币)
exclude_major_coins = cfg.get('EXCLUDE_MAJOR_COINS', True)
if exclude_major_coins:
# 主流币列表市值排名前15的主流币
major_coins = {
'BTCUSDT', 'ETHUSDT', 'BNBUSDT', 'SOLUSDT', 'XRPUSDT',
'ADAUSDT', 'DOGEUSDT', 'DOTUSDT', 'AVAXUSDT', 'MATICUSDT',
'LINKUSDT', 'UNIUSDT', 'ATOMUSDT', 'ETCUSDT', 'LTCUSDT',
'NEARUSDT', 'APTUSDT', 'ARBUSDT', 'OPUSDT', 'SUIUSDT'
}
symbols_before = len(symbols)
symbols = [s for s in symbols if s not in major_coins]
excluded_count = symbols_before - len(symbols)
if excluded_count > 0:
logger.info(f"排除主流币 {excluded_count} 个,剩余 {len(symbols)} 个交易对(专注于山寨币)")
# 先批量获取所有交易对的24小时行情数据减少API请求
logger.info(f"批量获取 {len(symbols)} 个交易对的24小时行情数据...")
all_tickers = await self.client.get_all_tickers_24h()
@ -247,7 +263,35 @@ class MarketScanner:
change_percent = ((current_price - prev_price) / prev_price) * 100
# 计算技术指标
# ⚠️ 优化检查技术指标计算结果缓存基于K线数据的最后更新时间
# 如果K线数据没有更新可以直接使用缓存的技术指标
primary_interval = config.TRADING_CONFIG.get('PRIMARY_INTERVAL', '1h')
confirm_interval = config.TRADING_CONFIG.get('CONFIRM_INTERVAL', '4h')
cache_key_indicators = f"indicators:{symbol}:{primary_interval}:{confirm_interval}"
last_kline_time = int(klines[-1][0]) if klines else 0 # 最后一根K线的时间戳
# 尝试从缓存获取技术指标计算结果
cached_indicators = None
try:
cached_indicators = await self.client.redis_cache.get(cache_key_indicators)
except Exception:
pass
use_cached_indicators = False
if cached_indicators and cached_indicators.get('last_kline_time') == last_kline_time:
# 缓存命中,使用缓存的技术指标
use_cached_indicators = True
logger.debug(f"{symbol} 使用缓存的技术指标计算结果")
rsi = cached_indicators.get('rsi')
macd = cached_indicators.get('macd')
bollinger = cached_indicators.get('bollinger')
atr = cached_indicators.get('atr')
ema20 = cached_indicators.get('ema20')
ema50 = cached_indicators.get('ema50')
ema20_4h = cached_indicators.get('ema20_4h')
market_regime = cached_indicators.get('marketRegime')
else:
# 缓存未命中,重新计算技术指标
rsi = TechnicalIndicators.calculate_rsi(close_prices, period=14)
macd = TechnicalIndicators.calculate_macd(close_prices)
bollinger = TechnicalIndicators.calculate_bollinger_bands(close_prices, period=20)
@ -262,6 +306,24 @@ class MarketScanner:
# 判断市场状态
market_regime = TechnicalIndicators.detect_market_regime(close_prices)
# 保存技术指标计算结果到缓存TTL: 30秒与K线缓存一致
try:
indicators_cache = {
'last_kline_time': last_kline_time,
'rsi': rsi,
'macd': macd,
'bollinger': bollinger,
'atr': atr,
'ema20': ema20,
'ema50': ema50,
'ema20_4h': ema20_4h,
'marketRegime': market_regime,
}
await self.client.redis_cache.set(cache_key_indicators, indicators_cache, ttl=30)
logger.debug(f"{symbol} 技术指标计算结果已缓存 (TTL: 30秒)")
except Exception as e:
logger.debug(f"{symbol} 缓存技术指标计算结果失败: {e}")
# 计算交易信号得分(用于排序)
signal_score = 0