Several changes
- List generation delay on currency choice activity reduced - Sort currencies by market order in currencies selection activity - Rewritten suggestion list - Add default icon when currencies' icons are missing - Optimize details storage - Enable Binance key input - Replacing Binance library by compiled jar from API's github - New main gradient - Fix crash when balance requests complete before details request
This commit is contained in:
parent
1363c04202
commit
375afee570
@ -34,7 +34,15 @@ dependencies {
|
|||||||
implementation 'com.android.support:recyclerview-v7:26.1.0'
|
implementation 'com.android.support:recyclerview-v7:26.1.0'
|
||||||
implementation 'com.daimajia.swipelayout:library:1.2.0@aar'
|
implementation 'com.daimajia.swipelayout:library:1.2.0@aar'
|
||||||
implementation 'com.github.armcha:SpaceNavigationView:1.6.0'
|
implementation 'com.github.armcha:SpaceNavigationView:1.6.0'
|
||||||
|
implementation 'com.fasterxml.jackson.core:jackson-databind:2.8.5'
|
||||||
|
implementation 'com.fasterxml.jackson.core:jackson-core:2.8.5'
|
||||||
|
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.8.5'
|
||||||
|
implementation 'com.squareup.retrofit2:retrofit:2.2.0'
|
||||||
|
implementation 'com.squareup.retrofit2:converter-jackson:2.2.0'
|
||||||
|
implementation 'com.squareup.okhttp3:logging-interceptor:3.6.0'
|
||||||
|
implementation 'org.apache.commons:commons-lang3:3.6'
|
||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.12'
|
||||||
androidTestImplementation 'com.android.support.test:runner:1.0.1'
|
androidTestImplementation 'com.android.support.test:runner:1.0.1'
|
||||||
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
|
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
|
||||||
|
implementation files('C:/Users/Guitoune/Documents/GitHub/Coinfolio/libs/binance-api.jar')
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import android.support.test.runner.AndroidJUnit4;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instrumented test, which will execute on an Android device.
|
* Instrumented test, which will execute on an Android device.
|
||||||
|
@ -2,12 +2,10 @@ package com.nauk.coinfolio.Activities;
|
|||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.design.widget.BottomNavigationView;
|
import android.support.design.widget.BottomNavigationView;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
@ -1,15 +1,20 @@
|
|||||||
package com.nauk.coinfolio.Activities;
|
package com.nauk.coinfolio.Activities;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.view.KeyEvent;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.AutoCompleteTextView;
|
import android.widget.AutoCompleteTextView;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.ListView;
|
||||||
|
import android.widget.SearchView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.nauk.coinfolio.DataManagers.CurrencyData.Currency;
|
import com.nauk.coinfolio.DataManagers.CurrencyData.Currency;
|
||||||
import com.nauk.coinfolio.LayoutManagers.CurrencyAdapter;
|
import com.nauk.coinfolio.LayoutManagers.CurrencyAdapter;
|
||||||
@ -17,10 +22,13 @@ import com.nauk.coinfolio.R;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class CurrencySelectionActivity extends AppCompatActivity {
|
public class CurrencySelectionActivity extends AppCompatActivity implements SearchView.OnQueryTextListener{
|
||||||
|
|
||||||
String[] currencySymbols;
|
private String[] currencySymbols;
|
||||||
String[] currencyNames;
|
private String[] currencyNames;
|
||||||
|
private CurrencyAdapter adapter;
|
||||||
|
private ListView listView;
|
||||||
|
private android.widget.Filter filter;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@ -37,25 +45,21 @@ public class CurrencySelectionActivity extends AppCompatActivity {
|
|||||||
currencyNames = intent.getStringArrayExtra("currencyListNames");
|
currencyNames = intent.getStringArrayExtra("currencyListNames");
|
||||||
|
|
||||||
setTitle("Select a coin");
|
setTitle("Select a coin");
|
||||||
|
|
||||||
|
setupAdapter();
|
||||||
|
|
||||||
|
setupList();
|
||||||
|
|
||||||
|
SearchView searchView = findViewById(R.id.search_bar);
|
||||||
|
|
||||||
|
searchView.setIconifiedByDefault(false);
|
||||||
|
searchView.setOnQueryTextListener(this);
|
||||||
|
searchView.setSubmitButtonEnabled(false);
|
||||||
|
searchView.onActionViewExpanded();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void setupAdapter()
|
||||||
public boolean onCreateOptionsMenu(Menu menu)
|
|
||||||
{
|
{
|
||||||
final AutoCompleteTextView searchAutoComplete = findViewById(R.id.search_bar);
|
|
||||||
|
|
||||||
searchAutoComplete.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
|
|
||||||
Currency selectedCurrency = (Currency) adapterView.getItemAtPosition(i);
|
|
||||||
Intent intent = new Intent(CurrencySelectionActivity.this, RecordTransactionActivity.class);
|
|
||||||
intent.putExtra("coin", selectedCurrency.getName());
|
|
||||||
intent.putExtra("symbol", selectedCurrency.getSymbol());
|
|
||||||
startActivity(intent);
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
String[] currencyFullname = new String[currencyNames.length];
|
String[] currencyFullname = new String[currencyNames.length];
|
||||||
|
|
||||||
for(int i = 0; i < currencyFullname.length; i++)
|
for(int i = 0; i < currencyFullname.length; i++)
|
||||||
@ -70,11 +74,58 @@ public class CurrencySelectionActivity extends AppCompatActivity {
|
|||||||
currencyArrayList.add(new Currency(currencyNames[i], currencySymbols[i]));
|
currencyArrayList.add(new Currency(currencyNames[i], currencySymbols[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrencyAdapter adapter = new CurrencyAdapter(this, currencyArrayList);
|
adapter = new CurrencyAdapter(this, currencyArrayList);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupList()
|
||||||
|
{
|
||||||
|
listView = findViewById(R.id.coinsPreview);
|
||||||
|
|
||||||
|
listView.setAdapter(adapter);
|
||||||
|
listView.setTextFilterEnabled(false);
|
||||||
|
|
||||||
|
filter = adapter.getFilter();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu)
|
||||||
|
{
|
||||||
|
/*final AutoCompleteTextView searchAutoComplete = findViewById(R.id.search_bar);
|
||||||
|
|
||||||
|
searchAutoComplete.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
|
||||||
|
Currency selectedCurrency = (Currency) adapterView.getItemAtPosition(i);
|
||||||
|
Intent intent = new Intent(CurrencySelectionActivity.this, RecordTransactionActivity.class);
|
||||||
|
intent.putExtra("coin", selectedCurrency.getName());
|
||||||
|
intent.putExtra("symbol", selectedCurrency.getSymbol());
|
||||||
|
startActivity(intent);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
searchAutoComplete.setAdapter(adapter);
|
searchAutoComplete.setAdapter(adapter);
|
||||||
searchAutoComplete.setThreshold(0);
|
searchAutoComplete.setThreshold(0);*/
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onQueryTextChange(String text)
|
||||||
|
{
|
||||||
|
filter.filter(text);
|
||||||
|
|
||||||
|
if (TextUtils.isEmpty(text)) {
|
||||||
|
listView.clearTextFilter();
|
||||||
|
} else {
|
||||||
|
listView.setFilterText(text);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onQueryTextSubmit(String query)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package com.nauk.coinfolio.Activities;
|
package com.nauk.coinfolio.Activities;
|
||||||
|
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.app.Fragment;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
@ -13,22 +13,21 @@ import android.support.annotation.NonNull;
|
|||||||
import android.support.design.widget.AppBarLayout;
|
import android.support.design.widget.AppBarLayout;
|
||||||
import android.support.design.widget.BottomNavigationView;
|
import android.support.design.widget.BottomNavigationView;
|
||||||
import android.support.design.widget.CollapsingToolbarLayout;
|
import android.support.design.widget.CollapsingToolbarLayout;
|
||||||
import android.support.design.widget.CoordinatorLayout;
|
|
||||||
import android.support.design.widget.FloatingActionButton;
|
import android.support.design.widget.FloatingActionButton;
|
||||||
import android.support.design.widget.Snackbar;
|
import android.support.design.widget.Snackbar;
|
||||||
|
import android.support.v4.widget.NestedScrollView;
|
||||||
import android.support.v4.widget.SwipeRefreshLayout;
|
import android.support.v4.widget.SwipeRefreshLayout;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.support.v7.graphics.Palette;
|
import android.support.v7.graphics.Palette;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.View;
|
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.FrameLayout;
|
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
@ -40,8 +39,8 @@ import com.luseen.spacenavigation.SpaceNavigationView;
|
|||||||
import com.luseen.spacenavigation.SpaceOnClickListener;
|
import com.luseen.spacenavigation.SpaceOnClickListener;
|
||||||
import com.nauk.coinfolio.DataManagers.BalanceManager;
|
import com.nauk.coinfolio.DataManagers.BalanceManager;
|
||||||
import com.nauk.coinfolio.DataManagers.CurrencyData.Currency;
|
import com.nauk.coinfolio.DataManagers.CurrencyData.Currency;
|
||||||
import com.nauk.coinfolio.LayoutManagers.HomeLayoutGenerator;
|
|
||||||
import com.nauk.coinfolio.DataManagers.PreferencesManager;
|
import com.nauk.coinfolio.DataManagers.PreferencesManager;
|
||||||
|
import com.nauk.coinfolio.LayoutManagers.HomeLayoutGenerator;
|
||||||
import com.nauk.coinfolio.R;
|
import com.nauk.coinfolio.R;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -79,6 +78,7 @@ public class HomeActivity extends AppCompatActivity {
|
|||||||
private Dialog loadingDialog;
|
private Dialog loadingDialog;
|
||||||
private Handler handler;
|
private Handler handler;
|
||||||
private Runnable updateRunnable;
|
private Runnable updateRunnable;
|
||||||
|
private ViewFlipper viewFlipper;
|
||||||
|
|
||||||
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
|
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
|
||||||
= new BottomNavigationView.OnNavigationItemSelectedListener() {
|
= new BottomNavigationView.OnNavigationItemSelectedListener() {
|
||||||
@ -148,6 +148,8 @@ public class HomeActivity extends AppCompatActivity {
|
|||||||
toolbarLayout = findViewById(R.id.toolbar_layout);
|
toolbarLayout = findViewById(R.id.toolbar_layout);
|
||||||
toolbarSubtitle = findViewById(R.id.toolbarSubtitle);
|
toolbarSubtitle = findViewById(R.id.toolbarSubtitle);
|
||||||
currencyLayout = findViewById(R.id.currencyListLayout);
|
currencyLayout = findViewById(R.id.currencyListLayout);
|
||||||
|
viewFlipper = findViewById(R.id.viewFlipperSummary);
|
||||||
|
viewFlipper.setDisplayedChild(1);
|
||||||
|
|
||||||
ImageButton addCurrencyButton = findViewById(R.id.floatingAddButton);
|
ImageButton addCurrencyButton = findViewById(R.id.floatingAddButton);
|
||||||
ImageButton detailsButton = findViewById(R.id.switch_button);
|
ImageButton detailsButton = findViewById(R.id.switch_button);
|
||||||
@ -160,11 +162,11 @@ public class HomeActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
toolbarSubtitle.setText("US$0.00");
|
toolbarSubtitle.setText("US$0.00");
|
||||||
|
|
||||||
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation_home);
|
/*BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation_home);
|
||||||
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
|
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
|
||||||
navigation.setSelectedItemId(R.id.navigation_view_list);
|
navigation.setSelectedItemId(R.id.navigation_view_list);
|
||||||
navigation.setFitsSystemWindows(true);
|
navigation.setFitsSystemWindows(true);
|
||||||
navigation.setItemBackgroundResource(R.color.colorAccent);
|
navigation.setItemBackgroundResource(R.color.colorAccent);*/
|
||||||
|
|
||||||
//Events setup
|
//Events setup
|
||||||
detailsButton.setOnClickListener(new View.OnClickListener() {
|
detailsButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@ -223,7 +225,6 @@ public class HomeActivity extends AppCompatActivity {
|
|||||||
spaceNavigationView.addSpaceItem(new SpaceItem("Charts", R.drawable.ic_show_chart_black_24dp));
|
spaceNavigationView.addSpaceItem(new SpaceItem("Charts", R.drawable.ic_show_chart_black_24dp));
|
||||||
spaceNavigationView.addSpaceItem(new SpaceItem("Market Cap.", R.drawable.ic_pie_chart_black_24dp));
|
spaceNavigationView.addSpaceItem(new SpaceItem("Market Cap.", R.drawable.ic_pie_chart_black_24dp));
|
||||||
spaceNavigationView.setSpaceBackgroundColor(getResources().getColor(R.color.colorPrimary));
|
spaceNavigationView.setSpaceBackgroundColor(getResources().getColor(R.color.colorPrimary));
|
||||||
//spaceNavigationView.setCentreButtonIcon(R.drawable.ic_add_white_24dp);
|
|
||||||
spaceNavigationView.setCentreButtonIcon(R.drawable.ic_view_list_white_24dp);
|
spaceNavigationView.setCentreButtonIcon(R.drawable.ic_view_list_white_24dp);
|
||||||
spaceNavigationView.setCentreButtonColor(getResources().getColor(R.color.colorAccent));
|
spaceNavigationView.setCentreButtonColor(getResources().getColor(R.color.colorAccent));
|
||||||
spaceNavigationView.setCentreButtonIconColorFilterEnabled(false);
|
spaceNavigationView.setCentreButtonIconColorFilterEnabled(false);
|
||||||
@ -237,8 +238,13 @@ public class HomeActivity extends AppCompatActivity {
|
|||||||
SpaceNavigationView nav = findViewById(R.id.space);
|
SpaceNavigationView nav = findViewById(R.id.space);
|
||||||
|
|
||||||
nav.changeCurrentItem(-1);
|
nav.changeCurrentItem(-1);
|
||||||
((AppBarLayout) findViewById(R.id.app_bar)).setNestedScrollingEnabled(true);
|
|
||||||
|
((NestedScrollView) findViewById(R.id.nestedScrollViewLayout)).setNestedScrollingEnabled(true);
|
||||||
((AppBarLayout) findViewById(R.id.app_bar)).setExpanded(true, true);
|
((AppBarLayout) findViewById(R.id.app_bar)).setExpanded(true, true);
|
||||||
|
|
||||||
|
findViewById(R.id.switch_button).setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
viewFlipper.setDisplayedChild(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -248,9 +254,14 @@ public class HomeActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
//0 : Unknown
|
//0 : Unknown
|
||||||
//1 : Market cap
|
//1 : Market cap
|
||||||
((AppBarLayout) findViewById(R.id.app_bar)).setNestedScrollingEnabled(false);
|
((NestedScrollView) findViewById(R.id.nestedScrollViewLayout)).setNestedScrollingEnabled(false);
|
||||||
((AppBarLayout) findViewById(R.id.app_bar)).setExpanded(false, true);
|
((AppBarLayout) findViewById(R.id.app_bar)).setExpanded(false, true);
|
||||||
|
|
||||||
|
findViewById(R.id.switch_button).setVisibility(View.GONE);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
viewFlipper.setDisplayedChild(itemIndex * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -394,7 +405,9 @@ public class HomeActivity extends AppCompatActivity {
|
|||||||
result = BitmapFactory.decodeStream(input);
|
result = BitmapFactory.decodeStream(input);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
result = null;
|
result = BitmapFactory.decodeResource(this.getResources(),
|
||||||
|
R.mipmap.icon_coinfolio);
|
||||||
|
result = Bitmap.createScaledBitmap(result, 50, 50, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
callBack.onSuccess(result);
|
callBack.onSuccess(result);
|
||||||
@ -470,7 +483,7 @@ public class HomeActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
if(balanceManager.getTotalBalance() != null)
|
if(balanceManager.getTotalBalance() != null)
|
||||||
{
|
{
|
||||||
if(coinCounter == balanceManager.getTotalBalance().size())
|
if(coinCounter == balanceManager.getTotalBalance().size() && detailsChecker)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < balanceManager.getTotalBalance().size(); i++)
|
for (int i = 0; i < balanceManager.getTotalBalance().size(); i++)
|
||||||
{
|
{
|
||||||
@ -502,6 +515,8 @@ public class HomeActivity extends AppCompatActivity {
|
|||||||
{
|
{
|
||||||
ImageButton imgButton = findViewById(R.id.switch_button);
|
ImageButton imgButton = findViewById(R.id.switch_button);
|
||||||
|
|
||||||
|
imgButton.setBackgroundColor(this.getResources().getColor(R.color.buttonColor));
|
||||||
|
|
||||||
if(isDetailed)
|
if(isDetailed)
|
||||||
{
|
{
|
||||||
imgButton.setBackground(this.getResources().getDrawable(R.drawable.ic_unfold_less_black_24dp));
|
imgButton.setBackground(this.getResources().getDrawable(R.drawable.ic_unfold_less_black_24dp));
|
||||||
@ -517,6 +532,7 @@ public class HomeActivity extends AppCompatActivity {
|
|||||||
private void generateSplash()
|
private void generateSplash()
|
||||||
{
|
{
|
||||||
LinearLayout loadingLayout = new LinearLayout(this);
|
LinearLayout loadingLayout = new LinearLayout(this);
|
||||||
|
|
||||||
loadingLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
loadingLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||||
loadingLayout.setGravity(Gravity.CENTER);
|
loadingLayout.setGravity(Gravity.CENTER);
|
||||||
loadingLayout.setOrientation(LinearLayout.VERTICAL);
|
loadingLayout.setOrientation(LinearLayout.VERTICAL);
|
||||||
@ -683,6 +699,14 @@ public class HomeActivity extends AppCompatActivity {
|
|||||||
@Override
|
@Override
|
||||||
protected Void doInBackground(Void... params)
|
protected Void doInBackground(Void... params)
|
||||||
{
|
{
|
||||||
|
balanceManager.updateDetails(new BalanceManager.IconCallBack() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess()
|
||||||
|
{
|
||||||
|
countCoins(false, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
balanceManager.updateTotalBalance(new BalanceManager.VolleyCallBack() {
|
balanceManager.updateTotalBalance(new BalanceManager.VolleyCallBack() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess() {
|
public void onSuccess() {
|
||||||
@ -731,14 +755,6 @@ public class HomeActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
balanceManager.updateDetails(new BalanceManager.IconCallBack() {
|
|
||||||
@Override
|
|
||||||
public void onSuccess()
|
|
||||||
{
|
|
||||||
countCoins(false, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package com.nauk.coinfolio.Activities;
|
package com.nauk.coinfolio.Activities;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
@ -12,10 +12,10 @@ import android.os.Bundle;
|
|||||||
import android.preference.ListPreference;
|
import android.preference.ListPreference;
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
import android.preference.PreferenceActivity;
|
import android.preference.PreferenceActivity;
|
||||||
import android.support.v7.app.ActionBar;
|
|
||||||
import android.preference.PreferenceFragment;
|
import android.preference.PreferenceFragment;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.preference.RingtonePreference;
|
import android.preference.RingtonePreference;
|
||||||
|
import android.support.v7.app.ActionBar;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
|
||||||
|
@ -12,6 +12,10 @@ import com.android.volley.VolleyError;
|
|||||||
import com.android.volley.toolbox.JsonArrayRequest;
|
import com.android.volley.toolbox.JsonArrayRequest;
|
||||||
import com.android.volley.toolbox.StringRequest;
|
import com.android.volley.toolbox.StringRequest;
|
||||||
import com.android.volley.toolbox.Volley;
|
import com.android.volley.toolbox.Volley;
|
||||||
|
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.nauk.coinfolio.DataManagers.CurrencyData.Currency;
|
import com.nauk.coinfolio.DataManagers.CurrencyData.Currency;
|
||||||
import com.nauk.coinfolio.R;
|
import com.nauk.coinfolio.R;
|
||||||
|
|
||||||
@ -21,6 +25,7 @@ import org.json.JSONObject;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
@ -39,24 +44,24 @@ public class BalanceManager {
|
|||||||
private String privatePoloniex;
|
private String privatePoloniex;
|
||||||
final private String hitBalanceUrl = "https://api.hitbtc.com/api/2/trading/balance";
|
final private String hitBalanceUrl = "https://api.hitbtc.com/api/2/trading/balance";
|
||||||
final private String detailUrl = "https://www.cryptocompare.com/api/data/coinlist/";
|
final private String detailUrl = "https://www.cryptocompare.com/api/data/coinlist/";
|
||||||
final private String binanceBalanceUrl = "https://api.binance.com/api/v3/account";
|
|
||||||
final private String binanceTimeUrl = "https://api.binance.com/api/v1/time";
|
|
||||||
private RequestQueue requestQueue;
|
private RequestQueue requestQueue;
|
||||||
|
private List<Currency> binanceBalance;
|
||||||
private List<Currency> hitBalance;
|
private List<Currency> hitBalance;
|
||||||
private List<Currency> manualBalances;
|
private List<Currency> manualBalances;
|
||||||
private List<Currency> totalBalance;
|
private List<Currency> totalBalance;
|
||||||
private android.content.Context context;
|
private android.content.Context context;
|
||||||
private Map<String, String> iconUrlList;
|
private LinkedHashMap<String, String> coinInfosHashmap;
|
||||||
private Map<String, String> coinList;
|
|
||||||
private Map<String, Integer> coinIdList;
|
|
||||||
private PreferencesManager preferenceManager;
|
private PreferencesManager preferenceManager;
|
||||||
private DatabaseManager databaseManager;
|
private DatabaseManager databaseManager;
|
||||||
|
|
||||||
|
private BinanceApiClientFactory binanceApiClientFactory;
|
||||||
|
|
||||||
public BalanceManager(android.content.Context context)
|
public BalanceManager(android.content.Context context)
|
||||||
{
|
{
|
||||||
this.context = context;
|
this.context = context;
|
||||||
preferenceManager = new PreferencesManager(context);
|
preferenceManager = new PreferencesManager(context);
|
||||||
requestQueue = Volley.newRequestQueue(context);
|
requestQueue = Volley.newRequestQueue(context);
|
||||||
|
binanceBalance = new ArrayList<Currency>();
|
||||||
hitBalance = new ArrayList<Currency>();
|
hitBalance = new ArrayList<Currency>();
|
||||||
manualBalances = new ArrayList<Currency>();
|
manualBalances = new ArrayList<Currency>();
|
||||||
databaseManager = new DatabaseManager(context);
|
databaseManager = new DatabaseManager(context);
|
||||||
@ -64,18 +69,62 @@ public class BalanceManager {
|
|||||||
|
|
||||||
public List<String> getCurrenciesName()
|
public List<String> getCurrenciesName()
|
||||||
{
|
{
|
||||||
return new ArrayList<>(coinList.values());
|
List<String> currenciesName = new ArrayList<>();
|
||||||
|
|
||||||
|
for (String symbol : coinInfosHashmap.keySet())
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
JSONObject jsonObject = new JSONObject(coinInfosHashmap.get(symbol));
|
||||||
|
currenciesName.add(jsonObject.getString("CoinName"));
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return currenciesName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getOrders()
|
||||||
|
{
|
||||||
|
List<String> currenciesOrder = new ArrayList<>();
|
||||||
|
|
||||||
|
for(String symbol : coinInfosHashmap.keySet())
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
JSONObject jsonObject = new JSONObject(coinInfosHashmap.get(symbol));
|
||||||
|
currenciesOrder.add(jsonObject.getString("SortOrder"));
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return currenciesOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getCurrenciesSymbol()
|
public List<String> getCurrenciesSymbol()
|
||||||
{
|
{
|
||||||
return new ArrayList<>(coinList.keySet());
|
return new ArrayList<>(coinInfosHashmap.keySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateExchangeKeys()
|
public void updateExchangeKeys()
|
||||||
{
|
{
|
||||||
publicHitKey = preferenceManager.getHitBTCPublicKey();
|
publicHitKey = preferenceManager.getHitBTCPublicKey();
|
||||||
privateHitKey = preferenceManager.getHitBTCPrivateKey();
|
privateHitKey = preferenceManager.getHitBTCPrivateKey();
|
||||||
|
|
||||||
|
publicBinanceKey = preferenceManager.getBinancePublicKey();
|
||||||
|
privateBinanceKey = preferenceManager.getBinancePrivateKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBinanceConfigured()
|
||||||
|
{
|
||||||
|
boolean isConfigured = true;
|
||||||
|
|
||||||
|
if(publicBinanceKey == null || privateBinanceKey == null)
|
||||||
|
{
|
||||||
|
isConfigured = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isConfigured;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isHitBTCConfigured()
|
public boolean isHitBTCConfigured()
|
||||||
@ -117,19 +166,61 @@ public class BalanceManager {
|
|||||||
|
|
||||||
public void updateTotalBalance(final VolleyCallBack callBack)
|
public void updateTotalBalance(final VolleyCallBack callBack)
|
||||||
{
|
{
|
||||||
|
boolean isUpdated = false;
|
||||||
manualBalances = databaseManager.getAllCurrencyFromManualCurrency();
|
manualBalances = databaseManager.getAllCurrencyFromManualCurrency();
|
||||||
|
|
||||||
|
Log.d("coinfolio", "Updating balances " + (privateBinanceKey != null && publicBinanceKey != null && preferenceManager.isBinanceActivated()));
|
||||||
|
|
||||||
if(privateHitKey != null && publicHitKey != null && preferenceManager.isHitBTCActivated())
|
if(privateHitKey != null && publicHitKey != null && preferenceManager.isHitBTCActivated())
|
||||||
{
|
{
|
||||||
updateHitBalance(callBack);
|
updateHitBalance(callBack);
|
||||||
|
isUpdated = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hitBalance = new ArrayList<Currency>();
|
hitBalance = new ArrayList<Currency>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(privateBinanceKey != null && publicBinanceKey != null && preferenceManager.isBinanceActivated())
|
||||||
|
{
|
||||||
|
Log.d("coinfolio", "Updating Binance");
|
||||||
|
updateBinanceBalance();
|
||||||
|
isUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!isUpdated)
|
||||||
|
{
|
||||||
refreshAllBalances(callBack);
|
refreshAllBalances(callBack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateBinanceBalance()
|
||||||
|
{
|
||||||
|
Map<String, AssetBalance> accountBalanceCache;
|
||||||
|
BinanceApiClientFactory factory = BinanceApiClientFactory.newInstance(publicBinanceKey, privateBinanceKey);
|
||||||
|
BinanceApiRestClient client = factory.newRestClient();
|
||||||
|
|
||||||
|
Account account = client.getAccount();
|
||||||
|
List<AssetBalance> assets = account.getBalances();
|
||||||
|
|
||||||
|
binanceBalance = new ArrayList<Currency>();
|
||||||
|
|
||||||
|
for(int i = 0; i < assets.size(); i++)
|
||||||
|
{
|
||||||
|
if(Double.parseDouble(assets.get(i).getFree()) > 0)
|
||||||
|
{
|
||||||
|
binanceBalance.add(new Currency(assets.get(i).getAsset(), assets.get(i).getFree()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d("coinfolio", "Binance size : " + binanceBalance.size());
|
||||||
|
|
||||||
|
for(int i = 0; i < binanceBalance.size(); i++)
|
||||||
|
{
|
||||||
|
Log.d("coinfolio", "Binance : " + binanceBalance.get(i).getSymbol() + " " + binanceBalance.get(i).getBalance());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateHitBalance(final VolleyCallBack callBack)
|
private void updateHitBalance(final VolleyCallBack callBack)
|
||||||
{
|
{
|
||||||
JsonArrayRequest arrReq = new JsonArrayRequest(Request.Method.GET, hitBalanceUrl,
|
JsonArrayRequest arrReq = new JsonArrayRequest(Request.Method.GET, hitBalanceUrl,
|
||||||
@ -269,10 +360,14 @@ public class BalanceManager {
|
|||||||
String url;
|
String url;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
url = iconUrlList.get(symbol);
|
JSONObject jsonObject = new JSONObject(coinInfosHashmap.get(symbol));
|
||||||
|
url = "https://www.cryptocompare.com" + jsonObject.getString("ImageUrl") + "?width=50";
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
Log.d(context.getResources().getString(R.string.debug), symbol + " has no icon URL");
|
Log.d(context.getResources().getString(R.string.debug), symbol + " has no icon URL");
|
||||||
url = null;
|
url = null;
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.d(context.getResources().getString(R.string.debug), "Url parsing error for " + symbol);
|
||||||
|
url = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
@ -280,12 +375,30 @@ public class BalanceManager {
|
|||||||
|
|
||||||
public String getCurrencyName(String symbol)
|
public String getCurrencyName(String symbol)
|
||||||
{
|
{
|
||||||
return coinList.get(symbol);
|
String currencyName = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSONObject jsonObject = new JSONObject(coinInfosHashmap.get(symbol));
|
||||||
|
currencyName = jsonObject.getString("CoinName");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return currencyName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCurrencyId(String symbol)
|
public int getCurrencyId(String symbol)
|
||||||
{
|
{
|
||||||
return coinIdList.get(symbol);
|
int id = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSONObject jsonObject = new JSONObject(coinInfosHashmap.get(symbol));
|
||||||
|
id = jsonObject.getInt("Id");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processDetailResult(String response, final IconCallBack callBack)
|
private void processDetailResult(String response, final IconCallBack callBack)
|
||||||
@ -293,9 +406,7 @@ public class BalanceManager {
|
|||||||
response = response.substring(response.indexOf("\"Data\"") + 7, response.lastIndexOf("},\"Type\":100}"));
|
response = response.substring(response.indexOf("\"Data\"") + 7, response.lastIndexOf("},\"Type\":100}"));
|
||||||
String[] tab = response.split(Pattern.quote("},"));
|
String[] tab = response.split(Pattern.quote("},"));
|
||||||
|
|
||||||
iconUrlList = new HashMap<>();
|
coinInfosHashmap = new LinkedHashMap<>();
|
||||||
coinList = new HashMap<>();
|
|
||||||
coinIdList = new HashMap<>();
|
|
||||||
|
|
||||||
for(int i = 0; i < tab.length; i++)
|
for(int i = 0; i < tab.length; i++)
|
||||||
{
|
{
|
||||||
@ -305,16 +416,42 @@ public class BalanceManager {
|
|||||||
StrictMode.setThreadPolicy(policy);
|
StrictMode.setThreadPolicy(policy);
|
||||||
JSONObject jsonObject = new JSONObject(tab[i]);
|
JSONObject jsonObject = new JSONObject(tab[i]);
|
||||||
|
|
||||||
iconUrlList.put(jsonObject.getString("Symbol"), "https://www.cryptocompare.com" + jsonObject.getString("ImageUrl") + "?width=50");
|
coinInfosHashmap.put(jsonObject.getString("Symbol"), tab[i]);
|
||||||
|
|
||||||
coinList.put(jsonObject.getString("Symbol"), jsonObject.getString("CoinName"));
|
|
||||||
|
|
||||||
coinIdList.put(jsonObject.getString("Symbol"), jsonObject.getInt("Id"));
|
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
Log.d(context.getResources().getString(R.string.debug), "ImageUrl not found.");
|
Log.d(context.getResources().getString(R.string.debug), "ImageUrl not found.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sortDetails();
|
||||||
|
|
||||||
callBack.onSuccess();
|
callBack.onSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void sortDetails()
|
||||||
|
{
|
||||||
|
LinkedHashMap<String, String> sortedHashmap = new LinkedHashMap<>();
|
||||||
|
List<String> listInfos = new ArrayList<>(coinInfosHashmap.values());
|
||||||
|
List<String> listSymbols = new ArrayList<>(coinInfosHashmap.keySet());
|
||||||
|
|
||||||
|
for(int i = 0; i < coinInfosHashmap.keySet().size(); i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSONObject jsonObject = new JSONObject(listInfos.get(i));
|
||||||
|
int index = jsonObject.getInt("SortOrder");
|
||||||
|
|
||||||
|
listInfos.add(index, listInfos.get(i));
|
||||||
|
listSymbols.add(index, listSymbols.get(i));
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < listInfos.size(); i++)
|
||||||
|
{
|
||||||
|
sortedHashmap.put(listSymbols.get(i), listInfos.get(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
coinInfosHashmap = sortedHashmap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package com.nauk.coinfolio.DataManagers.CurrencyData;
|
|||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -5,13 +5,11 @@ import android.content.Context;
|
|||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
import android.database.sqlite.SQLiteOpenHelper;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.nauk.coinfolio.DataManagers.CurrencyData.Currency;
|
import com.nauk.coinfolio.DataManagers.CurrencyData.Currency;
|
||||||
import com.nauk.coinfolio.DataManagers.CurrencyData.Transaction;
|
import com.nauk.coinfolio.DataManagers.CurrencyData.Transaction;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,4 +65,25 @@ public class PreferencesManager {
|
|||||||
editor.apply();
|
editor.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getBinancePublicKey()
|
||||||
|
{
|
||||||
|
return settingPreferences.getString("binance_publickey", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBinancePrivateKey()
|
||||||
|
{
|
||||||
|
return settingPreferences.getString("binance_privatekey", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBinanceActivated()
|
||||||
|
{
|
||||||
|
return settingPreferences.getBoolean("enable_binance", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disableBinance()
|
||||||
|
{
|
||||||
|
SharedPreferences.Editor editor = settingPreferences.edit();
|
||||||
|
editor.putBoolean("enable_binance", false);
|
||||||
|
editor.apply();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,11 @@ import android.widget.ArrayAdapter;
|
|||||||
import android.widget.Filter;
|
import android.widget.Filter;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import com.nauk.coinfolio.DataManagers.CurrencyData.Currency;
|
import com.nauk.coinfolio.DataManagers.CurrencyData.Currency;
|
||||||
import com.nauk.coinfolio.R;
|
import com.nauk.coinfolio.R;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Guitoune on 17/01/2018.
|
* Created by Guitoune on 17/01/2018.
|
||||||
*/
|
*/
|
||||||
@ -46,9 +46,9 @@ public class CurrencyAdapter extends ArrayAdapter<Currency> {
|
|||||||
}
|
}
|
||||||
// Now assign alternate color for rows
|
// Now assign alternate color for rows
|
||||||
if (position % 2 == 0)
|
if (position % 2 == 0)
|
||||||
convertView.setBackgroundColor(context.getResources().getColor(R.color.listBackground));
|
|
||||||
else
|
|
||||||
convertView.setBackgroundColor(context.getResources().getColor(R.color.listBackground2));
|
convertView.setBackgroundColor(context.getResources().getColor(R.color.listBackground2));
|
||||||
|
else
|
||||||
|
convertView.setBackgroundColor(context.getResources().getColor(R.color.listBackground));
|
||||||
|
|
||||||
return convertView;
|
return convertView;
|
||||||
}
|
}
|
||||||
@ -70,13 +70,28 @@ public class CurrencyAdapter extends ArrayAdapter<Currency> {
|
|||||||
if (constraint != null) {
|
if (constraint != null) {
|
||||||
suggestions.clear();
|
suggestions.clear();
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
int found = 0;
|
||||||
String temp = constraint.toString().toLowerCase();
|
String temp = constraint.toString().toLowerCase();
|
||||||
for (Currency currency : tempCurrency) {
|
|
||||||
|
while(i < tempCurrency.size() && found < 25)
|
||||||
|
{
|
||||||
|
Currency currency = tempCurrency.get(i);
|
||||||
|
if (currency.getName().toLowerCase().startsWith(temp)
|
||||||
|
|| currency.getSymbol().toLowerCase().startsWith(temp)) {
|
||||||
|
suggestions.add(currency);
|
||||||
|
found++;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*for (Currency currency : tempCurrency) {
|
||||||
if (currency.getName().toLowerCase().startsWith(temp)
|
if (currency.getName().toLowerCase().startsWith(temp)
|
||||||
|| currency.getSymbol().toLowerCase().startsWith(temp)) {
|
|| currency.getSymbol().toLowerCase().startsWith(temp)) {
|
||||||
suggestions.add(currency);
|
suggestions.add(currency);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
FilterResults filterResults = new FilterResults();
|
FilterResults filterResults = new FilterResults();
|
||||||
filterResults.values = suggestions;
|
filterResults.values = suggestions;
|
||||||
|
@ -1,20 +1,13 @@
|
|||||||
package com.nauk.coinfolio.LayoutManagers;
|
package com.nauk.coinfolio.LayoutManagers;
|
||||||
|
|
||||||
import android.animation.AnimatorInflater;
|
|
||||||
import android.animation.StateListAnimator;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.PorterDuff;
|
import android.graphics.PorterDuff;
|
||||||
import android.graphics.PorterDuffColorFilter;
|
import android.graphics.PorterDuffColorFilter;
|
||||||
import android.support.v7.widget.CardView;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.db.chart.model.ChartSet;
|
import com.db.chart.model.ChartSet;
|
||||||
@ -26,18 +19,12 @@ import com.nauk.coinfolio.DataManagers.CurrencyData.Currency;
|
|||||||
import com.nauk.coinfolio.DataManagers.CurrencyData.CurrencyDataChart;
|
import com.nauk.coinfolio.DataManagers.CurrencyData.CurrencyDataChart;
|
||||||
import com.nauk.coinfolio.R;
|
import com.nauk.coinfolio.R;
|
||||||
|
|
||||||
import org.w3c.dom.Text;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import static java.lang.Math.abs;
|
import static java.lang.Math.abs;
|
||||||
import static java.lang.Math.floorDiv;
|
|
||||||
import static java.lang.Math.floorMod;
|
|
||||||
import static java.lang.Math.incrementExact;
|
|
||||||
import static java.sql.Types.NULL;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Tiji on 05/01/2018.
|
* Created by Tiji on 05/01/2018.
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
|
||||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<item>
|
|
||||||
<shape>
|
|
||||||
<gradient
|
<gradient
|
||||||
android:angle="0"
|
android:type="linear"
|
||||||
android:startColor="@color/colorPrimary"
|
android:centerX="60%"
|
||||||
android:endColor="@color/colorAccent"
|
android:startColor="#FF1CB5E0"
|
||||||
android:type="linear"/>
|
android:centerColor="#FF000046"
|
||||||
</shape>
|
android:endColor="#FF111124"
|
||||||
</item>
|
android:angle="90"/>
|
||||||
|
</shape>
|
||||||
</selector>
|
|
@ -4,6 +4,6 @@
|
|||||||
android:viewportWidth="24.0"
|
android:viewportWidth="24.0"
|
||||||
android:viewportHeight="24.0">
|
android:viewportHeight="24.0">
|
||||||
<path
|
<path
|
||||||
android:fillColor="@color/listBackground"
|
android:fillColor="@color/buttonColor"
|
||||||
android:pathData="M3,4l9,16 9,-16L3,4zM6.38,6h11.25L12,16 6.38,6z"/>
|
android:pathData="M3,4l9,16 9,-16L3,4zM6.38,6h11.25L12,16 6.38,6z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
@ -4,6 +4,6 @@
|
|||||||
android:viewportWidth="24.0"
|
android:viewportWidth="24.0"
|
||||||
android:viewportHeight="24.0">
|
android:viewportHeight="24.0">
|
||||||
<path
|
<path
|
||||||
android:fillColor="@color/listBackground"
|
android:fillColor="@color/buttonColor"
|
||||||
android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"/>
|
android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
@ -4,6 +4,6 @@
|
|||||||
android:viewportWidth="24.0"
|
android:viewportWidth="24.0"
|
||||||
android:viewportHeight="24.0">
|
android:viewportHeight="24.0">
|
||||||
<path
|
<path
|
||||||
android:fillColor="@color/listBackground"
|
android:fillColor="@color/buttonColor"
|
||||||
android:pathData="M7.41,18.59L8.83,20 12,16.83 15.17,20l1.41,-1.41L12,14l-4.59,4.59zM16.59,5.41L15.17,4 12,7.17 8.83,4 7.41,5.41 12,10l4.59,-4.59z"/>
|
android:pathData="M7.41,18.59L8.83,20 12,16.83 15.17,20l1.41,-1.41L12,14l-4.59,4.59zM16.59,5.41L15.17,4 12,7.17 8.83,4 7.41,5.41 12,10l4.59,-4.59z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
@ -10,22 +9,21 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@drawable/soft_gradient"
|
android:background="@drawable/soft_gradient"
|
||||||
android:gravity="center">
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<!--<EditText
|
<SearchView
|
||||||
android:layout_width="200dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:background="@drawable/rounded_corners"/>-->
|
|
||||||
|
|
||||||
<AutoCompleteTextView
|
|
||||||
android:id="@+id/search_bar"
|
android:id="@+id/search_bar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center|top"
|
android:layout_gravity="center|top"
|
||||||
android:padding="15dp"
|
|
||||||
android:background="@color/listBackground"/>
|
android:background="@color/listBackground"/>
|
||||||
|
|
||||||
|
<ListView
|
||||||
|
android:id="@+id/coinsPreview"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</android.support.constraint.ConstraintLayout>
|
</android.support.constraint.ConstraintLayout>
|
||||||
|
@ -44,8 +44,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
app:layout_collapseMode="pin"
|
app:layout_collapseMode="pin"
|
||||||
app:popupTheme="@style/AppTheme.PopupOverlay"
|
app:popupTheme="@style/AppTheme.PopupOverlay">
|
||||||
android:background="@drawable/gradient_background">
|
|
||||||
|
|
||||||
</android.support.v7.widget.Toolbar>
|
</android.support.v7.widget.Toolbar>
|
||||||
|
|
||||||
@ -61,7 +60,8 @@
|
|||||||
android:id="@+id/switch_button"
|
android:id="@+id/switch_button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/quick_button"/>
|
android:text="@string/quick_button"
|
||||||
|
android:visibility="visible"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
@ -77,7 +77,8 @@
|
|||||||
android:id="@+id/settings_button"
|
android:id="@+id/settings_button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/action_settings" />
|
android:text="@string/action_settings"
|
||||||
|
android:visibility="visible"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
@ -86,7 +87,7 @@
|
|||||||
|
|
||||||
<include layout="@layout/content_currency_summary" />
|
<include layout="@layout/content_currency_summary" />
|
||||||
|
|
||||||
<android.support.design.widget.BottomNavigationView
|
<!--<android.support.design.widget.BottomNavigationView
|
||||||
android:id="@+id/navigation_home"
|
android:id="@+id/navigation_home"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -99,7 +100,7 @@
|
|||||||
app:menu="@menu/navigation_home"
|
app:menu="@menu/navigation_home"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:layout_gravity="bottom"
|
android:layout_gravity="bottom"
|
||||||
android:visibility="gone"/>
|
android:visibility="gone"/>-->
|
||||||
|
|
||||||
<com.luseen.spacenavigation.SpaceNavigationView
|
<com.luseen.spacenavigation.SpaceNavigationView
|
||||||
android:id="@+id/space"
|
android:id="@+id/space"
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
@ -13,6 +12,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="10dp"
|
android:layout_margin="10dp"
|
||||||
android:clickable="false"
|
android:clickable="false"
|
||||||
|
android:backgroundTint="@color/listBackground2"
|
||||||
app:cardCornerRadius="8dp"
|
app:cardCornerRadius="8dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent">
|
app:layout_constraintBottom_toBottomOf="parent">
|
||||||
|
|
||||||
|
@ -4,11 +4,39 @@
|
|||||||
android:id="@+id/swiperefresh"
|
android:id="@+id/swiperefresh"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||||
|
android:layout_marginBottom="50dp">
|
||||||
|
|
||||||
|
<ViewFlipper
|
||||||
|
android:id="@+id/viewFlipperSummary"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progressBarWatchlist"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
style="?android:attr/progressBarStyleLarge"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:background="@drawable/circular_progress_bar" />
|
||||||
|
|
||||||
|
<!--<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Watch list"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:gravity="center_horizontal"/>-->
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/nestedScrollViewLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context="com.nauk.coinfolio.Activities.HomeActivity"
|
tools:context="com.nauk.coinfolio.Activities.HomeActivity"
|
||||||
@ -35,4 +63,35 @@
|
|||||||
|
|
||||||
</android.support.v4.widget.NestedScrollView>
|
</android.support.v4.widget.NestedScrollView>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<!--<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Market cap"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:gravity="center_horizontal"/>-->
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layoutProgressMarketCap"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:visibility="visible">
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progressBarMarketCap"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
style="?android:attr/progressBarStyleLarge"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:background="@drawable/circular_progress_bar" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ViewFlipper>
|
||||||
|
|
||||||
</android.support.v4.widget.SwipeRefreshLayout>
|
</android.support.v4.widget.SwipeRefreshLayout>
|
@ -1,4 +1,23 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
<resources>
|
||||||
|
<color name="colorPrimary">#093e93</color>
|
||||||
|
<color name="colorPrimaryDark">#000046</color>
|
||||||
|
<color name="colorAccent">#1cb5e0</color>
|
||||||
|
<color name="mainTextViewColor">#FFFFFFFF</color>
|
||||||
|
<color name="secondaryTextViewColor">#FFDDDDDD</color>
|
||||||
|
<color name="transparent">#00000000</color>
|
||||||
|
<color name="decrease">#FFED143D</color>
|
||||||
|
<color name="increase">#FF00E000</color>
|
||||||
|
<color name="buttonColor">#FFFFFFFF</color>
|
||||||
|
<color name="listBackground">#000046</color>
|
||||||
|
<color name="listBackground2">#000046</color>
|
||||||
|
<color name="separationLine">#FF999999</color>
|
||||||
|
<color name="red">#FFF44336</color>
|
||||||
|
<color name="green">#FF4CAF50</color>
|
||||||
|
</resources>
|
||||||
|
-->
|
||||||
|
|
||||||
<resources>
|
<resources>
|
||||||
<color name="colorPrimary">#000046</color>
|
<color name="colorPrimary">#000046</color>
|
||||||
<color name="colorPrimaryDark">#111124</color>
|
<color name="colorPrimaryDark">#111124</color>
|
||||||
@ -11,6 +30,7 @@
|
|||||||
<color name="listBackground">#FFEEEEEE</color>
|
<color name="listBackground">#FFEEEEEE</color>
|
||||||
<color name="listBackground2">#FFFFFFFF</color>
|
<color name="listBackground2">#FFFFFFFF</color>
|
||||||
<color name="separationLine">#FF999999</color>
|
<color name="separationLine">#FF999999</color>
|
||||||
|
<color name="buttonColor">#FFFFFFFF</color>
|
||||||
<color name="red">#FFF44336</color>
|
<color name="red">#FFF44336</color>
|
||||||
<color name="green">#FF4CAF50</color>
|
<color name="green">#FF4CAF50</color>
|
||||||
</resources>
|
</resources>
|
@ -59,7 +59,7 @@
|
|||||||
|
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:title="@string/pref_title_exchange_binance"
|
android:title="@string/pref_title_exchange_binance"
|
||||||
android:enabled="false">
|
android:enabled="true">
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
android:key="enable_binance"
|
android:key="enable_binance"
|
||||||
@ -79,7 +79,7 @@
|
|||||||
android:capitalize="words"
|
android:capitalize="words"
|
||||||
android:dependency="enable_binance"
|
android:dependency="enable_binance"
|
||||||
android:inputType="text"
|
android:inputType="text"
|
||||||
android:key="binance_privatekey"
|
android:key="binance_publickey"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:selectAllOnFocus="true"
|
android:selectAllOnFocus="true"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
|
@ -2,7 +2,7 @@ package com.nauk.coinfolio;
|
|||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Example local unit test, which will execute on the development machine (host).
|
* Example local unit test, which will execute on the development machine (host).
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
# Specifies the JVM arguments used for the daemon process.
|
# Specifies the JVM arguments used for the daemon process.
|
||||||
# The setting is particularly useful for tweaking memory settings.
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
org.gradle.jvmargs=-Xmx1536m
|
org.gradle.jvmargs=-Xmx1536m
|
||||||
|
android.enableD8=true
|
||||||
|
|
||||||
# When configured, Gradle will run in incubating parallel mode.
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
# This option should only be used with decoupled projects. More details, visit
|
# This option should only be used with decoupled projects. More details, visit
|
||||||
|
131
library/Binance/.gitignore
vendored
131
library/Binance/.gitignore
vendored
@ -1,131 +0,0 @@
|
|||||||
*.class
|
|
||||||
|
|
||||||
# Mobile Tools for Java (J2ME)
|
|
||||||
.mtj.tmp/
|
|
||||||
|
|
||||||
# Package Files #
|
|
||||||
*.jar
|
|
||||||
*.war
|
|
||||||
*.ear
|
|
||||||
|
|
||||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
|
||||||
hs_err_pid*
|
|
||||||
|
|
||||||
# https://github.com/github/gitignore/blob/master/Scala.gitignore
|
|
||||||
*.class
|
|
||||||
*.log
|
|
||||||
|
|
||||||
# sbt specific
|
|
||||||
.cache
|
|
||||||
.history
|
|
||||||
.lib/
|
|
||||||
dist/*
|
|
||||||
target/
|
|
||||||
lib_managed/
|
|
||||||
src_managed/
|
|
||||||
project/boot/
|
|
||||||
project/plugins/project/
|
|
||||||
|
|
||||||
# Scala-IDE specific
|
|
||||||
.scala_dependencies
|
|
||||||
.worksheet
|
|
||||||
|
|
||||||
**/.cache-main
|
|
||||||
|
|
||||||
# https://github.com/github/gitignore/blob/master/Global/Eclipse.gitignore
|
|
||||||
.metadata
|
|
||||||
bin/
|
|
||||||
tmp/
|
|
||||||
*.tmp
|
|
||||||
*.bak
|
|
||||||
*.swp
|
|
||||||
*~.nib
|
|
||||||
local.properties
|
|
||||||
.settings/
|
|
||||||
.loadpath
|
|
||||||
.recommenders
|
|
||||||
|
|
||||||
# Eclipse Core
|
|
||||||
.project
|
|
||||||
.classpath
|
|
||||||
|
|
||||||
# External tool builders
|
|
||||||
.externalToolBuilders/
|
|
||||||
|
|
||||||
# Locally stored "Eclipse launch configurations"
|
|
||||||
*.launch
|
|
||||||
|
|
||||||
# PyDev specific (Python IDE for Eclipse)
|
|
||||||
*.pydevproject
|
|
||||||
|
|
||||||
# CDT-specific (C/C++ Development Tooling)
|
|
||||||
.cproject
|
|
||||||
|
|
||||||
# JDT-specific (Eclipse Java Development Tools)
|
|
||||||
**/.classpath
|
|
||||||
|
|
||||||
# Java annotation processor (APT)
|
|
||||||
.factorypath
|
|
||||||
|
|
||||||
# PDT-specific (PHP Development Tools)
|
|
||||||
.buildpath
|
|
||||||
|
|
||||||
# sbteclipse plugin
|
|
||||||
.target
|
|
||||||
|
|
||||||
# Tern plugin
|
|
||||||
.tern-project
|
|
||||||
|
|
||||||
# TeXlipse plugin
|
|
||||||
.texlipse
|
|
||||||
|
|
||||||
# STS (Spring Tool Suite)
|
|
||||||
.springBeans
|
|
||||||
|
|
||||||
# Code Recommenders
|
|
||||||
.recommenders/
|
|
||||||
|
|
||||||
# https://github.com/github/gitignore/blob/master/Global/JetBrains.gitignore
|
|
||||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
|
||||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
|
||||||
|
|
||||||
# IntelliJ
|
|
||||||
.idea
|
|
||||||
*.iml
|
|
||||||
|
|
||||||
# Mongo Explorer plugin:
|
|
||||||
.idea/mongoSettings.xml
|
|
||||||
|
|
||||||
## File-based project format:
|
|
||||||
*.iws
|
|
||||||
|
|
||||||
## Plugin-specific files:
|
|
||||||
|
|
||||||
# IntelliJ
|
|
||||||
/out/
|
|
||||||
|
|
||||||
# mpeltonen/sbt-idea plugin
|
|
||||||
.idea_modules/
|
|
||||||
|
|
||||||
# JIRA plugin
|
|
||||||
atlassian-ide-plugin.xml
|
|
||||||
|
|
||||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
|
||||||
com_crashlytics_export_strings.xml
|
|
||||||
crashlytics.properties
|
|
||||||
crashlytics-build.properties
|
|
||||||
fabric.properties
|
|
||||||
|
|
||||||
# https://github.com/github/gitignore/blob/master/Maven.gitignore
|
|
||||||
target/
|
|
||||||
pom.xml.tag
|
|
||||||
pom.xml.releaseBackup
|
|
||||||
pom.xml.versionsBackup
|
|
||||||
pom.xml.next
|
|
||||||
release.properties
|
|
||||||
dependency-reduced-pom.xml
|
|
||||||
buildNumber.properties
|
|
||||||
.mvn/timing.properties
|
|
||||||
|
|
||||||
# test
|
|
||||||
test-output
|
|
@ -1,92 +0,0 @@
|
|||||||
# Contributing
|
|
||||||
|
|
||||||
When contributing to this repository, please first discuss the change you wish to make via issue,
|
|
||||||
email, or any other method with the owners of this repository before making a change.
|
|
||||||
|
|
||||||
Please note we have a code of conduct, please follow it in all your interactions with the project.
|
|
||||||
|
|
||||||
## Pull Request Process
|
|
||||||
|
|
||||||
1. Ensure any install or build dependencies are removed before the end of the layer when doing a
|
|
||||||
build.
|
|
||||||
2. Update the README.md with details of changes to the interface, this includes new environment
|
|
||||||
variables, exposed ports, useful file locations and container parameters.
|
|
||||||
3. Increase the version numbers in any examples files and the README.md to the new version that this
|
|
||||||
Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/).
|
|
||||||
4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you
|
|
||||||
do not have permission to do that, you may request the second reviewer to merge it for you.
|
|
||||||
|
|
||||||
## Code of Conduct
|
|
||||||
|
|
||||||
### Our Pledge
|
|
||||||
|
|
||||||
In the interest of fostering an open and welcoming environment, we as
|
|
||||||
contributors and maintainers pledge to making participation in our project and
|
|
||||||
our community a harassment-free experience for everyone, regardless of age, body
|
|
||||||
size, disability, ethnicity, gender identity and expression, level of experience,
|
|
||||||
nationality, personal appearance, race, religion, or sexual identity and
|
|
||||||
orientation.
|
|
||||||
|
|
||||||
### Our Standards
|
|
||||||
|
|
||||||
Examples of behavior that contributes to creating a positive environment
|
|
||||||
include:
|
|
||||||
|
|
||||||
* Using welcoming and inclusive language
|
|
||||||
* Being respectful of differing viewpoints and experiences
|
|
||||||
* Gracefully accepting constructive criticism
|
|
||||||
* Focusing on what is best for the community
|
|
||||||
* Showing empathy towards other community members
|
|
||||||
|
|
||||||
Examples of unacceptable behavior by participants include:
|
|
||||||
|
|
||||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
|
||||||
advances
|
|
||||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
|
||||||
* Public or private harassment
|
|
||||||
* Publishing others' private information, such as a physical or electronic
|
|
||||||
address, without explicit permission
|
|
||||||
* Other conduct which could reasonably be considered inappropriate in a
|
|
||||||
professional setting
|
|
||||||
|
|
||||||
### Our Responsibilities
|
|
||||||
|
|
||||||
Project maintainers are responsible for clarifying the standards of acceptable
|
|
||||||
behavior and are expected to take appropriate and fair corrective action in
|
|
||||||
response to any instances of unacceptable behavior.
|
|
||||||
|
|
||||||
Project maintainers have the right and responsibility to remove, edit, or
|
|
||||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
|
||||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
|
||||||
permanently any contributor for other behaviors that they deem inappropriate,
|
|
||||||
threatening, offensive, or harmful.
|
|
||||||
|
|
||||||
### Scope
|
|
||||||
|
|
||||||
This Code of Conduct applies both within project spaces and in public spaces
|
|
||||||
when an individual is representing the project or its community. Examples of
|
|
||||||
representing a project or community include using an official project e-mail
|
|
||||||
address, posting via an official social media account, or acting as an appointed
|
|
||||||
representative at an online or offline event. Representation of a project may be
|
|
||||||
further defined and clarified by project maintainers.
|
|
||||||
|
|
||||||
### Enforcement
|
|
||||||
|
|
||||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
||||||
reported by contacting the project team. All
|
|
||||||
complaints will be reviewed and investigated and will result in a response that
|
|
||||||
is deemed necessary and appropriate to the circumstances. The project team is
|
|
||||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
|
||||||
Further details of specific enforcement policies may be posted separately.
|
|
||||||
|
|
||||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
|
||||||
faith may face temporary or permanent repercussions as determined by other
|
|
||||||
members of the project's leadership.
|
|
||||||
|
|
||||||
### Attribution
|
|
||||||
|
|
||||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
|
||||||
available at [http://contributor-covenant.org/version/1/4][version]
|
|
||||||
|
|
||||||
[homepage]: http://contributor-covenant.org
|
|
||||||
[version]: http://contributor-covenant.org/version/1/4/
|
|
@ -1,107 +0,0 @@
|
|||||||
# Java client for [Binance API](https://www.binance.com/restapipub.html)
|
|
||||||
|
|
||||||
## Synopsis
|
|
||||||
Client for accessing Binance API using Java. An [async](src/main/java/com/github/johnsiu/binance/httpclients/AsyncBinanceClient.java) and a [sync](src/main/java/com/github/johnsiu/binance/httpclients/BinanceClient.java) versions of the client are available.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
Add the bintray repo to the pom of your maven project:
|
|
||||||
|
|
||||||
```xml
|
|
||||||
<repositories>
|
|
||||||
<repository>
|
|
||||||
<id>bintray-johnsiu-maven-repo</id>
|
|
||||||
<url>https://dl.bintray.com/johnsiu/maven-repo</url>
|
|
||||||
</repository>
|
|
||||||
</repositories>
|
|
||||||
```
|
|
||||||
then, add the dependency:
|
|
||||||
```xml
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.github.johnsiu</groupId>
|
|
||||||
<artifactId>binance-java-client</artifactId>
|
|
||||||
<version>1.0.1</version>
|
|
||||||
</dependency>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
### Creating an instance of the async client using Guice
|
|
||||||
```java
|
|
||||||
Injector injector = Guice.createInjector(new BinanceClientModule());
|
|
||||||
AsyncBinanceClient asyncClient = injector.getInstance(AsyncBinanceClient.class);
|
|
||||||
```
|
|
||||||
### Creating an instance of the sync client using Guice
|
|
||||||
```java
|
|
||||||
Injector injector = Guice.createInjector(new BinanceClientModule());
|
|
||||||
BinanceClient client = injector.getInstance(BinanceClient.class);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Getting latest price of a symbol
|
|
||||||
```java
|
|
||||||
Ticker ticker = client.getTicker("ETHBTC"));
|
|
||||||
double price = ticker.getLastPrice();
|
|
||||||
```
|
|
||||||
### Getting depth of a symbol
|
|
||||||
```java
|
|
||||||
Depth depth = client.getDepth("ETHBTC"));
|
|
||||||
```
|
|
||||||
### Placing a LIMIT order
|
|
||||||
```java
|
|
||||||
Keys keys = new Keys("YOUR_API_KEY", "YOUR_SECRET_KEY");
|
|
||||||
double quantity = 1;
|
|
||||||
double price = 0.020041;
|
|
||||||
Order order = client.placeLimitOrder(keys, "MCOETH", OrderSide.BUY, TimeInForce.GTC, quantity, price);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Placing a MARKET order
|
|
||||||
```java
|
|
||||||
double quantity = 1;
|
|
||||||
Order order = client.placeMarketOrder(keys, "MCOETH", OrderSide.SELL, quantity);
|
|
||||||
```
|
|
||||||
### Checking an order’s status
|
|
||||||
```java
|
|
||||||
OrderStatus orderStatus = client.checkOrderStatus(keys, order);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Cancelling an order
|
|
||||||
```java
|
|
||||||
CancelOrder cancelOrder = client.cancelOrder(keys, order);
|
|
||||||
// or
|
|
||||||
CancelOrder cancelOrder = client.cancelOrder(keys, orderStatus);
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### Getting a list of open orders
|
|
||||||
```java
|
|
||||||
List<OrderStatus> openOrders = client.getOpenOrders(keys, "MCOETH");
|
|
||||||
```
|
|
||||||
|
|
||||||
### Getting a list of current position
|
|
||||||
```java
|
|
||||||
Account account = client.getAccount(keys);
|
|
||||||
Map<String, Balance> balances = account.getBalances();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Exception handling
|
|
||||||
```java
|
|
||||||
try {
|
|
||||||
Depth depth = client.getDepth("invalid symbol"));
|
|
||||||
} catch (ClientErrorException e) {
|
|
||||||
int httpStatusCode = e.getHttpStatusCode();
|
|
||||||
String errorCode = e.getErrorDetails().getCode();
|
|
||||||
String errorMessage = e.getErrorDetails().getMsg();
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us.
|
|
||||||
|
|
||||||
## Versioning
|
|
||||||
|
|
||||||
We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/johnsiu/binance-java-client/tags).
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
This project is released into the public domain - see the [UNLICENSE](UNLICENSE) file for details.
|
|
@ -1,24 +0,0 @@
|
|||||||
This is free and unencumbered software released into the public domain.
|
|
||||||
|
|
||||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
|
||||||
distribute this software, either in source code form or as a compiled
|
|
||||||
binary, for any purpose, commercial or non-commercial, and by any
|
|
||||||
means.
|
|
||||||
|
|
||||||
In jurisdictions that recognize copyright laws, the author or authors
|
|
||||||
of this software dedicate any and all copyright interest in the
|
|
||||||
software to the public domain. We make this dedication for the benefit
|
|
||||||
of the public at large and to the detriment of our heirs and
|
|
||||||
successors. We intend this dedication to be an overt act of
|
|
||||||
relinquishment in perpetuity of all present and future rights to this
|
|
||||||
software under copyright law.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
||||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
||||||
OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
For more information, please refer to <http://unlicense.org/>
|
|
@ -1,83 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<groupId>com.github.johnsiu</groupId>
|
|
||||||
<artifactId>binance-java-client</artifactId>
|
|
||||||
<version>1.0.1</version>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<jackson-version>2.9.1</jackson-version>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<distributionManagement>
|
|
||||||
<repository>
|
|
||||||
<id>bintray-repo-binance-java-client</id>
|
|
||||||
<url>https://api.bintray.com/maven/johnsiu/maven-repo/binance-java-client/;publish=1</url>
|
|
||||||
</repository>
|
|
||||||
</distributionManagement>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<source>1.8</source>
|
|
||||||
<target>1.8</target>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-source-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>attach-sources</id>
|
|
||||||
<phase>verify</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>jar-no-fork</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.asynchttpclient</groupId>
|
|
||||||
<artifactId>async-http-client</artifactId>
|
|
||||||
<version>2.0.37</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.guava</groupId>
|
|
||||||
<artifactId>guava</artifactId>
|
|
||||||
<version>23.1-jre</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
|
||||||
<artifactId>jackson-databind</artifactId>
|
|
||||||
<version>${jackson-version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
|
||||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
|
||||||
<version>${jackson-version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.inject</groupId>
|
|
||||||
<artifactId>guice</artifactId>
|
|
||||||
<version>4.1.0</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<version>4.12</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
|
@ -1,29 +0,0 @@
|
|||||||
package com.github.johnsiu.binance.deser;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonParser;
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
|
||||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
|
||||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
|
||||||
import com.github.johnsiu.binance.models.Account.Balance;
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
import com.google.common.collect.ImmutableMap.Builder;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Jackson deserializer for turning an array of balances into a map of asset to balance.
|
|
||||||
*/
|
|
||||||
public class BalanceMapDeserializer extends JsonDeserializer<Map<String, Balance>> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, Balance> deserialize(JsonParser p, DeserializationContext ctxt)
|
|
||||||
throws IOException, JsonProcessingException {
|
|
||||||
List<Balance> balances = p.readValueAs(new TypeReference<List<Balance>>() {
|
|
||||||
});
|
|
||||||
Builder<String, Balance> builder = ImmutableMap.<String, Balance>builder();
|
|
||||||
balances.forEach(balance -> builder.put(balance.getAsset(), balance));
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
package com.github.johnsiu.binance.exceptions;
|
|
||||||
|
|
||||||
import com.github.johnsiu.binance.models.ErrorDetails;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exception thrown when Binance API returned an HTTP 4xx client error.
|
|
||||||
*/
|
|
||||||
public class ClientErrorException extends RuntimeException {
|
|
||||||
|
|
||||||
private int httpStatusCode;
|
|
||||||
// error message from Binance API.
|
|
||||||
private ErrorDetails errorDetails;
|
|
||||||
|
|
||||||
public ClientErrorException(int httpStatusCode, ErrorDetails errorDetails) {
|
|
||||||
super(errorDetails.getMsg());
|
|
||||||
this.httpStatusCode = httpStatusCode;
|
|
||||||
this.errorDetails = errorDetails;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getHttpStatusCode() {
|
|
||||||
return httpStatusCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ErrorDetails getErrorDetails() {
|
|
||||||
return errorDetails;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,69 +0,0 @@
|
|||||||
package com.github.johnsiu.binance.httpclients;
|
|
||||||
|
|
||||||
import com.github.johnsiu.binance.models.Account;
|
|
||||||
import com.github.johnsiu.binance.models.CancelOrder;
|
|
||||||
import com.github.johnsiu.binance.models.Depth;
|
|
||||||
import com.github.johnsiu.binance.models.Keys;
|
|
||||||
import com.github.johnsiu.binance.models.Order;
|
|
||||||
import com.github.johnsiu.binance.models.Order.OrderSide;
|
|
||||||
import com.github.johnsiu.binance.models.Order.TimeInForce;
|
|
||||||
import com.github.johnsiu.binance.models.OrderStatus;
|
|
||||||
import com.github.johnsiu.binance.models.Ticker;
|
|
||||||
import com.google.inject.ImplementedBy;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CompletionStage;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Async client for accessing Binance API.
|
|
||||||
*/
|
|
||||||
@ImplementedBy(AsyncBinanceClientImpl.class)
|
|
||||||
public interface AsyncBinanceClient {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the ticker given the symbol.
|
|
||||||
*/
|
|
||||||
CompletionStage<Ticker> getTicker(String symbol);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the depth given the symbol. Limit defaults to 100.
|
|
||||||
*/
|
|
||||||
CompletionStage<Depth> getDepth(String symbol);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the depth given the symbol and limit.
|
|
||||||
*/
|
|
||||||
CompletionStage<Depth> getDepth(String symbol, int limit);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Place a LIMIT order.
|
|
||||||
*/
|
|
||||||
CompletionStage<Order> placeLimitOrder(Keys keys, String symbol, OrderSide side,
|
|
||||||
TimeInForce timeInForce, double quantity, double price);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Place a MARKET order.
|
|
||||||
*/
|
|
||||||
CompletionStage<Order> placeMarketOrder(Keys keys, String symbol, OrderSide side,
|
|
||||||
double quantity);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check the status of an order.
|
|
||||||
*/
|
|
||||||
CompletionStage<OrderStatus> checkOrderStatus(Keys keys, Order order);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cancel an order.
|
|
||||||
*/
|
|
||||||
CompletionStage<CancelOrder> cancelOrder(Keys keys, Order order);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all open orders.
|
|
||||||
*/
|
|
||||||
CompletionStage<List<OrderStatus>> getOpenOrders(Keys keys, String symbol);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get account info.
|
|
||||||
*/
|
|
||||||
CompletionStage<Account> getAccount(Keys keys);
|
|
||||||
|
|
||||||
}
|
|
@ -1,223 +0,0 @@
|
|||||||
package com.github.johnsiu.binance.httpclients;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.github.johnsiu.binance.exceptions.ClientErrorException;
|
|
||||||
import com.github.johnsiu.binance.inject.BinanceClientModule;
|
|
||||||
import com.github.johnsiu.binance.models.Account;
|
|
||||||
import com.github.johnsiu.binance.models.CancelOrder;
|
|
||||||
import com.github.johnsiu.binance.models.Depth;
|
|
||||||
import com.github.johnsiu.binance.models.ErrorDetails;
|
|
||||||
import com.github.johnsiu.binance.models.Keys;
|
|
||||||
import com.github.johnsiu.binance.models.Order;
|
|
||||||
import com.github.johnsiu.binance.models.Order.OrderSide;
|
|
||||||
import com.github.johnsiu.binance.models.Order.OrderType;
|
|
||||||
import com.github.johnsiu.binance.models.Order.TimeInForce;
|
|
||||||
import com.github.johnsiu.binance.models.OrderStatus;
|
|
||||||
import com.github.johnsiu.binance.models.Ticker;
|
|
||||||
import io.netty.handler.codec.http.HttpMethod;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.security.InvalidKeyException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.CompletionException;
|
|
||||||
import java.util.concurrent.CompletionStage;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import javax.crypto.Mac;
|
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Named;
|
|
||||||
import org.asynchttpclient.AsyncHttpClient;
|
|
||||||
import org.asynchttpclient.BoundRequestBuilder;
|
|
||||||
import org.asynchttpclient.Response;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Concrete implementation of {@link AsyncBinanceClient}.
|
|
||||||
*/
|
|
||||||
public class AsyncBinanceClientImpl implements AsyncBinanceClient {
|
|
||||||
|
|
||||||
private static final String HMAC_SHA256 = "HmacSHA256";
|
|
||||||
private static final String APIKEY_HEADER = "X-MBX-APIKEY";
|
|
||||||
private static final String ORDER_ENDPOINT = "order";
|
|
||||||
private static final String OPEN_ORDERS_ENDPOINT = "openOrders";
|
|
||||||
private static final String ACCOUNT_ENDPOINT = "account";
|
|
||||||
private final String API_URL = "https://www.binance.com/api/v1/";
|
|
||||||
private final String API_V3_URL = "https://www.binance.com/api/v3/";
|
|
||||||
private final AsyncHttpClient asyncHttpClient;
|
|
||||||
private final ObjectMapper objectMapper;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public AsyncBinanceClientImpl(AsyncHttpClient asyncHttpClient,
|
|
||||||
@Named(BinanceClientModule.BINANCE_CLIENT) ObjectMapper objectMapper) {
|
|
||||||
this.asyncHttpClient = asyncHttpClient;
|
|
||||||
this.objectMapper = objectMapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletionStage<Ticker> getTicker(String symbol) {
|
|
||||||
|
|
||||||
return handleResponse(
|
|
||||||
asyncHttpClient.prepareGet(API_URL + "ticker/24hr?symbol=" + symbol).execute()
|
|
||||||
.toCompletableFuture(), new TypeReference<Ticker>() {
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletionStage<Depth> getDepth(String symbol) {
|
|
||||||
return getDepth(symbol, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletionStage<Depth> getDepth(String symbol, int limit) {
|
|
||||||
|
|
||||||
return handleResponse(asyncHttpClient.prepareGet(API_URL + "depth?symbol=" + symbol).execute()
|
|
||||||
.toCompletableFuture(), new TypeReference<Depth>() {
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletionStage<Order> placeLimitOrder(Keys keys, String symbol, OrderSide side,
|
|
||||||
TimeInForce timeInForce, double quantity, double price) {
|
|
||||||
|
|
||||||
String queryStr = String.format(
|
|
||||||
"symbol=%s&side=%s&type=%s&timeInForce=%s&quantity=%f&price=%f×tamp=%d",
|
|
||||||
symbol, side.name(), OrderType.LIMIT, timeInForce.name(), quantity, price,
|
|
||||||
System.currentTimeMillis());
|
|
||||||
|
|
||||||
return makeSignedRequest(keys, HttpMethod.POST, ORDER_ENDPOINT, queryStr,
|
|
||||||
new TypeReference<Order>() {
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletionStage<Order> placeMarketOrder(Keys keys, String symbol, OrderSide side,
|
|
||||||
double quantity) {
|
|
||||||
|
|
||||||
String queryStr = String.format(
|
|
||||||
"symbol=%s&side=%s&type=%s&quantity=%f×tamp=%d",
|
|
||||||
symbol, side.name(), OrderType.MARKET, quantity,
|
|
||||||
System.currentTimeMillis());
|
|
||||||
|
|
||||||
return makeSignedRequest(keys, HttpMethod.POST, ORDER_ENDPOINT, queryStr,
|
|
||||||
new TypeReference<Order>() {
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletionStage<OrderStatus> checkOrderStatus(Keys keys, Order order) {
|
|
||||||
|
|
||||||
String queryStr = String.format(
|
|
||||||
"symbol=%s&orderId=%d&origClientOrderId=%s×tamp=%d",
|
|
||||||
order.getSymbol(), order.getOrderId(), order.getClientOrderId(),
|
|
||||||
System.currentTimeMillis());
|
|
||||||
|
|
||||||
return makeSignedRequest(keys, HttpMethod.GET, ORDER_ENDPOINT, queryStr,
|
|
||||||
new TypeReference<OrderStatus>() {
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletionStage<CancelOrder> cancelOrder(Keys keys, Order order) {
|
|
||||||
|
|
||||||
String queryStr = String.format(
|
|
||||||
"symbol=%s&orderId=%d&origClientOrderId=%s×tamp=%d",
|
|
||||||
order.getSymbol(), order.getOrderId(), order.getClientOrderId(),
|
|
||||||
System.currentTimeMillis());
|
|
||||||
return makeSignedRequest(keys, HttpMethod.DELETE, ORDER_ENDPOINT, queryStr,
|
|
||||||
new TypeReference<CancelOrder>() {
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletionStage<List<OrderStatus>> getOpenOrders(Keys keys, String symbol) {
|
|
||||||
|
|
||||||
String queryStr = String.format(
|
|
||||||
"symbol=%s×tamp=%d", symbol, System.currentTimeMillis());
|
|
||||||
|
|
||||||
return makeSignedRequest(keys, HttpMethod.GET, OPEN_ORDERS_ENDPOINT, queryStr,
|
|
||||||
new TypeReference<List<OrderStatus>>() {
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletionStage<Account> getAccount(Keys keys) {
|
|
||||||
|
|
||||||
String queryStr = String.format(
|
|
||||||
"timestamp=%d", System.currentTimeMillis());
|
|
||||||
|
|
||||||
return makeSignedRequest(keys, HttpMethod.GET, ACCOUNT_ENDPOINT, queryStr,
|
|
||||||
new TypeReference<Account>() {
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T> CompletionStage<T> makeSignedRequest(Keys keys, HttpMethod method, String endpoint,
|
|
||||||
String queryStr, TypeReference<T> typeReference) {
|
|
||||||
|
|
||||||
return CompletableFuture.supplyAsync(() -> {
|
|
||||||
try {
|
|
||||||
String signature = signQueryString(keys, queryStr);
|
|
||||||
String url = API_V3_URL + endpoint + "?" + queryStr + "&signature=" + signature;
|
|
||||||
BoundRequestBuilder boundRequestBuilder;
|
|
||||||
if (method == HttpMethod.GET) {
|
|
||||||
boundRequestBuilder = asyncHttpClient.prepareGet(url);
|
|
||||||
} else if (method == HttpMethod.POST) {
|
|
||||||
boundRequestBuilder = asyncHttpClient.preparePost(url);
|
|
||||||
} else if (method == HttpMethod.DELETE) {
|
|
||||||
boundRequestBuilder = asyncHttpClient.prepareDelete(url);
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Unsupported method: " + method);
|
|
||||||
}
|
|
||||||
return handleResponse(boundRequestBuilder
|
|
||||||
.addHeader(
|
|
||||||
APIKEY_HEADER, keys.getApiKey())
|
|
||||||
.execute().toCompletableFuture(), typeReference);
|
|
||||||
} catch (UnsupportedEncodingException | NoSuchAlgorithmException | InvalidKeyException e) {
|
|
||||||
throw new CompletionException(e);
|
|
||||||
}
|
|
||||||
}).thenCompose(Function.identity());
|
|
||||||
}
|
|
||||||
|
|
||||||
private String signQueryString(Keys keys, String queryString)
|
|
||||||
throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
|
|
||||||
|
|
||||||
byte[] byteKey = keys.getSecretKey().getBytes("UTF-8");
|
|
||||||
Mac sha256HMAC = Mac.getInstance(HMAC_SHA256);
|
|
||||||
sha256HMAC.init(new SecretKeySpec(byteKey, HMAC_SHA256));
|
|
||||||
return bytesToHex(sha256HMAC.doFinal(queryString.getBytes("UTF-8")));
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T> CompletionStage<T> handleResponse(CompletableFuture<Response> responseFuture,
|
|
||||||
TypeReference<T> typeReference) {
|
|
||||||
|
|
||||||
return responseFuture.thenApply(response -> {
|
|
||||||
try {
|
|
||||||
if (response.getStatusCode() >= 400) {
|
|
||||||
throw new ClientErrorException(response.getStatusCode(),
|
|
||||||
objectMapper.readValue(response.getResponseBody(), ErrorDetails.class));
|
|
||||||
}
|
|
||||||
return objectMapper.readValue(response.getResponseBody(), typeReference);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new CompletionException(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
final private static char[] hexArray = "0123456789ABCDEF"
|
|
||||||
.toCharArray();
|
|
||||||
|
|
||||||
private String bytesToHex(byte[] bytes) {
|
|
||||||
|
|
||||||
char[] hexChars = new char[bytes.length * 2];
|
|
||||||
int v;
|
|
||||||
for (int j = 0; j < bytes.length; j++) {
|
|
||||||
v = bytes[j] & 0xFF;
|
|
||||||
hexChars[j * 2] = hexArray[v >>> 4];
|
|
||||||
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
|
|
||||||
}
|
|
||||||
return new String(hexChars);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
package com.github.johnsiu.binance.httpclients;
|
|
||||||
|
|
||||||
import com.github.johnsiu.binance.models.Account;
|
|
||||||
import com.github.johnsiu.binance.models.CancelOrder;
|
|
||||||
import com.github.johnsiu.binance.models.Depth;
|
|
||||||
import com.github.johnsiu.binance.models.Keys;
|
|
||||||
import com.github.johnsiu.binance.models.Order;
|
|
||||||
import com.github.johnsiu.binance.models.Order.OrderSide;
|
|
||||||
import com.github.johnsiu.binance.models.Order.TimeInForce;
|
|
||||||
import com.github.johnsiu.binance.models.OrderStatus;
|
|
||||||
import com.github.johnsiu.binance.models.Ticker;
|
|
||||||
import com.google.inject.ImplementedBy;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Client for accessing Binance API.
|
|
||||||
*/
|
|
||||||
@ImplementedBy(BinanceClientImpl.class)
|
|
||||||
public interface BinanceClient {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the ticker given the symbol.
|
|
||||||
*/
|
|
||||||
Ticker getTicker(String symbol);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the depth given the symbol. Limit defaults to 100.
|
|
||||||
*/
|
|
||||||
Depth getDepth(String symbol);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the depth given the symbol and limit.
|
|
||||||
*/
|
|
||||||
Depth getDepth(String symbol, int limit);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Place a LIMIT order.
|
|
||||||
*/
|
|
||||||
Order placeLimitOrder(Keys keys, String symbol, OrderSide side,
|
|
||||||
TimeInForce timeInForce, double quantity, double price);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Place a MARKET order.
|
|
||||||
*/
|
|
||||||
Order placeMarketOrder(Keys keys, String symbol, OrderSide side,
|
|
||||||
double quantity);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check the status of an order.
|
|
||||||
*/
|
|
||||||
OrderStatus checkOrderStatus(Keys keys, Order order);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cancel an order.
|
|
||||||
*/
|
|
||||||
CancelOrder cancelOrder(Keys keys, Order order);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all open orders.
|
|
||||||
*/
|
|
||||||
List<OrderStatus> getOpenOrders(Keys keys, String symbol);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get account info.
|
|
||||||
*/
|
|
||||||
Account getAccount(Keys keys);
|
|
||||||
|
|
||||||
}
|
|
@ -1,90 +0,0 @@
|
|||||||
package com.github.johnsiu.binance.httpclients;
|
|
||||||
|
|
||||||
import com.github.johnsiu.binance.models.Account;
|
|
||||||
import com.github.johnsiu.binance.models.CancelOrder;
|
|
||||||
import com.github.johnsiu.binance.models.Depth;
|
|
||||||
import com.github.johnsiu.binance.models.Keys;
|
|
||||||
import com.github.johnsiu.binance.models.Order;
|
|
||||||
import com.github.johnsiu.binance.models.Order.OrderSide;
|
|
||||||
import com.github.johnsiu.binance.models.Order.TimeInForce;
|
|
||||||
import com.github.johnsiu.binance.models.OrderStatus;
|
|
||||||
import com.github.johnsiu.binance.models.Ticker;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CompletionException;
|
|
||||||
import java.util.concurrent.CompletionStage;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Concrete implementation of {@link BinanceClient}.
|
|
||||||
*/
|
|
||||||
public class BinanceClientImpl implements BinanceClient {
|
|
||||||
|
|
||||||
private final AsyncBinanceClient asyncBinanceClient;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public BinanceClientImpl(AsyncBinanceClient asyncBinanceClient) {
|
|
||||||
this.asyncBinanceClient = asyncBinanceClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Ticker getTicker(String symbol) {
|
|
||||||
return joinAsync(asyncBinanceClient.getTicker(symbol));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Depth getDepth(String symbol) {
|
|
||||||
return joinAsync(asyncBinanceClient.getDepth(symbol));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Depth getDepth(String symbol, int limit) {
|
|
||||||
return joinAsync(asyncBinanceClient.getDepth(symbol, limit));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Order placeLimitOrder(Keys keys, String symbol, OrderSide side,
|
|
||||||
TimeInForce timeInForce, double quantity, double price) {
|
|
||||||
return joinAsync(
|
|
||||||
asyncBinanceClient.placeLimitOrder(keys, symbol, side, timeInForce, quantity, price)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Order placeMarketOrder(Keys keys, String symbol, OrderSide side,
|
|
||||||
double quantity) {
|
|
||||||
return joinAsync(
|
|
||||||
asyncBinanceClient.placeMarketOrder(keys, symbol, side, quantity)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public OrderStatus checkOrderStatus(Keys keys, Order order) {
|
|
||||||
return joinAsync(asyncBinanceClient.checkOrderStatus(keys, order));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CancelOrder cancelOrder(Keys keys, Order order) {
|
|
||||||
return joinAsync(asyncBinanceClient.cancelOrder(keys, order));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<OrderStatus> getOpenOrders(Keys keys, String symbol) {
|
|
||||||
return joinAsync(asyncBinanceClient.getOpenOrders(keys, symbol));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Account getAccount(Keys keys) {
|
|
||||||
return joinAsync(asyncBinanceClient.getAccount(keys));
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T> T joinAsync(CompletionStage<T> completionStage) {
|
|
||||||
try {
|
|
||||||
return completionStage.toCompletableFuture().join();
|
|
||||||
} catch (CompletionException e) {
|
|
||||||
if (e.getCause() instanceof RuntimeException) {
|
|
||||||
throw (RuntimeException) e.getCause();
|
|
||||||
}
|
|
||||||
throw new RuntimeException(e.getCause());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
package com.github.johnsiu.binance.inject;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.google.inject.AbstractModule;
|
|
||||||
import com.google.inject.name.Names;
|
|
||||||
import org.asynchttpclient.AsyncHttpClient;
|
|
||||||
import org.asynchttpclient.DefaultAsyncHttpClient;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Guice module for dependency injection.
|
|
||||||
*/
|
|
||||||
public class BinanceClientModule extends AbstractModule {
|
|
||||||
|
|
||||||
public static final String BINANCE_CLIENT = "BinanceClient";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure() {
|
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
|
||||||
bind(ObjectMapper.class)
|
|
||||||
.annotatedWith(Names.named(BINANCE_CLIENT))
|
|
||||||
.toInstance(objectMapper);
|
|
||||||
bind(AsyncHttpClient.class).to(DefaultAsyncHttpClient.class);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,98 +0,0 @@
|
|||||||
package com.github.johnsiu.binance.models;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
|
||||||
import java.util.Map;
|
|
||||||
import com.github.johnsiu.binance.deser.BalanceMapDeserializer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents an account info.
|
|
||||||
*/
|
|
||||||
public class Account {
|
|
||||||
|
|
||||||
private int makerCommission;
|
|
||||||
private int takerCommission;
|
|
||||||
private int buyerCommission;
|
|
||||||
private int sellerCommission;
|
|
||||||
private boolean canTrade;
|
|
||||||
private boolean canWithdraw;
|
|
||||||
private boolean canDeposit;
|
|
||||||
// asset to Balance
|
|
||||||
private Map<String, Balance> balances;
|
|
||||||
|
|
||||||
public int getMakerCommission() {
|
|
||||||
return makerCommission;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTakerCommission() {
|
|
||||||
return takerCommission;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getBuyerCommission() {
|
|
||||||
return buyerCommission;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSellerCommission() {
|
|
||||||
return sellerCommission;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isCanTrade() {
|
|
||||||
return canTrade;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isCanWithdraw() {
|
|
||||||
return canWithdraw;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isCanDeposit() {
|
|
||||||
return canDeposit;
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonDeserialize(using = BalanceMapDeserializer.class)
|
|
||||||
public Map<String, Balance> getBalances() {
|
|
||||||
return balances;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Account{" +
|
|
||||||
"makerCommission=" + makerCommission +
|
|
||||||
", takerCommission=" + takerCommission +
|
|
||||||
", buyerCommission=" + buyerCommission +
|
|
||||||
", sellerCommission=" + sellerCommission +
|
|
||||||
", canTrade=" + canTrade +
|
|
||||||
", canWithdraw=" + canWithdraw +
|
|
||||||
", canDeposit=" + canDeposit +
|
|
||||||
", balances=" + balances +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Balance {
|
|
||||||
|
|
||||||
private String asset;
|
|
||||||
private double free;
|
|
||||||
private double locked;
|
|
||||||
|
|
||||||
public String getAsset() {
|
|
||||||
return asset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getFree() {
|
|
||||||
return free;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getLocked() {
|
|
||||||
return locked;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Balance{" +
|
|
||||||
"asset='" + asset + '\'' +
|
|
||||||
", free=" + free +
|
|
||||||
", locked=" + locked +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
|||||||
package com.github.johnsiu.binance.models;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a cancel order.
|
|
||||||
*/
|
|
||||||
public class CancelOrder {
|
|
||||||
|
|
||||||
private String symbol;
|
|
||||||
private long orderId;
|
|
||||||
private String origClientOrderId;
|
|
||||||
private String clientOrderId;
|
|
||||||
|
|
||||||
public String getSymbol() {
|
|
||||||
return symbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getOrderId() {
|
|
||||||
return orderId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getOrigClientOrderId() {
|
|
||||||
return origClientOrderId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClientOrderId() {
|
|
||||||
return clientOrderId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "CancelOrder{" +
|
|
||||||
"symbol='" + symbol + '\'' +
|
|
||||||
", orderId=" + orderId +
|
|
||||||
", origClientOrderId='" + origClientOrderId + '\'' +
|
|
||||||
", clientOrderId='" + clientOrderId + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
package com.github.johnsiu.binance.models;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.google.common.collect.ImmutableList.Builder;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents depth of a symbol.
|
|
||||||
*/
|
|
||||||
public class Depth {
|
|
||||||
|
|
||||||
private long lastUpdateId;
|
|
||||||
private List<PriceQuantity> bids;
|
|
||||||
private List<PriceQuantity> asks;
|
|
||||||
|
|
||||||
@JsonCreator
|
|
||||||
public Depth(@JsonProperty("lastUpdateId") long lastUpdateId, @JsonProperty("bids") List<?> bids,
|
|
||||||
@JsonProperty("asks") List<?> asks) {
|
|
||||||
this.lastUpdateId = lastUpdateId;
|
|
||||||
|
|
||||||
Function<List<?>, List<PriceQuantity>> buildOrdersFunc = (orders) -> {
|
|
||||||
Builder<PriceQuantity> ordersBuilder = ImmutableList.<PriceQuantity>builder();
|
|
||||||
if (orders != null && orders.size() >= 2) {
|
|
||||||
orders.forEach(value -> {
|
|
||||||
Iterator iterator = Collection.class.cast(value).iterator();
|
|
||||||
ordersBuilder.add(new PriceQuantity(Double.valueOf((String) iterator.next()),
|
|
||||||
Double.valueOf((String) iterator.next())));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return ordersBuilder.build();
|
|
||||||
};
|
|
||||||
this.bids = buildOrdersFunc.apply(bids);
|
|
||||||
this.asks = buildOrdersFunc.apply(asks);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getLastUpdateId() {
|
|
||||||
return lastUpdateId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<PriceQuantity> getBids() {
|
|
||||||
return bids;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<PriceQuantity> getAsks() {
|
|
||||||
return asks;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Depth{" +
|
|
||||||
"lastUpdateId=" + lastUpdateId +
|
|
||||||
", bids=" + bids +
|
|
||||||
", asks=" + asks +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
package com.github.johnsiu.binance.models;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents an error from Binance API.
|
|
||||||
*/
|
|
||||||
public class ErrorDetails {
|
|
||||||
|
|
||||||
private long code;
|
|
||||||
private String msg;
|
|
||||||
|
|
||||||
public long getCode() {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMsg() {
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "ErrorDetails{" +
|
|
||||||
"code=" + code +
|
|
||||||
", msg='" + msg + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
package com.github.johnsiu.binance.models;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents API key and secret key for accessing SIGNED endpoints.
|
|
||||||
*/
|
|
||||||
public class Keys {
|
|
||||||
|
|
||||||
private String apiKey;
|
|
||||||
private String secretKey;
|
|
||||||
|
|
||||||
public Keys(String apiKey, String secretKey) {
|
|
||||||
this.apiKey = apiKey;
|
|
||||||
this.secretKey = secretKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getApiKey() {
|
|
||||||
return apiKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSecretKey() {
|
|
||||||
return secretKey;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
package com.github.johnsiu.binance.models;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents an Order. Can be cancelled.
|
|
||||||
*/
|
|
||||||
public class Order {
|
|
||||||
|
|
||||||
private String symbol;
|
|
||||||
private long orderId;
|
|
||||||
private String clientOrderId;
|
|
||||||
private Date transactTime;
|
|
||||||
|
|
||||||
public String getSymbol() {
|
|
||||||
return symbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getOrderId() {
|
|
||||||
return orderId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClientOrderId() {
|
|
||||||
return clientOrderId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getTransactTime() {
|
|
||||||
return transactTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Order{" +
|
|
||||||
"symbol='" + symbol + '\'' +
|
|
||||||
", orderId=" + orderId +
|
|
||||||
", clientOrderId='" + clientOrderId + '\'' +
|
|
||||||
", transactTime=" + transactTime +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum OrderSide {
|
|
||||||
BUY, SELL
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum OrderType {
|
|
||||||
LIMIT, MARKET
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum TimeInForce {
|
|
||||||
// Good Till Cancel
|
|
||||||
GTC,
|
|
||||||
// Immediate or Cancel
|
|
||||||
IOC
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,86 +0,0 @@
|
|||||||
package com.github.johnsiu.binance.models;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents an order status. Can be cancelled.
|
|
||||||
*/
|
|
||||||
public class OrderStatus extends Order {
|
|
||||||
|
|
||||||
private String price;
|
|
||||||
private String origQty;
|
|
||||||
private String executedQty;
|
|
||||||
private Status status;
|
|
||||||
private TimeInForce timeInForce;
|
|
||||||
private OrderType type;
|
|
||||||
private OrderSide side;
|
|
||||||
private String stopPrice;
|
|
||||||
private String icebergQty;
|
|
||||||
private Date time;
|
|
||||||
|
|
||||||
public String getPrice() {
|
|
||||||
return price;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getOrigQty() {
|
|
||||||
return origQty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getExecutedQty() {
|
|
||||||
return executedQty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Status getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TimeInForce getTimeInForce() {
|
|
||||||
return timeInForce;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OrderType getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OrderSide getSide() {
|
|
||||||
return side;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStopPrice() {
|
|
||||||
return stopPrice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getIcebergQty() {
|
|
||||||
return icebergQty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getTime() {
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "OrderStatus{" +
|
|
||||||
"price='" + price + '\'' +
|
|
||||||
", origQty='" + origQty + '\'' +
|
|
||||||
", executedQty='" + executedQty + '\'' +
|
|
||||||
", status=" + status +
|
|
||||||
", timeInForce=" + timeInForce +
|
|
||||||
", type=" + type +
|
|
||||||
", side=" + side +
|
|
||||||
", stopPrice='" + stopPrice + '\'' +
|
|
||||||
", icebergQty='" + icebergQty + '\'' +
|
|
||||||
", time=" + time +
|
|
||||||
"} " + super.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum Status {
|
|
||||||
NEW,
|
|
||||||
PARTIALLY_FILLED,
|
|
||||||
FILLED,
|
|
||||||
CANCELED,
|
|
||||||
PENDING_CANCEL,
|
|
||||||
REJECTED,
|
|
||||||
EXPIRED
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
package com.github.johnsiu.binance.models;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents price and quantity of a bid or an ask.
|
|
||||||
*/
|
|
||||||
public class PriceQuantity {
|
|
||||||
|
|
||||||
private double price;
|
|
||||||
private double quantity;
|
|
||||||
|
|
||||||
public PriceQuantity(double price, double quantity) {
|
|
||||||
this.price = price;
|
|
||||||
this.quantity = quantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getPrice() {
|
|
||||||
return price;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getQuantity() {
|
|
||||||
return quantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "PriceQuantity{" +
|
|
||||||
"price=" + price +
|
|
||||||
", quantity=" + quantity +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,137 +0,0 @@
|
|||||||
package com.github.johnsiu.binance.models;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a ticker of a symbol.
|
|
||||||
*/
|
|
||||||
public class Ticker {
|
|
||||||
|
|
||||||
private double priceChange;
|
|
||||||
private double priceChangePercent;
|
|
||||||
private double weightedAvgPrice;
|
|
||||||
private double prevClosePrice;
|
|
||||||
private double lastPrice;
|
|
||||||
private double lastQty;
|
|
||||||
private double bidPrice;
|
|
||||||
private double bidQty;
|
|
||||||
private double askPrice;
|
|
||||||
private double askQty;
|
|
||||||
private double openPrice;
|
|
||||||
private double highPrice;
|
|
||||||
private double lowPrice;
|
|
||||||
private double volume;
|
|
||||||
private double quoteVolume;
|
|
||||||
private Date openTime;
|
|
||||||
private Date closeTime;
|
|
||||||
private long firstId;
|
|
||||||
private long lastId;
|
|
||||||
private long count;
|
|
||||||
|
|
||||||
public double getPriceChange() {
|
|
||||||
return priceChange;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getPriceChangePercent() {
|
|
||||||
return priceChangePercent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getWeightedAvgPrice() {
|
|
||||||
return weightedAvgPrice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getPrevClosePrice() {
|
|
||||||
return prevClosePrice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getLastPrice() {
|
|
||||||
return lastPrice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getLastQty() {
|
|
||||||
return lastQty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getBidPrice() {
|
|
||||||
return bidPrice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getBidQty() {
|
|
||||||
return bidQty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getAskPrice() {
|
|
||||||
return askPrice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getAskQty() {
|
|
||||||
return askQty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getOpenPrice() {
|
|
||||||
return openPrice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getHighPrice() {
|
|
||||||
return highPrice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getLowPrice() {
|
|
||||||
return lowPrice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getVolume() {
|
|
||||||
return volume;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getQuoteVolume() {
|
|
||||||
return quoteVolume;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getOpenTime() {
|
|
||||||
return openTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getCloseTime() {
|
|
||||||
return closeTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getFirstId() {
|
|
||||||
return firstId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getLastId() {
|
|
||||||
return lastId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getCount() {
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Ticker{" +
|
|
||||||
"priceChange=" + priceChange +
|
|
||||||
", priceChangePercent=" + priceChangePercent +
|
|
||||||
", weightedAvgPrice=" + weightedAvgPrice +
|
|
||||||
", prevClosePrice=" + prevClosePrice +
|
|
||||||
", lastPrice=" + lastPrice +
|
|
||||||
", lastQty=" + lastQty +
|
|
||||||
", bidPrice=" + bidPrice +
|
|
||||||
", bidQty=" + bidQty +
|
|
||||||
", askPrice=" + askPrice +
|
|
||||||
", askQty=" + askQty +
|
|
||||||
", openPrice=" + openPrice +
|
|
||||||
", highPrice=" + highPrice +
|
|
||||||
", lowPrice=" + lowPrice +
|
|
||||||
", volume=" + volume +
|
|
||||||
", quoteVolume=" + quoteVolume +
|
|
||||||
", openTime=" + openTime +
|
|
||||||
", closeTime=" + closeTime +
|
|
||||||
", firstId=" + firstId +
|
|
||||||
", lastId=" + lastId +
|
|
||||||
", count=" + count +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,87 +0,0 @@
|
|||||||
package com.github.johnsiu.binance.httpclients;
|
|
||||||
|
|
||||||
import com.github.johnsiu.binance.exceptions.ClientErrorException;
|
|
||||||
import com.github.johnsiu.binance.inject.BinanceClientModule;
|
|
||||||
import com.github.johnsiu.binance.models.Account;
|
|
||||||
import com.github.johnsiu.binance.models.Depth;
|
|
||||||
import com.github.johnsiu.binance.models.Keys;
|
|
||||||
import com.github.johnsiu.binance.models.Order;
|
|
||||||
import com.github.johnsiu.binance.models.Order.OrderSide;
|
|
||||||
import com.github.johnsiu.binance.models.Order.TimeInForce;
|
|
||||||
import com.github.johnsiu.binance.models.OrderStatus;
|
|
||||||
import com.google.inject.Guice;
|
|
||||||
import com.google.inject.Injector;
|
|
||||||
import java.util.List;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test case for {@link BinanceClientImpl}
|
|
||||||
*/
|
|
||||||
public class BinanceClientImplTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetTicker() {
|
|
||||||
Injector injector = Guice.createInjector(new BinanceClientModule());
|
|
||||||
BinanceClient client = injector.getInstance(BinanceClient.class);
|
|
||||||
|
|
||||||
Assert.assertNotNull(client.getTicker("ETHBTC"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetDepth() {
|
|
||||||
Injector injector = Guice.createInjector(new BinanceClientModule());
|
|
||||||
BinanceClient client = injector.getInstance(BinanceClient.class);
|
|
||||||
|
|
||||||
Assert.assertNotNull(client.getDepth("ETHBTC"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetDepthError() {
|
|
||||||
Injector injector = Guice.createInjector(new BinanceClientModule());
|
|
||||||
BinanceClient client = injector.getInstance(BinanceClient.class);
|
|
||||||
|
|
||||||
try {
|
|
||||||
Depth depth = client.getDepth("ETHBT");
|
|
||||||
Assert.fail();
|
|
||||||
} catch (Exception e) {
|
|
||||||
ClientErrorException cast = (ClientErrorException) e;
|
|
||||||
Assert.assertEquals("Invalid symbol.", cast.getErrorDetails().getMsg());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testOrder() {
|
|
||||||
Injector injector = Guice.createInjector(new BinanceClientModule());
|
|
||||||
BinanceClient client = injector.getInstance(BinanceClient.class);
|
|
||||||
|
|
||||||
Keys keys = new Keys(System.getProperty("apiKey"),
|
|
||||||
System.getProperty("secretKey"));
|
|
||||||
String symbol = "MCOETH";
|
|
||||||
Order order = client
|
|
||||||
.placeLimitOrder(keys, symbol, OrderSide.BUY, TimeInForce.GTC, 1, 0.020041);
|
|
||||||
Assert.assertNotNull(order);
|
|
||||||
|
|
||||||
OrderStatus orderStatus = client.checkOrderStatus(keys, order);
|
|
||||||
Assert.assertNotNull(orderStatus);
|
|
||||||
|
|
||||||
List<OrderStatus> openOrders = client.getOpenOrders(keys, symbol);
|
|
||||||
Assert.assertFalse(openOrders.isEmpty());
|
|
||||||
|
|
||||||
openOrders.forEach(openOrder -> client.cancelOrder(keys, openOrder));
|
|
||||||
|
|
||||||
openOrders = client.getOpenOrders(keys, symbol);
|
|
||||||
Assert.assertTrue(openOrders.isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAccount() {
|
|
||||||
Injector injector = Guice.createInjector(new BinanceClientModule());
|
|
||||||
BinanceClient client = injector.getInstance(BinanceClient.class);
|
|
||||||
|
|
||||||
Keys keys = new Keys(System.getProperty("apiKey"),
|
|
||||||
System.getProperty("secretKey"));
|
|
||||||
Account account = client.getAccount(keys);
|
|
||||||
Assert.assertNotNull(account);
|
|
||||||
}
|
|
||||||
}
|
|
BIN
libs/binance-api.jar
Normal file
BIN
libs/binance-api.jar
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user