Compare commits
3 Commits
48f087dc6e
...
6ff5cb73bb
| Author | SHA256 | Date | |
|---|---|---|---|
| 6ff5cb73bb | |||
| d62a2af2ee | |||
| 091de624f6 |
+54
-3
@@ -59,8 +59,8 @@ public final class AlarmConfigurationParser {
|
||||
|
||||
BigDecimal target = parseTarget(cursor.nextToken("target"));
|
||||
|
||||
AlarmTrigger trigger = AlarmTrigger.valueOf(
|
||||
cursor.nextToken("trigger").toUpperCase(Locale.ROOT)
|
||||
TriggerConfiguration triggerConfiguration = parseTrigger(
|
||||
cursor.nextToken("trigger")
|
||||
);
|
||||
|
||||
AlarmSeverity severity = AlarmSeverity.valueOf(
|
||||
@@ -81,7 +81,8 @@ public final class AlarmConfigurationParser {
|
||||
asset,
|
||||
direction,
|
||||
target,
|
||||
trigger,
|
||||
triggerConfiguration.trigger(),
|
||||
triggerConfiguration.gracePeriod(),
|
||||
severity,
|
||||
note
|
||||
);
|
||||
@@ -109,6 +110,50 @@ public final class AlarmConfigurationParser {
|
||||
return target;
|
||||
}
|
||||
|
||||
private static TriggerConfiguration parseTrigger(String triggerText) {
|
||||
String normalized = triggerText.toUpperCase(Locale.ROOT);
|
||||
|
||||
if (normalized.equals("ONETIME")) {
|
||||
return new TriggerConfiguration(AlarmTrigger.ONETIME, 0);
|
||||
}
|
||||
|
||||
if (normalized.equals("PERSISTENT")) {
|
||||
return new TriggerConfiguration(AlarmTrigger.PERSISTENT, 0);
|
||||
}
|
||||
|
||||
if (normalized.startsWith("PERSISTENT:")) {
|
||||
String graceText = normalized.substring("PERSISTENT:".length());
|
||||
|
||||
if (graceText.isEmpty()) {
|
||||
throw new IllegalArgumentException("Missing persistent grace period: " + triggerText);
|
||||
}
|
||||
|
||||
ΩsecondsΩ gracePeriodSeconds;
|
||||
try {
|
||||
gracePeriodSeconds = Integer.parseInt(graceText);
|
||||
} catch (NumberFormatException exception) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid persistent grace period: " + triggerText,
|
||||
exception
|
||||
);
|
||||
}
|
||||
|
||||
if (gracePeriodSeconds < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Persistent grace period cannot be negative: " + triggerText
|
||||
);
|
||||
}
|
||||
|
||||
return new TriggerConfiguration(AlarmTrigger.PERSISTENT, gracePeriodSeconds);
|
||||
}
|
||||
|
||||
if (normalized.startsWith("ONETIME:")) {
|
||||
throw new IllegalArgumentException("ONETIME cannot have a grace period: " + triggerText);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unknown trigger: " + triggerText);
|
||||
}
|
||||
|
||||
private static void validateTarget(BigDecimal target, String originalTargetStr) {
|
||||
if (target.compareTo(BigDecimal.ZERO) < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
@@ -274,6 +319,12 @@ public final class AlarmConfigurationParser {
|
||||
}
|
||||
}
|
||||
|
||||
private record TriggerConfiguration(
|
||||
AlarmTrigger trigger,
|
||||
ΩsecondsΩ gracePeriod
|
||||
) {
|
||||
}
|
||||
|
||||
private AlarmConfigurationParser() {
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.r35157.jupiterperpsalarm.impl.ref;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
public final class PriceAlarm {
|
||||
|
||||
public PriceAlarm(PriceAlarmDefinition definition, AlarmAction action) {
|
||||
@@ -25,16 +27,27 @@ public final class PriceAlarm {
|
||||
|
||||
previousReached = reached;
|
||||
|
||||
if (!enteredTriggeredSide) {
|
||||
if (!reached) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (definition.trigger() == AlarmTrigger.ONETIME && triggerCount > 0) {
|
||||
if (definition.trigger() == AlarmTrigger.ONETIME) {
|
||||
if (!enteredTriggeredSide || triggerCount > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
triggerCount++;
|
||||
action.trigger(price, definition);
|
||||
trigger(price);
|
||||
return;
|
||||
}
|
||||
|
||||
if (definition.trigger() == AlarmTrigger.PERSISTENT) {
|
||||
if (enteredTriggeredSide || persistentGracePeriodHasPassed()) {
|
||||
trigger(price);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Unsupported alarm trigger: " + definition.trigger());
|
||||
}
|
||||
|
||||
public PriceAlarmDefinition definition() {
|
||||
@@ -45,9 +58,32 @@ public final class PriceAlarm {
|
||||
return triggerCount;
|
||||
}
|
||||
|
||||
private boolean persistentGracePeriodHasPassed() {
|
||||
if (lastTriggeredAt == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ΩsecondsΩ gracePeriod = definition.triggerGracePeriod();
|
||||
|
||||
if (gracePeriod == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !Instant.now().isBefore(
|
||||
lastTriggeredAt.plusSeconds(gracePeriod)
|
||||
);
|
||||
}
|
||||
|
||||
private void trigger(OraclePrice price) {
|
||||
triggerCount++;
|
||||
lastTriggeredAt = Instant.now();
|
||||
action.trigger(price, definition);
|
||||
}
|
||||
|
||||
private final PriceAlarmDefinition definition;
|
||||
private final AlarmAction action;
|
||||
|
||||
private Instant lastTriggeredAt;
|
||||
private Boolean previousReached;
|
||||
private long triggerCount;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ public record PriceAlarmDefinition(
|
||||
PriceDirection direction,
|
||||
BigDecimal target,
|
||||
AlarmTrigger trigger,
|
||||
ΩsecondsΩ triggerGracePeriod,
|
||||
AlarmSeverity severity,
|
||||
String note
|
||||
) {
|
||||
@@ -24,5 +25,11 @@ public record PriceAlarmDefinition(
|
||||
if (target.signum() < 0) {
|
||||
throw new IllegalArgumentException("Target price cannot be negative (was: " + target.signum() + ")!");
|
||||
}
|
||||
|
||||
if (triggerGracePeriod < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Trigger grace period cannot be negative: " + triggerGracePeriod
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
package com.r35157.jupiterperpsalarm.impl.ref;
|
||||
|
||||
Reference in New Issue
Block a user