|
|
|
|
@@ -6,316 +6,491 @@ import org.apache.commons.math3.stat.regression.SimpleRegression;
|
|
|
|
|
import org.json.JSONArray;
|
|
|
|
|
import org.json.JSONObject;
|
|
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Scanner;
|
|
|
|
|
import java.io.*;
|
|
|
|
|
import java.nio.charset.Charset;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
|
|
|
|
|
public class Main {
|
|
|
|
|
private static final String APP_NAME = "den_ac_deka_ct3_15_35";
|
|
|
|
|
private static final double VALUE_ETH = 100.0;
|
|
|
|
|
private static final double VALUE_EUR = 0.0;
|
|
|
|
|
private static final int ROUNDTRIP_TIME_MS = 20000;
|
|
|
|
|
private static int NUM_ITERATIONS_FOR_ORDER = 15;
|
|
|
|
|
private static int BUY_THRESHOLD = 35;
|
|
|
|
|
private static int SELL_THRESHOLD = -35;
|
|
|
|
|
|
|
|
|
|
static SimpleRegression srbuyvolume = new SimpleRegression(true);
|
|
|
|
|
static SimpleRegression srsellvolume = new SimpleRegression(true);
|
|
|
|
|
static SimpleRegression srprice = new SimpleRegression(true);
|
|
|
|
|
private static SimpleRegression srbuyvolume = new SimpleRegression(true);
|
|
|
|
|
private static SimpleRegression srsellvolume = new SimpleRegression(true);
|
|
|
|
|
private static SimpleRegression srprice = new SimpleRegression(true);
|
|
|
|
|
|
|
|
|
|
static ArrayList<Double> list = new ArrayList<Double>();
|
|
|
|
|
static OrderHistory orders = new OrderHistory();
|
|
|
|
|
public static Funds funds = new Funds();
|
|
|
|
|
public static TradeHistory trades;
|
|
|
|
|
private static OrderHistory orders = new OrderHistory();
|
|
|
|
|
private static Funds funds = new Funds();
|
|
|
|
|
private static TradeHistory trades;
|
|
|
|
|
|
|
|
|
|
public static double buyvslope = 0.0;
|
|
|
|
|
public static double sellvslope = 0.0;
|
|
|
|
|
public static double priceslope = 0.0;
|
|
|
|
|
public static int buyindicator = 0;
|
|
|
|
|
public static double currentPrice = 0.0;
|
|
|
|
|
static int counter = 0;
|
|
|
|
|
private static double buyvslope = 0.0;
|
|
|
|
|
private static double sellvslope = 0.0;
|
|
|
|
|
private static double priceslope = 0.0;
|
|
|
|
|
private static int buyindicator = 0;
|
|
|
|
|
private static double currentPrice = 0.0;
|
|
|
|
|
private static int counter = 0;
|
|
|
|
|
private static double fees = 0.0;
|
|
|
|
|
private static long sinceid = 0L;
|
|
|
|
|
private static String trend = "";
|
|
|
|
|
|
|
|
|
|
public static int counterbuys = 0;
|
|
|
|
|
public static int countersells = 0;
|
|
|
|
|
public static int counterneutrals = 0;
|
|
|
|
|
private static int counterbuys = 0;
|
|
|
|
|
private static int countersells = 0;
|
|
|
|
|
private static int counterneutrals = 0;
|
|
|
|
|
|
|
|
|
|
public static void main(String [ ] args) throws InterruptedException {
|
|
|
|
|
private static boolean regressionbacktest = false;
|
|
|
|
|
private static boolean backtest = false;
|
|
|
|
|
|
|
|
|
|
private static Map<String, Double > results = new HashMap<>();
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args) throws InterruptedException {
|
|
|
|
|
System.out.println("Starting DekaBot...");
|
|
|
|
|
|
|
|
|
|
System.out.println("Starting simulation... initializing Funds...");
|
|
|
|
|
|
|
|
|
|
funds.addFund("ETH", VALUE_ETH);
|
|
|
|
|
funds.addFund("EUR", VALUE_EUR);
|
|
|
|
|
|
|
|
|
|
System.out.println("Do Backtesting? y/r/n");
|
|
|
|
|
Scanner in = new Scanner(System.in);
|
|
|
|
|
String input = in.next();
|
|
|
|
|
//String input = "n";
|
|
|
|
|
|
|
|
|
|
System.out.println("Start simulation? (y/n)");
|
|
|
|
|
String s = in.next();
|
|
|
|
|
if(input.equals("r")){
|
|
|
|
|
regressionbacktest = true;
|
|
|
|
|
|
|
|
|
|
long sinceid = 0L;
|
|
|
|
|
for(int x = 4; x < 30; x++){
|
|
|
|
|
System.out.println("x:"+x);
|
|
|
|
|
NUM_ITERATIONS_FOR_ORDER = x;
|
|
|
|
|
for(int y = x-1;y < 3*x;y++){
|
|
|
|
|
BUY_THRESHOLD = y;
|
|
|
|
|
SELL_THRESHOLD = -y;
|
|
|
|
|
|
|
|
|
|
if(s.equals("y")){
|
|
|
|
|
try{
|
|
|
|
|
HttpResponse<JsonNode> jsonResponse = Unirest.post("https://api.kraken.com/0/public/Trades")
|
|
|
|
|
.header("accept", "application/json")
|
|
|
|
|
.queryString("pair", "ETHEUR")
|
|
|
|
|
.asJson();
|
|
|
|
|
doBacktest();
|
|
|
|
|
|
|
|
|
|
sinceid = jsonResponse.getBody().getObject().getJSONObject("result").getLong("last");
|
|
|
|
|
}catch(UnirestException ue){
|
|
|
|
|
System.out.println("Could not establish connection.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
System.out.println("Starting simulation... initializing Funds...");
|
|
|
|
|
|
|
|
|
|
funds.addFund("ETH", 0.0);
|
|
|
|
|
funds.addFund("EUR", 3000);
|
|
|
|
|
|
|
|
|
|
try{
|
|
|
|
|
sendStats();
|
|
|
|
|
}catch(UnirestException ue){
|
|
|
|
|
System.out.println("Could not send stats - just continue");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
System.out.println(funds.getFundsStringOutput());
|
|
|
|
|
|
|
|
|
|
while(true){
|
|
|
|
|
Thread.sleep(20000);
|
|
|
|
|
|
|
|
|
|
sinceid = analyzeVolume(sinceid);
|
|
|
|
|
analyzePrice();
|
|
|
|
|
|
|
|
|
|
System.out.println("Trend: "+calculateTrend_2()+" // Price: "+currentPrice);
|
|
|
|
|
|
|
|
|
|
if(((counter % 6) == 0) && (counter != 0)){
|
|
|
|
|
Order order = decide();
|
|
|
|
|
|
|
|
|
|
if(order.ordertype != null) doOrder(order);
|
|
|
|
|
|
|
|
|
|
buyindicator = 0;
|
|
|
|
|
System.out.println("Funds: "+funds.getFundsStringOutput());
|
|
|
|
|
|
|
|
|
|
srbuyvolume.clear();
|
|
|
|
|
srsellvolume.clear();
|
|
|
|
|
srprice.clear();
|
|
|
|
|
doOrder(new Order("buy"));
|
|
|
|
|
results.put(x+":"+y,funds.getValue("ETH"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
counter++;
|
|
|
|
|
System.out.println("-------"+counter+"-------");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
System.out.println("Output of best results: ");
|
|
|
|
|
HashMap<String, Double> sortedResult = (HashMap<String, Double>) sortByValue(results);
|
|
|
|
|
|
|
|
|
|
for (Map.Entry<String, Double> entry : sortedResult.entrySet()) {
|
|
|
|
|
System.out.println(entry.getKey() + " Value: "+entry.getValue());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}else if(input.equals("y")){
|
|
|
|
|
backtest = true;
|
|
|
|
|
doBacktest();
|
|
|
|
|
|
|
|
|
|
doOrder(new Order("buy"));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
System.out.println("");
|
|
|
|
|
System.out.println("Final ETH count: "+funds.getValue("ETH"));
|
|
|
|
|
System.out.println("Buys: "+counterbuys+" Sells: "+countersells+" Neutral: "+counterneutrals+" Fees: "+fees);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sendStats();
|
|
|
|
|
|
|
|
|
|
System.out.println(funds.getFundsStringOutput());
|
|
|
|
|
System.out.println("-------Start-------");
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
HttpResponse<JsonNode> jsonResponse = Unirest.post("https://api.kraken.com/0/public/Trades")
|
|
|
|
|
.header("accept", "application/json")
|
|
|
|
|
.queryString("pair", "ETHEUR")
|
|
|
|
|
.asJson();
|
|
|
|
|
|
|
|
|
|
sinceid = jsonResponse.getBody().getObject().getJSONObject("result").getLong("last");
|
|
|
|
|
} catch (UnirestException ue) {
|
|
|
|
|
System.out.println("Could not establish connection: " + ue.getMessage());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
|
Thread.sleep(ROUNDTRIP_TIME_MS);
|
|
|
|
|
|
|
|
|
|
getPrice();
|
|
|
|
|
getVolume();
|
|
|
|
|
|
|
|
|
|
trend = calculateTrend_3();
|
|
|
|
|
outputAnalyzationResults();
|
|
|
|
|
|
|
|
|
|
if (((counter % NUM_ITERATIONS_FOR_ORDER) == 0) && (counter != 0)) {
|
|
|
|
|
Order order = decide();
|
|
|
|
|
|
|
|
|
|
if (order.ordertype != null) doOrder(order);
|
|
|
|
|
|
|
|
|
|
buyindicator = 0;
|
|
|
|
|
System.out.println("Funds: " + funds.getFundsStringOutput());
|
|
|
|
|
|
|
|
|
|
srbuyvolume.clear();
|
|
|
|
|
srsellvolume.clear();
|
|
|
|
|
srprice.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
counter++;
|
|
|
|
|
System.out.println("-------" + counter + "-------");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void doOrder(Order order){
|
|
|
|
|
if(order.ordertype.equals("buy")){
|
|
|
|
|
if(Double.compare(funds.getValue("EUR"),0) > 0) {
|
|
|
|
|
orders.addOrder(order);
|
|
|
|
|
|
|
|
|
|
funds.addValue("ETH", funds.getValue("EUR") / currentPrice);
|
|
|
|
|
funds.takeValue("EUR", funds.getValue("EUR"));
|
|
|
|
|
private static void doOrder(Order order) {
|
|
|
|
|
Double tmpFees = 0.0;
|
|
|
|
|
switch(order.ordertype){
|
|
|
|
|
case "buy":
|
|
|
|
|
if (Double.compare(funds.getValue("EUR"), 0) > 0) {
|
|
|
|
|
orders.addOrder(order);
|
|
|
|
|
|
|
|
|
|
counterbuys++;
|
|
|
|
|
}else{
|
|
|
|
|
System.out.println("Would like to buy but conditions not met (out of funds)");
|
|
|
|
|
}
|
|
|
|
|
}else if(order.ordertype.equals("sell")){
|
|
|
|
|
if(Double.compare(funds.getValue("ETH"),0) > 0){
|
|
|
|
|
orders.addOrder(order);
|
|
|
|
|
tmpFees = funds.getValue("EUR") * 0.0026;
|
|
|
|
|
funds.addValue("ETH", (funds.getValue("EUR") - tmpFees) / currentPrice);
|
|
|
|
|
funds.takeValue("EUR", funds.getValue("EUR"));
|
|
|
|
|
|
|
|
|
|
funds.addValue("EUR", funds.getValue("ETH") * currentPrice);
|
|
|
|
|
funds.takeValue("ETH", funds.getValue("ETH"));
|
|
|
|
|
if(!regressionbacktest) System.out.printf("Fees for order: %.3f - Total Fees: %.3f",tmpFees,fees);
|
|
|
|
|
counterbuys++;
|
|
|
|
|
} else {
|
|
|
|
|
if(!regressionbacktest) System.out.println("Would like to buy but conditions not met (out of funds)");
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "sell":
|
|
|
|
|
if (Double.compare(funds.getValue("ETH"), 0) > 0) {
|
|
|
|
|
orders.addOrder(order);
|
|
|
|
|
|
|
|
|
|
tmpFees = funds.getValue("ETH") * currentPrice * 0.0026;
|
|
|
|
|
funds.addValue("EUR", (funds.getValue("ETH") * currentPrice) - tmpFees);
|
|
|
|
|
funds.takeValue("ETH", funds.getValue("ETH"));
|
|
|
|
|
|
|
|
|
|
if(!regressionbacktest) System.out.printf("Fees for order: %.3f - Total Fees: %.3f",tmpFees,fees);
|
|
|
|
|
countersells++;
|
|
|
|
|
} else {
|
|
|
|
|
if(!regressionbacktest) System.out.println("Would like to sell but conditions not met (out of funds)");
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
System.out.println("ERROR: Order not recognized: " + order.type);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
countersells++;
|
|
|
|
|
}else{
|
|
|
|
|
System.out.println("Would like to sell but conditions not met (out of funds)");
|
|
|
|
|
}
|
|
|
|
|
}else{
|
|
|
|
|
System.out.println("ERROR: Order not recoginized: "+order.type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try{
|
|
|
|
|
sendStats();
|
|
|
|
|
}catch(UnirestException ue){
|
|
|
|
|
System.out.println("Error sending stats - just continue...");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void sendStats() throws UnirestException {
|
|
|
|
|
HttpResponse<JsonNode> jsonResponse = Unirest.post("https://www.riskahead.de/api/v1/deka/updatestats/")
|
|
|
|
|
.header("accept", "application/json")
|
|
|
|
|
.queryString("app_id", "den_deka_2_6")
|
|
|
|
|
.field("funds_start", "EUR: 3000")
|
|
|
|
|
.field("funds_current", funds.getFundsStringOutput())
|
|
|
|
|
.field("trades_buy", counterbuys)
|
|
|
|
|
.field("trades_sell", countersells)
|
|
|
|
|
.field("trades_neutral", counterneutrals)
|
|
|
|
|
.asJson();
|
|
|
|
|
fees += tmpFees;
|
|
|
|
|
sendStats();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static Order decide() {
|
|
|
|
|
Order newOrder = new Order();
|
|
|
|
|
newOrder.price = currentPrice;
|
|
|
|
|
|
|
|
|
|
if(buyindicator > 6){
|
|
|
|
|
if(!regressionbacktest) System.out.println("------- START ORDER -------");
|
|
|
|
|
if (buyindicator > BUY_THRESHOLD) {
|
|
|
|
|
|
|
|
|
|
System.out.println("BUY NOW - PRICE: "+currentPrice);
|
|
|
|
|
newOrder.ordertype = "buy";
|
|
|
|
|
if(!regressionbacktest) System.out.println("BUY NOW - PRICE: " + currentPrice);
|
|
|
|
|
newOrder.ordertype = "buy";
|
|
|
|
|
|
|
|
|
|
}else if(buyindicator > -6){
|
|
|
|
|
System.out.println("DO NOTHING - NEUTRAL: "+currentPrice);
|
|
|
|
|
} else if (buyindicator > SELL_THRESHOLD) {
|
|
|
|
|
if(!regressionbacktest) System.out.println("DO NOTHING - NEUTRAL: " + currentPrice);
|
|
|
|
|
counterneutrals++;
|
|
|
|
|
}else{
|
|
|
|
|
if(orders.getLastOrder() == null || Double.compare(orders.getLastOrder().price,currentPrice*0.995) < 0 || Double.compare(orders.getLastOrder().price,currentPrice*0.985) > 0){
|
|
|
|
|
} else {
|
|
|
|
|
if (orders.getLastOrder() == null || Double.compare(orders.getLastOrder().price, currentPrice * 0.995) < 0 || Double.compare(orders.getLastOrder().price, currentPrice * 0.985) > 0) {
|
|
|
|
|
|
|
|
|
|
System.out.println("SELL NOW - PRICE: "+currentPrice);
|
|
|
|
|
if(!regressionbacktest) System.out.println("SELL NOW - PRICE: " + currentPrice);
|
|
|
|
|
newOrder.ordertype = "sell";
|
|
|
|
|
|
|
|
|
|
}else{
|
|
|
|
|
System.out.println("Would like to sell but percentage not reached");
|
|
|
|
|
} else {
|
|
|
|
|
if(!regressionbacktest) System.out.println("Would like to sell but percentage not reached");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!regressionbacktest) System.out.println("------- END ORDER -------");
|
|
|
|
|
|
|
|
|
|
return newOrder;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void analyzePrice() {
|
|
|
|
|
try{
|
|
|
|
|
HttpResponse<JsonNode> jsonResponse;
|
|
|
|
|
jsonResponse = Unirest.post("https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=BTC,USD,EUR")
|
|
|
|
|
.header("accept", "application/json")
|
|
|
|
|
.queryString("fsyn", "ETH")
|
|
|
|
|
.field("tsyms", "BTC,USD,EUR")
|
|
|
|
|
.asJson();
|
|
|
|
|
private static String calculateTrend() {
|
|
|
|
|
if ((Double.compare(buyvslope, 0) > 0) && (Double.compare(priceslope, 0) > 0)) {
|
|
|
|
|
if (Double.compare(trades.volumeOfBuyTrades, trades.volumeOfSellTrades) > 0) {
|
|
|
|
|
buyindicator += 3;
|
|
|
|
|
return "strong buy";
|
|
|
|
|
} else {
|
|
|
|
|
buyindicator += 2;
|
|
|
|
|
return "normal buy";
|
|
|
|
|
}
|
|
|
|
|
} else if ((Double.compare(sellvslope, 0) > 0) && (Double.compare(priceslope, 0) < 0)) {
|
|
|
|
|
if (Double.compare(trades.volumeOfBuyTrades, trades.volumeOfSellTrades) < 0) {
|
|
|
|
|
buyindicator -= 3;
|
|
|
|
|
return "strong sell";
|
|
|
|
|
} else {
|
|
|
|
|
buyindicator -= 2;
|
|
|
|
|
return "normal sell";
|
|
|
|
|
}
|
|
|
|
|
} else if (Double.compare(buyvslope, sellvslope) > 0 && (Double.compare(priceslope, 0) > 0)) {
|
|
|
|
|
buyindicator += 1;
|
|
|
|
|
return "weak buy";
|
|
|
|
|
} else if (Double.compare(buyvslope, sellvslope) < 0 && (Double.compare(priceslope, 0) < 0)) {
|
|
|
|
|
buyindicator -= 1;
|
|
|
|
|
return "weak sell";
|
|
|
|
|
} else {
|
|
|
|
|
return "neutral";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static String calculateTrend_2() {
|
|
|
|
|
if (Double.isNaN(priceslope)) {
|
|
|
|
|
if (Double.compare(trades.volumeOfBuyTrades, trades.volumeOfSellTrades) > 0) {
|
|
|
|
|
buyindicator += 1;
|
|
|
|
|
return "weak buy";
|
|
|
|
|
} else {
|
|
|
|
|
buyindicator -= 1;
|
|
|
|
|
return "weak sell";
|
|
|
|
|
}
|
|
|
|
|
} else if ((Double.compare(priceslope, 0) > 0)) {
|
|
|
|
|
if ((Double.compare(trades.volumeOfBuyTrades, trades.volumeOfSellTrades) > 0) && (Double.compare(buyvslope, 0) > 0) && (Double.compare(sellvslope, 0) < 0)) {
|
|
|
|
|
buyindicator += 3;
|
|
|
|
|
return "strong buy";
|
|
|
|
|
} else if ((Double.compare(trades.volumeOfBuyTrades, trades.volumeOfSellTrades) > 0) && (Double.compare(buyvslope, 0) > 0)) {
|
|
|
|
|
buyindicator += 2;
|
|
|
|
|
return "normal buy";
|
|
|
|
|
} else {
|
|
|
|
|
buyindicator += 1;
|
|
|
|
|
return "weak buy";
|
|
|
|
|
}
|
|
|
|
|
} else if ((Double.compare(priceslope, 0) < 0)) {
|
|
|
|
|
if ((Double.compare(trades.volumeOfBuyTrades, trades.volumeOfSellTrades) < 0) && (Double.compare(buyvslope, 0) < 0) && (Double.compare(sellvslope, 0) > 0)) {
|
|
|
|
|
buyindicator -= 3;
|
|
|
|
|
return "strong sell";
|
|
|
|
|
} else if ((Double.compare(trades.volumeOfBuyTrades, trades.volumeOfSellTrades) < 0) && (Double.compare(sellvslope, 0) > 0)) {
|
|
|
|
|
buyindicator -= 2;
|
|
|
|
|
return "normal sell";
|
|
|
|
|
} else {
|
|
|
|
|
buyindicator -= 1;
|
|
|
|
|
return "weak sell";
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
return "neutral";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static String calculateTrend_3() {
|
|
|
|
|
if (Double.isNaN(priceslope)) {
|
|
|
|
|
if (Double.compare(trades.volumeOfBuyTrades, trades.volumeOfSellTrades) > 0) {
|
|
|
|
|
buyindicator += 1;
|
|
|
|
|
return "weak buy";
|
|
|
|
|
} else {
|
|
|
|
|
buyindicator -= 1;
|
|
|
|
|
return "weak sell";
|
|
|
|
|
}
|
|
|
|
|
} else if ((Double.compare(priceslope, 0) > 0)) {
|
|
|
|
|
if ((Double.compare(trades.volumeOfBuyTrades, trades.volumeOfSellTrades) > 0)) {
|
|
|
|
|
buyindicator += 3;
|
|
|
|
|
return "strong buy";
|
|
|
|
|
} else {
|
|
|
|
|
buyindicator += 2;
|
|
|
|
|
return "normal buy";
|
|
|
|
|
}
|
|
|
|
|
} else if ((Double.compare(priceslope, 0) < 0)) {
|
|
|
|
|
if ((Double.compare(trades.volumeOfBuyTrades, trades.volumeOfSellTrades) < 0)) {
|
|
|
|
|
buyindicator -= 3;
|
|
|
|
|
return "strong sell";
|
|
|
|
|
} else {
|
|
|
|
|
buyindicator -= 2;
|
|
|
|
|
return "normal sell";
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
return "neutral";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void doBacktest(){
|
|
|
|
|
try {
|
|
|
|
|
funds.clearFunds();
|
|
|
|
|
orders.clearOrders();
|
|
|
|
|
if(trades != null) trades.clearTrades();
|
|
|
|
|
funds.addFund("ETH", VALUE_ETH);
|
|
|
|
|
funds.addFund("EUR", VALUE_EUR);
|
|
|
|
|
|
|
|
|
|
String priceline = "";
|
|
|
|
|
String volumeline = "";
|
|
|
|
|
int counter = 0;
|
|
|
|
|
|
|
|
|
|
InputStream fis = new FileInputStream("C:\\Development\\Projects\\DekaBot\\DekaBot\\src\\main\\resources\\price.txt");
|
|
|
|
|
InputStreamReader isr = new InputStreamReader(fis, Charset.forName("UTF-8"));
|
|
|
|
|
BufferedReader br = new BufferedReader(isr);
|
|
|
|
|
|
|
|
|
|
InputStream fis2 = new FileInputStream("C:\\Development\\Projects\\DekaBot\\DekaBot\\src\\main\\resources\\volume.txt");
|
|
|
|
|
InputStreamReader isr2 = new InputStreamReader(fis2, Charset.forName("UTF-8"));
|
|
|
|
|
BufferedReader br2 = new BufferedReader(isr2);
|
|
|
|
|
|
|
|
|
|
while ((priceline = br.readLine()) != null) {
|
|
|
|
|
volumeline = br2.readLine();
|
|
|
|
|
|
|
|
|
|
priceline = br.readLine();
|
|
|
|
|
volumeline = br2.readLine();
|
|
|
|
|
|
|
|
|
|
if(volumeline == null || priceline == null){
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(volumeline.charAt(volumeline.length()-1) != '}'){
|
|
|
|
|
volumeline += br2.readLine();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JSONObject jsonPriceObject = new JSONObject(priceline);
|
|
|
|
|
JSONObject jsonVolumeObject = new JSONObject(volumeline);
|
|
|
|
|
|
|
|
|
|
jsonVolumeObject = jsonVolumeObject.getJSONObject("result");
|
|
|
|
|
sinceid = jsonVolumeObject.getLong("last");
|
|
|
|
|
JSONArray volumeArray = jsonVolumeObject.getJSONArray("XETHZEUR");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
currentPrice = jsonPriceObject.getDouble("EUR");
|
|
|
|
|
srprice.addData((double) counter, currentPrice);
|
|
|
|
|
|
|
|
|
|
trades = new TradeHistory(volumeArray, sinceid);
|
|
|
|
|
|
|
|
|
|
srbuyvolume.addData((double) counter, trades.volumeOfBuyTrades);
|
|
|
|
|
srsellvolume.addData((double) counter, trades.volumeOfSellTrades);
|
|
|
|
|
|
|
|
|
|
priceslope = srprice.getSlope();
|
|
|
|
|
buyvslope = srbuyvolume.getSlope();
|
|
|
|
|
sellvslope = srsellvolume.getSlope();
|
|
|
|
|
|
|
|
|
|
trend = calculateTrend_2();
|
|
|
|
|
outputAnalyzationResults();
|
|
|
|
|
|
|
|
|
|
if (((counter % NUM_ITERATIONS_FOR_ORDER) == 0) && (counter != 0)) {
|
|
|
|
|
Order order = decide();
|
|
|
|
|
|
|
|
|
|
if (order.ordertype != null) doOrder(order);
|
|
|
|
|
|
|
|
|
|
buyindicator = 0;
|
|
|
|
|
if(!regressionbacktest) System.out.println("Funds: " + funds.getFundsStringOutput());
|
|
|
|
|
|
|
|
|
|
srbuyvolume.clear();
|
|
|
|
|
srsellvolume.clear();
|
|
|
|
|
srprice.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!regressionbacktest && !backtest) System.out.println("-------" + counter + "-------");
|
|
|
|
|
counter++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void getPrice() {
|
|
|
|
|
try {
|
|
|
|
|
HttpResponse<JsonNode> jsonResponse;
|
|
|
|
|
jsonResponse = Unirest.post("https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=BTC,USD,EUR")
|
|
|
|
|
.header("accept", "application/json")
|
|
|
|
|
.queryString("fsyn", "ETH")
|
|
|
|
|
.field("tsyms", "BTC,USD,EUR")
|
|
|
|
|
.asJson();
|
|
|
|
|
|
|
|
|
|
writeResponseToFile(jsonResponse,"price");
|
|
|
|
|
|
|
|
|
|
currentPrice = jsonResponse.getBody().getObject().getDouble("EUR");
|
|
|
|
|
|
|
|
|
|
srprice.addData((double)counter,currentPrice);
|
|
|
|
|
System.out.printf("Current price slope: %.3f \n",srprice.getSlope());
|
|
|
|
|
}catch(UnirestException ue){
|
|
|
|
|
srprice.addData((double) counter, currentPrice);
|
|
|
|
|
} catch (UnirestException ue) {
|
|
|
|
|
System.out.println("Exception was thrown - just continue and ignore");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static String calculateTrend(){
|
|
|
|
|
if((Double.compare(buyvslope, 0) > 0) && (Double.compare(priceslope, 0) > 0)){
|
|
|
|
|
if(Double.compare(trades.volumeOfBuyTrades, trades.volumeOfSellTrades) > 0){
|
|
|
|
|
buyindicator += 3;
|
|
|
|
|
return "strong buy";
|
|
|
|
|
}else{
|
|
|
|
|
buyindicator += 2;
|
|
|
|
|
return "normal buy";
|
|
|
|
|
}
|
|
|
|
|
}else if((Double.compare(sellvslope, 0) > 0) && (Double.compare(priceslope, 0) < 0)){
|
|
|
|
|
if(Double.compare(trades.volumeOfBuyTrades, trades.volumeOfSellTrades) < 0){
|
|
|
|
|
buyindicator -= 3;
|
|
|
|
|
return "strong sell";
|
|
|
|
|
}else{
|
|
|
|
|
buyindicator -= 2;
|
|
|
|
|
return "normal sell";
|
|
|
|
|
}
|
|
|
|
|
}else if(Double.compare(buyvslope, sellvslope) > 0 && (Double.compare(priceslope, 0) > 0)){
|
|
|
|
|
buyindicator += 1;
|
|
|
|
|
return "weak buy";
|
|
|
|
|
}else if(Double.compare(buyvslope, sellvslope) < 0 && (Double.compare(priceslope, 0) < 0)){
|
|
|
|
|
buyindicator -= 1;
|
|
|
|
|
return "weak sell";
|
|
|
|
|
}else{
|
|
|
|
|
return "neutral";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static String calculateTrend_2(){
|
|
|
|
|
if((Double.compare(priceslope, 0.1) > 0)){
|
|
|
|
|
if((Double.compare(trades.volumeOfBuyTrades, trades.volumeOfSellTrades) > 0) && (Double.compare(buyvslope, 0) > 0) && (Double.compare(sellvslope, 0) < 0)){
|
|
|
|
|
buyindicator += 5;
|
|
|
|
|
return "strong buy";
|
|
|
|
|
}else if((Double.compare(trades.volumeOfBuyTrades, trades.volumeOfSellTrades) > 0) && (Double.compare(buyvslope, 0) > 0)){
|
|
|
|
|
buyindicator += 3;
|
|
|
|
|
return "normal buy";
|
|
|
|
|
}else{
|
|
|
|
|
buyindicator += 1;
|
|
|
|
|
return "weak buy";
|
|
|
|
|
}
|
|
|
|
|
}else if((Double.compare(priceslope, 0.0) < 0)){
|
|
|
|
|
if((Double.compare(trades.volumeOfBuyTrades, trades.volumeOfSellTrades) < 0) && (Double.compare(buyvslope, 0) < 0) && (Double.compare(sellvslope, 0) > 0)){
|
|
|
|
|
buyindicator -= 5;
|
|
|
|
|
return "strong sell";
|
|
|
|
|
}else if((Double.compare(trades.volumeOfBuyTrades, trades.volumeOfSellTrades) < 0) && (Double.compare(sellvslope, 0) > 0)){
|
|
|
|
|
buyindicator -= 3;
|
|
|
|
|
return "normal sell";
|
|
|
|
|
}else{
|
|
|
|
|
buyindicator -= 1;
|
|
|
|
|
return "weak sell";
|
|
|
|
|
}
|
|
|
|
|
}else{
|
|
|
|
|
return "neutral";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static long analyzeVolume(long sinceid) {
|
|
|
|
|
try{
|
|
|
|
|
HttpResponse<JsonNode> jsonResponse;
|
|
|
|
|
jsonResponse = Unirest.post("https://api.kraken.com/0/public/Trades")
|
|
|
|
|
private static void getVolume() {
|
|
|
|
|
try {
|
|
|
|
|
HttpResponse<JsonNode> jsonResponse = Unirest.post("https://api.kraken.com/0/public/Trades")
|
|
|
|
|
.header("accept", "application/json")
|
|
|
|
|
.queryString("pair", "ETHEUR")
|
|
|
|
|
.field("since", sinceid)
|
|
|
|
|
.asJson();
|
|
|
|
|
|
|
|
|
|
writeResponseToFile(jsonResponse,"volume");
|
|
|
|
|
|
|
|
|
|
JSONArray array = jsonResponse.getBody().getObject().getJSONObject("result").getJSONArray("XETHZEUR");
|
|
|
|
|
sinceid = jsonResponse.getBody().getObject().getJSONObject("result").getLong("last");
|
|
|
|
|
trades = new TradeHistory(array,sinceid);
|
|
|
|
|
trades = new TradeHistory(array, sinceid);
|
|
|
|
|
|
|
|
|
|
System.out.print("Number of buy trades: "+trades.numberOfBuyTrades);
|
|
|
|
|
System.out.printf(" - Volume of buy trades: %.3f \n",trades.volumeOfBuyTrades);
|
|
|
|
|
System.out.print("Number of sell trades: "+trades.numberOfSellTrades);
|
|
|
|
|
System.out.printf(" - Volume of sell trades: %.3f \n",trades.volumeOfSellTrades);
|
|
|
|
|
System.out.println("Timeframe in sec: "+trades.timeframesec);
|
|
|
|
|
|
|
|
|
|
srbuyvolume.addData((double) counter,trades.volumeOfBuyTrades);
|
|
|
|
|
System.out.printf("buy volume slope: %.3f //",srbuyvolume.getSlope());
|
|
|
|
|
|
|
|
|
|
srsellvolume.addData((double) counter,trades.volumeOfSellTrades);
|
|
|
|
|
System.out.printf("sell volume slope: %.3f \n",srsellvolume.getSlope());
|
|
|
|
|
srbuyvolume.addData((double) counter, trades.volumeOfBuyTrades);
|
|
|
|
|
srsellvolume.addData((double) counter, trades.volumeOfSellTrades);
|
|
|
|
|
|
|
|
|
|
priceslope = srprice.getSlope();
|
|
|
|
|
buyvslope = srbuyvolume.getSlope();
|
|
|
|
|
sellvslope = srsellvolume.getSlope();
|
|
|
|
|
|
|
|
|
|
}catch(UnirestException ue){
|
|
|
|
|
System.out.println("Exception thrown. Just continoue..");
|
|
|
|
|
} catch (UnirestException ue) {
|
|
|
|
|
System.out.println("Exception thrown. Just continue..");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return sinceid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static int calculatePercentage(Double first, Double second){
|
|
|
|
|
private static void sendStats() {
|
|
|
|
|
if(regressionbacktest || backtest) return;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
Unirest.post("https://www.riskahead.de/api/v1/deka/updatestats/")
|
|
|
|
|
.header("accept", "application/json")
|
|
|
|
|
.queryString("app_id", APP_NAME)
|
|
|
|
|
.field("funds_start", "ETH: " + VALUE_ETH + " EUR: " + VALUE_EUR)
|
|
|
|
|
.field("funds_current", funds.getFundsStringOutput())
|
|
|
|
|
.field("trades_buy", counterbuys)
|
|
|
|
|
.field("trades_sell", countersells)
|
|
|
|
|
.field("trades_fees", fees)
|
|
|
|
|
.field("trades_neutral", counterneutrals)
|
|
|
|
|
.asJson();
|
|
|
|
|
} catch (UnirestException ue) {
|
|
|
|
|
System.out.println("Error sending stats: " + ue.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void outputAnalyzationResults() {
|
|
|
|
|
if(regressionbacktest || backtest) return;
|
|
|
|
|
System.out.printf("Price: "+ currentPrice +" => Slope: %.3f \n",srprice.getSlope());
|
|
|
|
|
System.out.printf("Buy-Trades -- Amount: " + trades.numberOfBuyTrades + " Volume: %.3f => Slope: %.3f\n",trades.volumeOfBuyTrades,srbuyvolume.getSlope());
|
|
|
|
|
System.out.printf("Sell-Trades -- Amount: " + trades.numberOfSellTrades + " Volume: %.3f => Slope: %.3f\n",trades.volumeOfSellTrades,srsellvolume.getSlope());
|
|
|
|
|
System.out.println("Trend: " + trend);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void writeResponseToFile(HttpResponse<JsonNode> jsonResponse, String filename) {
|
|
|
|
|
try{
|
|
|
|
|
PrintWriter writer = new PrintWriter(new FileOutputStream(
|
|
|
|
|
new File(filename+"_"+APP_NAME+".txt"),
|
|
|
|
|
true ));
|
|
|
|
|
writer.append(jsonResponse.getBody().toString()+"\r\n");
|
|
|
|
|
writer.close();
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
// do something
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static <K, V> Map<K, V> sortByValue(Map<K, V> map) {
|
|
|
|
|
List<Map.Entry<K, V>> list = new LinkedList<>(map.entrySet());
|
|
|
|
|
Collections.sort(list, new Comparator<Object>() {
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
|
public int compare(Object o2, Object o1) {
|
|
|
|
|
return ((Comparable<V>) ((Map.Entry<K, V>) (o1)).getValue()).compareTo(((Map.Entry<K, V>) (o2)).getValue());
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
Map<K, V> result = new LinkedHashMap<>();
|
|
|
|
|
for (Iterator<Map.Entry<K, V>> it = list.iterator(); it.hasNext();) {
|
|
|
|
|
Map.Entry<K, V> entry = (Map.Entry<K, V>) it.next();
|
|
|
|
|
result.put(entry.getKey(), entry.getValue());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static int calculatePercentage(Double first, Double second) {
|
|
|
|
|
Double d = (1 - first / second) * 100;
|
|
|
|
|
|
|
|
|
|
return Math.abs(d.intValue());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static void analyzeAverage(String shortname) throws UnirestException {
|
|
|
|
|
HttpResponse<JsonNode> jsonResponse = Unirest.get("https://min-api.cryptocompare.com/data/histominute")
|
|
|
|
|
.queryString("fsym", shortname)
|
|
|
|
|
.queryString("tsym", "EUR" )
|
|
|
|
|
.queryString("limit","10")
|
|
|
|
|
.queryString("aggregate","1")
|
|
|
|
|
.queryString("e","Kraken")
|
|
|
|
|
.asJson();
|
|
|
|
|
|
|
|
|
|
JSONArray dataArray = jsonResponse.getBody().getObject().getJSONArray("Data");
|
|
|
|
|
|
|
|
|
|
double priceAvg = dataArray.getJSONObject(0).getDouble("close");
|
|
|
|
|
double tmpPrice = priceAvg;
|
|
|
|
|
int numRising = 0;
|
|
|
|
|
int numFalling = 0;
|
|
|
|
|
|
|
|
|
|
for(int i = 1; i < dataArray.length(); i++){
|
|
|
|
|
JSONObject obj = dataArray.getJSONObject(i);
|
|
|
|
|
tmpPrice = obj.getDouble("close");
|
|
|
|
|
priceAvg += tmpPrice;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Integer seconds = (jsonResponse.getBody().getObject().getInt("TimeTo")-jsonResponse.getBody().getObject().getInt("TimeFrom")) / 60;
|
|
|
|
|
priceAvg = priceAvg / dataArray.length();
|
|
|
|
|
System.out.printf("Latest price: "+currentPrice+", calculated AVG from last "+seconds+ " minutes: %.2f€ ",priceAvg);
|
|
|
|
|
|
|
|
|
|
if(Double.compare(currentPrice,priceAvg) > 0){
|
|
|
|
|
buyindicator--;
|
|
|
|
|
}else{
|
|
|
|
|
buyindicator++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|