import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class Main {
private record Asset3(Asset2 asset, double capitalCostUsd, double capitalPrice, double delta) {}
public static void main(String[] args) {
List<Asset2> assets = sortByTotalUsdDesc(getBalancesWithPrices());
for (Asset2 asset : assets) {
System.out.println(asset.asset() + " -> " + asset.lastPrice() + " -> " + asset.totalUsd());
}
System.out.println();
List<Asset2> assetSublist4 = new ArrayList<>(assets.subList(0, 4));
List<Asset3> asset3List = new ArrayList<>();
for (Asset2 asset : assetSublist4) {
System.out.println(asset.asset() + " -> " + asset.lastPrice() + " -> " + asset.totalUsd());
System.out.print("Please enter the capital cost in USD: ");
double capitalCostUsd = Double.parseDouble(System.console().readLine());
double capitalPrice = capitalCostUsd / asset.asset().totalAmount();
double delta = calculateDelta(capitalCostUsd, asset.totalUsd());
asset3List.add(new Asset3(asset, capitalCostUsd, capitalPrice, delta));
}
System.out.println();
asset3List.sort(Comparator.comparingDouble(Asset3::delta).reversed());
double averageDelta = 0;
for (Asset3 asset : asset3List) {
averageDelta += asset.delta() / asset3List.size();
}
System.out.println("Average delta: " + averageDelta);
double fairDelta = calculateFairDelta(asset3List);
System.out.println("Fair delta: " + fairDelta);
System.out.println();
double sumSell = 0;
double sumBuy = 0;
for (Asset3 asset : asset3List) {
System.out.println(asset + " -> " + (asset.delta() - fairDelta));
if (asset.delta() > fairDelta) {
System.out.println("Sell " + asset.asset().asset().name());
double amount = asset.asset().asset().totalAmount() - calculateAmount(asset, fairDelta);
double sum = amount * asset.asset().lastPrice();
sumSell += sum;
double newTotal = asset.asset().totalUsd() - sum;
double newDelta = calculateDelta(asset.capitalCostUsd(), newTotal);
System.out.println(
"Sell amount: "
+ amount
+ " ("
+ asset.asset().lastPrice()
+ " x "
+ amount
+ " = "
+ sum
+ ") -> New delta: "
+ newDelta);
} else {
System.out.println("Buy " + asset.asset().asset().name());
double amount = calculateAmount(asset, fairDelta) - asset.asset().asset().totalAmount();
double sum = amount * asset.asset().lastPrice();
sumBuy += sum;
double newTotal = asset.asset().totalUsd() + sum;
double newDelta = calculateDelta(asset.capitalCostUsd(), newTotal);
System.out.println(
"Buy amount: "
+ amount
+ " ("
+ asset.asset().lastPrice()
+ " x "
+ amount
+ " = "
+ sum
+ ") -> New delta: "
+ newDelta);
}
System.out.println();
}
System.out.println("Total sell : " + sumSell);
System.out.println("Total buy : " + sumBuy);
}
private static double calculateDelta(double initialCosts, double currentCosts) {
return 1.0 + (currentCosts - initialCosts) / initialCosts;
}
private static double calculateCosts(Asset3 asset, double targetDelta) {
return asset.capitalCostUsd() * targetDelta;
}
private static double calculateAmount(Asset3 asset, double targetDelta) {
return calculateCosts(asset, targetDelta) / asset.asset().lastPrice();
}
private static double calculateDeltaSum(List<Asset3> assets, double targetDelta) {
double sum = 0;
for (Asset3 asset : assets) {
double delta = asset.delta();
if (delta > targetDelta) {
// Sell
sum -=
(asset.asset().asset().totalAmount() - calculateAmount(asset, targetDelta))
* asset.asset().lastPrice();
} else {
// Buy
sum +=
(calculateAmount(asset, targetDelta) - asset.asset().asset().totalAmount())
* asset.asset().lastPrice();
}
}
return sum;
}
private static double calculateFairDelta(List<Asset3> assets) {
double lowerBound = 0.0;
double upperBound = 2.0;
double targetDelta = (lowerBound + upperBound) / 2.0;
double deltaSum = calculateDeltaSum(assets, targetDelta);
while (Math.abs(deltaSum) > 0.00001) {
if (deltaSum > 0) {
upperBound = targetDelta;
} else {
lowerBound = targetDelta;
}
targetDelta = (lowerBound + upperBound) / 2.0;
deltaSum = calculateDeltaSum(assets, targetDelta);
}
return targetDelta;
}
}