diff --git a/src/main/tjava/com/fanitas/evelyn/core/impl/ref/DesiredPositionCalculatorImpl.tjava b/src/main/tjava/com/fanitas/evelyn/core/impl/ref/DesiredPositionCalculatorImpl.tjava index 3f93a68..284207d 100644 --- a/src/main/tjava/com/fanitas/evelyn/core/impl/ref/DesiredPositionCalculatorImpl.tjava +++ b/src/main/tjava/com/fanitas/evelyn/core/impl/ref/DesiredPositionCalculatorImpl.tjava @@ -4,10 +4,9 @@ import com.r35157.libs.basic.Pair; import com.fanitas.evelyn.raydium.RaydiumLiquidityPoolPositionConcentrated; import com.fanitas.evelyn.core.DesiredPositionCalculator; -import com.r35157.libs.valuetypes.basic.AssetPrice; -import com.r35157.libs.valuetypes.basic.CurrencyType; -import com.r35157.libs.valuetypes.basic.MoneyAmount; +import com.r35157.libs.valuetypes.basic.*; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.math.BigDecimal; import java.math.MathContext; @@ -43,7 +42,7 @@ public class DesiredPositionCalculatorImpl implements DesiredPositionCalculator ); ΩSyrupPriceΩ lastLessThanOrEqual = intervalEnds.get(indexOfPositionWithAnEndPriceBeforePositionWithCurrentPrice); - HashMap<ΩRaydiumLiquidityPoolPositionIdΩ, MoneyAmount> desiredPositions = new HashMap<>(); + HashMap<ΩRaydiumLiquidityPoolPositionIdΩ, Pair<ΩSolanaAmountΩ, ΩSyrupAmountΩ>> desiredPositions = new HashMap<>(); boolean beforeNonZeroPos = true; @@ -68,18 +67,8 @@ public class DesiredPositionCalculatorImpl implements DesiredPositionCalculator break; } - ΩSolanaAmountΩ desiredPositionSizeSolana = new MoneyAmount( - desiredSolanaPosSize, - totalReadyAmountMintA.currencyType() - ); - - ΩSyrupAmountΩ desiredPositionSizeSyrup = new MoneyAmount( - desiredSyrupPosSize, - totalReadyAmountMintB.currencyType() - ); - Pair<ΩSolanaAmountΩ, ΩSyrupAmountΩ> desiredPositionSizes = - new Pair<>(desiredPositionSizeSolana, desiredPositionSizeSyrup); + new Pair<>(desiredSolanaPosSize, desiredSyrupPosSize); RaydiumLiquidityPoolPositionConcentrated position = getPositionByStartPriceA(iStart); // TODO: What if null is return above? @@ -121,7 +110,7 @@ public class DesiredPositionCalculatorImpl implements DesiredPositionCalculator @Override public Pair<ΩSolanaAmountΩ, ΩSyrupAmountΩ> calculateLockedSums(ΩSyrupPriceΩ currentPrice) { - List<ΩPriceΩ> ascendingPrices = getSortedPositionIntervalFromValues(liquidityProviderPositions); + List<ΩSyrupPriceΩ> ascendingPrices = getSortedPositionIntervalFromValues(liquidityProviderPositions); ΩAmountΩ sumA = ZERO; ΩAmountΩ sumB = ZERO; @@ -129,9 +118,9 @@ public class DesiredPositionCalculatorImpl implements DesiredPositionCalculator CurrencyType ctA = null; CurrencyType ctB = null; - int index = lookupIndexOfFirstGreaterThanOrEqual(ascendingPrices, currentPrice.price()); + int index = lookupIndexOfFirstGreaterThanOrEqual(ascendingPrices, currentPrice); if(index >= 0) { - ΩPriceΩ startPriceOfStartPos = ascendingPrices.get(index); + AssetPrice startPriceOfStartPos = ascendingPrices.get(index); for (RaydiumLiquidityPoolPositionConcentrated position : liquidityProviderPositions.values()) { if (position.priceRange().from().compareTo(startPriceOfStartPos) >= 0) { @@ -157,15 +146,15 @@ public class DesiredPositionCalculatorImpl implements DesiredPositionCalculator ΩSyrupAmountΩ inactiveInAccountMintB, ΩSyrupAmountΩ reservedForBurnMintB ) { - List<ΩPriceΩ> ascendingValues = getSortedPositionIntervalFromValues(liquidityProviderPositions); + List ascendingValues = getSortedPositionIntervalFromValues(liquidityProviderPositions); ΩAmountΩ redistSumA = ZERO; ΩAmountΩ redistSumB = ZERO; CurrencyType ctA = null; CurrencyType ctB = null; - int index = lookupIndexOfLastLessThan(ascendingValues, currentPrice.price()); + int index = lookupIndexOfLastLessThan(ascendingValues, currentPrice); if(index >= 0) { - ΩPriceΩ startPriceOfStartPos = ascendingValues.get(index); + AssetPrice startPriceOfStartPos = ascendingValues.get(index); for (RaydiumLiquidityPoolPositionConcentrated position : liquidityProviderPositions.values()) { if (position.priceRange().from().compareTo(startPriceOfStartPos) <= 0) { @@ -205,8 +194,8 @@ public class DesiredPositionCalculatorImpl implements DesiredPositionCalculator return a.subtract(b.amount()); } - private RaydiumLiquidityPoolPositionConcentrated getPositionByStartPriceA(@NotNull ΩPriceΩ startPriceA) { - for (RaydiumLiquidityPoolPositionConcentrated candidate : liquidityProviderPositions.values()) { + private @Nullable RaydiumLiquidityPoolPositionConcentrated getPositionByStartPriceA(@NotNull AssetPrice startPriceA) { + for(RaydiumLiquidityPoolPositionConcentrated candidate : liquidityProviderPositions.values()) { if (candidate.priceRange().from().compareTo(startPriceA) == 0) { return candidate; } @@ -222,47 +211,51 @@ public class DesiredPositionCalculatorImpl implements DesiredPositionCalculator @NotNull ΩSyrupPriceΩ intervalPriceTo, @NotNull ΩSyrupPriceΩ lookupPrice ) { - ΩPriceΩ curveStartPrice = currentPrice.multiply( + ΩPriceΩ curveStartPrice = currentPrice.price().multiply( ONE.subtract(curveWidth, MC), MC ); boolean intervalIsCompletelyBeforeCurve = - intervalPriceTo.compareTo(curveStartPrice) <= 0; + intervalPriceTo.price().compareTo(curveStartPrice) <= 0; boolean intervalIsCompletelyAfterLookupLimit = - intervalPriceFrom.compareTo(lookupPrice) >= 0; + intervalPriceFrom.price().compareTo(lookupPrice.price()) >= 0; if (intervalIsCompletelyBeforeCurve || intervalIsCompletelyAfterLookupLimit) { - return ZERO; + return new ΩSyrupAmountΩ(ZERO, WellKnownCurrencyTypes.SYRUPUSDC.getCurrencyType()); } - ΩPriceΩ effectiveIntervalFrom = max(intervalPriceFrom, curveStartPrice); - ΩPriceΩ effectiveIntervalTo = min(intervalPriceTo, lookupPrice); + ΩPriceΩ effectiveIntervalFrom = max(intervalPriceFrom.price(), curveStartPrice); + ΩPriceΩ effectiveIntervalTo = min(intervalPriceTo.price(), lookupPrice.price()); - BigDecimal sigma = currentPrice.multiply(curveWidth, MC) + BigDecimal sigma = currentPrice.price().multiply(curveWidth, MC) .divide(THREE, MC); BigDecimal sqrtTwo = sqrt(TWO, MC); BigDecimal denominator = sigma.multiply(sqrtTwo, MC); - ΩPriceΩ normalizedEffectiveTo = effectiveIntervalTo.subtract(currentPrice, MC) + ΩPriceΩ normalizedEffectiveTo = effectiveIntervalTo.subtract(currentPrice.price(), MC) .divide(denominator, MC); - ΩPriceΩ normalizedEffectiveFrom = effectiveIntervalFrom.subtract(currentPrice, MC) + ΩPriceΩ normalizedEffectiveFrom = effectiveIntervalFrom.subtract(currentPrice.price(), MC) .divide(denominator, MC); - ΩPriceΩ normalizedLookupPrice = lookupPrice.subtract(currentPrice, MC) + ΩPriceΩ normalizedLookupPrice = lookupPrice.price().subtract(currentPrice.price(), MC) .divide(denominator, MC); - ΩPriceΩ normalizedCurveStart = curveStartPrice.subtract(currentPrice, MC) + ΩPriceΩ normalizedCurveStart = curveStartPrice.subtract(currentPrice.price(), MC) .divide(denominator, MC); BigDecimal intervalWeight = new BigDecimal(erf(normalizedEffectiveTo) - erf(normalizedEffectiveFrom)); BigDecimal totalWeightInActiveCurve = new BigDecimal(erf(normalizedLookupPrice) - erf(normalizedCurveStart)); - ΩAmountΩ dps = totalSyrupToDistribution.multiply(intervalWeight, MC) - .divide(totalWeightInActiveCurve, MC); + ΩSyrupAmountΩ dps = new ΩSyrupAmountΩ( + totalSyrupToDistribution.amount() + .multiply(intervalWeight, MC) + .divide(totalWeightInActiveCurve, MC), + WellKnownCurrencyTypes.SYRUPUSDC.getCurrencyType() + ); return dps; } @@ -274,8 +267,8 @@ public class DesiredPositionCalculatorImpl implements DesiredPositionCalculator int index = -1; for (int i = ascendingPrices.size() - 1; i >= 0; i--) { - BigDecimal p = ascendingPrices.get(i); - if (p.compareTo(searchPrice) <= 0) { + ΩPriceΩ p = ascendingPrices.get(i).price(); + if (p.compareTo(searchPrice.price()) <= 0) { break; } else { index = i; @@ -298,8 +291,8 @@ public class DesiredPositionCalculatorImpl implements DesiredPositionCalculator int index = -1; for (int i = ascendingPrices.size() - 1; i >= 0; i--) { - BigDecimal p = ascendingPrices.get(i); - if (p.compareTo(searchPrice) <= 0) { + ΩPriceΩ p = ascendingPrices.get(i).price(); + if (p.compareTo(searchPrice.price()) <= 0) { break; } else { index = i; @@ -321,8 +314,8 @@ public class DesiredPositionCalculatorImpl implements DesiredPositionCalculator ) { int index = -1; for (int i = 0; i < ascendingPrices.size() - 1; i++) { - ΩSyrupPriceΩ p = ascendingPrices.get(i); - if (p.compareTo(searchPrice) < 0) { + ΩPriceΩ p = ascendingPrices.get(i).price(); + if (p.compareTo(searchPrice.price()) < 0) { index = i - 1; } else { break; @@ -339,8 +332,8 @@ public class DesiredPositionCalculatorImpl implements DesiredPositionCalculator int index = -1; for (int i = 0; i < ascendingPrices.size() - 1; i++) { - ΩPriceΩ p = ascendingPrices.get(i); - if (p.compareTo(searchPrice) < 0) { + ΩPriceΩ p = ascendingPrices.get(i).price(); + if (p.compareTo(searchPrice.price()) < 0) { index = i - 1; } else { break; diff --git a/src/main/tjava/com/fanitas/evelyn/core/impl/ref/EvelynImpl.tjava b/src/main/tjava/com/fanitas/evelyn/core/impl/ref/EvelynImpl.tjava index 4caee2c..654373b 100644 --- a/src/main/tjava/com/fanitas/evelyn/core/impl/ref/EvelynImpl.tjava +++ b/src/main/tjava/com/fanitas/evelyn/core/impl/ref/EvelynImpl.tjava @@ -10,9 +10,7 @@ import com.r35157.libs.raydium.RaydiumLiquidityPoolPrice; import com.r35157.libs.solana.SPLTokenHolding; import com.r35157.libs.solana.SolanaBlockChain; import com.r35157.libs.solana.SolanaConstants; -import com.r35157.libs.solana.valuetypes.WellKnownCurrencyTypes; import com.r35157.libs.valuetypes.basic.AssetPrice; -import com.r35157.libs.valuetypes.basic.CurrencyType; import com.r35157.libs.valuetypes.basic.MoneyAmount; import com.r35157.libs.valuetypes.basic.TradingPair; @@ -22,8 +20,8 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; -import static com.r35157.libs.solana.valuetypes.WellKnownCurrencyTypes.SOLANA; -import static com.r35157.libs.solana.valuetypes.WellKnownCurrencyTypes.SYRUPUSDC; +import static com.r35157.libs.valuetypes.basic.WellKnownCurrencyTypes.SOLANA; +import static com.r35157.libs.valuetypes.basic.WellKnownCurrencyTypes.SYRUPUSDC; import static com.r35157.libs.solana.valuetypes.economic.SolanaSPLTokenProgram.SPL_TOKEN_PROGRAM; import static com.r35157.libs.solana.valuetypes.economic.SolanaSPLTokenProgram.TOKEN_2022_PROGRAM; @@ -102,7 +100,6 @@ public class EvelynImpl implements Evelyn { ΩSPLMintAddressΩ syrupUSDCMintAddr = SolanaConstants.SPL_TOKEN_SYRUPUSDC; AssetPrice currentPriceFromRaydium; - ΩSyrupPriceΩ currentPriceFromChain; SPLTokenHolding syrupHolding = getSPLHolding(solanaAddressForEvelynIOU, syrupUSDCMintAddr); ΩSyrupAmountΩ inactiveInAccountSyrup = new ΩSyrupAmountΩ( @@ -124,16 +121,9 @@ public class EvelynImpl implements Evelyn { ); concentratedResult = cFuture.get(); - - currentPriceFromRaydium = new AssetPrice( - concentratedResult.price(), - tpSolSyrup - ); + currentPriceFromRaydium = concentratedResult.price(); } - ΩPriceΩ price = raydium.fetchPoolPrice(state.getRaydiumPoolId()); - currentPriceFromChain = new AssetPrice(price, tpSolSyrup); - System.out.println("Iteration interval: " + (state.getIterationInterval() / 1000) + " secs"); System.out.println("Solana balances:"); @@ -144,7 +134,7 @@ public class EvelynImpl implements Evelyn { System.out.println("SYRUP owned by Evelyn: " + state.getSyrupOwnedByEvelyn().amount()); System.out.println("SYRUP inactive on Evelyn account: " + inactiveInAccountSyrup); - System.out.println("Pool price: " + currentPriceFromRaydium + "/" + currentPriceFromChain); + System.out.println("Pool price: " + currentPriceFromRaydium); Pair<ΩSolanaAmountΩ, ΩSyrupAmountΩ> totalDistributedSums = desiredPositionCalculator.calculateTotalDistributedSums(); @@ -154,7 +144,7 @@ public class EvelynImpl implements Evelyn { + " / " + totalDistributedSumSyrup); Pair<ΩSolanaAmountΩ, ΩSyrupAmountΩ> amountsLocked = - desiredPositionCalculator.calculateLockedSums(currentPriceFromChain); + desiredPositionCalculator.calculateLockedSums(currentPriceFromRaydium); ΩSolanaAmountΩ amountLockedSolana = amountsLocked.left(); ΩSyrupAmountΩ amountLockedSyrup = amountsLocked.right(); System.out.println("Total amount locked due to HIGH price: " + amountLockedSolana); @@ -170,7 +160,7 @@ public class EvelynImpl implements Evelyn { Pair<ΩSolanaAmountΩ, ΩSyrupAmountΩ> totalReadyAmount = desiredPositionCalculator .calculateRedistributableSums( - currentPriceFromChain, + currentPriceFromRaydium, solBalanceEvelynAccount, amountZeroSolana, // We do not burn Solana inactiveInAccountSyrup, @@ -182,7 +172,7 @@ public class EvelynImpl implements Evelyn { HashMap<ΩRaydiumLiquidityPoolPositionNftIdΩ, Pair<ΩSolanaAmountΩ, ΩSyrupAmountΩ>> rebalancingProposal = desiredPositionCalculator.calculateRebalancingProposal( - currentPriceFromChain, + currentPriceFromRaydium, solTotalReadyAmount, syrupTotalReadyAmount ); @@ -194,32 +184,35 @@ public class EvelynImpl implements Evelyn { calculateDiffs(rebalancingProposal, liquidityPositions); String minKey = diffs.entrySet().stream() - .min(Comparator.comparing(entry -> entry.getValue().diff())) + .min(Comparator.comparing(entry -> entry.getValue().right().amount())) .map(Map.Entry::getKey) .orElseThrow(); String maxKey = diffs.entrySet().stream() - .max(Comparator.comparing(entry -> entry.getValue().diff())) + .max(Comparator.comparing(entry -> entry.getValue().right().amount())) .map(Map.Entry::getKey) .orElseThrow(); System.out.println("Move value from (" + maxKey + "): "); RaydiumLiquidityPoolPositionConcentrated maxPos = liquidityPositions.get(maxKey); - Triblet maxDiff = diffs.get(maxKey); + Triblet<ΩSyrupAmountΩ, ΩSyrupAmountΩ, ΩSyrupAmountΩ> maxDiff = diffs.get(maxKey); System.out.println(" " + maxPos.priceRange().from() + ".." - + maxPos.priceRange().to() + " - Current: " - + maxDiff.currentAmount() + ", Suggested: " + maxDiff.suggestedAmount() - + ", Diff: " + maxDiff.diff()); + + maxPos.priceRange().to() + + " - Current: " + maxDiff.left().amount() + + ", Suggested: " + maxDiff.middle().amount() + + ", Diff: " + maxDiff.right().amount() + ); System.out.println(" --> "); RaydiumLiquidityPoolPositionConcentrated minPos = liquidityPositions.get(minKey); - Triblet minDiff = diffs.get(minKey); + Triblet<ΩSyrupAmountΩ, ΩSyrupAmountΩ, ΩSyrupAmountΩ> minDiff = diffs.get(minKey); System.out.println(" " + minPos.priceRange().from() + ".." - + minPos.priceRange().to() + " - Current: " - + minDiff.currentAmount() + ", Suggested: " + minDiff.suggestedAmount() - + ", Diff: " + minDiff.diff()); + + minPos.priceRange().to() + + " - Current: " + minDiff.left().amount() + + ", Suggested: " + minDiff.middle().amount() + + ", Diff: " + minDiff.right().amount()); ΩmilliSecondsΩ iterationExecutionTime = (System.currentTimeMillis() - iterationStartTime); @@ -245,12 +238,12 @@ public class EvelynImpl implements Evelyn { for(ΩRaydiumLiquidityPoolPositionNftIdΩ nftId : rebalancingProposal.keySet()) { RaydiumLiquidityPoolPositionConcentrated pos = liquidityProviderPositionMap.get(nftId); - ΩAmountΩ currentlyAmountAdded = pos.amountMintB().amount(); - ΩSyrupAmountΩ suggestedAmount = rebalancingProposal.get(nftId); - ΩAmountΩ diff = subtract(currentlyAmountAdded, suggestedAmount); + ΩSyrupAmountΩ currentlyAmountAdded = pos.amountMintB(); + ΩSyrupAmountΩ suggestedAmount = rebalancingProposal.get(nftId).right(); + ΩSyrupAmountΩ diff = subtract(currentlyAmountAdded, suggestedAmount); Triblet<ΩSyrupAmountΩ, ΩSyrupAmountΩ, ΩSyrupAmountΩ> t = new Triblet<>( currentlyAmountAdded, - suggestedAmount.amount(), + suggestedAmount, diff ); diffs.put(nftId, t); @@ -259,11 +252,6 @@ public class EvelynImpl implements Evelyn { return diffs; } - private final static TradingPair tpSolSyrup = new TradingPair( - SOLANA.getCurrencyType(), - SYRUPUSDC.getCurrencyType() - ); - private final static ΩSolanaAmountΩ amountZeroSolana = new ΩSolanaAmountΩ( BigDecimal.ZERO, SOLANA.getCurrencyType() diff --git a/src/main/tjava/com/fanitas/evelyn/core/impl/ref/StateImpl.tjava b/src/main/tjava/com/fanitas/evelyn/core/impl/ref/StateImpl.tjava index fec2b24..a7cd6b7 100644 --- a/src/main/tjava/com/fanitas/evelyn/core/impl/ref/StateImpl.tjava +++ b/src/main/tjava/com/fanitas/evelyn/core/impl/ref/StateImpl.tjava @@ -1,11 +1,10 @@ package com.fanitas.evelyn.core.impl.ref; import com.fanitas.evelyn.core.State; -import com.fanitas.evelyn.raydium.PriceRange; import com.fanitas.evelyn.raydium.RaydiumLiquidityPoolPositionAccounting; import com.fanitas.evelyn.raydium.RaydiumLiquidityPoolPositionConcentrated; import com.r35157.libs.raydium.*; -import com.r35157.libs.solana.valuetypes.WellKnownCurrencyTypes; +import com.r35157.libs.valuetypes.basic.WellKnownCurrencyTypes; import com.r35157.libs.valuetypes.basic.*; import java.io.BufferedReader; @@ -105,17 +104,12 @@ public class StateImpl implements State { CurrencyType ctSyrup = WellKnownCurrencyTypes.SYRUPUSDC.getCurrencyType(); int mintBDecimals = poolInfo.mintBDecimals(); - Range<ΩPriceΩ> raydiumPriceRange = raydium.calculateConcentratedPositionPriceRange( + Range priceRange = raydium.calculateConcentratedPositionPriceRange( positionState, poolInfo, mintBDecimals ); - PriceRange priceRange = new PriceRange( - ctSyrup, - raydiumPriceRange - ); - RaydiumLiquidityPoolTokenAmounts tokenAmounts = raydium.calculateConcentratedPositionTokenAmounts( positionState, diff --git a/src/main/tjava/com/fanitas/evelyn/raydium/PriceRange.tjava b/src/main/tjava/com/fanitas/evelyn/raydium/PriceRange.tjava deleted file mode 100644 index e235cde..0000000 --- a/src/main/tjava/com/fanitas/evelyn/raydium/PriceRange.tjava +++ /dev/null @@ -1,33 +0,0 @@ -package com.fanitas.evelyn.raydium; - -import com.r35157.libs.valuetypes.basic.CurrencyType; -import com.r35157.libs.valuetypes.basic.Range; -import org.jetbrains.annotations.NotNull; - -import java.math.BigDecimal; - -public record PriceRange( - CurrencyType currencyType, - Range<ΩPriceΩ> range -) { - public ΩPriceΩ from() { - return range.from(); - } - - public boolean fromIncluding() { - return range.fromIncluding(); - } - - public ΩPriceΩ to() { - return range.to(); - } - - public boolean toIncluding() { - return range.toIncluding(); - } - - @Override - public @NotNull String toString() { - return range + " " + currencyType().name(); - } -} \ No newline at end of file diff --git a/src/main/tjava/com/fanitas/evelyn/raydium/RaydiumLiquidityPoolPositionConcentrated.tjava b/src/main/tjava/com/fanitas/evelyn/raydium/RaydiumLiquidityPoolPositionConcentrated.tjava index 00e3cc0..342eaa2 100644 --- a/src/main/tjava/com/fanitas/evelyn/raydium/RaydiumLiquidityPoolPositionConcentrated.tjava +++ b/src/main/tjava/com/fanitas/evelyn/raydium/RaydiumLiquidityPoolPositionConcentrated.tjava @@ -1,10 +1,10 @@ package com.fanitas.evelyn.raydium; +import com.r35157.libs.valuetypes.basic.AssetPrice; import com.r35157.libs.valuetypes.basic.MoneyAmount; +import com.r35157.libs.valuetypes.basic.Range; import org.jetbrains.annotations.NotNull; -import java.math.BigDecimal; - /** * Represents a concentrated liquidity position in a Raydium liquidity pool. * @@ -24,7 +24,7 @@ import java.math.BigDecimal; public record RaydiumLiquidityPoolPositionConcentrated( @NotNull ΩRaydiumLiquidityPoolConcentratedIdΩ poolId, @NotNull ΩRaydiumLiquidityPoolPositionNftIdΩ nftId, - @NotNull PriceRange priceRange, + @NotNull Range priceRange, @NotNull MoneyAmount amountMintA, @NotNull MoneyAmount amountMintB, @NotNull RaydiumLiquidityPoolPositionAccounting accountingInfo diff --git a/src/main/tjava/com/r35157/libs/raydium/Raydium.tjava b/src/main/tjava/com/r35157/libs/raydium/Raydium.tjava index c70cf81..9e56d6d 100644 --- a/src/main/tjava/com/r35157/libs/raydium/Raydium.tjava +++ b/src/main/tjava/com/r35157/libs/raydium/Raydium.tjava @@ -1,5 +1,6 @@ package com.r35157.libs.raydium; +import com.r35157.libs.valuetypes.basic.AssetPrice; import com.r35157.libs.valuetypes.basic.MoneyAmount; import com.r35157.libs.valuetypes.basic.Range; @@ -19,7 +20,7 @@ public interface Raydium { * @throws IOException if the price could not be fetched or the response could not be parsed * @throws InterruptedException if the calling thread is interrupted while fetching the price */ - ΩPriceΩ fetchPoolPrice(ΩRaydiumLiquidityPoolIdΩ poolId) throws IOException, InterruptedException; + AssetPrice fetchPoolPrice(ΩRaydiumLiquidityPoolIdΩ poolId) throws IOException, InterruptedException; /** * Fetches the Raydium liquidity pool ids where the supplied Solana owner address has positions. @@ -183,7 +184,7 @@ public interface Raydium { * @param decimalPlaces the number decimal places in the resulting price currency * @return the price range represented by the concentrated liquidity position */ - Range<ΩPriceΩ> calculateConcentratedPositionPriceRange( + Range calculateConcentratedPositionPriceRange( RaydiumConcentratedPositionState positionState, RaydiumConcentratedPoolInfo poolInfo, int decimalPlaces diff --git a/src/main/tjava/com/r35157/libs/raydium/RaydiumLiquidityPoolPrice.tjava b/src/main/tjava/com/r35157/libs/raydium/RaydiumLiquidityPoolPrice.tjava index 98f7b03..e44309e 100644 --- a/src/main/tjava/com/r35157/libs/raydium/RaydiumLiquidityPoolPrice.tjava +++ b/src/main/tjava/com/r35157/libs/raydium/RaydiumLiquidityPoolPrice.tjava @@ -1,6 +1,6 @@ package com.r35157.libs.raydium; -import java.math.BigDecimal; +import com.r35157.libs.valuetypes.basic.AssetPrice; /** * Represents the current price of the tokens in a Raydium liquidity pool. @@ -13,6 +13,6 @@ import java.math.BigDecimal; */ public record RaydiumLiquidityPoolPrice( ΩRaydiumLiquidityPoolIdΩ poolId, - ΩPriceΩ price + AssetPrice price ) { } \ No newline at end of file diff --git a/src/main/tjava/com/r35157/libs/raydium/impl/ref/RaydiumImpl.tjava b/src/main/tjava/com/r35157/libs/raydium/impl/ref/RaydiumImpl.tjava index 5ed8408..c86fe49 100644 --- a/src/main/tjava/com/r35157/libs/raydium/impl/ref/RaydiumImpl.tjava +++ b/src/main/tjava/com/r35157/libs/raydium/impl/ref/RaydiumImpl.tjava @@ -1,5 +1,6 @@ package com.r35157.libs.raydium.impl.ref; +import com.r35157.libs.valuetypes.basic.WellKnownTradingPairs; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.r35157.libs.raydium.Raydium; @@ -13,11 +14,8 @@ import com.r35157.libs.solana.SolanaAccountInfo; import com.r35157.libs.solana.SolanaBlockChain; import com.r35157.libs.solana.SolanaProgramAddressSeed; import com.r35157.libs.solana.valuetypes.SolanaProgramDerivedAddress; -import com.r35157.libs.solana.valuetypes.WellKnownCurrencyTypes; -import com.r35157.libs.solana.valuetypes.economic.SolanaSPLTokenProgram; -import com.r35157.libs.valuetypes.basic.CurrencyType; -import com.r35157.libs.valuetypes.basic.MoneyAmount; -import com.r35157.libs.valuetypes.basic.Range; +import com.r35157.libs.valuetypes.basic.*; + import java.io.IOException; import java.math.BigDecimal; import java.math.BigInteger; @@ -27,7 +25,6 @@ import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; -import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.HashSet; import java.util.List; @@ -45,7 +42,7 @@ public class RaydiumImpl implements Raydium { } @Override - public ΩPriceΩ fetchPoolPrice(ΩRaydiumLiquidityPoolIdΩ raydiumLiquidityPoolId) throws IOException, InterruptedException { + public AssetPrice fetchPoolPrice(ΩRaydiumLiquidityPoolIdΩ raydiumLiquidityPoolId) throws IOException, InterruptedException { ΩRestEndpointΩ endpoint = createPoolInfoByIdEndpoint(raydiumLiquidityPoolId); JsonNode root = fetchJson(endpoint); @@ -57,8 +54,12 @@ public class RaydiumImpl implements Raydium { throw new IOException("Could NOT find field 'price' in JSON!"); } - ΩPriceΩ price = new ΩPriceΩ(priceNode.toString()); - return price; + // TODO: Find out how not to hardcode the trading pair here + TradingPair tp = WellKnownTradingPairs.SOL_SYRUPUSDC.getTradingPair(); + ΩPriceΩ p = new ΩPriceΩ(priceNode.toString()); + AssetPrice ap = new AssetPrice(p, tp); + + return ap; } @Override @@ -257,24 +258,28 @@ public class RaydiumImpl implements Raydium { } @Override - public Range<ΩPriceΩ> calculateConcentratedPositionPriceRange( + public Range calculateConcentratedPositionPriceRange( RaydiumConcentratedPositionState positionState, RaydiumConcentratedPoolInfo poolInfo, int decimalPlaces ) { + TradingPair tp = WellKnownTradingPairs.SOL_SYRUPUSDC.getTradingPair(); + ΩPriceΩ priceFrom = calculatePriceFromTick( positionState.tickLowerIndex(), poolInfo, decimalPlaces ); + AssetPrice apFrom = new AssetPrice(priceFrom, tp); ΩPriceΩ priceTo = calculatePriceFromTick( positionState.tickUpperIndex(), poolInfo, decimalPlaces ); + AssetPrice apTo = new AssetPrice(priceTo, tp); - Range<ΩPriceΩ> range = new Range<>(priceFrom, true, priceTo, false); + Range range = new Range<>(apFrom, true, apTo, false); return range; } diff --git a/src/main/tjava/com/r35157/libs/solana/impl/ref/SolanaBlockChainImpl.tjava b/src/main/tjava/com/r35157/libs/solana/impl/ref/SolanaBlockChainImpl.tjava index 24ad2fb..fe308a5 100644 --- a/src/main/tjava/com/r35157/libs/solana/impl/ref/SolanaBlockChainImpl.tjava +++ b/src/main/tjava/com/r35157/libs/solana/impl/ref/SolanaBlockChainImpl.tjava @@ -4,10 +4,10 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.r35157.libs.solana.*; import com.r35157.libs.solana.valuetypes.SolanaProgramDerivedAddress; -import com.r35157.libs.solana.valuetypes.WellKnownCurrencyTypes; +import com.r35157.libs.valuetypes.basic.MoneyAmount; +import com.r35157.libs.valuetypes.basic.WellKnownCurrencyTypes; import com.r35157.libs.solana.valuetypes.economic.SolanaSPLTokenProgram; import com.r35157.libs.valuetypes.basic.CurrencyType; -import com.r35157.libs.valuetypes.basic.MoneyAmount; import java.io.IOException; import java.math.BigDecimal; diff --git a/src/main/tjava/com/r35157/libs/solana/valuetypes/WellKnownCurrencyTypes.tjava b/src/main/tjava/com/r35157/libs/valuetypes/basic/WellKnownCurrencyTypes.tjava similarity index 93% rename from src/main/tjava/com/r35157/libs/solana/valuetypes/WellKnownCurrencyTypes.tjava rename to src/main/tjava/com/r35157/libs/valuetypes/basic/WellKnownCurrencyTypes.tjava index 7c88278..d4eea1f 100644 --- a/src/main/tjava/com/r35157/libs/solana/valuetypes/WellKnownCurrencyTypes.tjava +++ b/src/main/tjava/com/r35157/libs/valuetypes/basic/WellKnownCurrencyTypes.tjava @@ -1,6 +1,4 @@ -package com.r35157.libs.solana.valuetypes; - -import com.r35157.libs.valuetypes.basic.CurrencyType; +package com.r35157.libs.valuetypes.basic; import java.util.UUID; diff --git a/src/main/tjava/com/r35157/libs/valuetypes/basic/WellKnownTradingPairs.tjava b/src/main/tjava/com/r35157/libs/valuetypes/basic/WellKnownTradingPairs.tjava new file mode 100644 index 0000000..9ba23ec --- /dev/null +++ b/src/main/tjava/com/r35157/libs/valuetypes/basic/WellKnownTradingPairs.tjava @@ -0,0 +1,18 @@ +package com.r35157.libs.valuetypes.basic; + +import static com.r35157.libs.valuetypes.basic.WellKnownCurrencyTypes.SOLANA; +import static com.r35157.libs.valuetypes.basic.WellKnownCurrencyTypes.SYRUPUSDC; + +public enum WellKnownTradingPairs { + SOL_SYRUPUSDC(new TradingPair(SOLANA.getCurrencyType(), SYRUPUSDC.getCurrencyType())); + + WellKnownTradingPairs(TradingPair tradingPair) { + this.tradingPair = tradingPair; + } + + public TradingPair getTradingPair() { + return tradingPair; + } + + private final TradingPair tradingPair; +}