9: Support percentage expressions in alarm targets

This commit is contained in:
2026-06-21 18:17:34 +02:00
parent b74e4ad286
commit 0a6a7b4a3b
2 changed files with 60 additions and 5 deletions
+8 -4
View File
@@ -1,4 +1,8 @@
# ID Asset Direction Target TRIGGER SEVERITY NOTE # Id Asset Direction Target Trigger Severity Note
################################################################################################################ ######################################################################################################################
1 SOL BELOW 170.0 ONETIME INFO "EMERGENCY: Risiko for Perps Solana long LIKVIDERING!" 1 SOL ABOVE 97.03-1.25% ONETIME CRITICAL "CRITICAL: Risiko for Perps Solana short LIKVIDERING!"
2 SOL BELOW 71.4 ONETIME CRITICAL "CRITICAL: Risiko for Solana Raydium LÅN LIKVIDERING!" 2 SOL BELOW 48.72+1.25% ONETIME CRITICAL "CRITICAL: Risiko for Perps Solana long LIKVIDERING!"
3 BTC ABOVE 85032.87-1% ONETIME CRITICAL "CRITICAL: Risiko for Perps Bitcoin short LIKVIDERING!"
4 BTC BELOW 42779.40+1% ONETIME CRITICAL "CRITICAL: Risiko for Perps Bitcoin long LIKVIDERING!"
5 ETH ABOVE 2296.13-1% ONETIME CRITICAL "CRITICAL: Risiko for Perps Ethereum short LIKVIDERING!"
6 ETH BELOW 1155.19+1% ONETIME CRITICAL "CRITICAL: Risiko for Perps Ethereum long LIKVIDERING!"
@@ -53,7 +53,7 @@ public final class AlarmConfigurationParser {
cursor.nextToken("direction").toUpperCase(Locale.ROOT) cursor.nextToken("direction").toUpperCase(Locale.ROOT)
); );
BigDecimal target = new BigDecimal(cursor.nextToken("target")); BigDecimal target = parseTarget(cursor.nextToken("target"));
AlarmTrigger trigger = AlarmTrigger.valueOf( AlarmTrigger trigger = AlarmTrigger.valueOf(
cursor.nextToken("trigger").toUpperCase(Locale.ROOT) cursor.nextToken("trigger").toUpperCase(Locale.ROOT)
@@ -83,6 +83,57 @@ public final class AlarmConfigurationParser {
); );
} }
private static BigDecimal parseTargetPercentage(
String targetStr,
int operatorIndex,
boolean add
) {
BigDecimal base = new BigDecimal(targetStr.substring(0, operatorIndex));
String percentStr = targetStr.substring(operatorIndex + 1, targetStr.length() - 1);
BigDecimal percent = new BigDecimal(percentStr);
BigDecimal delta = base
.multiply(percent)
.divide(BigDecimal.valueOf(100));
BigDecimal target = add ? base.add(delta) : base.subtract(delta);
validateTarget(base, targetStr);
validateTarget(percent, targetStr);
validateTarget(target, targetStr);
return target;
}
private static void validateTarget(BigDecimal target, String originalTargetStr) {
if (target.compareTo(BigDecimal.ZERO) < 0) {
throw new IllegalArgumentException(
"Target must be zero or positive: " + originalTargetStr
);
}
}
private static BigDecimal parseTarget(String targetStr) {
String trimmedTargetStr = targetStr.trim();
if (trimmedTargetStr.endsWith("%")) {
int plusIndex = trimmedTargetStr.indexOf('+');
int minusIndex = trimmedTargetStr.indexOf('-', 1);
if (plusIndex >= 0) {
return parseTargetPercentage(trimmedTargetStr, plusIndex, true);
}
if (minusIndex >= 0) {
return parseTargetPercentage(trimmedTargetStr, minusIndex, false);
}
}
BigDecimal target = new BigDecimal(trimmedTargetStr);
validateTarget(target, targetStr);
return target;
}
private static final class Cursor { private static final class Cursor {
private Cursor(String line) { private Cursor(String line) {
this.line = line; this.line = line;