44: Restrict CROSSING conditions to directional operators only

This commit is contained in:
2026-08-05 10:12:39 +02:00
parent f5c449fe23
commit bf492c9db1
2 changed files with 31 additions and 3 deletions
+5 -3
View File
@@ -226,15 +226,17 @@ On the first accepted oracle price after startup, an already-satisfied `ONETIME`
- Remaining inside the condition does not trigger again.
- Leaving the condition re-arms the alarm, so the next entry triggers again.
- A grace period is not supported; `CROSSING:1m` is rejected.
- Only the strict directional comparisons `<` and `>` are supported.
- `=`, `<=`, `>=`, and range conditions are rejected during configuration parsing.
The condition determines the crossing direction. For example:
```text
19 SOL >={{SOL_LONG_ENTRY_PRICE}} CROSSING
20 SOL <{{SOL_LONG_ENTRY_PRICE}} CROSSING
19 SOL >{{SOL_LONG_ENTRY_PRICE}} CROSSING
20 SOL <{{SOL_LONG_ENTRY_PRICE}} CROSSING
```
Alarm 19 triggers when the price enters the profitable side from below. Alarm 20 triggers when it enters the losing side from above. With a range condition, `CROSSING` triggers whenever the price enters the range from either side.
Alarm 19 triggers when the price moves from at or below the entry price to above it. Alarm 20 triggers when the price moves from at or above the entry price to below it. Landing exactly on the entry price is not a crossing.
### `PERSISTENT`
@@ -58,6 +58,11 @@ public final class AlarmConfigurationParser {
cursor.nextToken("trigger")
);
validateConditionForTrigger(
conditionExpression,
triggerConfiguration.trigger()
);
cursor.skipWhitespace();
if (!cursor.atEnd() && cursor.current() != '#') {
throw new IllegalArgumentException(
@@ -89,6 +94,27 @@ public final class AlarmConfigurationParser {
return conditionExpression;
}
private static void validateConditionForTrigger(
String conditionExpression,
AlarmTrigger trigger
) {
if (trigger != AlarmTrigger.CROSSING) {
return;
}
boolean directionalCondition =
(conditionExpression.startsWith("<")
&& !conditionExpression.startsWith("<="))
|| (conditionExpression.startsWith(">")
&& !conditionExpression.startsWith(">="));
if (!directionalCondition) {
throw new IllegalArgumentException(
"CROSSING requires a '<' or '>' condition: " + conditionExpression
);
}
}
private static TriggerConfiguration parseTrigger(String triggerText) {
String normalized = triggerText.toUpperCase(Locale.ROOT);