package com.example.dcav2gui; import static com.example.dcav2gui.MainActivity.globalSettings; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonSyntaxException; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.concurrent.CompletableFuture; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; public class InstanceInterface { private static final String API_BASE_URL = globalSettings.apiUrl; private static final String API_KEY = globalSettings.apiKey; private static final OkHttpClient httpClient = new OkHttpClient(); 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) .build(); 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(); double todaysProfit = getTodaysProfit(stockResponseBody); double thisMonthProfit = getThisMonthsProfit(stockResponseBody); // Return the stock quote data return new ProfitStatsData( todaysProfit, thisMonthProfit ); } } private static double getTodaysProfit(String jsonResponse) { try { JsonElement jsonElement = JsonParser.parseString(jsonResponse); if (!jsonElement.isJsonObject()) { System.err.println("The parsed JSON response is not a JsonObject."); return 0.0; } JsonObject jsonObject = jsonElement.getAsJsonObject(); if (jsonObject.has("combined")) { JsonArray combinedArray = jsonObject.get("combined").getAsJsonArray(); return combinedArray.get(0).getAsDouble(); } else { System.err.println("The parsed JSON response does not contain a 'combined' array."); return 0.0; } } catch (Exception e) { System.err.println("Error processing combined profit data: " + e.getMessage()); return 0.0; } } private static double getThisMonthsProfit(String jsonResponse) { try { JsonElement jsonElement = JsonParser.parseString(jsonResponse); if (!jsonElement.isJsonObject()) { System.err.println("The parsed JSON response is not a JsonObject."); return 0.0; } JsonObject jsonObject = jsonElement.getAsJsonObject(); if (jsonObject.has("combined")) { JsonArray combinedArray = jsonObject.get("combined").getAsJsonArray(); return combinedArray.get(1).getAsDouble(); } else { System.err.println("The parsed JSON response does not contain a 'combined' array."); return 0.0; } } catch (Exception e) { System.err.println("Error processing combined profit data: " + e.getMessage()); return 0.0; } } 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 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 = uptimeResponse.body().string(); try { JsonElement jsonElement = JsonParser.parseString(stockResponseBody); if (!jsonElement.isJsonObject()) { System.err.println("The parsed JSON response is not a JsonObject."); return 0.0; } JsonObject jsonObject = jsonElement.getAsJsonObject(); if (jsonObject.has("Time")) { return jsonObject.get("Time").getAsDouble(); } else { System.err.println("The parsed JSON response does not contain a 'Time' entry."); return 0.0; } } catch (Exception e) { System.err.println("Error processing uptime data: " + e.getMessage()); return 0.0; } } } public static List getAllTrades() throws IOException { CompletableFuture> binanceFuture = CompletableFuture.supplyAsync(() -> { try { return getLastTradesFromExchange("binance", true); } catch (IOException e) { throw new RuntimeException(e); } }); CompletableFuture> gateioFuture = CompletableFuture.supplyAsync(() -> { try { return getLastTradesFromExchange("gateio", true); } catch (IOException e) { throw new RuntimeException(e); } }); CompletableFuture> kucoinFuture = CompletableFuture.supplyAsync(() -> { try { return getLastTradesFromExchange("kucoin", true); } catch (IOException e) { throw new RuntimeException(e); } }); CompletableFuture> okxFuture = CompletableFuture.supplyAsync(() -> { try { return getLastTradesFromExchange("okex", true); } catch (IOException e) { throw new RuntimeException(e); } }); CompletableFuture allFutures = CompletableFuture.allOf(binanceFuture, gateioFuture, kucoinFuture, okxFuture); List binanceDeals = binanceFuture.join(); List gateioDeals = gateioFuture.join(); List kucoinDeals = kucoinFuture.join(); List okxDeals = okxFuture.join(); List allDeals = new ArrayList<>(); allDeals.addAll(binanceDeals); allDeals.addAll(gateioDeals); allDeals.addAll(kucoinDeals); allDeals.addAll(okxDeals); //Sort deals by timestamp allDeals.sort(Comparator.comparingDouble(DealData::getTimestamp)); Collections.reverse(allDeals); return allDeals.subList(0,globalSettings.amountOfLastTrades); } public static List getLastTradesFromExchange(String exchange, boolean retry) throws IOException { Request dealsRequest = new Request.Builder() .url(API_BASE_URL + "/" + exchange + "/get_deals_cache") .header("X-API-KEY", API_KEY) .build(); 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."); return null; } JsonObject jsonObject = jsonElement.getAsJsonObject(); if (!jsonObject.has("Deals")) { System.err.println("The parsed JSON response does not contain the deals key."); return null; } //Return a list of items of the format: //(timestamp,pair,amount,exchange_name,order_id,order_history) //order history always is an empty string when querying the deals cache //It can be safely ignored JsonArray dealsArray = jsonObject.getAsJsonArray("Deals"); List dealDataList = new ArrayList<>(); for (int i=0; i logList = new ArrayList<>(); for (int i = logsArray.size()-1; i >= 0; i--) { logList.add(logsArray.get(i).getAsString()); } //Collections.reverse(logList); return joinWithLineLimit(" ",globalSettings.amountOfLogLines,logList); } } private static double gibSoSize(double orderSize, int n, double safetyOrderScale) { double targetOrderSize = orderSize; for (int i = 0; i < n; i++) { targetOrderSize = targetOrderSize*safetyOrderScale*100; } return targetOrderSize; } public static ExchangeStatsData getExchangeStatsData(String exchange) throws IOException { double lastSeen; double fundsAvailable; double fundsNeeded = 0; int onlineWorkers = 0; int longWorkers = 0; int shortWorkers = 0; List workers; InstanceGlobalStatsData instanceGlobalStats; CompletableFuture traderTimeFuture = CompletableFuture.supplyAsync(() -> { try { return getTraderTime(exchange, true); } catch (IOException e) { throw new RuntimeException(e); } }); CompletableFuture fundsAvailableFuture = CompletableFuture.supplyAsync(() -> { try { return getFundsAvailable(exchange,"USDT", true); } catch (IOException e) { throw new RuntimeException(e); } }); CompletableFuture> workerStatsFuture = CompletableFuture.supplyAsync(() -> { try { return getAllWorkersStats(exchange, true); } catch (IOException e) { throw new RuntimeException(e); } }); CompletableFuture instanceGlobalStatsFuture = CompletableFuture.supplyAsync(() -> { try { return getInstanceGlobalStatus(exchange, true); } catch (IOException e) { throw new RuntimeException(e); } }); CompletableFuture allFutures = CompletableFuture.allOf(traderTimeFuture, fundsAvailableFuture, workerStatsFuture, instanceGlobalStatsFuture); lastSeen = traderTimeFuture.join(); fundsAvailable = fundsAvailableFuture.join(); workers = workerStatsFuture.join(); instanceGlobalStats = instanceGlobalStatsFuture.join(); //Funds needed if (workers != null) { for (WorkerStatsData worker : workers) { if (!worker.isShort) { for (int i = worker.getSoAmount(); i <= worker.getNumberOfSafetyOrders(); i++) { fundsNeeded += gibSoSize(worker.getOrderSize(),i,0.0105); // I know I know } } } } //Online workers if (workers != null) { onlineWorkers = workers.size(); } //Long workers if (workers != null) { for (WorkerStatsData worker : workers) { if (!worker.isShort) { longWorkers++; } else { shortWorkers++; } } } return new ExchangeStatsData(lastSeen,fundsAvailable,fundsNeeded,onlineWorkers,longWorkers,shortWorkers,instanceGlobalStats); } 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 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 = fundsResponse.body().string(); JsonElement jsonElement = JsonParser.parseString(fundsResponseBody); if (!jsonElement.isJsonObject()) { System.err.println("The parsed JSON response is not a JsonObject."); return 0.0; } JsonObject jsonObject = jsonElement.getAsJsonObject(); if (!jsonObject.has(coin)) { System.err.println("The parsed JSON response does not contain the coin requested."); return 0.0; } return jsonObject.get(coin).getAsDouble(); } } public static List getAllWorkersStats(String exchange, boolean retry) throws IOException { List valueToReturn = new ArrayList<>(); Request workersStatsRequest = new Request.Builder() .url(API_BASE_URL + "/" + exchange + "/get_all_worker_status") .header("X-API-KEY", API_KEY) .build(); try (Response workersStatsResponse = httpClient.newCall(workersStatsRequest).execute()) { if (!workersStatsResponse.isSuccessful()) { if (workersStatsResponse.code() == 503 && retry) { return getAllWorkersStats(exchange, false); } throw new IOException("Unexpected code " + workersStatsResponse); } String workersStatsResponseBody = workersStatsResponse.body().string(); JsonElement jsonElement = JsonParser.parseString(workersStatsResponseBody); if (!jsonElement.isJsonObject()) { System.err.println("The parsed JSON response is not a JsonObject."); return null; } JsonObject jsonObject = jsonElement.getAsJsonObject(); if (jsonObject.has("Error")) { System.err.println("The parsed JSON response contains Error"); return null; } for (String key : jsonObject.keySet()) { JsonObject value = jsonObject.get(key).getAsJsonObject(); try { boolean isShort = value.has("is_short") && value.get("is_short").isJsonPrimitive() && value.get("is_short").getAsBoolean(); boolean stopWhenProfit = value.has("stop_when_profit") && value.get("stop_when_profit").isJsonPrimitive() && value.get("stop_when_profit").getAsBoolean(); double orderSize = value.has("order_size") && value.get("order_size").isJsonPrimitive() ? value.get("order_size").getAsDouble() : 0.0; double quoteSpent = value.has("quote_spent") && value.get("quote_spent").isJsonPrimitive() ? value.get("quote_spent").getAsDouble() : 0.0; double baseBought = value.has("base_bought") && value.get("base_bought").isJsonPrimitive() ? value.get("base_bought").getAsDouble() : 0.0; int soAmount = value.has("so_amount") && value.get("so_amount").isJsonPrimitive() ? value.get("so_amount").getAsInt() : 0; int numberOfSafetyOrders = value.has("no_of_safety_orders") && value.get("no_of_safety_orders").isJsonPrimitive() ? value.get("no_of_safety_orders").getAsInt() : 0; int tpMode = value.has("tp_mode") && value.get("tp_mode").isJsonPrimitive() ? value.get("tp_mode").getAsInt() : 0; String profitTable = value.has("profit_table") && value.get("profit_table").isJsonPrimitive() ? value.get("profit_table").getAsString() : null; double startTime = value.has("start_time") && value.get("start_time").isJsonPrimitive() ? value.get("start_time").getAsDouble() : 0.0; double startPrice = value.has("start_price") && value.get("start_price").isJsonPrimitive() ? value.get("start_price").getAsDouble() : 0.0; double dealStartTime = value.has("deal_start_time") && value.get("deal_start_time").isJsonPrimitive() ? value.get("deal_start_time").getAsDouble() : 0.0; double dealUptime = value.has("deal_uptime") && value.get("deal_uptime").isJsonPrimitive() ? value.get("deal_uptime").getAsDouble() : 0.0; double totalUptime = value.has("total_uptime") && value.get("total_uptime").isJsonPrimitive() ? value.get("total_uptime").getAsDouble() : 0.0; double price = value.has("price") && value.get("price").isJsonPrimitive() ? value.get("price").getAsDouble() : 0.0; double takeProfitPrice = value.has("take_profit_price") && value.get("take_profit_price").isJsonPrimitive() ? value.get("take_profit_price").getAsDouble() : 0.0; double nextSoPrice = value.has("next_so_price") && value.get("next_so_price").isJsonPrimitive() ? value.get("next_so_price").getAsDouble() : 0.0; String tpOrderId = value.has("tp_order_id") && value.get("tp_order_id").isJsonPrimitive() ? value.get("tp_order_id").getAsString() : null; //String takeProfitOrder = value.has("take_profit_order") && value.get("take_profit_order").isJsonPrimitive() ? value.get("take_profit_order").getAsString() : null; JsonObject takeProfitOrder = value.get("take_profit_order").getAsJsonObject(); String safetyOrderId = value.has("safety_order_id") && value.get("safety_order_id").isJsonPrimitive() ? value.get("safety_order_id").getAsString() : null; //String safetyOrder = value.has("safety_order") && value.get("safety_order").isJsonPrimitive() ? value.get("safety_order").getAsString() : null; JsonObject safetyOrder = value.get("safety_order").getAsJsonObject(); double feesPaidInBase = value.has("fees_paid_in_base") && value.get("fees_paid_in_base").isJsonPrimitive() ? value.get("fees_paid_in_base").getAsDouble() : 0.0; double feesPaidInQuote = value.has("fees_paid_in_quote") && value.get("fees_paid_in_quote").isJsonPrimitive() ? value.get("fees_paid_in_quote").getAsDouble() : 0.0; double partialProfit = value.has("partial_profit") && value.get("partial_profit").isJsonPrimitive() ? value.get("partial_profit").getAsDouble() : 0.0; String safetyPriceTable = value.has("safety_price_table") && value.get("safety_price_table").isJsonPrimitive() ? value.get("safety_price_table").getAsString() : null; String dealOrderHistory = value.has("deal_order_history") && value.get("deal_order_history").isJsonPrimitive() ? value.get("deal_order_history").getAsString() : null; String pauseReason = value.has("pause_reason") && value.get("pause_reason").isJsonPrimitive() ? value.get("pause_reason").getAsString() : null; String statusString = value.has("status_string") && value.get("status_string").isJsonPrimitive() ? value.get("status_string").getAsString() : null; JsonObject oldLong = null; if (value.has("old_long")) { oldLong = value.get("old_long").getAsJsonObject(); } valueToReturn.add(new WorkerStatsData( isShort, stopWhenProfit, orderSize, quoteSpent, baseBought, soAmount, numberOfSafetyOrders, tpMode, profitTable, startTime, startPrice, dealStartTime, dealUptime, totalUptime, price, takeProfitPrice, nextSoPrice, tpOrderId, takeProfitOrder, safetyOrderId, safetyOrder, feesPaidInBase, feesPaidInQuote, partialProfit, safetyPriceTable, dealOrderHistory, pauseReason, oldLong, statusString )); } catch (Exception e) { System.err.println("Error processing JSON for key '" + key + "': " + e.getMessage()); } } } return valueToReturn; } public static String joinWithLineLimit(String delimiter, int maxLines, Iterable elements) { StringBuilder result = new StringBuilder(); int currentLineCount = 0; for (String element : elements) { if (currentLineCount >= maxLines) { break; } if (result.length() > 0) { result.append(delimiter); } result.append(element); currentLineCount++; } return result.toString(); } private static InstanceGlobalStatsData getInstanceGlobalStatus(String exchange, boolean retry) throws IOException { List valueToReturn = new ArrayList<>(); Request globalStatsRequest = new Request.Builder() .url(API_BASE_URL + "/" + exchange + "/global_status") .header("X-API-KEY", API_KEY) .build(); try (Response globalStatsResponse = httpClient.newCall(globalStatsRequest).execute()) { if (!globalStatsResponse.isSuccessful()) { if (globalStatsResponse.code() == 503 && retry) { return getInstanceGlobalStatus(exchange, false); } throw new IOException("Unexpected code " + globalStatsResponse.code()); } String globalStatsResponseBody = globalStatsResponse.body().string(); JsonElement jsonElement = JsonParser.parseString(globalStatsResponseBody); if (!jsonElement.isJsonObject()) { System.err.println("The parsed JSON response is not a JsonObject."); return null; } if (jsonElement.getAsJsonObject().has("Error")) { System.err.println("There is an Error field in the JSON response." + jsonElement.getAsJsonObject().get("Error").getAsString()); return null; } JsonObject jsonObject = jsonElement.getAsJsonObject(); // Extracting online_workers and paused_traders from the response JsonArray onlineWorkersJsonArray = jsonObject.get("online_workers").getAsJsonArray(); List onlineWorkers = new ArrayList<>(); for (int i = 0; i < onlineWorkersJsonArray.size(); i++) { onlineWorkers.add(onlineWorkersJsonArray.get(i).getAsString()); } JsonArray pausedTradersJsonArray = jsonObject.get("paused_traders").getAsJsonArray(); List pausedTraders = new ArrayList<>(); for (int i = 0; i < pausedTradersJsonArray.size(); i++) { pausedTraders.add(pausedTradersJsonArray.get(i).getAsString()); } // Assuming jsonObject is already defined and represents the root JSON object JsonObject generalDataObject = jsonObject.getAsJsonObject("config"); JsonArray pairJsonArray = generalDataObject.get("pairs").getAsJsonArray(); List pairsInConfig = new ArrayList<>(); for (int i = 0; i < pairJsonArray.size(); i++) { pairsInConfig.add(pairJsonArray.get(i).getAsString()); } //Extract BrokerConfigData from the JSON response BrokerConfigData brokerConfigData; try { String exchangeName = generalDataObject.has("exchange") && generalDataObject.get("exchange").isJsonPrimitive() ? generalDataObject.get("exchange").getAsString() : null; boolean isSandbox = generalDataObject.has("is_sandbox") && generalDataObject.get("is_sandbox").isJsonPrimitive() && generalDataObject.get("is_sandbox").getAsBoolean(); boolean simulateMarketOrders = generalDataObject.has("simulate_market_orders") && generalDataObject.get("simulate_market_orders").isJsonPrimitive() && generalDataObject.get("simulate_market_orders").getAsBoolean(); //pairsInConfig double lap_time = generalDataObject.has("lap_time") && generalDataObject.get("lap_time").isJsonPrimitive() ? generalDataObject.get("lap_time").getAsDouble() : 2.0; double cooldown_multiplier = generalDataObject.has("cooldown_multiplier") && generalDataObject.get("cooldown_multiplier").isJsonPrimitive() ? generalDataObject.get("cooldown_multiplier").getAsDouble() : 1.0; double wait_before_new_safety_order = generalDataObject.has("wait_before_new_safety_order") && generalDataObject.get("wait_before_new_safety_order").isJsonPrimitive() ? generalDataObject.get("wait_before_new_safety_order").getAsDouble() : 0.0; boolean telegram = generalDataObject.has("telegram") && generalDataObject.get("telegram").isJsonPrimitive() && generalDataObject.get("telegram").getAsBoolean(); boolean attempt_to_restart = !generalDataObject.has("attempt_to_restart") || !generalDataObject.get("attempt_to_restart").isJsonPrimitive() || generalDataObject.get("attempt_to_restart").getAsBoolean(); double default_order_size = generalDataObject.has("default_order_size") && generalDataObject.get("default_order_size").isJsonPrimitive() ? generalDataObject.get("default_order_size").getAsDouble() : 12.0; boolean unifiedOrderQuery = !generalDataObject.has("unifiedOrderQuery") || !generalDataObject.get("unifiedOrderQuery").isJsonPrimitive() || generalDataObject.get("unifiedOrderQuery").getAsBoolean(); brokerConfigData = new BrokerConfigData(exchangeName, isSandbox, simulateMarketOrders, pairsInConfig, lap_time, cooldown_multiplier, wait_before_new_safety_order, telegram, attempt_to_restart, default_order_size, unifiedOrderQuery); } catch (Exception e) { e.printStackTrace(); return null; } InstanceGlobalStatsData returnValue; try { returnValue = new InstanceGlobalStatsData( jsonObject.get("name").getAsString(), jsonObject.get("instance_uptime").getAsDouble(), onlineWorkers, pausedTraders, jsonObject.get("version").getAsString(), jsonObject.get("ccxt_version").getAsString(), brokerConfigData); } catch (Exception e) { e.printStackTrace(); return null; } return returnValue; } catch (JsonSyntaxException e) { System.err.println("The JSON response is not valid."); return null; } } public static class DealData { private final double timestamp; private final String pair; private final double amount; private final String exchangeName; private final String orderId; private final String orderHistory; public DealData(double timestamp, String pair, double amount, String exchangeName, String orderId, String orderHistory) { this.timestamp = timestamp; this.pair = pair; this.amount = amount; this.exchangeName = exchangeName; this.orderId = orderId; this.orderHistory = orderHistory; } public double getTimestamp() { return timestamp; } public String getPair() { return pair; } public double getAmount() {return amount; } public String getExchangeName() { return exchangeName; } public String getOrderId() { return orderId; } public String getOrderHistory() { return orderHistory; } } public static class InstanceGlobalStatsData { private final String instanceName; private final double instanceUptime; private final List onlineWorkers; private final List pausedTraders; private final String version; private final String ccxtVersion; private final BrokerConfigData config; public InstanceGlobalStatsData(String name, double uptime, List onlineWorkers, List pausedTraders, String version, String ccxtVersion, BrokerConfigData config) { this.instanceName = name; this.instanceUptime = uptime; this.onlineWorkers = onlineWorkers; this.pausedTraders = pausedTraders; this.version = version; this.ccxtVersion = ccxtVersion; this.config = config; } public String getName() { return instanceName; } public double getUptime() { return instanceUptime; } public List getOnlineWorkers() { return onlineWorkers; } public List getPausedTraders() { return pausedTraders; } public String getVersion() { return version; } public String getCcxtVersion() { return ccxtVersion; } public BrokerConfigData getConfig() { return config; } } public static class BrokerConfigData { // Some fields are ignored, even though they are in the JSON private final String brokerName; private final Boolean isSandbox; private final Boolean simulateMarketOrders; private final List pairs; private final double laptime; private final double cooldownMultiplier; private final double waitBeforeNewSafetyOrder; private final Boolean sendTelegram; private final Boolean attemptToRestart; private final double defaultOrderSize; private final Boolean unifiedOrderQuery; public BrokerConfigData(String brokerName, Boolean isSandbox, Boolean simulateMarketOrders, List pairs, double laptime, double cooldownMultiplier, double waitBeforeNewSafetyOrder, Boolean sendTelegram, Boolean attemptToRestart, double defaultOrderSize, Boolean unifiedOrderQuery) { this.brokerName = brokerName; this.isSandbox = isSandbox; this.simulateMarketOrders = simulateMarketOrders; this.pairs = pairs; this.laptime = laptime; this.cooldownMultiplier = cooldownMultiplier; this.waitBeforeNewSafetyOrder = waitBeforeNewSafetyOrder; this.sendTelegram = sendTelegram; this.attemptToRestart = attemptToRestart; this.defaultOrderSize = defaultOrderSize; this.unifiedOrderQuery = unifiedOrderQuery; } public String getBrokerName() { return brokerName; } public Boolean getIsSandbox() { return isSandbox; } public Boolean getSimulateMarketOrders() { return simulateMarketOrders; } public List getPairs() { return pairs; } public double getLaptime() { return laptime; } public double getCooldownMultiplier() { return cooldownMultiplier; } public double getWaitBeforeNewSafetyOrder() { return waitBeforeNewSafetyOrder; } public Boolean getSendTelegram() { return sendTelegram; } public Boolean getAttemptToRestart() { return attemptToRestart; } public double getDefaultOrderSize() { return defaultOrderSize; } public Boolean getUnifiedOrderQuery() { return unifiedOrderQuery; } } public static class ProfitStatsData { private final double profitsToday; private final double profitsThisMonth; public ProfitStatsData(double profitsToday, double profitsThisMonth) { this.profitsToday = profitsToday; this.profitsThisMonth = profitsThisMonth; } public double getProfitsToday() { return profitsToday; } public double getProfitsThisMonth() { return profitsThisMonth; } } public static class ExchangeStatsData { private final double lastSeen; private final double fundsAvailable; private final double fundsNeeded; private final int onlineWorkers; private final int longWorkers; private final int shortWorkers; private final InstanceGlobalStatsData globalStats; public ExchangeStatsData(double lastSeen, double fundsAvailable, double fundsNeeded, int onlineWorkers, int longWorkers, int shortWorkers, InstanceGlobalStatsData globalStats) { this.lastSeen = lastSeen; this.fundsAvailable = fundsAvailable; this.fundsNeeded = fundsNeeded; this.onlineWorkers = onlineWorkers; this.longWorkers = longWorkers; this.shortWorkers = shortWorkers; this.globalStats = globalStats; } public double getLastSeen() { return lastSeen; } public double getFundsAvailable() { return fundsAvailable; } public double getFundsNeeded() { return fundsNeeded; } public int getOnlineWorkers() { return onlineWorkers; } public int getLongWorkers() { return longWorkers; } public int getShortWorkers() { return shortWorkers; } public InstanceGlobalStatsData getGlobalStats() { return globalStats; } } public static class WorkerStatsData { private final boolean isShort; private final boolean stopWhenProfit; private final double orderSize; private final double quoteSpent; private final double baseBought; private final int soAmount; private final int numberOfSafetyOrders; private final int tpMode; private final String profitTable; private final double startTime; private final double startPrice; private final double dealStartTime; private final double dealUptime; private final double totalUptime; private final double price; private final double takeProfitPrice; private final double nextSoPrice; private final String tpOrderId; private final JsonObject takeProfitOrder; private final String soOrderId; private final JsonObject safetyOrder; private final double feesPaidInBase; private final double feesPaidInQuote; private final double partialProfit; private final String safetyPriceTable; private final String dealOrderHistory; private final String pauseReason; private final JsonObject oldLongDictionary; //Change type private final String statusString; public WorkerStatsData(boolean isShort, boolean stopWhenProfit, double orderSize, double quoteSpent, double baseBought, int soAmount, int numberOfSafetyOrders, int tpMode, String profitTable, double startTime, double startPrice, double dealStartTime, double dealUptime, double totalUptime, double price, double takeProfitPrice, double nextSoPrice, String tpOrderId, JsonObject takeProfitOrder, String soOrderId, JsonObject safetyOrder, double feesPaidInBase, double feesPaidInQuote, double partialProfit, String safetyPriceTable, String dealOrderHistory, String pauseReason, JsonObject oldLong, String statusString) { this.isShort = isShort; this.stopWhenProfit = stopWhenProfit; this.orderSize = orderSize; this.quoteSpent = quoteSpent; this.baseBought = baseBought; this.soAmount = soAmount; this.numberOfSafetyOrders = numberOfSafetyOrders; this.tpMode = tpMode; this.profitTable = profitTable; this.startTime = startTime; this.startPrice = startPrice; this.dealStartTime = dealStartTime; this.dealUptime = dealUptime; this.totalUptime = totalUptime; this.price = price; this.takeProfitPrice = takeProfitPrice; this.nextSoPrice = nextSoPrice; this.tpOrderId = tpOrderId; this.takeProfitOrder = takeProfitOrder; this.soOrderId = soOrderId; this.safetyOrder = safetyOrder; this.feesPaidInBase = feesPaidInBase; this.feesPaidInQuote = feesPaidInQuote; this.partialProfit = partialProfit; this.safetyPriceTable = safetyPriceTable; this.dealOrderHistory = dealOrderHistory; this.pauseReason = pauseReason; this.oldLongDictionary = oldLong; this.statusString = statusString; } public boolean getIsShort() { return isShort; } public boolean getStopWhenProfit() { return stopWhenProfit; } public double getOrderSize() { return orderSize; } public double getQuoteSpent() { return quoteSpent; } public double getBaseBought() { return baseBought; } public int getSoAmount() { return soAmount; } public int getNumberOfSafetyOrders() {return numberOfSafetyOrders; } public int getTpMode() { return tpMode; } public String getProfitTable() { return profitTable; } public double getStartTime() { return startTime; } public double getStartPrice() { return startPrice; } public double getDealStartTime() { return dealStartTime; } public double getDealUptime() { return dealUptime; } public double getTotalUptime() { return totalUptime; } public double getPrice() { return price; } public double getTakeProfitPrice() { return takeProfitPrice; } public double getNextSoPrice() { return nextSoPrice; } public String getTpOrderId() { return tpOrderId; } public JsonObject getTakeProfitOrder() { return takeProfitOrder; } public String getSoOrderId() { return soOrderId; } public JsonObject getSafetyOrder() { return safetyOrder; } public double getFeesPaidInBase() { return feesPaidInBase; } public double getFeesPaidInQuote() { return feesPaidInQuote; } public double getPartialProfit() { return partialProfit; } public String getSafetyPriceTable() { return safetyPriceTable; } public String getDealOrderHistory() { return dealOrderHistory; } public String getPauseReason() { return pauseReason; } public JsonObject getOldLongDictionary() { return oldLongDictionary; } public String getStatusString() { return statusString; } } public static class Order { private final String id; private final String status; private final double filled; private final double remaining; private final double price; private final double cost; private final String fees; private final String symbol; public Order(String id, String status, double filled, double remaining, double price, double cost, String fees, String symbol) { this.id = id; this.status = status; this.filled = filled; this.remaining = remaining; this.price = price; this.cost = cost; this.fees = fees; this.symbol = symbol; } public String getId() { return id; } public String getStatus() { return status; } public double getFilled() { return filled; } public double getRemaining() { return remaining; } public double getPrice() { return price; } public double getCost() { return cost; } public String getFees() { return fees; } public String getSymbol() { return symbol; } } public static class OldLongDictionary { private final String datetime; private final double feesPaidInQuote; private final double quoteSpent; private final double tpAmount; private final double tpPrice; public OldLongDictionary(String datetime, double feesPaidInQuote, double quoteSpent, double tpAmount, double tpPrice) { this.datetime = datetime; this.feesPaidInQuote = feesPaidInQuote; this.quoteSpent = quoteSpent; this.tpAmount = tpAmount; this.tpPrice = tpPrice; } public String getDatetime() { return datetime; } public double getFeesPaidInQuote() { return feesPaidInQuote; } public double getQuoteSpent() { return quoteSpent; } public double getTpAmount() { return tpAmount; } public double getTpPrice() { return tpPrice; } } }