Last trades details
This commit is contained in:
parent
f45a9e2840
commit
0b44878e7c
|
|
@ -2,6 +2,11 @@ package com.example.dcav2gui;
|
||||||
|
|
||||||
import static com.example.dcav2gui.MainActivity.globalSettings;
|
import static com.example.dcav2gui.MainActivity.globalSettings;
|
||||||
|
|
||||||
|
import android.text.Spannable;
|
||||||
|
import android.text.SpannableString;
|
||||||
|
import android.text.SpannableStringBuilder;
|
||||||
|
import android.text.style.ForegroundColorSpan;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.example.dcav2gui.ui.exchanges.WorkerData;
|
import com.example.dcav2gui.ui.exchanges.WorkerData;
|
||||||
|
|
@ -16,6 +21,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
|
|
@ -220,6 +226,53 @@ public class InstanceInterface {
|
||||||
return allDeals.subList(0,globalSettings.amountOfLastTrades);
|
return allDeals.subList(0,globalSettings.amountOfLastTrades);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<DealData> getLastNTrades(int amount, boolean retry) throws IOException {
|
||||||
|
// Reads the data directly from the db, instead of from the cache
|
||||||
|
Request dealsRequest = new Request.Builder()
|
||||||
|
.url(API_BASE_URL + "/statistics_server/fetch_last_n_deals_without_history?amount_of_deals=" + amount)
|
||||||
|
.header("X-API-KEY", API_KEY)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
|
||||||
|
try (Response dealsResponse = httpClient.newCall(dealsRequest).execute()) {
|
||||||
|
if (!dealsResponse.isSuccessful()) {
|
||||||
|
if (dealsResponse.code() == 503 && retry) {
|
||||||
|
return getLastNTrades(amount,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("last_deals")) {
|
||||||
|
System.err.println("The parsed JSON response does not contain the last_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("last_deals");
|
||||||
|
List<DealData> dealDataList = new ArrayList<>();
|
||||||
|
for (int i=0; i<dealsArray.size(); i++){
|
||||||
|
JsonElement stringToMince = dealsArray.get(i);
|
||||||
|
dealDataList.add(new DealData(
|
||||||
|
stringToMince.getAsJsonArray().get(0).getAsDouble(),
|
||||||
|
stringToMince.getAsJsonArray().get(1).getAsString(),
|
||||||
|
stringToMince.getAsJsonArray().get(2).getAsDouble(),
|
||||||
|
stringToMince.getAsJsonArray().get(3).getAsString(),
|
||||||
|
stringToMince.getAsJsonArray().get(4).getAsString(),
|
||||||
|
""));
|
||||||
|
}
|
||||||
|
return dealDataList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static List<DealData> getLastTradesFromExchange(String exchange, boolean retry) throws IOException {
|
public static List<DealData> getLastTradesFromExchange(String exchange, boolean retry) throws IOException {
|
||||||
|
|
||||||
Request dealsRequest = new Request.Builder()
|
Request dealsRequest = new Request.Builder()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package com.example.dcav2gui.ui.home;
|
package com.example.dcav2gui.ui.home;
|
||||||
|
|
||||||
|
import static com.example.dcav2gui.InstanceInterface.getLastNTrades;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
|
|
@ -33,6 +35,7 @@ import com.example.dcav2gui.MainActivity;
|
||||||
import com.example.dcav2gui.R;
|
import com.example.dcav2gui.R;
|
||||||
import com.example.dcav2gui.TickerTracker;
|
import com.example.dcav2gui.TickerTracker;
|
||||||
import com.example.dcav2gui.databinding.FragmentHomeBinding;
|
import com.example.dcav2gui.databinding.FragmentHomeBinding;
|
||||||
|
import com.example.dcav2gui.ui.exchanges.WorkerData;
|
||||||
import com.example.dcav2gui.ui.exchanges.adapters.WorkerCardAdapter;
|
import com.example.dcav2gui.ui.exchanges.adapters.WorkerCardAdapter;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
|
@ -46,6 +49,7 @@ import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class HomeFragment extends Fragment {
|
public class HomeFragment extends Fragment {
|
||||||
private HomeViewModel homeViewModel;
|
private HomeViewModel homeViewModel;
|
||||||
|
|
@ -361,8 +365,7 @@ public class HomeFragment extends Fragment {
|
||||||
@Override
|
@Override
|
||||||
public boolean onMenuItemClick(MenuItem item) {
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
if (item.getItemId() == R.id.last_trades_details) {
|
if (item.getItemId() == R.id.last_trades_details) {
|
||||||
// Handle the "Details..." option
|
fetchLastNDeals(100);
|
||||||
// For example, navigate to a details fragment
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -494,6 +497,59 @@ public class HomeFragment extends Fragment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void fetchLastNDeals(int amount) {
|
||||||
|
new Thread(() -> {
|
||||||
|
try {
|
||||||
|
List<InstanceInterface.DealData> result = getLastNTrades(amount, true);
|
||||||
|
new Handler(Looper.getMainLooper()).post(() -> showLastTradesDetailsDialog(result));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
new Handler(Looper.getMainLooper()).post(() -> Toast.makeText(getContext(), "Failed to fetch details", Toast.LENGTH_SHORT).show());
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> getShortWorkers(String exchange, List<InstanceInterface.WorkerStatsData> workerList) {
|
||||||
|
List<String> shortWorkers = new ArrayList<>();
|
||||||
|
for (InstanceInterface.WorkerStatsData worker : MainActivity.getInstanceCache(exchange).getWorkers()) {
|
||||||
|
if (worker.getIsShort()) {
|
||||||
|
shortWorkers.add(worker.getPair());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return shortWorkers;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showLastTradesDetailsDialog(List<InstanceInterface.DealData> result) {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||||
|
List<String> shortWorkers = new ArrayList<>();
|
||||||
|
if (MainActivity.getInstanceCache("binance")!=null) {
|
||||||
|
shortWorkers.addAll(getShortWorkers("binance", MainActivity.getInstanceCache("binance").getWorkers()));
|
||||||
|
}
|
||||||
|
if (MainActivity.getInstanceCache("gateio")!=null) {
|
||||||
|
shortWorkers.addAll(getShortWorkers("binance", MainActivity.getInstanceCache("gateio").getWorkers()));
|
||||||
|
}
|
||||||
|
if (MainActivity.getInstanceCache("kucoin")!=null) {
|
||||||
|
shortWorkers.addAll(getShortWorkers("binance", MainActivity.getInstanceCache("kucoin").getWorkers()));
|
||||||
|
}
|
||||||
|
if (MainActivity.getInstanceCache("okex")!=null) {
|
||||||
|
shortWorkers.addAll(getShortWorkers("binance", MainActivity.getInstanceCache("okex").getWorkers()));
|
||||||
|
}
|
||||||
|
|
||||||
|
LayoutInflater inflater = LayoutInflater.from(getContext());
|
||||||
|
View customLayout = inflater.inflate(R.layout.trades_detail_dialog, null);
|
||||||
|
TextView titleTextView = customLayout.findViewById(R.id.trades_details_title);
|
||||||
|
TextView detailsTextView = customLayout.findViewById(R.id.trades_details_content);
|
||||||
|
|
||||||
|
String title = "Last " + result.size() + " trades";
|
||||||
|
titleTextView.setText(title);
|
||||||
|
detailsTextView.setText(parseDeals(result, shortWorkers));
|
||||||
|
|
||||||
|
builder.setView(customLayout);
|
||||||
|
builder.setPositiveButton("OK", null);
|
||||||
|
builder.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void showInstanceDetailsDialog(InstanceInterface.InstanceGlobalStatsData result) {
|
private void showInstanceDetailsDialog(InstanceInterface.InstanceGlobalStatsData result) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||||
builder.setTitle(result.getName() + " details");
|
builder.setTitle(result.getName() + " details");
|
||||||
|
|
@ -744,6 +800,35 @@ public class HomeFragment extends Fragment {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SpannableStringBuilder parseDeals(List<InstanceInterface.DealData> dealData, List<String> shortWorkers) {
|
||||||
|
int shortColor = ContextCompat.getColor(requireContext(), R.color.orange);
|
||||||
|
int LongColor = ContextCompat.getColor(requireContext(), R.color.dark_cyan);
|
||||||
|
if (dealData != null) {
|
||||||
|
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
|
||||||
|
for (InstanceInterface.DealData deal : dealData) {
|
||||||
|
String timestamp = timeStampConverter(deal.getTimestamp());
|
||||||
|
String pair = deal.getPair();
|
||||||
|
String amount = String.format(Locale.ROOT, "%.2f", deal.getAmount());
|
||||||
|
String exchange = Character.toUpperCase(deal.getExchangeName().charAt(0)) + deal.getExchangeName().substring(1);
|
||||||
|
String dealString = timestamp + " | " + pair + " | " + amount + " USDT | " + exchange + "\n";
|
||||||
|
SpannableString spannableString = new SpannableString(dealString);
|
||||||
|
int startIndex = dealString.indexOf(pair);
|
||||||
|
int endIndex = startIndex + pair.length();
|
||||||
|
if ((startIndex != -1) && (endIndex != -1)) {
|
||||||
|
//If pair in shortWorkers, set color to yellow, else cyan
|
||||||
|
if (shortWorkers.contains(pair)) {
|
||||||
|
spannableString.setSpan(new ForegroundColorSpan(shortColor), startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
} else {
|
||||||
|
spannableString.setSpan(new ForegroundColorSpan(LongColor), startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spannableStringBuilder.append(spannableString);
|
||||||
|
}
|
||||||
|
return spannableStringBuilder;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public void populateHome(TickerTracker.PriceChangeData firstTickerChangeData,
|
public void populateHome(TickerTracker.PriceChangeData firstTickerChangeData,
|
||||||
TickerTracker.PriceChangeData secondTickerChangeData,
|
TickerTracker.PriceChangeData secondTickerChangeData,
|
||||||
TickerTracker.PriceChangeData thirdTickerChangeData,
|
TickerTracker.PriceChangeData thirdTickerChangeData,
|
||||||
|
|
@ -758,9 +843,6 @@ public class HomeFragment extends Fragment {
|
||||||
String kucoinLogs,
|
String kucoinLogs,
|
||||||
String okexLogs) {
|
String okexLogs) {
|
||||||
|
|
||||||
int shortColor = ContextCompat.getColor(requireContext(), R.color.orange);
|
|
||||||
int LongColor = ContextCompat.getColor(requireContext(), R.color.dark_cyan);
|
|
||||||
|
|
||||||
List<String> shortWorkers = new ArrayList<>();
|
List<String> shortWorkers = new ArrayList<>();
|
||||||
|
|
||||||
//Populate short traders list
|
//Populate short traders list
|
||||||
|
|
@ -960,29 +1042,9 @@ public class HomeFragment extends Fragment {
|
||||||
exchange4WorkersLongShort.setText(longShortWorkers);
|
exchange4WorkersLongShort.setText(longShortWorkers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deals list
|
||||||
if (dealData != null) {
|
if (dealData != null) {
|
||||||
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
|
lastTrades.setText(parseDeals(dealData, shortWorkers));
|
||||||
String dealsList = "";
|
|
||||||
for (InstanceInterface.DealData deal : dealData) {
|
|
||||||
String timestamp = timeStampConverter(deal.getTimestamp());
|
|
||||||
String pair = deal.getPair();
|
|
||||||
String amount = String.format(Locale.ROOT, "%.2f", deal.getAmount());
|
|
||||||
String exchange = Character.toUpperCase(deal.getExchangeName().charAt(0)) + deal.getExchangeName().substring(1);
|
|
||||||
String dealString = timestamp + " | " + pair + " | " + amount + " USDT | " + exchange + "\n";
|
|
||||||
SpannableString spannableString = new SpannableString(dealString);
|
|
||||||
int startIndex = dealString.indexOf(pair);
|
|
||||||
int endIndex = startIndex + pair.length();
|
|
||||||
if ((startIndex != -1) && (endIndex != -1)) {
|
|
||||||
//If pair in shortWorkers, set color to yellow, else cyan
|
|
||||||
if (shortWorkers.contains(pair)) {
|
|
||||||
spannableString.setSpan(new ForegroundColorSpan(shortColor), startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
||||||
} else {
|
|
||||||
spannableString.setSpan(new ForegroundColorSpan(LongColor), startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spannableStringBuilder.append(spannableString);
|
|
||||||
}
|
|
||||||
lastTrades.setText(spannableStringBuilder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Populate logs
|
//Populate logs
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/trades_details_title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="24sp"
|
||||||
|
android:textColor="#000000"
|
||||||
|
android:text="Title" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/trades_details_content"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textColor="#000000"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="Message" />
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
Loading…
Reference in New Issue