From a62f1bd6e8d4786863adeefe4ba8d39b87d19603 Mon Sep 17 00:00:00 2001 From: WrBug Date: Sun, 15 Feb 2026 00:58:14 +0800 Subject: [PATCH] =?UTF-8?q?feat(cryptotail):=20=E5=B0=BE=E7=9B=98=E7=AD=96?= =?UTF-8?q?=E7=95=A5=E9=A6=96=E6=AC=A1=E6=BB=A1=E8=B6=B3=E6=9D=A1=E4=BB=B6?= =?UTF-8?q?=E6=97=B6=E6=89=93=E5=8D=B0=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在价格与时间区间首次满足且本周期未触发时打印日志 - 日志包含:开盘价、收盘价、当前市场价格、方向、策略名 - 日志放在 passMinSpreadCheck 前 - 使用 Caffeine LRU 缓存(容量100)保证每周期只打印一次 Co-authored-by: Cursor --- .../CryptoTailStrategyExecutionService.kt | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/cryptotail/CryptoTailStrategyExecutionService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/cryptotail/CryptoTailStrategyExecutionService.kt index 1d461ce..18c5fdc 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/cryptotail/CryptoTailStrategyExecutionService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/cryptotail/CryptoTailStrategyExecutionService.kt @@ -20,6 +20,8 @@ import com.wrbug.polymarketbot.util.div import com.wrbug.polymarketbot.util.fromJson import com.wrbug.polymarketbot.util.multi import com.wrbug.polymarketbot.util.toSafeBigDecimal +import com.github.benmanes.caffeine.cache.Cache +import com.github.benmanes.caffeine.cache.Caffeine import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import org.slf4j.LoggerFactory @@ -84,6 +86,11 @@ class CryptoTailStrategyExecutionService( /** 周期预置上下文缓存:(strategyId-periodStartUnix) -> PeriodContext,过期周期在读取时剔除 */ private val periodContextCache = ConcurrentHashMap() + /** 已打印「首次满足条件」日志的周期:LRU 容量 100,每周期只打一次 */ + private val conditionLoggedCache: Cache = Caffeine.newBuilder() + .maximumSize(100) + .build() + /** * 在周期内首次需要时构建并缓存预置上下文;失败返回 null,触发流程将走完整路径。 * 预置:账户、解密、费率、签名类型、CLOB 客户端;不预签订单,触发时再签名。 @@ -175,6 +182,20 @@ class CryptoTailStrategyExecutionService( val mutex = getTriggerMutex(strategy.id!!, periodStartUnix) mutex.withLock { if (triggerRepository.findByStrategyIdAndPeriodStartUnix(strategy.id!!, periodStartUnix) != null) return@withLock + val logKey = triggerLockKey(strategy.id!!, periodStartUnix) + if (conditionLoggedCache.getIfPresent(logKey) == null) { + conditionLoggedCache.put(logKey, periodStartUnix + strategy.intervalSeconds) + val oc = binanceKlineService.getCurrentOpenClose(strategy.intervalSeconds, periodStartUnix) + val openPrice = oc?.first?.toPlainString() ?: "-" + val closePrice = oc?.second?.toPlainString() ?: "-" + val strategyName = strategy.name?.takeIf { it.isNotBlank() } ?: "尾盘策略-${strategy.marketSlugPrefix}" + val direction = if (outcomeIndex == 0) "Up" else "Down" + logger.info( + "尾盘策略首次满足条件: strategyName=$strategyName, strategyId=${strategy.id}, " + + "openPrice=$openPrice, closePrice=$closePrice, marketPrice=${bestBid.toPlainString()}, " + + "direction=$direction, outcomeIndex=$outcomeIndex" + ) + } if (!passMinSpreadCheck(strategy, periodStartUnix, outcomeIndex)) return@withLock ensurePeriodContext(strategy, periodStartUnix, tokenIds, marketTitle) placeOrderForTrigger(strategy, periodStartUnix, marketTitle, tokenIds, outcomeIndex, bestBid)