feat(cryptotail): 尾盘策略首次满足条件时打印日志
- 在价格与时间区间首次满足且本周期未触发时打印日志 - 日志包含:开盘价、收盘价、当前市场价格、方向、策略名 - 日志放在 passMinSpreadCheck 前 - 使用 Caffeine LRU 缓存(容量100)保证每周期只打印一次 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+21
@@ -20,6 +20,8 @@ import com.wrbug.polymarketbot.util.div
|
|||||||
import com.wrbug.polymarketbot.util.fromJson
|
import com.wrbug.polymarketbot.util.fromJson
|
||||||
import com.wrbug.polymarketbot.util.multi
|
import com.wrbug.polymarketbot.util.multi
|
||||||
import com.wrbug.polymarketbot.util.toSafeBigDecimal
|
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.Mutex
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
@@ -84,6 +86,11 @@ class CryptoTailStrategyExecutionService(
|
|||||||
/** 周期预置上下文缓存:(strategyId-periodStartUnix) -> PeriodContext,过期周期在读取时剔除 */
|
/** 周期预置上下文缓存:(strategyId-periodStartUnix) -> PeriodContext,过期周期在读取时剔除 */
|
||||||
private val periodContextCache = ConcurrentHashMap<String, PeriodContext>()
|
private val periodContextCache = ConcurrentHashMap<String, PeriodContext>()
|
||||||
|
|
||||||
|
/** 已打印「首次满足条件」日志的周期:LRU 容量 100,每周期只打一次 */
|
||||||
|
private val conditionLoggedCache: Cache<String, Long> = Caffeine.newBuilder()
|
||||||
|
.maximumSize(100)
|
||||||
|
.build()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在周期内首次需要时构建并缓存预置上下文;失败返回 null,触发流程将走完整路径。
|
* 在周期内首次需要时构建并缓存预置上下文;失败返回 null,触发流程将走完整路径。
|
||||||
* 预置:账户、解密、费率、签名类型、CLOB 客户端;不预签订单,触发时再签名。
|
* 预置:账户、解密、费率、签名类型、CLOB 客户端;不预签订单,触发时再签名。
|
||||||
@@ -175,6 +182,20 @@ class CryptoTailStrategyExecutionService(
|
|||||||
val mutex = getTriggerMutex(strategy.id!!, periodStartUnix)
|
val mutex = getTriggerMutex(strategy.id!!, periodStartUnix)
|
||||||
mutex.withLock {
|
mutex.withLock {
|
||||||
if (triggerRepository.findByStrategyIdAndPeriodStartUnix(strategy.id!!, periodStartUnix) != null) return@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
|
if (!passMinSpreadCheck(strategy, periodStartUnix, outcomeIndex)) return@withLock
|
||||||
ensurePeriodContext(strategy, periodStartUnix, tokenIds, marketTitle)
|
ensurePeriodContext(strategy, periodStartUnix, tokenIds, marketTitle)
|
||||||
placeOrderForTrigger(strategy, periodStartUnix, marketTitle, tokenIds, outcomeIndex, bestBid)
|
placeOrderForTrigger(strategy, periodStartUnix, marketTitle, tokenIds, outcomeIndex, bestBid)
|
||||||
|
|||||||
Reference in New Issue
Block a user