43: Prevent Position Decrease from reducing a position below a configured size reserve
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
# Wallet and signer used for position-decrease transactions
|
# Wallet and signer used for position-decrease transactions
|
||||||
################################################################
|
################################################################
|
||||||
WALLET_ID {{JUPITER_PERPS_WALLET}}
|
WALLET_ID {{JUPITER_PERPS_WALLET}}
|
||||||
SIGNER_KEY_NAME <SIGNER>
|
SIGNER_KEY_NAME <SIGNER>
|
||||||
|
RESERVE_POSITION_SIZE_USD_LIMIT 10
|
||||||
|
|
||||||
# Id Asset Direction ReceiveToken SizeDeltaUSD MaxSlippageBPS
|
# Id Asset Direction ReceiveToken SizeDeltaUSD MaxSlippageBPS
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|||||||
+40
@@ -9,6 +9,7 @@ import com.r35157.libs.solana.SolanaSignedTransaction;
|
|||||||
import com.r35157.libs.solana.SolanaUnsignedTransaction;
|
import com.r35157.libs.solana.SolanaUnsignedTransaction;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -68,6 +69,10 @@ public final class JupiterPerpsPositionDecreaseAlarmAction
|
|||||||
JupiterPerpsPosition position =
|
JupiterPerpsPosition position =
|
||||||
findOpenPosition(positionDecrease);
|
findOpenPosition(positionDecrease);
|
||||||
|
|
||||||
|
if (!isPositionSizeOk(position, positionDecrease)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SolanaUnsignedTransaction utrans =
|
SolanaUnsignedTransaction utrans =
|
||||||
jupiter.buildPositionDecreaseTransaction(
|
jupiter.buildPositionDecreaseTransaction(
|
||||||
position.positionAccount(),
|
position.positionAccount(),
|
||||||
@@ -76,8 +81,10 @@ public final class JupiterPerpsPositionDecreaseAlarmAction
|
|||||||
positionDecrease.sizeUsdDelta(),
|
positionDecrease.sizeUsdDelta(),
|
||||||
positionDecrease.maxSlippageBps()
|
positionDecrease.maxSlippageBps()
|
||||||
);
|
);
|
||||||
|
|
||||||
SolanaSignedTransaction strans =
|
SolanaSignedTransaction strans =
|
||||||
wallet.signTransaction(utrans);
|
wallet.signTransaction(utrans);
|
||||||
|
|
||||||
ΩSolanaTransactionSignatureΩ signature =
|
ΩSolanaTransactionSignatureΩ signature =
|
||||||
jupiter.executePositionDecreaseTransaction(strans);
|
jupiter.executePositionDecreaseTransaction(strans);
|
||||||
|
|
||||||
@@ -135,6 +142,39 @@ public final class JupiterPerpsPositionDecreaseAlarmAction
|
|||||||
return matchingPosition;
|
return matchingPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isPositionSizeOk(
|
||||||
|
JupiterPerpsPosition position,
|
||||||
|
JupiterPerpsPositionDecreaseAlarmActionConfiguration
|
||||||
|
.ResolvedPositionDecrease positionDecrease
|
||||||
|
) {
|
||||||
|
ΩUSDCAmountΩ currentPositionSize = position.positionSize();
|
||||||
|
ΩUSDCAmountΩ decreaseSizeUsd = positionDecrease.sizeUsdDelta();
|
||||||
|
ΩUSDCAmountΩ reservePositionSizeUsdLimit =
|
||||||
|
configuration.reservePositionSizeUsdLimit();
|
||||||
|
|
||||||
|
ΩUSDCAmountΩ remainingPositionSize =
|
||||||
|
currentPositionSize.subtract(decreaseSizeUsd);
|
||||||
|
|
||||||
|
if (remainingPositionSize.compareTo(
|
||||||
|
reservePositionSizeUsdLimit
|
||||||
|
) < 0) {
|
||||||
|
System.err.println(
|
||||||
|
"Position Decrease of "
|
||||||
|
+ decreaseSizeUsd
|
||||||
|
+ " USD skipped: Position size is "
|
||||||
|
+ currentPositionSize
|
||||||
|
+ " USD and would become "
|
||||||
|
+ remainingPositionSize
|
||||||
|
+ " USD, which is below the "
|
||||||
|
+ reservePositionSizeUsdLimit
|
||||||
|
+ " USD reserve."
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private final JupiterPerpsPositionDecreaseAlarmActionConfiguration
|
private final JupiterPerpsPositionDecreaseAlarmActionConfiguration
|
||||||
configuration;
|
configuration;
|
||||||
private final SolanaWallet wallet;
|
private final SolanaWallet wallet;
|
||||||
|
|||||||
+10
@@ -10,11 +10,21 @@ import java.util.Objects;
|
|||||||
public record JupiterPerpsPositionDecreaseAlarmActionConfiguration(
|
public record JupiterPerpsPositionDecreaseAlarmActionConfiguration(
|
||||||
ΩSolanaWalletIdΩ walletId,
|
ΩSolanaWalletIdΩ walletId,
|
||||||
String signerKeyName,
|
String signerKeyName,
|
||||||
|
ΩUSDCAmountΩ reservePositionSizeUsdLimit,
|
||||||
Map<Integer, PositionDecrease> positionDecreases
|
Map<Integer, PositionDecrease> positionDecreases
|
||||||
) {
|
) {
|
||||||
public JupiterPerpsPositionDecreaseAlarmActionConfiguration {
|
public JupiterPerpsPositionDecreaseAlarmActionConfiguration {
|
||||||
Objects.requireNonNull(walletId, "walletId");
|
Objects.requireNonNull(walletId, "walletId");
|
||||||
Objects.requireNonNull(signerKeyName, "signerKeyName");
|
Objects.requireNonNull(signerKeyName, "signerKeyName");
|
||||||
|
Objects.requireNonNull(reservePositionSizeUsdLimit, "reservePositionSizeUsdLimit");
|
||||||
|
|
||||||
|
if (reservePositionSizeUsdLimit.signum() < 0) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Position size USD reserve limit cannot be negative: "
|
||||||
|
+ reservePositionSizeUsdLimit
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
positionDecreases = Map.copyOf(positionDecreases);
|
positionDecreases = Map.copyOf(positionDecreases);
|
||||||
|
|
||||||
if (walletId.isBlank()) {
|
if (walletId.isBlank()) {
|
||||||
|
|||||||
+23
@@ -1,6 +1,7 @@
|
|||||||
package com.r35157.jupiterperpsalarm.impl.ref;
|
package com.r35157.jupiterperpsalarm.impl.ref;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@@ -20,6 +21,7 @@ public final class JupiterPerpsPositionDecreaseAlarmActionConfigurationParser {
|
|||||||
positionDecreases = new LinkedHashMap<>();
|
positionDecreases = new LinkedHashMap<>();
|
||||||
ΩSolanaWalletIdΩ walletId = null;
|
ΩSolanaWalletIdΩ walletId = null;
|
||||||
String signerKeyName = null;
|
String signerKeyName = null;
|
||||||
|
ΩUSDCAmountΩ reservePositionSizeUsdLimit = null;
|
||||||
|
|
||||||
for (int lineNumber = 1; lineNumber <= lines.size(); lineNumber++) {
|
for (int lineNumber = 1; lineNumber <= lines.size(); lineNumber++) {
|
||||||
String line = removeComment(lines.get(lineNumber - 1)).trim();
|
String line = removeComment(lines.get(lineNumber - 1)).trim();
|
||||||
@@ -51,6 +53,20 @@ public final class JupiterPerpsPositionDecreaseAlarmActionConfigurationParser {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
signerKeyName = variableResolver.resolve(columns[1]);
|
signerKeyName = variableResolver.resolve(columns[1]);
|
||||||
|
} else if (firstColumn.equals("RESERVE_POSITION_SIZE_USD_LIMIT")) {
|
||||||
|
requireColumnCount(
|
||||||
|
columns,
|
||||||
|
2,
|
||||||
|
"RESERVE_POSITION_SIZE_USD_LIMIT value"
|
||||||
|
);
|
||||||
|
if (reservePositionSizeUsdLimit != null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Duplicate RESERVE_POSITION_SIZE_USD_LIMIT"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
reservePositionSizeUsdLimit = new ΩUSDCAmountΩ(
|
||||||
|
variableResolver.resolve(columns[1])
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
parsePositionDecrease(
|
parsePositionDecrease(
|
||||||
columns,
|
columns,
|
||||||
@@ -78,9 +94,16 @@ public final class JupiterPerpsPositionDecreaseAlarmActionConfigurationParser {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (reservePositionSizeUsdLimit == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Missing RESERVE_POSITION_SIZE_USD_LIMIT in " + path
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return new JupiterPerpsPositionDecreaseAlarmActionConfiguration(
|
return new JupiterPerpsPositionDecreaseAlarmActionConfiguration(
|
||||||
walletId,
|
walletId,
|
||||||
signerKeyName,
|
signerKeyName,
|
||||||
|
reservePositionSizeUsdLimit,
|
||||||
positionDecreases
|
positionDecreases
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user