From e05a47cce0a9179dc64e243dca794fb4fb5bc338 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20S=C3=A1nchez?= Date: Wed, 11 Dec 2024 19:37:41 -0300 Subject: [PATCH] Binance price tracker class --- app/build.gradle | 2 + .../example/dcav2gui/BinancePriceTracker.java | 131 ++++++++++++++++++ .../com/example/dcav2gui/MainActivity.java | 2 +- gradle/libs.versions.toml | 4 + 4 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/com/example/dcav2gui/BinancePriceTracker.java diff --git a/app/build.gradle b/app/build.gradle index c4ca91a..ac89ada 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -41,6 +41,8 @@ dependencies { implementation libs.navigation.fragment implementation libs.navigation.ui implementation libs.gson + implementation libs.okhttp + implementation libs.firebase.crashlytics.buildtools testImplementation libs.junit androidTestImplementation libs.ext.junit androidTestImplementation libs.espresso.core diff --git a/app/src/main/java/com/example/dcav2gui/BinancePriceTracker.java b/app/src/main/java/com/example/dcav2gui/BinancePriceTracker.java new file mode 100644 index 0000000..5bf6147 --- /dev/null +++ b/app/src/main/java/com/example/dcav2gui/BinancePriceTracker.java @@ -0,0 +1,131 @@ +package com.example.dcav2gui; + +import android.annotation.SuppressLint; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +import java.io.IOException; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +public class BinancePriceTracker { + private static final String BINANCE_API_BASE_URL = "https://api.binance.com/api/v3/ticker/24hr"; + private static final OkHttpClient httpClient = new OkHttpClient(); + private static final Gson gson = new Gson(); + + /** + * Retrieves price change percentages for a specific trading pair from Binance. + * + * @param symbol The trading pair symbol (e.g., "BTCUSDT") + * @return PriceChangeData object containing 24h, 7d, and 30d percentage changes + * @throws IOException If there's an error connecting to the Binance API + */ + public static PriceChangeData getPriceChanges(String symbol) throws IOException { + // Construct the API request URL for 24h change + Request request24h = new Request.Builder() + .url(BINANCE_API_BASE_URL + "?symbol=" + symbol) + .build(); + + // Send 24h request + try (Response response24h = httpClient.newCall(request24h).execute()) { + // Parse the JSON response + String responseBody24h = response24h.body().string(); + JsonObject jsonResponse = JsonParser.parseString(responseBody24h).getAsJsonObject(); + + // Extract current price + double currentPrice = jsonResponse.has("lastPrice") + ? jsonResponse.get("lastPrice").getAsDouble() + : 0.0; + + // Extract 24h percentage change + double priceChangePercent24h = jsonResponse.has("priceChangePercent") + ? jsonResponse.get("priceChangePercent").getAsDouble() + : 0.0; + + // Fetch historical data for 7d and 30d changes + Request historicalRequest = new Request.Builder() + .url("https://api.binance.com/api/v3/klines?symbol=" + symbol + "&interval=1d&limit=30") + .build(); + + // Send historical data request + try (Response historicalResponse = httpClient.newCall(historicalRequest).execute()) { + String historicalResponseBody = historicalResponse.body().string(); + + // Calculate 7d and 30d percentage changes + double priceChangePercent7d = calculatePercentageChange(historicalResponseBody, 7); + double priceChangePercent30d = calculatePercentageChange(historicalResponseBody, 30); + + // Return the price change data + return new PriceChangeData( + symbol, + currentPrice, + priceChangePercent24h, + priceChangePercent7d, + priceChangePercent30d + ); + } + } + } + + // Calculates the percentage change + private static double calculatePercentageChange(String jsonKlineData, int days) { + try { + // Parse the kline data + JsonArray klines = JsonParser.parseString(jsonKlineData).getAsJsonArray(); + + // Ensure we have enough data + if (klines == null || klines.size() < days) { + return 0.0; + } + + // Get the opening price of the first day in the period + // Kline data structure: [Open time, Open, High, Low, Close, Volume, Close time, Quote asset volume, Number of trades, Taker buy base asset volume, Taker buy quote asset volume, Ignore] + double firstOpenPrice = klines.get(0).getAsJsonArray().get(1).getAsDouble(); + + // Get the closing price of the last day in the period + double lastClosePrice = klines.get(days - 1).getAsJsonArray().get(4).getAsDouble(); + + // Calculate percentage change + return ((lastClosePrice - firstOpenPrice) / firstOpenPrice) * 100; + } catch (Exception e) { + System.err.println("Error calculating percentage change: " + e.getMessage()); + return 0.0; + } + } + + // Class to hold price information + public static class PriceChangeData { + private final String symbol; + private final double currentPrice; + private final double priceChangePercent24h; + private final double priceChangePercent7d; + private final double priceChangePercent30d; + + public PriceChangeData(String symbol, double currentPrice, double priceChangePercent24h, + double priceChangePercent7d, double priceChangePercent30d) { + this.symbol = symbol; + this.currentPrice = currentPrice; + this.priceChangePercent24h = priceChangePercent24h; + this.priceChangePercent7d = priceChangePercent7d; + this.priceChangePercent30d = priceChangePercent30d; + } + + // Getters + public String getSymbol() { return symbol; } + public double getCurrentPrice() { return currentPrice; } + public double getPriceChangePercent24h() { return priceChangePercent24h; } + public double getPriceChangePercent7d() { return priceChangePercent7d; } + public double getPriceChangePercent30d() { return priceChangePercent30d; } + + @Override + public String toString() { + return String.format("Symbol: %s\nPrice: %.2f%%\n24h Change: %.2f%%\n7d Change: %.2f%%\n30d Change: %.2f%%", + symbol, currentPrice, priceChangePercent24h, priceChangePercent7d, priceChangePercent30d); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/dcav2gui/MainActivity.java b/app/src/main/java/com/example/dcav2gui/MainActivity.java index 4423ca9..9068c3a 100644 --- a/app/src/main/java/com/example/dcav2gui/MainActivity.java +++ b/app/src/main/java/com/example/dcav2gui/MainActivity.java @@ -1,4 +1,4 @@ -package com.example.dcav2gui;//package com.example.dcav2gui; +package com.example.dcav2gui; import android.view.MenuItem; diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 58bcfe3..8421ba2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,6 +11,8 @@ lifecycleViewmodelKtx = "2.8.7" navigationFragment = "2.8.4" navigationUi = "2.8.4" gson = "2.11.0" +firebaseCrashlyticsBuildtools = "3.0.2" +okhttp = "3.14.6" [libraries] junit = { group = "junit", name = "junit", version.ref = "junit" } @@ -24,6 +26,8 @@ lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-view navigation-fragment = { group = "androidx.navigation", name = "navigation-fragment", version.ref = "navigationFragment" } navigation-ui = { group = "androidx.navigation", name = "navigation-ui", version.ref = "navigationUi" } gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" } +firebase-crashlytics-buildtools = { group = "com.google.firebase", name = "firebase-crashlytics-buildtools", version.ref = "firebaseCrashlyticsBuildtools" } +okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" }