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();
|
entryPriceVariableRefresher.refresh();
|
||||||
System.out.println("Fetching done.");
|
System.out.println("Fetching done.");
|
||||||
|
|
||||||
|
entryPriceVariableRefresher.startPeriodicRefresh();
|
||||||
|
|
||||||
JupiterPerpsEntryPriceVariableRefreshWatcher entryPriceVariableRefreshWatcher =
|
JupiterPerpsEntryPriceVariableRefreshWatcher entryPriceVariableRefreshWatcher =
|
||||||
new JupiterPerpsEntryPriceVariableRefreshWatcher(
|
new JupiterPerpsEntryPriceVariableRefreshWatcher(
|
||||||
config.alarmConfiguration().getParent(),
|
config.alarmConfiguration().getParent(),
|
||||||
@@ -106,7 +108,10 @@ public final class JupiterPerpsAlarmImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Runtime.getRuntime().addShutdownHook(new Thread(
|
Runtime.getRuntime().addShutdownHook(new Thread(
|
||||||
() -> clients.forEach(OracleWebSocketClient::close),
|
() -> {
|
||||||
|
entryPriceVariableRefresher.close();
|
||||||
|
clients.forEach(OracleWebSocketClient::close);
|
||||||
|
},
|
||||||
"shutdown"
|
"shutdown"
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|||||||
+148
-24
@@ -2,13 +2,17 @@ package com.r35157.jupiterperpsalarm.impl.ref;
|
|||||||
|
|
||||||
import com.r35157.libs.jupiter.perps.JupiterPerpsPosition;
|
import com.r35157.libs.jupiter.perps.JupiterPerpsPosition;
|
||||||
import com.r35157.libs.jupiter.perps.JupiterPerpsService;
|
import com.r35157.libs.jupiter.perps.JupiterPerpsService;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
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(
|
public JupiterPerpsEntryPriceVariableRefresher(
|
||||||
Map<String, String> variables,
|
Map<String, String> variables,
|
||||||
@@ -16,13 +20,46 @@ public final class JupiterPerpsEntryPriceVariableRefresher {
|
|||||||
) {
|
) {
|
||||||
this.variables = Objects.requireNonNull(variables, "variables");
|
this.variables = Objects.requireNonNull(variables, "variables");
|
||||||
this.jupiterPerpsService = Objects.requireNonNull(jupiterPerpsService, "jupiterPerpsService");
|
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() {
|
||||||
ΩSolanaWalletIdΩ wallet = variables.get("JUPITER_PERPS_WALLET");
|
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()) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,41 +72,92 @@ public final class JupiterPerpsEntryPriceVariableRefresher {
|
|||||||
+ " open Jupiter Perps positions for wallet: " + wallet
|
+ " open Jupiter Perps positions for wallet: " + wallet
|
||||||
);
|
);
|
||||||
|
|
||||||
removeEntryPriceVariables();
|
|
||||||
|
Map<String, String> previousPriceVariables = copyPriceVariables();
|
||||||
|
|
||||||
|
removePriceVariables();
|
||||||
|
|
||||||
for (JupiterPerpsPosition position : positions) {
|
for (JupiterPerpsPosition position : positions) {
|
||||||
String variableName = createEntryPriceVariableName(position);
|
String entryPriceVariableName = createEntryPriceVariableName(position);
|
||||||
|
|
||||||
System.out.println(
|
putPriceVariable(
|
||||||
"Jupiter Perps position maps to variable "
|
previousPriceVariables,
|
||||||
+ variableName
|
entryPriceVariableName,
|
||||||
+ " = "
|
position.entryPrice().toPlainString()
|
||||||
+ position.entryPrice()
|
|
||||||
);
|
);
|
||||||
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) {
|
if (exception instanceof InterruptedException) {
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
System.err.println(
|
System.err.println(
|
||||||
"Could not refresh Jupiter Perps entry price variables: "
|
"Could not refresh Jupiter Perps price variables: " + exception.getMessage()
|
||||||
+ exception.getMessage()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeEntryPriceVariables() {
|
private Map<String, String> copyPriceVariables() {
|
||||||
variables.remove("SOL_LONG_ENTRY_PRICE");
|
Map<String, String> previousPriceVariables = new HashMap<>();
|
||||||
variables.remove("SOL_SHORT_ENTRY_PRICE");
|
|
||||||
variables.remove("BTC_LONG_ENTRY_PRICE");
|
for (String variableName : PRICE_VARIABLE_NAMES) {
|
||||||
variables.remove("BTC_SHORT_ENTRY_PRICE");
|
String value = variables.get(variableName);
|
||||||
variables.remove("ETH_LONG_ENTRY_PRICE");
|
|
||||||
variables.remove("ETH_SHORT_ENTRY_PRICE");
|
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) {
|
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()) {
|
String asset = switch (position.tradedTokenMint()) {
|
||||||
case "So11111111111111111111111111111111111111112" -> "SOL";
|
case "So11111111111111111111111111111111111111112" -> "SOL";
|
||||||
case "3NZ9JMVBmGAqocybic2c7LQCJScmgsAZ6vQqTDzcqmJh" -> "BTC";
|
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 Map<String, String> variables;
|
||||||
private final JupiterPerpsService jupiterPerpsService;
|
private final JupiterPerpsService jupiterPerpsService;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user