From 02f55c715fe04a42a345028bd14ec9f91070fff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20S=C3=A1nchez?= Date: Sat, 14 Dec 2024 14:17:00 -0300 Subject: [PATCH] Retries to avoid 503 errors --- .../example/dcav2gui/InstanceInterface.java | 73 +++--- .../com/example/dcav2gui/TickerTracker.java | 5 +- .../dcav2gui/ui/home/HomeFragment.java | 219 ++++++++++-------- 3 files changed, 167 insertions(+), 130 deletions(-) diff --git a/app/src/main/java/com/example/dcav2gui/InstanceInterface.java b/app/src/main/java/com/example/dcav2gui/InstanceInterface.java index 160fba2..bd0c69e 100644 --- a/app/src/main/java/com/example/dcav2gui/InstanceInterface.java +++ b/app/src/main/java/com/example/dcav2gui/InstanceInterface.java @@ -25,7 +25,9 @@ public class InstanceInterface { private static final String API_KEY = globalSettings.apiKey; private static final OkHttpClient httpClient = new OkHttpClient(); - public static ProfitStatsData getProfitStatsData() throws IOException { + public static ProfitStatsData getProfitStatsData(boolean retry) throws IOException { + int retries = 3; + Request profitRequest = new Request.Builder() .url(API_BASE_URL + "/statistics_server/combined_totals") .header("X-API-KEY", API_KEY) @@ -33,6 +35,9 @@ public class InstanceInterface { try (Response statsResponse = httpClient.newCall(profitRequest).execute()) { if (!statsResponse.isSuccessful()) { + if (statsResponse.code() == 503 && retry) { + return getProfitStatsData(false); + } throw new IOException("Unexpected code " + statsResponse); } String stockResponseBody = statsResponse.body().string(); @@ -90,17 +95,20 @@ public class InstanceInterface { } } - public static double getTraderTime(String exchange) throws IOException { + public static double getTraderTime(String exchange, boolean retry) throws IOException { Request uptimeRequest = new Request.Builder() .url(API_BASE_URL + "/" + exchange + "/trader_time") .header("X-API-KEY", API_KEY) .build(); - try (Response statsResponse = httpClient.newCall(uptimeRequest).execute()) { - if (!statsResponse.isSuccessful()) { - throw new IOException("Unexpected code " + statsResponse); + try (Response uptimeResponse = httpClient.newCall(uptimeRequest).execute()) { + if (!uptimeResponse.isSuccessful()) { + if (uptimeResponse.code() == 503 && retry) { + return getTraderTime(exchange,false); + } + throw new IOException("Unexpected code " + uptimeResponse); } - String stockResponseBody = statsResponse.body().string(); + String stockResponseBody = uptimeResponse.body().string(); try { JsonElement jsonElement = JsonParser.parseString(stockResponseBody); @@ -127,7 +135,7 @@ public class InstanceInterface { CompletableFuture> binanceFuture = CompletableFuture.supplyAsync(() -> { try { - return getLastTradesFromExchange("binance"); + return getLastTradesFromExchange("binance", true); } catch (IOException e) { throw new RuntimeException(e); } @@ -135,7 +143,7 @@ public class InstanceInterface { CompletableFuture> gateioFuture = CompletableFuture.supplyAsync(() -> { try { - return getLastTradesFromExchange("gateio"); + return getLastTradesFromExchange("gateio", true); } catch (IOException e) { throw new RuntimeException(e); } @@ -143,7 +151,7 @@ public class InstanceInterface { CompletableFuture> kucoinFuture = CompletableFuture.supplyAsync(() -> { try { - return getLastTradesFromExchange("kucoin"); + return getLastTradesFromExchange("kucoin", true); } catch (IOException e) { throw new RuntimeException(e); } @@ -151,7 +159,7 @@ public class InstanceInterface { CompletableFuture> okxFuture = CompletableFuture.supplyAsync(() -> { try { - return getLastTradesFromExchange("okex"); + return getLastTradesFromExchange("okex", true); } catch (IOException e) { throw new RuntimeException(e); } @@ -177,7 +185,7 @@ public class InstanceInterface { return allDeals.subList(0,globalSettings.amountOfLastTrades); } - public static List getLastTradesFromExchange(String exchange) throws IOException { + public static List getLastTradesFromExchange(String exchange, boolean retry) throws IOException { Request dealsRequest = new Request.Builder() .url(API_BASE_URL + "/" + exchange + "/get_deals_cache") @@ -185,12 +193,13 @@ public class InstanceInterface { .build(); - try (Response statsResponse = httpClient.newCall(dealsRequest).execute()) { - if (!statsResponse.isSuccessful()) { - System.err.println("Unexpected code " + statsResponse); - throw new IOException("Unexpected code " + statsResponse); - } - String dealsResponseBody = statsResponse.body().string(); + try (Response dealsResponse = httpClient.newCall(dealsRequest).execute()) { + if (!dealsResponse.isSuccessful()) { + if (dealsResponse.code() == 503 && retry) { + return getLastTradesFromExchange(exchange,false); + } + throw new IOException("Unexpected code " + dealsResponse); } + String dealsResponseBody = dealsResponse.body().string(); JsonElement jsonElement = JsonParser.parseString(dealsResponseBody); if (!jsonElement.isJsonObject()) { System.err.println("The parsed JSON response is not a JsonObject."); @@ -222,18 +231,21 @@ public class InstanceInterface { } } - public static String getLastLogs(String exchange) throws IOException { + public static String getLastLogs(String exchange, boolean retry) throws IOException { Request logRequest = new Request.Builder() .url(API_BASE_URL + "/" + exchange + "/get_log_list") .header("X-API-KEY", API_KEY) .build(); - try (Response statsResponse = httpClient.newCall(logRequest).execute()) { - if (!statsResponse.isSuccessful()) { - throw new IOException("Unexpected code " + statsResponse); + try (Response logResponse = httpClient.newCall(logRequest).execute()) { + if (!logResponse.isSuccessful()) { + if (logResponse.code() == 503 && retry) { + return getLastLogs(exchange,false); + } + throw new IOException("Unexpected code " + logResponse); } - String dealsResponseBody = statsResponse.body().string(); + String dealsResponseBody = logResponse.body().string(); JsonElement jsonElement = JsonParser.parseString(dealsResponseBody); if (!jsonElement.isJsonObject()) { System.err.println("The parsed JSON response is not a JsonObject."); @@ -268,10 +280,10 @@ public class InstanceInterface { // Semaphore - lastSeen = getTraderTime(exchange); + lastSeen = getTraderTime(exchange, true); //Funds available - fundsAvailable = getFundsAvailable(exchange, "USDT"); + fundsAvailable = getFundsAvailable(exchange, "USDT", true); //Individual worker status needed to calculate this //Funds needed @@ -290,17 +302,20 @@ public class InstanceInterface { } - private static double getFundsAvailable(String exchange, String coin) throws IOException { + private static double getFundsAvailable(String exchange, String coin, boolean retry) throws IOException { Request fundsRequest = new Request.Builder() .url(API_BASE_URL + "/" + exchange + "/get_balance?coin=" + coin) .header("X-API-KEY", API_KEY) .build(); - try (Response statsResponse = httpClient.newCall(fundsRequest).execute()) { - if (!statsResponse.isSuccessful()) { - throw new IOException("Unexpected code " + statsResponse); + try (Response fundsResponse = httpClient.newCall(fundsRequest).execute()) { + if (!fundsResponse.isSuccessful()) { + if (fundsResponse.code() == 503 && retry) { + return getFundsAvailable(exchange, coin, false); + } + throw new IOException("Unexpected code " + fundsResponse); } - String fundsResponseBody = statsResponse.body().string(); + String fundsResponseBody = fundsResponse.body().string(); JsonElement jsonElement = JsonParser.parseString(fundsResponseBody); if (!jsonElement.isJsonObject()) { System.err.println("The parsed JSON response is not a JsonObject."); diff --git a/app/src/main/java/com/example/dcav2gui/TickerTracker.java b/app/src/main/java/com/example/dcav2gui/TickerTracker.java index 45fd762..9a0af3c 100644 --- a/app/src/main/java/com/example/dcav2gui/TickerTracker.java +++ b/app/src/main/java/com/example/dcav2gui/TickerTracker.java @@ -16,7 +16,7 @@ public class TickerTracker { static int requestDepth = 722; static String requestResolution = "15m"; - public static PriceChangeData getPriceChanges(String symbol) throws IOException { + public static PriceChangeData getPriceChanges(String symbol, boolean retry) throws IOException { // Construct the API request URL for 24h change Request historicalRequest = new Request.Builder() .url("https://api.binance.com/api/v3/klines?symbol=" + symbol.toUpperCase(Locale.ROOT) + "&interval=1h&limit=722") @@ -24,6 +24,9 @@ public class TickerTracker { try (Response historicalResponse = httpClient.newCall(historicalRequest).execute()) { if (!historicalResponse.isSuccessful()) { + if (historicalResponse.code() == 503 && retry) { + return getPriceChanges(symbol, false); + } throw new IOException("Unexpected code " + historicalResponse); } String historicalResponseBody = historicalResponse.body().string(); diff --git a/app/src/main/java/com/example/dcav2gui/ui/home/HomeFragment.java b/app/src/main/java/com/example/dcav2gui/ui/home/HomeFragment.java index 780c61c..da94389 100644 --- a/app/src/main/java/com/example/dcav2gui/ui/home/HomeFragment.java +++ b/app/src/main/java/com/example/dcav2gui/ui/home/HomeFragment.java @@ -308,7 +308,7 @@ public class HomeFragment extends Fragment { // Fetch price data in background using CompletableFuture CompletableFuture future1 = CompletableFuture.supplyAsync(() -> { try { - return TickerTracker.getPriceChanges(getString(R.string.ticker_1)); + return TickerTracker.getPriceChanges(getString(R.string.ticker_1),true); } catch (IOException e) { e.printStackTrace(); return null; @@ -317,7 +317,7 @@ public class HomeFragment extends Fragment { CompletableFuture future2 = CompletableFuture.supplyAsync(() -> { try { - return TickerTracker.getPriceChanges(getString(R.string.ticker_2)); + return TickerTracker.getPriceChanges(getString(R.string.ticker_2), true); } catch (IOException e) { e.printStackTrace(); return null; @@ -326,7 +326,7 @@ public class HomeFragment extends Fragment { CompletableFuture future3 = CompletableFuture.supplyAsync(() -> { try { - return TickerTracker.getPriceChanges(getString(R.string.ticker_3)); + return TickerTracker.getPriceChanges(getString(R.string.ticker_3), true); } catch (IOException e) { e.printStackTrace(); return null; @@ -335,7 +335,7 @@ public class HomeFragment extends Fragment { CompletableFuture future4 = CompletableFuture.supplyAsync(() -> { try { - return InstanceInterface.getProfitStatsData(); + return InstanceInterface.getProfitStatsData(true); } catch (IOException e) { e.printStackTrace(); return null; @@ -344,7 +344,7 @@ public class HomeFragment extends Fragment { CompletableFuture future5 = CompletableFuture.supplyAsync(() -> { try { - return InstanceInterface.getLastLogs("binance"); + return InstanceInterface.getLastLogs("binance", true); } catch (IOException e) { e.printStackTrace(); return null; @@ -353,7 +353,7 @@ public class HomeFragment extends Fragment { CompletableFuture future6 = CompletableFuture.supplyAsync(() -> { try { - return InstanceInterface.getLastLogs("gateio"); + return InstanceInterface.getLastLogs("gateio", true); } catch (IOException e) { e.printStackTrace(); return null; @@ -362,7 +362,7 @@ public class HomeFragment extends Fragment { CompletableFuture future7 = CompletableFuture.supplyAsync(() -> { try { - return InstanceInterface.getLastLogs("kucoin"); + return InstanceInterface.getLastLogs("kucoin", true); } catch (IOException e) { e.printStackTrace(); return null; @@ -371,7 +371,7 @@ public class HomeFragment extends Fragment { CompletableFuture future8 = CompletableFuture.supplyAsync(() -> { try { - return InstanceInterface.getLastLogs("okex"); + return InstanceInterface.getLastLogs("okex", true); } catch (IOException e) { e.printStackTrace(); return null; @@ -504,115 +504,134 @@ public class HomeFragment extends Fragment { } + if (priceData!= null) { + pricePair1.setText(String.format(Locale.ROOT, "%.2f", priceData.getCurrentPrice())); + pricePair124hPercentage.setText(formatPercentage(priceData.getPriceChangePercent24h())); + pricePair17dPercentage.setText(formatPercentage(priceData.getPriceChangePercent7d())); + pricePair130dPercentage.setText(formatPercentage(priceData.getPriceChangePercent30d())); + setPercentageColor(pricePair124hPercentage, priceData.getPriceChangePercent24h()); + setPercentageColor(pricePair17dPercentage, priceData.getPriceChangePercent7d()); + setPercentageColor(pricePair130dPercentage, priceData.getPriceChangePercent30d()); - pricePair1.setText(String.format(Locale.ROOT, "%.2f", priceData.getCurrentPrice())); - pricePair124hPercentage.setText(formatPercentage(priceData.getPriceChangePercent24h())); - pricePair17dPercentage.setText(formatPercentage(priceData.getPriceChangePercent7d())); - pricePair130dPercentage.setText(formatPercentage(priceData.getPriceChangePercent30d())); - setPercentageColor(pricePair124hPercentage, priceData.getPriceChangePercent24h()); - setPercentageColor(pricePair17dPercentage, priceData.getPriceChangePercent7d()); - setPercentageColor(pricePair130dPercentage, priceData.getPriceChangePercent30d()); + pricePair2.setText(String.format(Locale.ROOT, "%.2f", priceData2.getCurrentPrice())); + pricePair224hPercentage.setText(formatPercentage(priceData2.getPriceChangePercent24h())); + pricePair27dPercentage.setText(formatPercentage(priceData2.getPriceChangePercent7d())); + pricePair230dPercentage.setText(formatPercentage(priceData2.getPriceChangePercent30d())); + setPercentageColor(pricePair224hPercentage, priceData2.getPriceChangePercent24h()); + setPercentageColor(pricePair27dPercentage, priceData2.getPriceChangePercent7d()); + setPercentageColor(pricePair230dPercentage, priceData2.getPriceChangePercent30d()); - pricePair2.setText(String.format(Locale.ROOT, "%.2f", priceData2.getCurrentPrice())); - pricePair224hPercentage.setText(formatPercentage(priceData2.getPriceChangePercent24h())); - pricePair27dPercentage.setText(formatPercentage(priceData2.getPriceChangePercent7d())); - pricePair230dPercentage.setText(formatPercentage(priceData2.getPriceChangePercent30d())); - setPercentageColor(pricePair224hPercentage, priceData2.getPriceChangePercent24h()); - setPercentageColor(pricePair27dPercentage, priceData2.getPriceChangePercent7d()); - setPercentageColor(pricePair230dPercentage, priceData2.getPriceChangePercent30d()); + pricePair3.setText(String.format(Locale.ROOT, "%.2f", priceData3.getCurrentPrice())); + pricePair324hPercentage.setText(formatPercentage(priceData3.getPriceChangePercent24h())); + pricePair37dPercentage.setText(formatPercentage(priceData3.getPriceChangePercent7d())); + pricePair330dPercentage.setText(formatPercentage(priceData3.getPriceChangePercent30d())); + setPercentageColor(pricePair324hPercentage, priceData3.getPriceChangePercent24h()); + setPercentageColor(pricePair37dPercentage, priceData3.getPriceChangePercent7d()); + setPercentageColor(pricePair330dPercentage, priceData3.getPriceChangePercent30d()); + } - pricePair3.setText(String.format(Locale.ROOT, "%.2f", priceData3.getCurrentPrice())); - pricePair324hPercentage.setText(formatPercentage(priceData3.getPriceChangePercent24h())); - pricePair37dPercentage.setText(formatPercentage(priceData3.getPriceChangePercent7d())); - pricePair330dPercentage.setText(formatPercentage(priceData3.getPriceChangePercent30d())); - setPercentageColor(pricePair324hPercentage, priceData3.getPriceChangePercent24h()); - setPercentageColor(pricePair37dPercentage, priceData3.getPriceChangePercent7d()); - setPercentageColor(pricePair330dPercentage, priceData3.getPriceChangePercent30d()); - - profitsToday.setText(String.format(Locale.ROOT, "%.2f", profitsData.getProfitsToday())); - profitsThisMonth.setText(String.format(Locale.ROOT, "%.2f", profitsData.getProfitsThisMonth())); + if (profitsData != null) { + profitsToday.setText(String.format(Locale.ROOT, "%.2f", profitsData.getProfitsToday())); + profitsThisMonth.setText(String.format(Locale.ROOT, "%.2f", profitsData.getProfitsThisMonth())); + } //Exchange stats int timeoutForYellow = 30*1000; //30 seconds int timeoutForRed = 300*1000; //300 seconds //Icons - if (binanceStats.getLastSeen()*1000+timeoutForRed < System.currentTimeMillis()) { - exchange1Status.setImageResource(R.drawable.ic_red_circle_48); - System.err.println(binanceStats.getLastSeen());} - else if (binanceStats.getLastSeen()*1000+timeoutForYellow < System.currentTimeMillis()) { - exchange1Status.setImageResource(R.drawable.ic_yellow_circle_48);} - else { - exchange1Status.setImageResource(R.drawable.ic_green_circle_48); + if (binanceStats!=null){ + if (binanceStats.getLastSeen()*1000+timeoutForRed < System.currentTimeMillis()) { + exchange1Status.setImageResource(R.drawable.ic_red_circle_48); + System.err.println(binanceStats.getLastSeen());} + else if (binanceStats.getLastSeen()*1000+timeoutForYellow < System.currentTimeMillis()) { + exchange1Status.setImageResource(R.drawable.ic_yellow_circle_48);} + else { + exchange1Status.setImageResource(R.drawable.ic_green_circle_48); + } } - if (gateioStats.getLastSeen()*1000+timeoutForRed < System.currentTimeMillis()) { - exchange2Status.setImageResource(R.drawable.ic_red_circle_48); - System.err.println(gateioStats.getLastSeen());} - else if (gateioStats.getLastSeen()*1000+timeoutForYellow < System.currentTimeMillis()) { - exchange2Status.setImageResource(R.drawable.ic_yellow_circle_48);} - else { - exchange2Status.setImageResource(R.drawable.ic_green_circle_48); + if (gateioStats != null){ + if (gateioStats.getLastSeen()*1000+timeoutForRed < System.currentTimeMillis()) { + exchange2Status.setImageResource(R.drawable.ic_red_circle_48); + System.err.println(gateioStats.getLastSeen());} + else if (gateioStats.getLastSeen()*1000+timeoutForYellow < System.currentTimeMillis()) { + exchange2Status.setImageResource(R.drawable.ic_yellow_circle_48);} + else { + exchange2Status.setImageResource(R.drawable.ic_green_circle_48); + } } - if (kucoinStats.getLastSeen()*1000+timeoutForRed < System.currentTimeMillis()) { - exchange3Status.setImageResource(R.drawable.ic_red_circle_48); - System.err.println(kucoinStats.getLastSeen());} - else if (kucoinStats.getLastSeen()*1000+timeoutForYellow < System.currentTimeMillis()) { - exchange3Status.setImageResource(R.drawable.ic_yellow_circle_48);} - else { - exchange3Status.setImageResource(R.drawable.ic_green_circle_48); + if (kucoinStats != null) { + if (kucoinStats.getLastSeen() * 1000 + timeoutForRed < System.currentTimeMillis()) { + exchange3Status.setImageResource(R.drawable.ic_red_circle_48); + System.err.println(kucoinStats.getLastSeen()); + } else if (kucoinStats.getLastSeen() * 1000 + timeoutForYellow < System.currentTimeMillis()) { + exchange3Status.setImageResource(R.drawable.ic_yellow_circle_48); + } else { + exchange3Status.setImageResource(R.drawable.ic_green_circle_48); + } } - if (okexStats.getLastSeen()*1000+timeoutForRed < System.currentTimeMillis()) { - exchange4Status.setImageResource(R.drawable.ic_red_circle_48); - System.err.println(okexStats.getLastSeen()); - } - else if (okexStats.getLastSeen()*1000+timeoutForYellow < System.currentTimeMillis()) { - exchange4Status.setImageResource(R.drawable.ic_yellow_circle_48);} - else { - exchange4Status.setImageResource(R.drawable.ic_green_circle_48); + if (okexStats != null) { + if (okexStats.getLastSeen()*1000+timeoutForRed < System.currentTimeMillis()) { + exchange4Status.setImageResource(R.drawable.ic_red_circle_48); + System.err.println(okexStats.getLastSeen()); + } + else if (okexStats.getLastSeen()*1000+timeoutForYellow < System.currentTimeMillis()) { + exchange4Status.setImageResource(R.drawable.ic_yellow_circle_48);} + else { + exchange4Status.setImageResource(R.drawable.ic_green_circle_48); + } } //Funds available - String binanceFundsAvailable = String.format(Locale.ROOT,"%.2f",binanceStats.getFundsAvailable()); - String binanceFundsNeeded = String.format(Locale.ROOT,"%.2f",binanceStats.getFundsNeeded()); - String gateioFundsAvailable = String.format(Locale.ROOT,"%.2f",gateioStats.getFundsAvailable()); - String gateioFundsNeeded = String.format(Locale.ROOT,"%.2f",gateioStats.getFundsNeeded()); - String kucoinFundsAvailable = String.format(Locale.ROOT,"%.2f",kucoinStats.getFundsAvailable()); - String kucoinFundsNeeded = String.format(Locale.ROOT,"%.2f",kucoinStats.getFundsNeeded()); - String okexFundsAvailable = String.format(Locale.ROOT,"%.2f",okexStats.getFundsAvailable()); - String okexFundsNeeded = String.format(Locale.ROOT,"%.2f",okexStats.getFundsNeeded()); - String binanceFunds = binanceFundsAvailable+"/"+binanceFundsNeeded; - String gateioFunds = gateioFundsAvailable+"/"+gateioFundsNeeded; - String kucoinFunds = kucoinFundsAvailable+"/"+kucoinFundsNeeded; - String okexFunds = okexFundsAvailable+"/"+okexFundsNeeded; - double binanceFundsPercentage = 69.4231337; - if (binanceStats.getFundsNeeded()!=0) { - binanceFundsPercentage = 100 - (binanceStats.getFundsNeeded() - binanceStats.getFundsAvailable()) / binanceStats.getFundsNeeded() * 100; + if (binanceStats != null) { + String binanceFundsAvailable = String.format(Locale.ROOT, "%.2f", binanceStats.getFundsAvailable()); + String binanceFundsNeeded = String.format(Locale.ROOT, "%.2f", binanceStats.getFundsNeeded()); + String binanceFunds = binanceFundsAvailable + "/" + binanceFundsNeeded; + double binanceFundsPercentage = 69.4231337; + if (binanceStats.getFundsNeeded() != 0) { + binanceFundsPercentage = 100 - (binanceStats.getFundsNeeded() - binanceStats.getFundsAvailable()) / binanceStats.getFundsNeeded() * 100; + } + String binanceFundsPercentageString = String.format(Locale.ROOT, "%.2f", binanceFundsPercentage) + "%"; + exchange1Funds.setText(binanceFunds); + exchange1FundsPercentage.setText(binanceFundsPercentageString); } - double gateioFundsPercentage = 69.4231337; - if (gateioStats.getFundsNeeded()!=0) { - gateioFundsPercentage = 100 - (gateioStats.getFundsNeeded() - gateioStats.getFundsAvailable()) / gateioStats.getFundsNeeded() * 100; - } - double kucoinFundsPercentage = 69.4231337; - if (kucoinStats.getFundsNeeded()!=0) { - kucoinFundsPercentage = 100 - (kucoinStats.getFundsNeeded() - kucoinStats.getFundsAvailable()) / kucoinStats.getFundsNeeded() * 100; - } - double okexFundsPercentage = 69.4231337; - if (okexStats.getFundsNeeded()!=0) { - okexFundsPercentage = 100 - (okexStats.getFundsNeeded() - okexStats.getFundsAvailable()) / okexStats.getFundsNeeded() * 100; - } - String binanceFundsPercentageString = String.format(Locale.ROOT,"%.2f",binanceFundsPercentage)+"%"; - String gateioFundsPercentageString = String.format(Locale.ROOT,"%.2f",gateioFundsPercentage)+"%"; - String kucoinFundsPercentageString = String.format(Locale.ROOT,"%.2f",kucoinFundsPercentage)+"%"; - String okexFundsPercentageString = String.format(Locale.ROOT,"%.2f",okexFundsPercentage)+"%"; - exchange1Funds.setText(binanceFunds); - exchange2Funds.setText(gateioFunds); - exchange3Funds.setText(kucoinFunds); - exchange4Funds.setText(okexFunds); - exchange1FundsPercentage.setText(binanceFundsPercentageString); - exchange2FundsPercentage.setText(gateioFundsPercentageString); - exchange3FundsPercentage.setText(kucoinFundsPercentageString); - exchange4FundsPercentage.setText(okexFundsPercentageString); + if (gateioStats != null) { + String gateioFundsAvailable = String.format(Locale.ROOT, "%.2f", gateioStats.getFundsAvailable()); + String gateioFundsNeeded = String.format(Locale.ROOT, "%.2f", gateioStats.getFundsNeeded()); + String gateioFunds = gateioFundsAvailable + "/" + gateioFundsNeeded; + double gateioFundsPercentage = 69.4231337; + if (gateioStats.getFundsNeeded() != 0) { + gateioFundsPercentage = 100 - (gateioStats.getFundsNeeded() - gateioStats.getFundsAvailable()) / gateioStats.getFundsNeeded() * 100; + } + String gateioFundsPercentageString = String.format(Locale.ROOT, "%.2f", gateioFundsPercentage) + "%"; + exchange2Funds.setText(gateioFunds); + exchange2FundsPercentage.setText(gateioFundsPercentageString); + } + if (kucoinStats != null) { + String kucoinFundsAvailable = String.format(Locale.ROOT, "%.2f", kucoinStats.getFundsAvailable()); + String kucoinFundsNeeded = String.format(Locale.ROOT, "%.2f", kucoinStats.getFundsNeeded()); + String kucoinFunds = kucoinFundsAvailable + "/" + kucoinFundsNeeded; + double kucoinFundsPercentage = 69.4231337; + if (kucoinStats.getFundsNeeded() != 0) { + kucoinFundsPercentage = 100 - (kucoinStats.getFundsNeeded() - kucoinStats.getFundsAvailable()) / kucoinStats.getFundsNeeded() * 100; + } + String kucoinFundsPercentageString = String.format(Locale.ROOT, "%.2f", kucoinFundsPercentage) + "%"; + exchange3Funds.setText(kucoinFunds); + exchange3FundsPercentage.setText(kucoinFundsPercentageString); + } + if (okexStats != null) { + String okexFundsAvailable = String.format(Locale.ROOT, "%.2f", okexStats.getFundsAvailable()); + String okexFundsNeeded = String.format(Locale.ROOT, "%.2f", okexStats.getFundsNeeded()); + String okexFunds = okexFundsAvailable + "/" + okexFundsNeeded; + double okexFundsPercentage = 69.4231337; + if (okexStats.getFundsNeeded() != 0) { + okexFundsPercentage = 100 - (okexStats.getFundsNeeded() - okexStats.getFundsAvailable()) / okexStats.getFundsNeeded() * 100; + } + String okexFundsPercentageString = String.format(Locale.ROOT, "%.2f", okexFundsPercentage) + "%"; + exchange4Funds.setText(okexFunds); + exchange4FundsPercentage.setText(okexFundsPercentageString); + } //Populate logs log1Content.setText(logs1);