25: Add dynamic Jupiter Perps liquidation price variables to alarm config
This commit is contained in:
@@ -57,6 +57,8 @@ public final class JupiterPerpsAlarmImpl {
|
||||
entryPriceVariableRefresher.refresh();
|
||||
System.out.println("Fetching done.");
|
||||
|
||||
entryPriceVariableRefresher.startPeriodicRefresh();
|
||||
|
||||
JupiterPerpsEntryPriceVariableRefreshWatcher entryPriceVariableRefreshWatcher =
|
||||
new JupiterPerpsEntryPriceVariableRefreshWatcher(
|
||||
config.alarmConfiguration().getParent(),
|
||||
@@ -106,7 +108,10 @@ public final class JupiterPerpsAlarmImpl {
|
||||
}
|
||||
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(
|
||||
() -> clients.forEach(OracleWebSocketClient::close),
|
||||
() -> {
|
||||
entryPriceVariableRefresher.close();
|
||||
clients.forEach(OracleWebSocketClient::close);
|
||||
},
|
||||
"shutdown"
|
||||
));
|
||||
|
||||
|
||||
+147
-23
@@ -2,13 +2,17 @@ package com.r35157.jupiterperpsalarm.impl.ref;
|
||||
|
||||
import com.r35157.libs.jupiter.perps.JupiterPerpsPosition;
|
||||
import com.r35157.libs.jupiter.perps.JupiterPerpsService;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public final class JupiterPerpsEntryPriceVariableRefresher {
|
||||
public final class JupiterPerpsEntryPriceVariableRefresher
|
||||
implements AutoCloseable {
|
||||
|
||||
public JupiterPerpsEntryPriceVariableRefresher(
|
||||
Map<String, String> variables,
|
||||
@@ -16,13 +20,46 @@ public final class JupiterPerpsEntryPriceVariableRefresher {
|
||||
) {
|
||||
this.variables = Objects.requireNonNull(variables, "variables");
|
||||
this.jupiterPerpsService = Objects.requireNonNull(jupiterPerpsService, "jupiterPerpsService");
|
||||
|
||||
scheduler = Executors.newSingleThreadScheduledExecutor(runnable -> {
|
||||
Thread thread = new Thread(
|
||||
runnable,
|
||||
"jupiter-perps-price-variable-refresher"
|
||||
);
|
||||
|
||||
thread.setDaemon(true);
|
||||
|
||||
return thread;
|
||||
});
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
public void startPeriodicRefresh() {
|
||||
scheduler.scheduleWithFixedDelay(
|
||||
this::refreshPeriodically,
|
||||
REFRESH_INTERVAL_SECONDS,
|
||||
REFRESH_INTERVAL_SECONDS,
|
||||
TimeUnit.SECONDS
|
||||
);
|
||||
|
||||
System.out.println(
|
||||
"Periodic Jupiter Perps price variable refresh started with interval: "
|
||||
+ REFRESH_INTERVAL_SECONDS
|
||||
+ " seconds"
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
scheduler.shutdownNow();
|
||||
}
|
||||
|
||||
public synchronized void refresh() {
|
||||
System.out.println("Executing refresh now...");
|
||||
|
||||
ΩSolanaWalletIdΩ wallet = variables.get("JUPITER_PERPS_WALLET");
|
||||
|
||||
if (wallet == null || wallet.isBlank()) {
|
||||
System.err.println("Cannot refresh Jupiter Perps entry price variables: JUPITER_PERPS_WALLET is not configured");
|
||||
System.err.println("Cannot refresh Jupiter Perps price variables: JUPITER_PERPS_WALLET is not configured");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -35,41 +72,92 @@ public final class JupiterPerpsEntryPriceVariableRefresher {
|
||||
+ " open Jupiter Perps positions for wallet: " + wallet
|
||||
);
|
||||
|
||||
removeEntryPriceVariables();
|
||||
|
||||
Map<String, String> previousPriceVariables = copyPriceVariables();
|
||||
|
||||
removePriceVariables();
|
||||
|
||||
for (JupiterPerpsPosition position : positions) {
|
||||
String variableName = createEntryPriceVariableName(position);
|
||||
String entryPriceVariableName = createEntryPriceVariableName(position);
|
||||
|
||||
System.out.println(
|
||||
"Jupiter Perps position maps to variable "
|
||||
+ variableName
|
||||
+ " = "
|
||||
+ position.entryPrice()
|
||||
putPriceVariable(
|
||||
previousPriceVariables,
|
||||
entryPriceVariableName,
|
||||
position.entryPrice().toPlainString()
|
||||
);
|
||||
variables.put(variableName, position.entryPrice().toPlainString());
|
||||
|
||||
String liquidationPriceVariableName = createLiquidationPriceVariableName(position);
|
||||
|
||||
putPriceVariable(
|
||||
previousPriceVariables,
|
||||
liquidationPriceVariableName,
|
||||
position.liquidationPrice().toPlainString()
|
||||
);
|
||||
|
||||
}
|
||||
} catch (IOException | InterruptedException exception) {
|
||||
} catch (IOException |
|
||||
InterruptedException exception) {
|
||||
if (exception instanceof InterruptedException) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
||||
System.err.println(
|
||||
"Could not refresh Jupiter Perps entry price variables: "
|
||||
+ exception.getMessage()
|
||||
"Could not refresh Jupiter Perps price variables: " + exception.getMessage()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeEntryPriceVariables() {
|
||||
variables.remove("SOL_LONG_ENTRY_PRICE");
|
||||
variables.remove("SOL_SHORT_ENTRY_PRICE");
|
||||
variables.remove("BTC_LONG_ENTRY_PRICE");
|
||||
variables.remove("BTC_SHORT_ENTRY_PRICE");
|
||||
variables.remove("ETH_LONG_ENTRY_PRICE");
|
||||
variables.remove("ETH_SHORT_ENTRY_PRICE");
|
||||
private Map<String, String> copyPriceVariables() {
|
||||
Map<String, String> previousPriceVariables = new HashMap<>();
|
||||
|
||||
for (String variableName : PRICE_VARIABLE_NAMES) {
|
||||
String value = variables.get(variableName);
|
||||
|
||||
if (value != null) {
|
||||
previousPriceVariables.put(variableName, value);
|
||||
}
|
||||
}
|
||||
|
||||
return previousPriceVariables;
|
||||
}
|
||||
|
||||
private void removePriceVariables() {
|
||||
for (String variableName : PRICE_VARIABLE_NAMES) {
|
||||
variables.remove(variableName);
|
||||
}
|
||||
}
|
||||
|
||||
private void putPriceVariable(
|
||||
Map<String, String> previousPriceVariables,
|
||||
String variableName,
|
||||
String variableValue
|
||||
) {
|
||||
String previousValue = previousPriceVariables.get(variableName);
|
||||
|
||||
variables.put(variableName, variableValue);
|
||||
|
||||
if (previousValue == null || !previousValue.equals(variableValue)) {
|
||||
System.out.println(
|
||||
"{{" + variableName + "}} updated from " +
|
||||
previousValue +
|
||||
" --> " +
|
||||
variableValue
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static String createEntryPriceVariableName(JupiterPerpsPosition position) {
|
||||
return createPriceVariableName(position, "ENTRY_PRICE");
|
||||
}
|
||||
|
||||
private static String createLiquidationPriceVariableName(JupiterPerpsPosition position) {
|
||||
return createPriceVariableName(position, "LIQ_PRICE");
|
||||
}
|
||||
|
||||
private static String createPriceVariableName(
|
||||
JupiterPerpsPosition position,
|
||||
String suffix
|
||||
) {
|
||||
String asset = switch (position.tradedTokenMint()) {
|
||||
case "So11111111111111111111111111111111111111112" -> "SOL";
|
||||
case "3NZ9JMVBmGAqocybic2c7LQCJScmgsAZ6vQqTDzcqmJh" -> "BTC";
|
||||
@@ -79,9 +167,45 @@ public final class JupiterPerpsEntryPriceVariableRefresher {
|
||||
);
|
||||
};
|
||||
|
||||
return asset + "_" + position.direction() + "_ENTRY_PRICE";
|
||||
return asset + "_" + position.direction() + "_" + suffix;
|
||||
}
|
||||
|
||||
private static final Set<String> PRICE_VARIABLE_NAMES = Set.of(
|
||||
"SOL_LONG_ENTRY_PRICE",
|
||||
"SOL_SHORT_ENTRY_PRICE",
|
||||
|
||||
"BTC_LONG_ENTRY_PRICE",
|
||||
"BTC_SHORT_ENTRY_PRICE",
|
||||
|
||||
"ETH_LONG_ENTRY_PRICE",
|
||||
"ETH_SHORT_ENTRY_PRICE",
|
||||
|
||||
"SOL_LONG_LIQ_PRICE",
|
||||
"SOL_SHORT_LIQ_PRICE",
|
||||
|
||||
"BTC_LONG_LIQ_PRICE",
|
||||
"BTC_SHORT_LIQ_PRICE",
|
||||
|
||||
"ETH_LONG_LIQ_PRICE",
|
||||
"ETH_SHORT_LIQ_PRICE"
|
||||
);
|
||||
|
||||
private void refreshPeriodically() {
|
||||
try {
|
||||
refresh();
|
||||
} catch (RuntimeException exception) {
|
||||
System.err.println(
|
||||
"Unexpected error during periodic Jupiter Perps price variable refresh: "
|
||||
+ exception.getMessage()
|
||||
);
|
||||
|
||||
exception.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
|
||||
private static final ΩsecondsΩ REFRESH_INTERVAL_SECONDS = 60;
|
||||
|
||||
private final ScheduledExecutorService scheduler;
|
||||
private final Map<String, String> variables;
|
||||
private final JupiterPerpsService jupiterPerpsService;
|
||||
}
|
||||
Reference in New Issue
Block a user