This commit is contained in:
薇薇安 2026-02-15 08:46:20 +08:00
parent d3ca06a8ad
commit 7abf7db2df

View File

@ -229,6 +229,8 @@ const GlobalConfig = () => {
altcoin: { altcoin: {
name: '山寨币策略(推荐)', name: '山寨币策略(推荐)',
desc: '【安全推荐】总仓65%降低回撤,大盘-1%再屏蔽多单。3%风险/单30%第一止盈/55%第二止盈30%激活移动止损、10%保护。', desc: '【安全推荐】总仓65%降低回撤,大盘-1%再屏蔽多单。3%风险/单30%第一止盈/55%第二止盈30%激活移动止损、10%保护。',
//
signatureKeys: ['AUTO_TRADE_ONLY_TRENDING', 'RSI_EXTREME_REVERSE_ENABLED', 'USE_MARGIN_CAP_FOR_TP', 'USE_MARGIN_CAP_FOR_SL', 'MAX_POSITION_PERCENT', 'MAX_DAILY_ENTRIES', 'TOP_N_SYMBOLS', 'FIXED_RISK_PERCENT'],
configs: { configs: {
// //
ATR_STOP_LOSS_MULTIPLIER: 3.0, ATR_STOP_LOSS_MULTIPLIER: 3.0,
@ -908,17 +910,24 @@ const GlobalConfig = () => {
// account // account
const isGlobalStrategyAccount = isAdmin const isGlobalStrategyAccount = isAdmin
// string "8" / "true" // 0.2 20
const toNum = (v) => (typeof v === 'number' ? v : parseFloat(v))
const toBool = (v) => (v === true || v === false ? v : (v === 'true' || String(v).toLowerCase() === 'true' || v === 1 || v === '1'))
const toRatio = (v, key) => {
const n = toNum(v)
if (Number.isNaN(n)) return null
if (key && (key.includes('PERCENT') || key.includes('PCT')) && n > 1) return n / 100
return n
}
const valueMatches = (cur, exp, key) => { const valueMatches = (cur, exp, key) => {
if (exp === true || exp === false) { if (exp === true || exp === false) return toBool(cur) === exp
const b = cur === true || cur === false ? cur : (cur === 'true' || String(cur).toLowerCase() === 'true')
return b === exp
}
if (typeof exp === 'number') { if (typeof exp === 'number') {
const n = typeof cur === 'number' ? cur : parseFloat(cur) const r = key && (key.includes('PERCENT') || key.includes('PCT'))
if (Number.isNaN(n)) return false const a = r ? toRatio(cur, key) : toNum(cur)
const tolerance = (key && (key.includes('PERCENT') || key.includes('PCT'))) ? 0.001 : 0.0001 let b = exp
return Math.abs(n - exp) <= tolerance if (r && exp > 1) b = exp / 100
if (a == null || Number.isNaN(a)) return false
return Math.abs(a - b) <= 0.002
} }
return cur === exp return cur === exp
} }
@ -926,21 +935,19 @@ const GlobalConfig = () => {
if (configs && Object.keys(configs).length > 0 && presets) { if (configs && Object.keys(configs).length > 0 && presets) {
try { try {
for (const [presetKey, preset] of Object.entries(presets)) { for (const [presetKey, preset] of Object.entries(presets)) {
const keysToCheck = preset.signatureKeys && preset.signatureKeys.length > 0
? preset.signatureKeys
: Object.keys(preset.configs)
let match = true let match = true
for (const [key, expectedValue] of Object.entries(preset.configs)) { for (const key of keysToCheck) {
const currentConfig = configs[key] const currentConfig = configs[key]
if (!currentConfig) continue // key if (!currentConfig) { match = false; break }
let cur = currentConfig.value const exp = preset.configs[key]
let exp = expectedValue if (exp === undefined) continue
if (key.includes('PERCENT') || key.includes('PCT')) { const cur = currentConfig.value
if (typeof exp === 'number' && exp > 1) exp = exp / 100 if (!valueMatches(cur, exp, key)) { match = false; break }
}
if (!valueMatches(cur, exp, key)) {
match = false
break
}
} }
if (match) { if (match && keysToCheck.length > 0) {
currentPreset = presetKey currentPreset = presetKey
break break
} }