Skip to content

Commit 3b8ee39

Browse files
committed
Added UI
1 parent cd05c0a commit 3b8ee39

File tree

5 files changed

+297
-51
lines changed

5 files changed

+297
-51
lines changed

.idea/uiDesigner.xml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,26 @@
22
> Track your profits with your Binance export
33
>
44
This is a project for tracking your accumulated profits on trading pairs in Binance.
5-
This program currently only supports USDT pairings.
5+
This program has currently only been tested with USDT pairings. xBTC pairings may be inaccurate. (please tell me if it works, I don't trade with anything other than xUSDT)
66
## How to use
7-
1. Set your api keys
8-
2. Set your data
9-
3. Run the program with the arguments [PAIR, BNBFee] Example: [BTCUSDT, 0.00075]
7+
1. ~~Set your api keys in the settings tab~~
8+
> This is not needed until more features are added
9+
2. Export your transaction data from Binance
10+
3. Set your data file location in the 'Settings' tab
11+
4. Go to the 'Main' tab and set your pairing. For example: ADAUSDT
12+
1013
> BNBFee needs to be supplied so the value of BNB does not have to be queried for every transaction.
1114
> Moreover, this is a constant value so there is no point querying the BNB price for every transaction.
12-
## Set api keys
13-
Run this program to create the config file. This file will be created in your Documents/BinanceProfitTracker
14-
## Set data
15-
You can put your exported trade data in Documents/BinanceProfitTracker/data.xlsx
16-
17-
The format is as follows:
15+
## How to export data from Binance
16+
1. Go to your trade history
17+
2. Click on the tab 'Trade History'
18+
3. Click on 'Export Recent Trade History'
1819

19-
**Date (UTC)**|**Market**|**Type**|**Price**|**Amount**|**Total**|**Fee**|**Fee Coin**
20-
:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:
21-
2021-02-07 22:53:26|ADABTC|BUY|0.00001628|2752|0.04480256|2.752|ADA
22-
2021-02-07 22:53:26|ADABTC|BUY|0.00001628|319|0.00519332|0.319|ADA
20+
This will generate a .xlsx file which you can use for this program
2321
# TODO
22+
- Test accurate valuation for non xUSDT pairs
2423
- Add support for mixing trading pairs. For example: ETHUSDT in conjunction with ETHBTC
2524
- Add more exchange export support
2625
- Add profit calculation for all trading pairs
27-
- UI for better use and with graphs to plot your profits over time
26+
- UI with graphs to plot your profits over time
27+
- Add support for .csv binance export

src/main/java/com/nubebuster/cryptoprofittracker/BinanceProfitTracker.java

Lines changed: 72 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
import com.binance.api.client.domain.market.Candlestick;
66
import com.binance.api.client.domain.market.CandlestickInterval;
77
import com.nubebuster.cryptoprofittracker.caching.CandleStickCollector;
8+
import com.nubebuster.cryptoprofittracker.ui.ProfitTrackerUI;
89
import org.apache.poi.openxml4j.opc.OPCPackage;
910
import org.apache.poi.ss.usermodel.Row;
1011
import org.apache.poi.ss.usermodel.Sheet;
1112
import org.apache.poi.ss.usermodel.Workbook;
1213
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
1314

15+
import javax.swing.*;
1416
import java.io.File;
1517
import java.io.FileWriter;
1618
import java.math.BigDecimal;
@@ -25,10 +27,20 @@ public class BinanceProfitTracker {
2527
private static final CandlestickInterval CACHE_PRECISION = CandlestickInterval.FIVE_MINUTES;
2628

2729
public static void main(String[] args) {
30+
31+
JFrame frame = new JFrame();
32+
frame.setTitle("Binance profit tracker");
33+
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
34+
ProfitTrackerUI ui = new ProfitTrackerUI();
35+
frame.add(ui.panel1);
36+
frame.pack();
37+
frame.setBounds(0, 0, 512, 256);
38+
frame.setVisible(true);
39+
40+
2841
try {
29-
String pair = args[0];
30-
double bnbFee = Double.parseDouble(args[1]);
31-
String apiKey, apiSecret;
42+
// double bnbFee = Double.parseDouble(args[0]);//TODO add this to UI settings
43+
double bnbFee = 0.00075;
3244
File documents = new File(CryptoProfitTrackerUtils.getDocumentsPath());
3345
if (!documents.exists()) {
3446
documents.mkdir();
@@ -37,45 +49,70 @@ public static void main(String[] args) {
3749
File configFile = new File(documents, "config.txt");
3850
if (configFile.exists()) {
3951
String[] configData = CryptoProfitTrackerUtils.readData(configFile);
40-
apiKey = configData[0];
41-
apiSecret = configData[1];
42-
} else {
43-
configFile.createNewFile();
44-
FileWriter fr = new FileWriter(configFile);
45-
fr.write("apiKey=\napiSecret=");
46-
fr.flush();
47-
fr.close();
48-
System.out.println("Set your API keys in " + configFile.getPath());
49-
System.exit(0);
50-
return;
52+
ui.apiKeyTextField.setText(configData[0].replace("apiKey=", ""));
53+
ui.secretKeyTextField.setText(configData[1].replace("apiSecret=", ""));
54+
ui.dataTextField.setText(configData[2].replace("dataFile=", ""));
5155
}
5256

53-
File dataFile = new File(documents, "history.xlsx");
54-
if (!dataFile.exists()) {
55-
System.out.println("Put your data in " + dataFile.getPath());
56-
System.exit(0);
57-
return;
57+
if (ui.dataTextField.getText() == null || ui.dataTextField.getText().isEmpty()) {
58+
ui.dataTextField.setText(CryptoProfitTrackerUtils.getDocumentsPath() + File.separator + "data.xlsx");
5859
}
5960

60-
OPCPackage pkg = OPCPackage.open(dataFile);
61-
Workbook wb = new XSSFWorkbook(pkg);
62-
Sheet sheet = wb.getSheetAt(0);
63-
Iterator<Row> rows = sheet.rowIterator();
6461

65-
BinanceProfitTracker binanceProfitTracker = new BinanceProfitTracker(apiKey,
66-
apiSecret);
67-
binanceProfitTracker.printCalculations(pair, bnbFee, rows);
62+
ui.printCalculationsButton.addActionListener(e -> {
63+
ui.printCalculationsButton.setEnabled(false);
64+
ui.output.setText("");
65+
try {
66+
File dataFile = new File(ui.dataTextField.getText());
67+
if (!dataFile.exists()) {
68+
System.err.println("Data file not found: " + dataFile.getPath());
69+
ui.printCalculationsButton.setEnabled(true);
70+
return;
71+
}
72+
OPCPackage pkg = OPCPackage.open(dataFile);
73+
Workbook wb = new XSSFWorkbook(pkg);
74+
Sheet sheet = wb.getSheetAt(0);
75+
Iterator<Row> rows = sheet.rowIterator();
76+
BinanceProfitTracker binanceProfitTracker = new BinanceProfitTracker(ui, ui.apiKeyTextField.getText(),
77+
ui.secretKeyTextField.getText());
78+
binanceProfitTracker.printCalculations(ui.ticker.getText(), bnbFee, rows);
79+
pkg.close();
80+
} catch (Exception ex) {
81+
ex.printStackTrace();
82+
}
83+
ui.printCalculationsButton.setEnabled(true);
84+
});
6885
} catch (Exception e) {
6986
e.printStackTrace();
7087
System.exit(1);
7188
}
72-
System.exit(0);
89+
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
90+
try {
91+
File configFile = new File(CryptoProfitTrackerUtils.getDocumentsPath(), "config.txt");
92+
configFile.createNewFile();
93+
FileWriter fr = new FileWriter(configFile);
94+
fr.write("apiKey=" + ui.apiKeyTextField.getText() + "\napiSecret=" +
95+
ui.secretKeyTextField.getText() + "\ndataFile=" + ui.dataTextField.getText() + "\nNote: this file should not be edited manually.");
96+
fr.flush();
97+
fr.close();
98+
System.out.println("Saved data to " + configFile.getPath());
99+
} catch (Exception e) {
100+
e.printStackTrace();
101+
}
102+
}));
103+
}
104+
105+
public void log(String s) {
106+
System.out.println(s);
107+
ui.output.append("\n" + s);
73108
}
74109

75110
private BinanceApiRestClient client;
76111
private CandleStickCollector candleStickCollector;
112+
private ProfitTrackerUI ui;
77113

78-
public BinanceProfitTracker(String apiKey, String apiSecret) throws Exception {
114+
public BinanceProfitTracker(ProfitTrackerUI ui, String apiKey, String apiSecret) throws Exception {
115+
this.ui = ui;
79116
BinanceApiClientFactory factory = BinanceApiClientFactory.newInstance(apiKey,
80117
apiSecret);
81118
client = factory.newRestClient();
@@ -145,18 +182,18 @@ public void printCalculations(String pair, double bnbFeeValue, Iterator<Row> row
145182
}
146183
}
147184

148-
System.out.println("Data for " + pair);
149-
System.out.println("#Orders (BUY+SELL): " + orders.size());
150-
System.out.println("Volume: " + roundedToSignificance(volume));
151-
System.out.println("Sub Total Profit: " + roundedToSignificance(cumProfit));
185+
log("Data for " + pair);
186+
log("#Orders (BUY+SELL): " + orders.size());
187+
log("Volume: " + roundedToSignificance(volume));
188+
log("Sub Total Profit: " + roundedToSignificance(cumProfit));
152189

153190
double walletValue = getPrice(pair) * amountInWallet;
154-
System.out.println("Amount in wallet: " + roundedToSignificance(amountInWallet) + " (current value: " +
191+
log("Amount in wallet: " + roundedToSignificance(amountInWallet) + " (current value: " +
155192
Math.floor(walletValue) + ")");
156193

157-
System.out.println("\nFees total: " + roundedToSignificance(accruedFees));
194+
log("Fees total: " + roundedToSignificance(accruedFees));
158195

159-
System.out.println("\nTotal profit: " + Math.floor(cumProfit + walletValue - accruedFees));
196+
log("\nTotal profit: " + Math.floor(cumProfit + walletValue - accruedFees) + "\n-----------------------");
160197
}
161198

162199
/**
@@ -198,7 +235,6 @@ private double roundedToSignificance(double input) {
198235
/**
199236
* @deprecated this is slow and {@link #getHistoricalPrice(List, long)} should be used for a less precise, cached price.
200237
* Alternatively, you can use {@link #loadHistoricalPrice(String, long)} to load the price from the cache.
201-
*
202238
*/
203239
@Deprecated
204240
private Double queryPriceAtTime(String ticker, long timestamp) {

0 commit comments

Comments
 (0)