a
This commit is contained in:
parent
00751298bb
commit
07d3bf4398
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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'),
|
||||
|
|
|
|||
|
|
@ -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: {
|
||||
|
|
|
|||
|
|
@ -358,9 +358,10 @@ const GlobalConfig = () => {
|
|||
MIN_VOLUME_24H: 30000000, // 24H成交额≥3000万美元
|
||||
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, // 扫描前250个(增加覆盖率,从27.6%提升到46.0%)
|
||||
MIN_SIGNAL_STRENGTH: 5, // 信号强度≥5(MACD金叉/死叉已足够,配合其他筛选)
|
||||
EXCLUDE_MAJOR_COINS: true, // 排除主流币(BTC、ETH、BNB等),专注于山寨币
|
||||
|
||||
// 时间框架
|
||||
PRIMARY_INTERVAL: '4h', // 主周期4小时
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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%
|
||||
|
|
|
|||
|
|
@ -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,20 +263,66 @@ class MarketScanner:
|
|||
|
||||
change_percent = ((current_price - prev_price) / prev_price) * 100
|
||||
|
||||
# 计算技术指标
|
||||
rsi = TechnicalIndicators.calculate_rsi(close_prices, period=14)
|
||||
macd = TechnicalIndicators.calculate_macd(close_prices)
|
||||
bollinger = TechnicalIndicators.calculate_bollinger_bands(close_prices, period=20)
|
||||
atr_period = int(config.TRADING_CONFIG.get('ATR_PERIOD', 14) or 14)
|
||||
atr = TechnicalIndicators.calculate_atr(high_prices, low_prices, close_prices, period=atr_period)
|
||||
ema20 = TechnicalIndicators.calculate_ema(close_prices, period=20)
|
||||
ema50 = TechnicalIndicators.calculate_ema(close_prices, period=50)
|
||||
# ⚠️ 优化:检查技术指标计算结果缓存(基于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线的时间戳
|
||||
|
||||
# 计算4H周期的EMA20用于多周期共振检查
|
||||
ema20_4h = TechnicalIndicators.calculate_ema(close_prices_4h, period=20) if len(close_prices_4h) >= 20 else None
|
||||
# 尝试从缓存获取技术指标计算结果
|
||||
cached_indicators = None
|
||||
try:
|
||||
cached_indicators = await self.client.redis_cache.get(cache_key_indicators)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 判断市场状态
|
||||
market_regime = TechnicalIndicators.detect_market_regime(close_prices)
|
||||
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)
|
||||
atr_period = int(config.TRADING_CONFIG.get('ATR_PERIOD', 14) or 14)
|
||||
atr = TechnicalIndicators.calculate_atr(high_prices, low_prices, close_prices, period=atr_period)
|
||||
ema20 = TechnicalIndicators.calculate_ema(close_prices, period=20)
|
||||
ema50 = TechnicalIndicators.calculate_ema(close_prices, period=50)
|
||||
|
||||
# 计算4H周期的EMA20用于多周期共振检查
|
||||
ema20_4h = TechnicalIndicators.calculate_ema(close_prices_4h, period=20) if len(close_prices_4h) >= 20 else None
|
||||
|
||||
# 判断市场状态
|
||||
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
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user