2017-06-30 23:24:19 +02:00
|
|
|
package nl.komtek.gpi.controllers;
|
|
|
|
|
2017-07-11 22:36:22 +02:00
|
|
|
import com.cf.data.map.poloniex.PoloniexDataMapper;
|
|
|
|
import com.cf.data.model.poloniex.PoloniexChartData;
|
2017-07-29 11:21:45 +02:00
|
|
|
import com.cf.data.model.poloniex.PoloniexCompleteBalance;
|
2017-07-11 22:36:22 +02:00
|
|
|
import com.cf.data.model.poloniex.PoloniexTradeHistory;
|
2017-06-30 23:24:19 +02:00
|
|
|
import com.google.gson.JsonArray;
|
|
|
|
import com.google.gson.JsonElement;
|
|
|
|
import com.google.gson.JsonObject;
|
|
|
|
import com.google.gson.JsonParser;
|
|
|
|
import nl.komtek.gpi.services.GunbotProxyService;
|
2017-07-13 23:16:03 +02:00
|
|
|
import nl.komtek.gpi.utils.Util;
|
2017-07-11 22:36:22 +02:00
|
|
|
import org.apache.logging.log4j.LogManager;
|
|
|
|
import org.apache.logging.log4j.Logger;
|
2017-06-30 23:24:19 +02:00
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
2017-07-04 00:23:39 +02:00
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
2017-06-30 23:24:19 +02:00
|
|
|
import org.springframework.stereotype.Controller;
|
2017-07-21 06:46:53 +02:00
|
|
|
import org.springframework.util.StringUtils;
|
2017-06-30 23:24:19 +02:00
|
|
|
import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
|
import org.springframework.web.bind.annotation.RequestParam;
|
|
|
|
import org.springframework.web.bind.annotation.ResponseBody;
|
|
|
|
|
|
|
|
import javax.servlet.http.HttpServletRequest;
|
2017-07-13 23:16:03 +02:00
|
|
|
import javax.servlet.http.HttpServletResponse;
|
2017-07-14 20:27:10 +02:00
|
|
|
import java.io.IOException;
|
2017-06-30 23:24:19 +02:00
|
|
|
import java.math.BigDecimal;
|
2017-07-11 22:36:22 +02:00
|
|
|
import java.time.ZoneOffset;
|
2017-07-14 23:07:30 +02:00
|
|
|
import java.util.Arrays;
|
2017-07-29 11:21:24 +02:00
|
|
|
import java.util.Calendar;
|
2017-07-14 23:07:30 +02:00
|
|
|
import java.util.Iterator;
|
2017-07-11 22:36:22 +02:00
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
2017-06-30 23:24:19 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Created by Elroy on 17-6-2017.
|
|
|
|
*/
|
|
|
|
@Controller
|
|
|
|
public class GunbotProxyController {
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
private GunbotProxyService gunbotProxyService;
|
2017-07-04 00:23:39 +02:00
|
|
|
@Value("${doubleBuyProtection:false}")
|
|
|
|
private boolean doubleBuyProtection;
|
2017-07-12 22:23:05 +02:00
|
|
|
@Value("${doubleBuyProtectionSeconds:0}")
|
|
|
|
private int doubleBuyProtectionSeconds;
|
2017-07-13 23:16:03 +02:00
|
|
|
@Autowired
|
|
|
|
private Util util;
|
2017-07-11 22:36:22 +02:00
|
|
|
private Logger logger = LogManager.getLogger(GunbotProxyController.class);
|
|
|
|
private PoloniexDataMapper mapper = new PoloniexDataMapper();
|
2017-06-30 23:24:19 +02:00
|
|
|
|
|
|
|
@RequestMapping(value = "/public/**")
|
|
|
|
@ResponseBody
|
|
|
|
public String interceptAllCalls(HttpServletRequest request) {
|
2017-07-29 11:21:24 +02:00
|
|
|
logger.info("intercepted -- " + request.getRequestURL() + "?" + request.getQueryString() + "?command=" + request.getParameter("command"));
|
2017-06-30 23:24:19 +02:00
|
|
|
return "intercepted";
|
|
|
|
}
|
|
|
|
|
2017-07-29 11:21:24 +02:00
|
|
|
@RequestMapping(value = "/tradingApi/**")
|
|
|
|
@ResponseBody
|
|
|
|
public String tradingRequests(HttpServletRequest request) {
|
|
|
|
logger.debug(request.getRequestURL() + "??command=" + request.getParameter("command"));
|
|
|
|
request.getParameterMap().keySet().forEach((e) -> System.out.print(e + "-"));
|
|
|
|
return "trading api intercepted";
|
|
|
|
}
|
|
|
|
|
2017-07-29 11:21:45 +02:00
|
|
|
@RequestMapping(value = "/public/**", params = "command=returnOrderBook")
|
2017-07-29 11:21:24 +02:00
|
|
|
@ResponseBody
|
|
|
|
public String publicRequestOrderBook(@RequestParam String currencyPair) {
|
|
|
|
return gunbotProxyService.getOrderBook(currencyPair);
|
|
|
|
}
|
|
|
|
|
|
|
|
@RequestMapping(value = "/public/**", params = "command=return24hVolume")
|
|
|
|
@ResponseBody
|
|
|
|
public String publicRequest24hVolume() {
|
|
|
|
return gunbotProxyService.get24hVolume();
|
|
|
|
}
|
|
|
|
|
|
|
|
@RequestMapping(value = "/public/**", params = "command=returnTradeHistory")
|
|
|
|
@ResponseBody
|
|
|
|
public String publicRequestTradeHistory(@RequestParam String currencyPair,
|
|
|
|
@RequestParam(required = false) String start,
|
|
|
|
@RequestParam(required = false) String end) {
|
|
|
|
final long startLong;
|
|
|
|
if (start.indexOf(".") > 0) {
|
|
|
|
startLong = Long.valueOf(start.substring(0, start.indexOf(".")));
|
|
|
|
} else {
|
|
|
|
startLong = Long.valueOf(start);
|
|
|
|
}
|
|
|
|
final long endLong;
|
|
|
|
if (end == null) {
|
|
|
|
Calendar cal = Calendar.getInstance();
|
|
|
|
endLong = cal.getTimeInMillis() / 1000;
|
|
|
|
} else if (end.indexOf(".") > 0) {
|
|
|
|
endLong = Long.valueOf(end.substring(0, end.indexOf(".")));
|
|
|
|
} else {
|
|
|
|
endLong = Long.valueOf(end);
|
|
|
|
}
|
|
|
|
return gunbotProxyService.getPublicTradeHistory(currencyPair, startLong, endLong);
|
|
|
|
}
|
|
|
|
|
2017-06-30 23:24:19 +02:00
|
|
|
@RequestMapping(value = "/public/**", params = "command=returnChartData")
|
|
|
|
@ResponseBody
|
|
|
|
public String publicRequestChartData(HttpServletRequest request,
|
|
|
|
@RequestParam String currencyPair,
|
|
|
|
@RequestParam String start,
|
|
|
|
@RequestParam long period) throws InterruptedException {
|
|
|
|
|
2017-07-11 22:36:22 +02:00
|
|
|
String result = gunbotProxyService.getChartData(currencyPair, period);
|
|
|
|
|
2017-07-12 08:26:47 +02:00
|
|
|
return filterChartDataByDate(start, result);
|
2017-06-30 23:24:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@RequestMapping(value = "/public/**", params = "command=returnTicker")
|
|
|
|
@ResponseBody
|
|
|
|
public String publicRequestTicker() {
|
|
|
|
return gunbotProxyService.getTicker();
|
|
|
|
}
|
|
|
|
|
|
|
|
@RequestMapping(value = "/tradingApi/**", params = "command=returnCompleteBalances")
|
|
|
|
@ResponseBody
|
|
|
|
public String tradingRequestCompleteBalances(HttpServletRequest request) {
|
2017-07-04 00:23:39 +02:00
|
|
|
|
|
|
|
String market = "default";
|
|
|
|
if (gunbotProxyService.isUsingMultipleMarkets()) {
|
|
|
|
String key = request.getHeader("key");
|
|
|
|
market = gunbotProxyService.getMarket(key);
|
|
|
|
}
|
2017-07-29 11:21:45 +02:00
|
|
|
String result = gunbotProxyService.getCompleteBalances(market);
|
|
|
|
result = hideDust(result);
|
|
|
|
|
|
|
|
return result;
|
2017-06-30 23:24:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@RequestMapping(value = "/tradingApi/**", params = "command=returnOpenOrders")
|
|
|
|
@ResponseBody
|
|
|
|
public String tradingRequestOpenOrders(HttpServletRequest request,
|
|
|
|
@RequestParam String currencyPair) {
|
2017-07-04 00:23:39 +02:00
|
|
|
String market = "default";
|
|
|
|
if (gunbotProxyService.isUsingMultipleMarkets()) {
|
|
|
|
String key = request.getHeader("key");
|
|
|
|
market = gunbotProxyService.getMarket(key);
|
|
|
|
}
|
|
|
|
String result = gunbotProxyService.getOpenOrders(market);
|
2017-06-30 23:24:19 +02:00
|
|
|
|
2017-07-11 22:36:22 +02:00
|
|
|
JsonElement jElement = new JsonParser().parse(result);
|
|
|
|
JsonObject jObject = jElement.getAsJsonObject();
|
2017-07-14 23:07:30 +02:00
|
|
|
JsonArray jArray = hideOpenOrders(jObject.getAsJsonArray(currencyPair));
|
2017-07-11 22:36:22 +02:00
|
|
|
return jArray != null ? jArray.toString() : "[]";
|
2017-06-30 23:24:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@RequestMapping(value = "/tradingApi/**", params = "command=returnTradeHistory")
|
|
|
|
@ResponseBody
|
|
|
|
public String tradingRequestTradeHistory(HttpServletRequest request,
|
2017-07-11 22:36:22 +02:00
|
|
|
@RequestParam String currencyPair,
|
|
|
|
@RequestParam(required = false) String start) {
|
2017-06-30 23:24:19 +02:00
|
|
|
|
2017-07-04 00:23:39 +02:00
|
|
|
String market = "default";
|
|
|
|
if (gunbotProxyService.isUsingMultipleMarkets()) {
|
|
|
|
String key = request.getHeader("key");
|
|
|
|
market = gunbotProxyService.getMarket(key);
|
|
|
|
}
|
|
|
|
String result = gunbotProxyService.getTradeHistory(market);
|
2017-06-30 23:24:19 +02:00
|
|
|
|
2017-07-11 22:36:22 +02:00
|
|
|
return filterTradeHistoryByDate(currencyPair, start, result);
|
2017-06-30 23:24:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@RequestMapping(value = "/tradingApi/**", params = "command=cancelOrder")
|
|
|
|
@ResponseBody
|
|
|
|
public String tradingRequestCancelOrder(HttpServletRequest request,
|
|
|
|
@RequestParam String orderNumber) {
|
|
|
|
|
2017-07-04 00:23:39 +02:00
|
|
|
String key = request.getHeader("key");
|
|
|
|
return gunbotProxyService.cancelOrder(key, orderNumber);
|
2017-06-30 23:24:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@RequestMapping(value = "/tradingApi/**", params = "command=sell")
|
|
|
|
@ResponseBody
|
|
|
|
public String tradingRequestSell(HttpServletRequest request,
|
|
|
|
@RequestParam String currencyPair,
|
|
|
|
@RequestParam BigDecimal rate,
|
|
|
|
@RequestParam BigDecimal amount) {
|
2017-07-04 00:23:39 +02:00
|
|
|
String key = request.getHeader("key");
|
|
|
|
return gunbotProxyService.sellOrder(key, currencyPair, rate, amount);
|
2017-06-30 23:24:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@RequestMapping(value = "/tradingApi/**", params = "command=buy")
|
|
|
|
@ResponseBody
|
|
|
|
public String tradingRequestBuy(HttpServletRequest request,
|
2017-07-13 23:16:03 +02:00
|
|
|
HttpServletResponse response,
|
2017-06-30 23:24:19 +02:00
|
|
|
@RequestParam String currencyPair,
|
|
|
|
@RequestParam BigDecimal rate,
|
2017-07-14 20:27:10 +02:00
|
|
|
@RequestParam BigDecimal amount) throws IOException {
|
2017-06-30 23:24:19 +02:00
|
|
|
|
2017-07-13 23:16:03 +02:00
|
|
|
boolean globalSellOnlyMode = Boolean.parseBoolean(util.getConfigurationProperty("sellOnlyMode"));
|
|
|
|
boolean pairSellOnlyMode = Boolean.parseBoolean(util.getConfigurationProperty(String.format("%s_sellOnlyMode", currencyPair)));
|
|
|
|
if (globalSellOnlyMode || pairSellOnlyMode) {
|
2017-07-14 20:27:10 +02:00
|
|
|
JsonObject jsonObject = new JsonObject();
|
2017-07-13 23:16:03 +02:00
|
|
|
String message = String.format("You are not allowed to buy. Sell Only mode is active for %s", currencyPair);
|
2017-07-14 20:27:10 +02:00
|
|
|
jsonObject.addProperty("error", message);
|
|
|
|
logger.info(jsonObject.toString());
|
|
|
|
return jsonObject.toString();
|
2017-07-13 23:16:03 +02:00
|
|
|
}
|
|
|
|
|
2017-07-04 00:23:39 +02:00
|
|
|
String key = request.getHeader("key");
|
2017-07-12 22:23:05 +02:00
|
|
|
if (doubleBuyProtection || doubleBuyProtectionSeconds > 0) {
|
2017-07-04 00:23:39 +02:00
|
|
|
return gunbotProxyService.buyOrderWithProtection(key, currencyPair, rate, amount);
|
|
|
|
} else {
|
|
|
|
return gunbotProxyService.buyOrder(key, currencyPair, rate, amount);
|
|
|
|
}
|
2017-06-30 23:24:19 +02:00
|
|
|
}
|
2017-07-11 22:36:22 +02:00
|
|
|
|
|
|
|
private String filterTradeHistoryByDate(String currency, String start, String result) {
|
|
|
|
final long startLong;
|
|
|
|
if (start.indexOf(".") > 0) {
|
|
|
|
startLong = Long.valueOf(start.substring(0, start.indexOf(".")));
|
|
|
|
} else {
|
|
|
|
startLong = Long.valueOf(start);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (result.equals("[]")) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
JsonParser jsonParser = new JsonParser();
|
|
|
|
JsonElement jElement = jsonParser.parse(result);
|
|
|
|
JsonObject jObject = jElement.getAsJsonObject();
|
|
|
|
JsonObject filteredjObject = new JsonObject();
|
|
|
|
for (Map.Entry entry : jObject.entrySet()) {
|
|
|
|
if (!currency.equalsIgnoreCase("all") && !currency.equalsIgnoreCase(entry.getKey().toString())) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-07-12 08:26:47 +02:00
|
|
|
List<PoloniexTradeHistory> tradeHistory = mapper.mapTradeHistory(entry.getValue().toString());
|
|
|
|
JsonArray filteredjArray = new JsonArray();
|
2017-07-11 22:36:22 +02:00
|
|
|
tradeHistory.stream()
|
|
|
|
.filter(e -> e.date.toEpochSecond(ZoneOffset.UTC) >= startLong)
|
|
|
|
.map(e -> jsonParser.parse(e.toString()))
|
|
|
|
.forEach(filteredjArray::add);
|
|
|
|
|
|
|
|
filteredjObject.add(entry.getKey().toString(), filteredjArray);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (currency.equals("all")) {
|
|
|
|
return (filteredjObject.entrySet().size() == 0) ? "[]" : filteredjObject.toString();
|
|
|
|
} else {
|
2017-07-12 08:26:47 +02:00
|
|
|
return (filteredjObject.entrySet().size() == 0) ? "[]" : filteredjObject.getAsJsonArray(currency).toString();
|
2017-07-11 22:36:22 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private String filterChartDataByDate(String start, String result) {
|
|
|
|
final long startLong;
|
|
|
|
if (start.indexOf(".") > 0) {
|
|
|
|
startLong = Long.valueOf(start.substring(0, start.indexOf(".")));
|
|
|
|
} else {
|
|
|
|
startLong = Long.valueOf(start);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (result.equals("[]")) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-07-14 23:07:30 +02:00
|
|
|
if (result.contains("error")) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-07-11 22:36:22 +02:00
|
|
|
List<PoloniexChartData> chartData = mapper.mapChartData(result);
|
|
|
|
|
|
|
|
JsonParser jsonParser = new JsonParser();
|
|
|
|
JsonArray filteredjArray = new JsonArray();
|
|
|
|
chartData.stream()
|
|
|
|
.filter(e -> e.date >= startLong)
|
|
|
|
.map(e -> jsonParser.parse(e.toString()))
|
|
|
|
.forEach(filteredjArray::add);
|
|
|
|
|
|
|
|
return filteredjArray.toString();
|
|
|
|
}
|
2017-07-14 23:07:30 +02:00
|
|
|
|
2017-07-29 11:21:24 +02:00
|
|
|
private JsonArray hideOpenOrders(JsonArray jsonArray) {
|
2017-07-14 23:07:30 +02:00
|
|
|
|
|
|
|
for (Iterator<JsonElement> it = jsonArray.iterator(); it.hasNext(); ) {
|
|
|
|
JsonElement element = it.next();
|
|
|
|
JsonObject jsonObject = element.getAsJsonObject();
|
|
|
|
String orderNumber = jsonObject.get("orderNumber").getAsString();
|
2017-07-29 11:21:24 +02:00
|
|
|
String[] orderNumbersToHide = StringUtils.trimAllWhitespace(util.getConfigurationProperty("hideOrders", "")).split(",");
|
|
|
|
if (Arrays.asList(orderNumbersToHide).contains(orderNumber)) {
|
2017-07-14 23:07:30 +02:00
|
|
|
it.remove();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return jsonArray;
|
|
|
|
}
|
2017-07-29 11:21:45 +02:00
|
|
|
|
|
|
|
private String hideDust(String result) {
|
|
|
|
boolean hidedust = Boolean.parseBoolean(util.getConfigurationProperty("hideDust"));
|
|
|
|
if (!hidedust) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
JsonParser jsonParser = new JsonParser();
|
|
|
|
JsonElement jElement = jsonParser.parse(result);
|
|
|
|
JsonObject jObject = jElement.getAsJsonObject();
|
|
|
|
JsonObject filteredObject = new JsonObject();
|
|
|
|
for (Map.Entry entry : jObject.entrySet()) {
|
|
|
|
JsonElement element = (JsonElement) entry.getValue();
|
|
|
|
BigDecimal available = BigDecimal.valueOf(element.getAsJsonObject().get("available").getAsDouble());
|
|
|
|
BigDecimal onOrders = BigDecimal.valueOf(element.getAsJsonObject().get("onOrders").getAsDouble());
|
|
|
|
BigDecimal btcValue = BigDecimal.valueOf(element.getAsJsonObject().get("btcValue").getAsDouble());
|
|
|
|
|
|
|
|
if (available.doubleValue() == 0) {
|
2017-07-29 16:51:08 +02:00
|
|
|
filteredObject.add(entry.getKey().toString(), element);
|
2017-07-29 11:21:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
double approximatePrice = btcValue.doubleValue() / available.add(onOrders).doubleValue();
|
|
|
|
double availableValue = available.doubleValue() * approximatePrice;
|
|
|
|
if (availableValue < 0.00015) {
|
|
|
|
available = BigDecimal.ZERO;
|
|
|
|
}
|
|
|
|
PoloniexCompleteBalance balance = new PoloniexCompleteBalance(available, onOrders, btcValue);
|
|
|
|
filteredObject.add(entry.getKey().toString(), jsonParser.parse(balance.toString()));
|
|
|
|
}
|
|
|
|
return filteredObject.toString();
|
|
|
|
}
|
2017-06-30 23:24:19 +02:00
|
|
|
}
|