From 0ab73ddc87151e97366a674bac404981e75daf31 Mon Sep 17 00:00:00 2001 From: Tanguy Herbron Date: Mon, 9 Apr 2018 16:28:42 +0200 Subject: [PATCH] Add trade history from Binance --- .../Activities/CurrencyDetailsActivity.java | 92 +++++++++++++++++++ .../Activities/RecordTransactionActivity.java | 24 ++++- .../DataManagers/CurrencyData/Currency.java | 27 ++++++ .../CurrencyData/CurrencyDataRetriever.java | 43 ++++++++- .../CurrencyData/Transaction.java | 13 ++- .../DataManagers/DatabaseManager.java | 7 +- .../ExchangeManager/BinanceManager.java | 54 ++++++++++- .../res/layout/activity_currency_details.xml | 77 +++++++++------- app/src/main/res/layout/custom_trade_row.xml | 82 +++++++++++++++++ 9 files changed, 376 insertions(+), 43 deletions(-) create mode 100644 app/src/main/res/layout/custom_trade_row.xml diff --git a/app/src/main/java/com/nauk/coinfolio/Activities/CurrencyDetailsActivity.java b/app/src/main/java/com/nauk/coinfolio/Activities/CurrencyDetailsActivity.java index 22775b8..325dc2a 100644 --- a/app/src/main/java/com/nauk/coinfolio/Activities/CurrencyDetailsActivity.java +++ b/app/src/main/java/com/nauk/coinfolio/Activities/CurrencyDetailsActivity.java @@ -8,9 +8,11 @@ import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; +import android.os.AsyncTask; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.design.widget.BottomNavigationView; +import android.support.design.widget.Snackbar; import android.support.v4.app.NavUtils; import android.support.v4.content.ContextCompat; import android.support.v7.app.ActionBar; @@ -25,6 +27,7 @@ import android.widget.LinearLayout; import android.widget.TextView; import android.widget.ViewFlipper; +import com.binance.api.client.domain.account.Trade; import com.daimajia.swipe.SwipeLayout; import com.github.mikephil.charting.charts.BarChart; import com.github.mikephil.charting.charts.LineChart; @@ -36,10 +39,12 @@ import com.github.mikephil.charting.data.LineData; import com.github.mikephil.charting.data.LineDataSet; import com.github.mikephil.charting.highlight.Highlight; import com.github.mikephil.charting.listener.OnChartValueSelectedListener; +import com.nauk.coinfolio.DataManagers.BalanceManager; import com.nauk.coinfolio.DataManagers.CurrencyData.Currency; import com.nauk.coinfolio.DataManagers.CurrencyData.CurrencyDataChart; import com.nauk.coinfolio.DataManagers.CurrencyData.Transaction; import com.nauk.coinfolio.DataManagers.DatabaseManager; +import com.nauk.coinfolio.DataManagers.ExchangeManager.BinanceManager; import com.nauk.coinfolio.DataManagers.PreferencesManager; import com.nauk.coinfolio.R; @@ -60,6 +65,7 @@ public class CurrencyDetailsActivity extends AppCompatActivity { private ViewFlipper viewFlipper; private LinearLayout transactionLayout; + private LinearLayout tradeLayout; private DatabaseManager databaseManager; //private String symbol; private Currency currency; @@ -73,6 +79,7 @@ public class CurrencyDetailsActivity extends AppCompatActivity { private LineChart lineChart; private BarChart barChart; private PreferencesManager preferencesManager; + private BinanceManager binanceManager; private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() { @@ -128,8 +135,10 @@ public class CurrencyDetailsActivity extends AppCompatActivity { viewFlipper = findViewById(R.id.vfCurrencyDetails); transactionLayout = findViewById(R.id.listTransactions); + tradeLayout = findViewById(R.id.listTrades); lineChart = findViewById(R.id.chartPriceView); barChart = findViewById(R.id.chartVolumeView); + binanceManager = new BinanceManager(preferencesManager.getBinancePublicKey(), preferencesManager.getBinancePrivateKey()); ((BottomNavigationView) findViewById(R.id.navigation_details)).getMenu().getItem(1).setEnabled(false); @@ -145,6 +154,9 @@ public class CurrencyDetailsActivity extends AppCompatActivity { navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener); hasBeenModified = false; + + TradeUpdater updater = new TradeUpdater(); + updater.execute(); } private void setupActionBar() @@ -644,6 +656,39 @@ public class CurrencyDetailsActivity extends AppCompatActivity { return transColor; } + private void drawTradeList(List trades, String pairSymbol) + { + findViewById(R.id.tradeProgressBar).setVisibility(View.GONE); + + tradeLayout.removeAllViews(); + + for(int i = trades.size()-1; i >= 0; i--) + { + View view = LayoutInflater.from(this).inflate(R.layout.custom_trade_row, null); + TextView amountTxtView = view.findViewById(R.id.amountPurchased); + TextView purchasedPrice = view.findViewById(R.id.purchasedPrice); + TextView tradePair = view.findViewById(R.id.pair); + TextView dateTxtView = view.findViewById(R.id.tradeDate); + View tradeIndicator = view.findViewById(R.id.tradeIndicator); + + if(trades.get(i).isBuyer()) + { + tradeIndicator.setBackgroundColor(getColor(R.color.green)); + } + else + { + tradeIndicator.setBackgroundColor(getColor(R.color.red)); + } + + amountTxtView.setText(String.valueOf(trades.get(i).getQty())); + purchasedPrice.setText(trades.get(i).getPrice()); + dateTxtView.setText(getDate(trades.get(i).getTime())); + tradePair.setText(currency.getSymbol() + "/" + pairSymbol); + + tradeLayout.addView(view); + } + } + private void drawTransactionList() { transactionLayout.removeAllViews(); @@ -723,6 +768,53 @@ public class CurrencyDetailsActivity extends AppCompatActivity { }); } + private class TradeUpdater extends AsyncTask + { + @Override + protected void onPreExecute() + { + super.onPreExecute(); + + findViewById(R.id.tradeProgressBar).setVisibility(View.VISIBLE); + } + + @Override + protected void onProgressUpdate(Integer... values) + { + super.onProgressUpdate(values); + } + + @Override + protected Void doInBackground(Void... params) + { + binanceManager.updateTrades(new BinanceManager.BinanceCallBack() { + @Override + public void onSuccess() { + final List trades = binanceManager.getTrades(); + + runOnUiThread(new Runnable() { + @Override + public void run() { + drawTradeList(trades, "ETH"); + } + }); + } + + @Override + public void onError(String error) { + + } + }, currency.getSymbol()); + + return null; + } + + @Override + protected void onPostExecute(Void result) + { + + } + } } /*for(int i = 0; i < dataChartList.size(); i++) {*/ diff --git a/app/src/main/java/com/nauk/coinfolio/Activities/RecordTransactionActivity.java b/app/src/main/java/com/nauk/coinfolio/Activities/RecordTransactionActivity.java index 59851ae..50e34a2 100644 --- a/app/src/main/java/com/nauk/coinfolio/Activities/RecordTransactionActivity.java +++ b/app/src/main/java/com/nauk/coinfolio/Activities/RecordTransactionActivity.java @@ -13,6 +13,7 @@ import android.widget.EditText; import android.widget.TextView; import android.widget.TimePicker; +import com.nauk.coinfolio.DataManagers.CurrencyData.Currency; import com.nauk.coinfolio.DataManagers.DatabaseManager; import com.nauk.coinfolio.DataManagers.PreferencesManager; import com.nauk.coinfolio.R; @@ -33,6 +34,8 @@ public class RecordTransactionActivity extends AppCompatActivity { private Calendar calendar; private SimpleDateFormat sdf; private PreferencesManager preferenceManager; + private EditText purchasedPrice; + private Currency currency; @Override protected void onCreate(Bundle savedInstanceState) { @@ -49,13 +52,17 @@ public class RecordTransactionActivity extends AppCompatActivity { calendar = Calendar.getInstance(); + currency = new Currency(coin, symbol); + databaseManager = new DatabaseManager(this); preferenceManager = new PreferencesManager(this); validateButton = findViewById(R.id.validateButton); amountTxtView = findViewById(R.id.currencyAmount); purchasedDate = findViewById(R.id.purchaseDate); + purchasedPrice = findViewById(R.id.purchasePrice); + //purchasedPrice.setText(); purchasedDate.setText(sdf.format(calendar.getTime())); purchasedDate.setOnClickListener(new View.OnClickListener() { @@ -68,7 +75,7 @@ public class RecordTransactionActivity extends AppCompatActivity { validateButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - databaseManager.addCurrencyToManualCurrency(symbol, Double.parseDouble(amountTxtView.getText().toString()), calendar.getTime()); + databaseManager.addCurrencyToManualCurrency(symbol, Double.parseDouble(amountTxtView.getText().toString()), calendar.getTime(), purchasedPrice.getText().toString()); preferenceManager.setMustUpdate(true); Intent intent = new Intent(RecordTransactionActivity.this, HomeActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); @@ -76,6 +83,13 @@ public class RecordTransactionActivity extends AppCompatActivity { finish(); } }); + + currency.getTimestampPrice(this, new Currency.PriceCallBack() { + @Override + public void onSuccess(String price) { + purchasedPrice.setText(price); + } + }, calendar.getTimeInMillis() / 1000); } private void createDatePicker() @@ -108,6 +122,14 @@ public class RecordTransactionActivity extends AppCompatActivity { calendar.set(Calendar.HOUR_OF_DAY, hour); calendar.set(Calendar.MINUTE, minute); purchasedDate.setText(sdf.format(calendar.getTime())); + + currency.getTimestampPrice(RecordTransactionActivity.this, new Currency.PriceCallBack() { + @Override + public void onSuccess(String price) { + purchasedPrice.setText(price); + } + }, calendar.getTimeInMillis() / 1000); + Log.d("coinfolio", "Time : " + calendar.getTimeInMillis()); } }, calendar.get(Calendar.HOUR_OF_DAY), diff --git a/app/src/main/java/com/nauk/coinfolio/DataManagers/CurrencyData/Currency.java b/app/src/main/java/com/nauk/coinfolio/DataManagers/CurrencyData/Currency.java index 5befeb7..e84e742 100644 --- a/app/src/main/java/com/nauk/coinfolio/DataManagers/CurrencyData/Currency.java +++ b/app/src/main/java/com/nauk/coinfolio/DataManagers/CurrencyData/Currency.java @@ -63,6 +63,21 @@ public class Currency implements Parcelable { this.symbol = symbol; } + public void getTimestampPrice(android.content.Context context, final PriceCallBack callBack, long timestamp) + { + dataRetriver = new CurrencyDataRetriever(context); + + dataRetriver.getPriceTimestamp(symbol, new CurrencyDataRetriever.DataChartCallBack() { + @Override + public void onSuccess(List dataChart) {} + + @Override + public void onSuccess(String price) { + callBack.onSuccess(price); + } + }, timestamp); + } + public void updateHistoryMinutes(android.content.Context context, final CurrencyCallBack callBack) { dataRetriver = new CurrencyDataRetriever(context); @@ -84,6 +99,9 @@ public class Currency implements Parcelable { callBack.onSuccess(Currency.this); } + + @Override + public void onSuccess(String result){} }, CurrencyDataRetriever.MINUTES); } @@ -97,6 +115,9 @@ public class Currency implements Parcelable { callBack.onSuccess(Currency.this); } + + @Override + public void onSuccess(String price) {} }, CurrencyDataRetriever.HOURS); } @@ -110,6 +131,9 @@ public class Currency implements Parcelable { callBack.onSuccess(Currency.this); } + + @Override + public void onSuccess(String price) {} }, CurrencyDataRetriever.DAYS); } @@ -237,6 +261,9 @@ public class Currency implements Parcelable { void onSuccess(Currency currency); } + public interface PriceCallBack { + void onSuccess(String price); + } @Override public int describeContents() { diff --git a/app/src/main/java/com/nauk/coinfolio/DataManagers/CurrencyData/CurrencyDataRetriever.java b/app/src/main/java/com/nauk/coinfolio/DataManagers/CurrencyData/CurrencyDataRetriever.java index 2ffb89d..f4681bf 100644 --- a/app/src/main/java/com/nauk/coinfolio/DataManagers/CurrencyData/CurrencyDataRetriever.java +++ b/app/src/main/java/com/nauk/coinfolio/DataManagers/CurrencyData/CurrencyDataRetriever.java @@ -1,5 +1,6 @@ package com.nauk.coinfolio.DataManagers.CurrencyData; +import android.provider.ContactsContract; import android.util.Log; import com.android.volley.Request; @@ -42,6 +43,36 @@ public class CurrencyDataRetriever { requestQueue = Volley.newRequestQueue(context); } + private void getPriceTimestamp(final String symbolCurrencyFrom, String symbolCurrencyTo, final DataChartCallBack callBack, long timestamp) + { + final String requestUrl = "https://min-api.cryptocompare.com/data/pricehistorical?fsym=" + symbolCurrencyFrom + "&tsyms=" + symbolCurrencyTo + "&ts=" + timestamp; + + StringRequest stringRequest = new StringRequest(Request.Method.GET, requestUrl, + new Response.Listener() { + @Override + public void onResponse(String response) { + Log.d("coinfolio", response + " " + requestUrl); + callBack.onSuccess(processPriceTimestampResult(response)); + } + }, + new Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { + + } + }); + + requestQueue.add(stringRequest); + } + + private String processPriceTimestampResult(String result) + { + result = result.substring(result.lastIndexOf(':')+1); + result = result.substring(0, result.indexOf('}')); + + return result; + } + private void updateHistory(final String symbolCurrencyFrom, String symbolCyrrencyTo, final DataChartCallBack callBack, int timeUnit) { String requestUrl = getRequestUrl(timeUnit, symbolCurrencyFrom, symbolCyrrencyTo); @@ -56,7 +87,7 @@ public class CurrencyDataRetriever { new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { - callBack.onSuccess(null); + callBack.onSuccess((List) null); } }); @@ -134,11 +165,16 @@ public class CurrencyDataRetriever { return new CurrencyDataChart(timestamp, close, high, low, open, volumeFrom, volumeTo); } - void updateHistory(String symbolCurrencyFrom, final DataChartCallBack callBack, int timeUnit) + public void getPriceTimestamp(String symbolCurrencyFrom, final DataChartCallBack callBack, long timestamp) + { + getPriceTimestamp(symbolCurrencyFrom, "USD", callBack, timestamp); + } + + public void updateHistory(String symbolCurrencyFrom, final DataChartCallBack callBack, int timeUnit) { if(symbolCurrencyFrom.equals("USD")) { - callBack.onSuccess(null); + callBack.onSuccess((List) null); } else { @@ -148,5 +184,6 @@ public class CurrencyDataRetriever { public interface DataChartCallBack { void onSuccess(List dataChart); + void onSuccess(String price); } } diff --git a/app/src/main/java/com/nauk/coinfolio/DataManagers/CurrencyData/Transaction.java b/app/src/main/java/com/nauk/coinfolio/DataManagers/CurrencyData/Transaction.java index 420092a..507cfa2 100644 --- a/app/src/main/java/com/nauk/coinfolio/DataManagers/CurrencyData/Transaction.java +++ b/app/src/main/java/com/nauk/coinfolio/DataManagers/CurrencyData/Transaction.java @@ -13,12 +13,13 @@ public class Transaction { private double purchasedPrice; private boolean isMined; - public Transaction(int transactionId, String symbol, double amount, long timestamp) + public Transaction(int transactionId, String symbol, double amount, long timestamp, double purchasedPrice) { this.transactionId = transactionId; this.symbol = symbol; this.amount = amount; this.timestamp = timestamp; + this.purchasedPrice = purchasedPrice; } public int getTransactionId() { @@ -49,4 +50,14 @@ public class Transaction { public void setAmount(double amount) { this.amount = amount; } + + public void setPurchasedPrice(double purchasedPrice) + { + this.purchasedPrice = purchasedPrice; + } + + public double getPurchasedPrice() + { + return purchasedPrice; + } } diff --git a/app/src/main/java/com/nauk/coinfolio/DataManagers/DatabaseManager.java b/app/src/main/java/com/nauk/coinfolio/DataManagers/DatabaseManager.java index 01a1b4f..a804607 100644 --- a/app/src/main/java/com/nauk/coinfolio/DataManagers/DatabaseManager.java +++ b/app/src/main/java/com/nauk/coinfolio/DataManagers/DatabaseManager.java @@ -53,7 +53,7 @@ public class DatabaseManager extends SQLiteOpenHelper{ + KEY_CURRENCY_NAME + " VARCHAR(45)," + KEY_CURRENCY_BALANCE + " TEXT," + KEY_CURRENCY_DATE + " TEXT," - + KEY_CURRENCY_PURCHASED_PRICE + " TEXT," + + KEY_CURRENCY_PURCHASED_PRICE + " REAL," + KEY_CURRENCY_IS_MINED + " INTEGER" + ");"); @@ -76,7 +76,7 @@ public class DatabaseManager extends SQLiteOpenHelper{ onCreate(db); } - public void addCurrencyToManualCurrency(String symbol, double balance, Date date) + public void addCurrencyToManualCurrency(String symbol, double balance, Date date, String purchasedPrice) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); @@ -84,6 +84,7 @@ public class DatabaseManager extends SQLiteOpenHelper{ values.put(KEY_CURRENCY_SYMBOL, symbol); values.put(KEY_CURRENCY_BALANCE, balance); values.put(KEY_CURRENCY_DATE, date.getTime()); + values.put(KEY_CURRENCY_PURCHASED_PRICE, purchasedPrice); //values.put(KEY_CURRENCY_PURCHASED_PRICE, something); db.insert(TABLE_MANUAL_CURRENCIES, null, values); @@ -120,7 +121,7 @@ public class DatabaseManager extends SQLiteOpenHelper{ while(resultatList.moveToNext()) { - transactionList.add(new Transaction(resultatList.getInt(0), resultatList.getString(1), resultatList.getDouble(3), resultatList.getLong(4))); + transactionList.add(new Transaction(resultatList.getInt(0), resultatList.getString(1), resultatList.getDouble(3), resultatList.getLong(4), resultatList.getLong(5))); } resultatList.close(); diff --git a/app/src/main/java/com/nauk/coinfolio/DataManagers/ExchangeManager/BinanceManager.java b/app/src/main/java/com/nauk/coinfolio/DataManagers/ExchangeManager/BinanceManager.java index 07d9d15..a6270ec 100644 --- a/app/src/main/java/com/nauk/coinfolio/DataManagers/ExchangeManager/BinanceManager.java +++ b/app/src/main/java/com/nauk/coinfolio/DataManagers/ExchangeManager/BinanceManager.java @@ -1,9 +1,12 @@ package com.nauk.coinfolio.DataManagers.ExchangeManager; +import android.util.Log; + import com.binance.api.client.BinanceApiClientFactory; import com.binance.api.client.BinanceApiRestClient; import com.binance.api.client.domain.account.Account; import com.binance.api.client.domain.account.AssetBalance; +import com.binance.api.client.domain.account.Trade; import com.binance.api.client.exception.BinanceApiException; import com.nauk.coinfolio.DataManagers.CurrencyData.Currency; @@ -21,6 +24,7 @@ public class BinanceManager { private String privateKey; private List balance; + private List trades; public BinanceManager(String publicKey, String privateKey) { @@ -53,9 +57,52 @@ public class BinanceManager { } } - public void getTrades() + public void updateTrades(BinanceCallBack callBack, String symbol) { + List totalTrades = new ArrayList<>(); + updateTrades(null, symbol, "BTC"); + totalTrades.addAll(trades); + + updateTrades(null, symbol, "ETH"); + totalTrades.addAll(trades); + + updateTrades(null, symbol, "USDT"); + totalTrades.addAll(trades); + + trades = totalTrades; + + callBack.onSuccess(); + } + + public void updateTrades(BinanceCallBack callBack, String symbol, String pairSymbol) + { + BinanceApiClientFactory factory = BinanceApiClientFactory.newInstance(publicKey, privateKey); + BinanceApiRestClient client = factory.newRestClient(); + + Log.d("coinfolio", symbol + pairSymbol); + + trades = new ArrayList<>(); + + if(!symbol.equals(pairSymbol)) + { + try { + trades = client.getMyTrades(symbol + pairSymbol); + + } catch (BinanceApiException e) { + try { + trades = client.getMyTrades(pairSymbol + symbol); + + } catch (BinanceApiException f) { + f.printStackTrace(); + } + } + } + + if(callBack != null) + { + callBack.onSuccess(); + } } public void setPublicKey(String publicKey) @@ -73,6 +120,11 @@ public class BinanceManager { return balance; } + public List getTrades() + { + return trades; + } + public interface BinanceCallBack { void onSuccess(); void onError(String error); diff --git a/app/src/main/res/layout/activity_currency_details.xml b/app/src/main/res/layout/activity_currency_details.xml index 3bbb8fa..fa9d673 100644 --- a/app/src/main/res/layout/activity_currency_details.xml +++ b/app/src/main/res/layout/activity_currency_details.xml @@ -329,60 +329,69 @@ android:layout_gravity="center" android:background="@drawable/circular_progress_bar" /> - + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file