removed all code, this is old proxy code

This commit is contained in:
elroy 2017-10-21 21:19:33 +02:00
parent 473623565c
commit 798384bf03
25 changed files with 0 additions and 1993 deletions

4
.gitignore vendored
View File

@ -1,4 +0,0 @@
target
.idea
application.properties
logs

21
LICENSE
View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2017 taniman
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
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 OR COPYRIGHT HOLDERS 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.

View File

@ -1 +0,0 @@
theme: jekyll-theme-cayman

141
pom.xml
View File

@ -1,141 +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>nl.komtek</groupId>
<artifactId>GunbotProxyCommunity</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>GunbotProxyCommunity</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>4.3.7.RELEASE</spring.version>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!--Logging-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jcl</artifactId>
<version>2.8.2</version>
</dependency>
<!--other-->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.1</version>
</dependency>
<dependency>
<groupId>com.cf</groupId>
<artifactId>PoloniexClient</artifactId>
<version>1.1.4</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.9.0</version>
</dependency>
<!-- Spring caching framework inside this -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Support for Ehcache and others -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.9</version>
</dependency>
<dependency>
<groupId>net.jodah</groupId>
<artifactId>failsafe</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>eu.verdelhan</groupId>
<artifactId>ta4j</artifactId>
<version>0.8</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,120 +0,0 @@
package nl.komtek.gpi.application;
import net.sf.ehcache.Cache;
import org.apache.catalina.connector.Connector;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
/**
* Created by Elroy on 29-6-2017.
*/
@SpringBootApplication
@Configuration
@EnableScheduling
@EnableAsync
@EnableCaching
@ComponentScan(basePackages = "nl.komtek.gpi")
public class Application {
@Value("${server.additionalPort:8081}")
private int additionalPort;
@Value("${server.address:0.0.0.0}")
private String serverAddress;
@Value("${doubleBuyProtectionSeconds:0}")
private int doubleBuyProtectionSeconds;
@Value("${doubleBuyProtection:false}")
private boolean doubleBuyProtection;
public static void main(String[] args) {
Map<String, Object> props = new HashMap<>();
props.put("server.port", 443);
props.put("server.ssl.key-store", "classpath:poloniex.keystore");
props.put("server.ssl.key-store-password", "poloniex");
props.put("server.ssl.key-password", "poloniex");
new SpringApplicationBuilder()
.sources(Application.class)
.properties(props)
.run(args);
}
@Bean
public CacheManager cacheManager() {
net.sf.ehcache.CacheManager cacheManager = ehCacheCacheManager().getObject();
Cache tickerCache = new Cache("ticker", 500, false, true, 0, 0);
Cache tradeHistoryCache = new Cache("tradeHistory", 500, false, true, 0, 0);
Cache openOrdersCache = new Cache("openOrders", 500, false, true, 0, 0);
Cache completeBalancesCache = new Cache("completeBalances", 5, false, true, 0, 0);
Cache chartDataCache = new Cache("chartData", 500, false, false, 30, 30);
Cache balancesCache = new Cache("balances", 5, false, true, 0, 0);
Cache orderBookCache = new Cache("orderBook", 100, true, false, 5, 5);
Cache publicTradeHistoryCache = new Cache("publicTradeHistory", 500, true, false, 5, 5);
cacheManager.addCache(tickerCache);
cacheManager.addCache(tradeHistoryCache);
cacheManager.addCache(openOrdersCache);
cacheManager.addCache(completeBalancesCache);
cacheManager.addCache(chartDataCache);
cacheManager.addCache(balancesCache);
cacheManager.addCache(orderBookCache);
cacheManager.addCache(publicTradeHistoryCache);
if (doubleBuyProtectionSeconds > 0) {
Cache buyOrderProtectionCache = new Cache("buyOrderProtection", 100, false, false, doubleBuyProtectionSeconds, doubleBuyProtectionSeconds);
cacheManager.addCache(buyOrderProtectionCache);
} else if (doubleBuyProtection) {
Cache buyOrderProtectionCache = new Cache("buyOrderProtection", 100, false, false, 30, 30);
cacheManager.addCache(buyOrderProtectionCache);
}
return new EhCacheCacheManager(cacheManager);
}
@Bean
public EhCacheManagerFactoryBean ehCacheCacheManager() {
EhCacheManagerFactoryBean factory = new EhCacheManagerFactoryBean();
factory.setShared(true);
return factory;
}
@Bean
public TaskScheduler taskScheduler() {
return new ConcurrentTaskScheduler(Executors.newScheduledThreadPool(4));
}
@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
tomcat.addAdditionalTomcatConnectors(additionalConnector());
return tomcat;
}
private Connector additionalConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
connector.setPort(additionalPort);
if (!serverAddress.equals("0.0.0.0")) {
connector.setAttribute("address", serverAddress);
}
return connector;
}
}

View File

@ -1,176 +0,0 @@
package nl.komtek.gpi.controllers;
import nl.komtek.gpi.services.GunbotProxyService;
import nl.komtek.gpi.utils.Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Created by Elroy on 10-7-2017.
*/
@Controller
public class CheckSetupController {
@Autowired
private GunbotProxyService gunbotProxyService;
@Autowired
private Util util;
@RequestMapping("/checkSetup/**")
public ModelAndView checkSetup(ModelMap modelMap) {
modelMap.put("setupData", setupData(false));
return new ModelAndView("setupData", modelMap);
}
@ResponseBody
@RequestMapping("/checkSetupLinux/**")
public String checkSetupLinux() throws IOException {
StringBuilder stringData = new StringBuilder();
stringData.append("\n\n");
Map<String, String> setupData = setupData(false);
setupData.forEach((key, value) -> stringData.append(String.format("%s -- %s \n", key, value)));
return stringData.toString();
}
@RequestMapping("/checkSetupSecret/**")
public ModelAndView checkSetupSecret(ModelMap modelMap) {
modelMap.put("setupData", setupData(true));
return new ModelAndView("setupData", modelMap);
}
@ResponseBody
@RequestMapping("/checkSetupLinuxSecret/**")
public String checkSetupLinuxSecret() throws IOException {
StringBuilder stringData = new StringBuilder();
stringData.append("\n\n");
Map<String, String> setupData = setupData(true);
setupData.forEach((key, value) -> stringData.append(String.format("%s -- %s \n", key, value)));
return stringData.toString();
}
private Map<String, String> setupData(boolean showSecret) {
Map<String, String> setupData = new LinkedHashMap<>();
if (!gunbotProxyService.isUsingMultipleMarkets()) {
checkApiKeysForMarket(setupData, "", showSecret);
} else {
if (gunbotProxyService.isActiveMarket("BTC")) {
checkApiKeysForMarket(setupData, "BTC_", showSecret);
}
if (gunbotProxyService.isActiveMarket("ETH")) {
checkApiKeysForMarket(setupData, "ETH_", showSecret);
}
if (gunbotProxyService.isActiveMarket("XMR")) {
checkApiKeysForMarket(setupData, "XMR_", showSecret);
}
if (gunbotProxyService.isActiveMarket("USDT")) {
checkApiKeysForMarket(setupData, "USDT_", showSecret);
}
}
//check if hostfile was setup correctly
try {
InetAddress address = InetAddress.getByName("poloniex.com");
if (address.getHostAddress().equals("127.0.0.1")) {
setupData.put(String.format("hostfile (%s)", address.getHostAddress()), "Looking good!");
} else {
setupData.put(String.format("hostfile (%s)", address.getHostAddress()), "poloniex.com is not pointing to 127.0.0.1");
}
} catch (UnknownHostException e) {
setupData.put("hostfile", e.getMessage());
}
try {
InetAddress address = InetAddress.getByName("www.poloniex.com");
if (!address.getHostAddress().equals("127.0.0.1")) {
setupData.put(String.format("www.poloniex.com (%s)", address.getHostAddress()), "Looking good!");
} else {
setupData.put(String.format("www.poloniex.com (%s)", address.getHostAddress()), "www.poloniex.com should not point to 127.0.0.1");
}
} catch (UnknownHostException e) {
setupData.put("www.poloniex.com", e.getMessage());
}
String gunbotLocation = util.getEnvProperty("gunbot.location");
if (!StringUtils.isEmpty(gunbotLocation.length())) {
if (!gunbotLocation.startsWith("file://")) {
setupData.put("Gunbot location (Optional)", "Your file location should start with 'file://'");
} else {
File file = new File(gunbotLocation.replace("file://", ""));
if (file.exists()) {
setupData.put("Gunbot location (Optional)", "Looking good!");
} else {
setupData.put("Gunbot location (Optional)", "The specified location does not exist");
}
}
} else {
setupData.put("Gunbot location (Optional)", "You cannot use monitoring without this");
}
return setupData;
}
private void checkApiKeysForMarket(Map<String, String> setupData, String market, boolean showSecret) {
String keyName = String.format("default_%sapiKey", market);
String secretName = String.format("default_%sapiSecret", market);
try {
String apiKey = util.getEnvProperty(keyName);
String apiSecret = util.getEnvProperty(secretName);
if (StringUtils.isEmpty(apiKey) || StringUtils.isEmpty(apiSecret)) {
setupData.put(keyName, String.format("Please setup %s and %s", keyName, secretName));
} else {
if (showSecret) {
setupData.put(String.format("Your Key %s", keyName), String.format("**%s**", apiKey));
setupData.put(String.format("Your Secret %s", secretName), String.format("**%s**", apiSecret));
}
String theMarket = market.replace("_", "");
if (StringUtils.isEmpty(theMarket)) {
theMarket = "default";
}
gunbotProxyService.analyzeResult(gunbotProxyService.checkDefaultKey(theMarket));
setupData.put(keyName, "Looking good!");
}
} catch (Exception e) {
setupData.put(keyName + "", e.getMessage());
}
for (int i = 1; i <= 10; i++) {
keyName = String.format("%sapiKey%d", market, i);
secretName = String.format("%sapiSecret%d", market, i);
String apiKey = util.getEnvProperty(keyName);
String apiSecret = util.getEnvProperty(secretName);
if (i == 1 && (StringUtils.isEmpty(apiKey) || StringUtils.isEmpty(apiSecret))) {
setupData.put(keyName, String.format("Please setup %s and %s", keyName, secretName));
break;
}
if (StringUtils.isEmpty(apiKey) || StringUtils.isEmpty(apiSecret)) {
break;
}
try {
if (showSecret) {
setupData.put(String.format("Your Key %s", keyName), String.format("**%s**", apiKey));
setupData.put(String.format("Your Secret %s", secretName), String.format("**%s**", apiSecret));
}
if (StringUtils.isEmpty(market)) {
gunbotProxyService.analyzeResult(gunbotProxyService.checkTradingKey(apiKey));
} else {
gunbotProxyService.analyzeResult(gunbotProxyService.checkMultiMarketTradingKey(apiKey));
}
setupData.put(keyName, "Looking good!");
} catch (Exception e) {
setupData.put(keyName, e.getMessage());
}
}
}
}

View File

@ -1,289 +0,0 @@
package nl.komtek.gpi.controllers;
import com.cf.data.map.poloniex.PoloniexDataMapper;
import com.cf.data.model.poloniex.PoloniexChartData;
import com.cf.data.model.poloniex.PoloniexTradeHistory;
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;
import nl.komtek.gpi.utils.Util;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
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;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.ZoneOffset;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Created by Elroy on 17-6-2017.
*/
@Controller
public class GunbotProxyController {
@Autowired
private GunbotProxyService gunbotProxyService;
@Value("${doubleBuyProtection:false}")
private boolean doubleBuyProtection;
@Value("${doubleBuyProtectionSeconds:0}")
private int doubleBuyProtectionSeconds;
@Autowired
private Util util;
private Logger logger = LogManager.getLogger(GunbotProxyController.class);
private PoloniexDataMapper mapper = new PoloniexDataMapper();
@RequestMapping(value = "/public/**")
@ResponseBody
public String interceptAllCalls(HttpServletRequest request) {
logger.info("intercepted -- " + request.getRequestURL() + "?" + request.getQueryString() + "?command=" + request.getParameter("command"));
return "intercepted";
}
@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";
}
@RequestMapping(value = "/public/**", params = "command=returnOrderBook")
@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) {
long startLong;
if (start.indexOf(".") > 0) {
//Special fix for gunbot
String tradeHistoryMinutes = util.getConfigurationProperty("tradeHistoryMinutes");
Integer tradeHistory = 120;
if (tradeHistoryMinutes != null) {
try {
tradeHistory = Integer.parseInt(util.getConfigurationProperty("tradeHistoryMinutes"));
} catch (NumberFormatException e) {
}
}
Calendar calStart = Calendar.getInstance();
calStart.add(Calendar.MINUTE, -tradeHistory);
startLong = calStart.getTimeInMillis() / 1000;
} else {
startLong = Long.valueOf(start);
}
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);
}
@RequestMapping(value = "/public/**", params = "command=returnChartData")
@ResponseBody
public String publicRequestChartData(HttpServletRequest request,
@RequestParam String currencyPair,
@RequestParam String start,
@RequestParam long period) throws InterruptedException {
String result = gunbotProxyService.getChartData(currencyPair, period);
return filterChartDataByDate(start, result);
}
@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) {
String market = "default";
if (gunbotProxyService.isUsingMultipleMarkets()) {
String key = request.getHeader("key");
market = gunbotProxyService.getMarket(key);
}
return gunbotProxyService.getCompleteBalances(market);
}
@RequestMapping(value = "/tradingApi/**", params = "command=returnOpenOrders")
@ResponseBody
public String tradingRequestOpenOrders(HttpServletRequest request,
@RequestParam String currencyPair) {
String market = "default";
if (gunbotProxyService.isUsingMultipleMarkets()) {
String key = request.getHeader("key");
market = gunbotProxyService.getMarket(key);
}
String result = gunbotProxyService.getOpenOrders(market);
JsonElement jElement = new JsonParser().parse(result);
JsonObject jObject = jElement.getAsJsonObject();
JsonArray jArray = hideOpenOrders(jObject.getAsJsonArray(currencyPair));
return jArray != null ? jArray.toString() : "[]";
}
@RequestMapping(value = "/tradingApi/**", params = "command=returnTradeHistory")
@ResponseBody
public String tradingRequestTradeHistory(HttpServletRequest request,
@RequestParam String currencyPair,
@RequestParam(required = false) String start) {
String market = "default";
if (gunbotProxyService.isUsingMultipleMarkets()) {
String key = request.getHeader("key");
market = gunbotProxyService.getMarket(key);
}
String result = gunbotProxyService.getTradeHistory(market);
return filterTradeHistoryByDate(currencyPair, start, result);
}
@RequestMapping(value = "/tradingApi/**", params = "command=cancelOrder")
@ResponseBody
public String tradingRequestCancelOrder(HttpServletRequest request,
@RequestParam String orderNumber) {
String key = request.getHeader("key");
return gunbotProxyService.cancelOrder(key, orderNumber);
}
@RequestMapping(value = "/tradingApi/**", params = "command=sell")
@ResponseBody
public String tradingRequestSell(HttpServletRequest request,
@RequestParam String currencyPair,
@RequestParam BigDecimal rate,
@RequestParam BigDecimal amount) {
String key = request.getHeader("key");
return gunbotProxyService.sellOrder(key, currencyPair, rate, amount);
}
@RequestMapping(value = "/tradingApi/**", params = "command=buy")
@ResponseBody
public String tradingRequestBuy(HttpServletRequest request,
HttpServletResponse response,
@RequestParam String currencyPair,
@RequestParam BigDecimal rate,
@RequestParam BigDecimal amount) throws IOException {
String key = request.getHeader("key");
if (doubleBuyProtection || doubleBuyProtectionSeconds > 0) {
return gunbotProxyService.buyOrderWithProtection(key, currencyPair, rate, amount);
} else {
return gunbotProxyService.buyOrder(key, currencyPair, rate, amount);
}
}
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;
}
List<PoloniexTradeHistory> tradeHistory = mapper.mapTradeHistory(entry.getValue().toString());
JsonArray filteredjArray = new JsonArray();
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 {
return (filteredjObject.entrySet().size() == 0) ? "[]" : filteredjObject.getAsJsonArray(currency).toString();
}
}
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;
}
if (result.contains("error")) {
return result;
}
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();
}
private JsonArray hideOpenOrders(JsonArray jsonArray) {
for (Iterator<JsonElement> it = jsonArray.iterator(); it.hasNext(); ) {
JsonElement element = it.next();
JsonObject jsonObject = element.getAsJsonObject();
String orderNumber = jsonObject.get("orderNumber").getAsString();
String[] orderNumbersToHide = StringUtils.trimAllWhitespace(util.getConfigurationProperty("hideOrders", "")).split(",");
if (Arrays.asList(orderNumbersToHide).contains(orderNumber)) {
it.remove();
}
}
return jsonArray;
}
}

View File

@ -1,69 +0,0 @@
package nl.komtek.gpi.controllers;
import com.google.gson.Gson;
import nl.komtek.gpi.models.MonitoringData;
import nl.komtek.gpi.services.GunbotProxyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Elroy on 30-6-2017.
*/
@Controller
@RequestMapping("/monitoring/**")
public class MonitoringController {
@Autowired
private ResourceLoader resourceLoader;
@Autowired
private ResourcePatternResolver resourcePatternResolver;
@Value("${gunbot.location:}")
private String gunbotLocation;
private Gson gson = new Gson();
@Autowired
private GunbotProxyService gunbotProxyService;
@RequestMapping
public ModelAndView monitoring(ModelMap modelMap) throws IOException, InterruptedException {
String saveFilePatern = gunbotLocation.endsWith("/") ? gunbotLocation + "*-save.json" : gunbotLocation + "/*-save.json";
String logFilePatern = gunbotLocation.endsWith("/") ? gunbotLocation + "*-log.txt" : gunbotLocation + "/*-log.txt";
Resource[] saveResources = resourcePatternResolver.getResources(saveFilePatern);
Resource[] logResources = resourcePatternResolver.getResources(logFilePatern);
List<String> logPaths = new ArrayList<>();
for (Resource resource : logResources) {
logPaths.add(resource.getFilename().replace("-log.txt", ""));
}
List<MonitoringData> monitoringDatas = new ArrayList<>();
for (Resource resource : saveResources) {
String tmpName = resource.getFilename().replace("-save.json", "");
if (!logPaths.contains(tmpName)) {
continue;
}
byte[] data = Files.readAllBytes(resource.getFile().toPath());
monitoringDatas.add(gson.fromJson(new String(data), MonitoringData.class));
}
modelMap.put("monitoringDatas", monitoringDatas);
String market = "default";
if (gunbotProxyService.isUsingMultipleMarkets()) {
market = "BTC";
}
modelMap.put("balance", gunbotProxyService.getBTCBalance(market));
modelMap.put("gunbotLocation", !StringUtils.isEmpty(gunbotLocation));
return new ModelAndView("index", modelMap);
}
}

View File

@ -1,17 +0,0 @@
package nl.komtek.gpi.models;
/**
* Created by Elroy on 30-6-2017.
*/
public class Market {
private String _pair;
public String get_pair() {
return _pair;
}
public void set_pair(String _pair) {
this._pair = _pair;
}
}

View File

@ -1,89 +0,0 @@
package nl.komtek.gpi.models;
/**
* Created by Elroy on 30-6-2017.
*/
public class MonitoringData {
private Market market;
private Double altcoinBalance;
private Double lastPrice;
private Double boughtPrice;
private Double priceToBuy;
private Double priceToSell;
private Double soldPrice;
private String reason;
public MonitoringData(Market market, Double altcoinBalance, Double lastPrice, Double boughtPrice, Double priceToBuy, Double soldPrice) {
this.market = market;
this.altcoinBalance = altcoinBalance;
this.lastPrice = lastPrice;
this.boughtPrice = boughtPrice;
this.priceToBuy = priceToBuy;
this.soldPrice = soldPrice;
}
public Market getMarket() {
return market;
}
public void setMarket(Market market) {
this.market = market;
}
public Double getAltcoinBalance() {
return altcoinBalance;
}
public void setAltcoinBalance(Double altcoinBalance) {
this.altcoinBalance = altcoinBalance;
}
public Double getLastPrice() {
return lastPrice;
}
public void setLastPrice(Double lastPrice) {
this.lastPrice = lastPrice;
}
public Double getBoughtPrice() {
return boughtPrice;
}
public void setBoughtPrice(Double boughtPrice) {
this.boughtPrice = boughtPrice;
}
public Double getPriceToBuy() {
return priceToBuy;
}
public void setPriceToBuy(Double priceToBuy) {
this.priceToBuy = priceToBuy;
}
public Double getSoldPrice() {
return soldPrice;
}
public void setSoldPrice(Double soldPrice) {
this.soldPrice = soldPrice;
}
public Double getPriceToSell() {
return priceToSell;
}
public void setPriceToSell(Double priceToSell) {
this.priceToSell = priceToSell;
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
}

View File

@ -1,30 +0,0 @@
package nl.komtek.gpi.schedules;
import nl.komtek.gpi.services.GunbotProxyService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* Created by Elroy on 23-6-2017.
*/
@Component
public class AllScheduledTasks {
private Logger logger = LogManager.getLogger(AllScheduledTasks.class);
@Autowired
private GunbotProxyService gunbotProxyService;
@Scheduled(fixedDelay = 2000)
public void updateTicker() {
try {
gunbotProxyService.getTickerScheduled();
} catch (Exception e) {
logger.error(e);
}
}
}

View File

@ -1,69 +0,0 @@
package nl.komtek.gpi.schedules;
import nl.komtek.gpi.services.GunbotProxyService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* Created by Elroy on 23-6-2017.
*/
@Component
@ConditionalOnProperty(name="default_BTC_apiKey", havingValue = "")
public class BTCScheduledTasks {
private static final String market = "BTC";
private Logger logger = LogManager.getLogger(BTCScheduledTasks.class);
@Autowired
private GunbotProxyService gunbotProxyService;
@Scheduled(fixedDelay = 9000)
public void updateCompleteBalances() {
try {
if (gunbotProxyService.isActiveMarket(market)) {
gunbotProxyService.getCompleteBalancesScheduled(market);
}
} catch (Exception e) {
logger.error(e);
}
}
@Scheduled(fixedDelay = 1500)
public void updateTradeHistory() {
try {
if (gunbotProxyService.isActiveMarket(market)) {
gunbotProxyService.getTradeHistoryScheduled(market);
}
} catch (Exception e) {
logger.error(e);
}
}
@Scheduled(fixedDelay = 2000)
public void updateOpenOrders() {
try {
if (gunbotProxyService.isActiveMarket(market)) {
gunbotProxyService.getOpenOrdersScheduled(market);
}
} catch (Exception e) {
logger.error(e);
}
}
@Scheduled(fixedDelay = 10000)
public void updateBalancesBTC() {
try {
if (gunbotProxyService.isActiveMarket(market)) {
gunbotProxyService.getBalancesScheduled(market);
}
} catch (Exception e) {
logger.error(e);
}
}
}

View File

@ -1,59 +0,0 @@
package nl.komtek.gpi.schedules;
import nl.komtek.gpi.services.GunbotProxyService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* Created by Elroy on 23-6-2017.
*/
@Component
@ConditionalOnProperty(name="default_apiKey", havingValue = "")
public class DefaultScheduledTasks {
private static final String market = "default";
private Logger logger = LogManager.getLogger(DefaultScheduledTasks.class);
@Autowired
private GunbotProxyService gunbotProxyService;
@Scheduled(fixedDelay = 9000)
public void updateCompleteBalances() {
try {
gunbotProxyService.getCompleteBalancesScheduled(market);
} catch (Exception e) {
logger.error(e);
}
}
@Scheduled(fixedDelay = 1500)
public void updateTradeHistory() {
try {
gunbotProxyService.getTradeHistoryScheduled(market);
} catch (Exception e) {
logger.error(e);
}
}
@Scheduled(fixedDelay = 2000)
public void updateOpenOrders() {
try {
gunbotProxyService.getOpenOrdersScheduled(market);
} catch (Exception e) {
logger.error(e);
}
}
@Scheduled(fixedDelay = 10000)
public void updateBalances() {
try {
gunbotProxyService.getBalancesScheduled(market);
} catch (Exception e) {
logger.error(e);
}
}
}

View File

@ -1,66 +0,0 @@
package nl.komtek.gpi.schedules;
import nl.komtek.gpi.services.GunbotProxyService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* Created by Elroy on 23-6-2017.
*/
@Component
@ConditionalOnProperty(name = "default_ETH_apiKey", havingValue = "")
public class ETHScheduledTasks {
private Logger logger = LogManager.getLogger(ETHScheduledTasks.class);
@Autowired
private GunbotProxyService gunbotProxyService;
@Scheduled(fixedDelay = 9200)
public void updateCompleteBalancesETH() {
try {
if (gunbotProxyService.isActiveMarket("ETH")) {
gunbotProxyService.getCompleteBalancesScheduled("ETH");
}
} catch (Exception e) {
logger.error(e);
}
}
@Scheduled(fixedDelay = 1550)
public void updateTradeHistoryETH() {
try {
if (gunbotProxyService.isActiveMarket("ETH")) {
gunbotProxyService.getTradeHistoryScheduled("ETH");
}
} catch (Exception e) {
logger.error(e);
}
}
@Scheduled(fixedDelay = 2050)
public void updateOpenOrdersETH() {
try {
if (gunbotProxyService.isActiveMarket("ETH")) {
gunbotProxyService.getOpenOrdersScheduled("ETH");
}
} catch (Exception e) {
logger.error(e);
}
}
@Scheduled(fixedDelay = 10000)
public void updateBalancesETH() {
try {
if (gunbotProxyService.isActiveMarket("ETH")) {
gunbotProxyService.getBalancesScheduled("ETH");
}
} catch (Exception e) {
logger.error(e);
}
}
}

View File

@ -1,66 +0,0 @@
package nl.komtek.gpi.schedules;
import nl.komtek.gpi.services.GunbotProxyService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* Created by Elroy on 23-6-2017.
*/
@Component
@ConditionalOnProperty(name="default_USDT_apiKey", havingValue = "")
public class USDTScheduledTasks {
private Logger logger = LogManager.getLogger(USDTScheduledTasks.class);
@Autowired
private GunbotProxyService gunbotProxyService;
@Scheduled(fixedDelay = 9600)
public void updateCompleteBalancesUSDT() {
try {
if (gunbotProxyService.isActiveMarket("USDT")) {
gunbotProxyService.getCompleteBalancesScheduled("USDT");
}
} catch (Exception e) {
logger.error(e);
}
}
@Scheduled(fixedDelay = 1650)
public void updateTradeHistoryUSDT() {
try {
if (gunbotProxyService.isActiveMarket("USDT")) {
gunbotProxyService.getTradeHistoryScheduled("USDT");
}
} catch (Exception e) {
logger.error(e);
}
}
@Scheduled(fixedDelay = 2150)
public void updateOpenOrdersUSDT() {
try {
if (gunbotProxyService.isActiveMarket("USDT")) {
gunbotProxyService.getOpenOrdersScheduled("USDT");
}
} catch (Exception e) {
logger.error(e);
}
}
@Scheduled(fixedDelay = 10000)
public void updateBalancesUSDT() {
try {
if (gunbotProxyService.isActiveMarket("USDT")) {
gunbotProxyService.getBalancesScheduled("USDT");
}
} catch (Exception e) {
logger.error(e);
}
}
}

View File

@ -1,66 +0,0 @@
package nl.komtek.gpi.schedules;
import nl.komtek.gpi.services.GunbotProxyService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* Created by Elroy on 23-6-2017.
*/
@Component
@ConditionalOnProperty(name="default_XMR_apiKey", havingValue = "")
public class XMRScheduledTasks {
private Logger logger = LogManager.getLogger(XMRScheduledTasks.class);
@Autowired
private GunbotProxyService gunbotProxyService;
@Scheduled(fixedDelay = 9400)
public void updateCompleteBalancesXMR() {
try {
if (gunbotProxyService.isActiveMarket("XMR")) {
gunbotProxyService.getCompleteBalancesScheduled("XMR");
}
} catch (Exception e) {
logger.error(e);
}
}
@Scheduled(fixedDelay = 1600)
public void updateTradeHistoryXMR() {
try {
if (gunbotProxyService.isActiveMarket("XMR")) {
gunbotProxyService.getTradeHistoryScheduled("XMR");
}
} catch (Exception e) {
logger.error(e);
}
}
@Scheduled(fixedDelay = 2100)
public void updateOpenOrdersXMR() {
try {
if (gunbotProxyService.isActiveMarket("XMR")) {
gunbotProxyService.getOpenOrdersScheduled("XMR");
}
} catch (Exception e) {
logger.error(e);
}
}
@Scheduled(fixedDelay = 10000)
public void updateBalancesXMR() {
try {
if (gunbotProxyService.isActiveMarket("XMR")) {
gunbotProxyService.getBalancesScheduled("XMR");
}
} catch (Exception e) {
logger.error(e);
}
}
}

View File

@ -1,508 +0,0 @@
package nl.komtek.gpi.services;
import com.cf.PriceDataAPIClient;
import com.cf.client.poloniex.PoloniexPublicAPIClient;
import com.cf.client.poloniex.PoloniexTradingAPIClient;
import com.cf.data.model.poloniex.PoloniexCompleteBalance;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import net.jodah.failsafe.Failsafe;
import net.jodah.failsafe.RetryPolicy;
import nl.komtek.gpi.utils.ProxyHandledException;
import nl.komtek.gpi.utils.Util;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* Created by Elroy on 20-6-2017.
*/
@Component
public class GunbotProxyService {
private Logger logger = LogManager.getLogger(GunbotProxyService.class);
@Autowired
private ApplicationContext applicationContext;
@Autowired
private Util util;
@Value("${connection.maxRetries:6}")
private int maxRetries;
@Value("${connection.nonceLength:17}")
private int nonceLength;
private Map<String, PoloniexTradingAPIClient> poloniexDefaultAPIClients = new HashMap<>();
private Map<String, PoloniexTradingAPIClient> poloniexTradingAPIClients = new HashMap<>();
private Map<String, String> marketMapping = new HashMap<>();
private Map<String, PoloniexTradingAPIClient> poloniexMultiMarketTradingAPIClients = new HashMap<>();
private PriceDataAPIClient publicClient;
private RetryPolicy retryPolicy;
public GunbotProxyService() {
publicClient = new PoloniexPublicAPIClient();
}
@PostConstruct
private void initService() {
if (!createMarketMapping()) {
String apiKey = util.getEnvProperty("default_apiKey");
String apiSecret = util.getEnvProperty("default_apiSecret");
poloniexDefaultAPIClients.put("default", new PoloniexTradingAPIClient(apiKey, apiSecret, nonceLength));
createDefaultTradingClients();
} else {
if (!createMarketDefaultApiClients("BTC")) {
return;
}
if (!createMarketDefaultApiClients("ETH")) {
return;
}
if (!createMarketDefaultApiClients("XMR")) {
return;
}
if (!createMarketDefaultApiClients("USDT")) {
return;
}
}
publicClient = new PoloniexPublicAPIClient();
retryPolicy = new RetryPolicy()
.retryOn(failure -> failure instanceof Exception)
.withDelay(500, TimeUnit.MILLISECONDS)
.withMaxRetries(maxRetries);
}
private boolean createMarketDefaultApiClients(String market) {
String apiKey = util.getEnvProperty("default_" + market + "_apiKey");
String apiSecret = util.getEnvProperty("default_" + market + "_apiSecret");
if (!StringUtils.isEmpty(apiKey) && !StringUtils.isEmpty(apiSecret)) {
if (!marketMapping.values().contains(market)) {
logger.error(String.format("Please setup the %s market correctly", market));
SpringApplication.exit(applicationContext);
return false;
} else {
poloniexDefaultAPIClients.put(market, new PoloniexTradingAPIClient(apiKey, apiSecret, nonceLength));
}
}
return true;
}
private boolean createMarketMapping() {
String[] markets = {"BTC", "ETH", "XMR", "USDT"};
for (String market : markets) {
for (int i = 1; i <= 10; i++) {
String apiKey = util.getEnvProperty(String.format("%s_apiKey%d", market, i));
String apiSecret = util.getEnvProperty(String.format("%s_apiSecret%d", market, i));
if (StringUtils.isEmpty(apiKey) || StringUtils.isEmpty(apiSecret)) {
break;
}
marketMapping.put(apiKey, market);
poloniexMultiMarketTradingAPIClients.put(apiKey, new PoloniexTradingAPIClient(apiKey, apiSecret, nonceLength));
}
}
return marketMapping.size() > 0 && marketMapping.size() == poloniexMultiMarketTradingAPIClients.size();
}
private void createDefaultTradingClients() {
for (int i = 1; i <= 10; i++) {
String apiKey = util.getEnvProperty(String.format("apiKey%d", i));
String apiSecret = util.getEnvProperty(String.format("apiSecret%d", i));
if (apiKey == null || apiSecret == null) {
break;
}
poloniexTradingAPIClients.put(apiKey, new PoloniexTradingAPIClient(apiKey, apiSecret, nonceLength));
}
}
//@Cacheable(value = "BBChartData", key = "#currencyPair")
public String getBBChartData(String currencyPair, long start, long end, long period) {
logger.debug("BB ChartData: " + currencyPair + " -- start:" + start + " -- period:" + period);
while (true) {
try {
String result = publicClient.getChartData(currencyPair, period, start, end);
return analyzeResult(result);
} catch (Exception e) {
handleException(e);
}
}
}
@Cacheable(value = "chartData", key = "#currencyPair+#period")
public String getChartData(String currencyPair, long period) {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, -2);
long start = cal.getTimeInMillis() / 1000;
while (true) {
try {
String result = publicClient.getChartData(currencyPair, period, start);
result = analyzeResult(result);
logger.debug("chartData: " + currencyPair + " -- start:" + start + " -- period:" + period + " -- " + result);
return result;
} catch (Exception e) {
handleException(e);
}
}
}
@Cacheable("ticker")
public String getTicker() {
return getTickerScheduled();
}
@CachePut("ticker")
public String getTickerScheduled() {
String result = Failsafe.with(retryPolicy)
.onFailedAttempt(this::handleException)
.get(() -> analyzeResult(publicClient.returnTicker()));
logger.debug("ticker: " + result);
return result;
}
@Cacheable(value = "orderBook", key = "#currencyPair")
public String getOrderBook(String currencyPair) {
return getOrderBookScheduled(currencyPair);
}
public String get24hVolume() {
return publicClient.return24Volume();
}
@CachePut(value = "orderBook", key = "#currencyPair")
public String getOrderBookScheduled(String currencyPair) {
String result = Failsafe.with(retryPolicy)
.onFailedAttempt(this::handleException)
.get(() -> analyzeResult(publicClient.returnOrderBook(currencyPair)));
logger.debug("OrderBook: " + result);
return result;
}
@Cacheable(value = "publicTradeHistory", key = "#currencyPair", sync = true)
public String getPublicTradeHistory(String currencyPair, long start, long end) {
return getPublicTradeHistoryScheduled(currencyPair, start, end);
}
@CachePut(value = "publicTradeHistory", key = "#currencyPair")
public String getPublicTradeHistoryScheduled(String currencyPair, long start, long end) {
String result = Failsafe.with(retryPolicy)
.onFailedAttempt(this::handleException)
.get(() -> analyzeResult(publicClient.returnTradeHistory(currencyPair, start, end)));
logger.debug(currencyPair + "-" + "public trade history: " + result);
return result;
}
@Cacheable(value = "publicTradeHistory", key = "#currencyPair", sync = true)
public String getPublicTradeHistory(String currencyPair) {
return getPublicTradeHistoryScheduled(currencyPair);
}
@CachePut(value = "publicTradeHistory", key = "#currencyPair")
public String getPublicTradeHistoryScheduled(String currencyPair) {
String result = Failsafe.with(retryPolicy)
.onFailedAttempt(this::handleException)
.get(() -> analyzeResult(publicClient.returnTradeHistory(currencyPair)));
logger.debug(currencyPair + "-" + "public trade history: " + result);
return result;
}
@Cacheable(value = "tradeHistory", key = "#market", sync = true)
public String getTradeHistory(String market) {
return getTradeHistoryScheduled(market);
}
@CachePut(value = "tradeHistory", key = "#market")
public String getTradeHistoryScheduled(String market) {
PoloniexTradingAPIClient tradingAPIClient = getMarketDefaultTradingClient(market);
String result = Failsafe.with(retryPolicy)
.onFailedAttempt(this::handleException)
.get(() -> analyzeResult(tradingAPIClient.returnTradeHistory("ALL")));
logger.debug(market + "-" + "trade history: " + result);
return result;
}
@Cacheable(value = "completeBalances", key = "#market", sync = true)
public String getCompleteBalances(String market) {
return getCompleteBalancesScheduled(market);
}
@CachePut(value = "completeBalances", key = "#market")
public String getCompleteBalancesScheduled(String market) {
PoloniexTradingAPIClient tradingAPIClient = getMarketDefaultTradingClient(market);
String result = Failsafe.with(retryPolicy)
.onFailedAttempt(this::handleException)
.get(() -> analyzeResult(tradingAPIClient.returnCompleteBalances()));
result = hideDust(result);
logger.debug(market + "-" + "complete balances: " + result);
return result;
}
@Cacheable(value = "balances", key = "#market")
public double getBTCBalance(String market) {
return getBalancesScheduled(market);
}
@CachePut(value = "balances", key = "#market")
public double getBalancesScheduled(String market) {
PoloniexTradingAPIClient tradingAPIClient = getMarketDefaultTradingClient(market);
String result = Failsafe.with(retryPolicy)
.onFailedAttempt(this::handleException)
.get(() -> analyzeResult(tradingAPIClient.returnBalances()));
logger.debug("balances" + result);
JsonElement jsonElement = new JsonParser().parse(result);
JsonObject jsonObject = jsonElement.getAsJsonObject();
return jsonObject.get("BTC").getAsDouble();
}
@Cacheable(value = "openOrders", key = "#market", sync = true)
public String getOpenOrders(String market) {
return getOpenOrdersScheduled(market);
}
@CachePut(value = "openOrders", key = "#market")
public String getOpenOrdersScheduled(String market) {
PoloniexTradingAPIClient tradingAPIClient = getMarketDefaultTradingClient(market);
String result = Failsafe.with(retryPolicy)
.onFailedAttempt(this::handleException)
.get(() -> analyzeResult(tradingAPIClient.returnOpenOrders("ALL")));
logger.debug(market + "-" + "open orders: " + result);
return result;
}
@Caching(evict = {@CacheEvict(value = "openOrders", allEntries = true),
@CacheEvict(value = "completeBalances", allEntries = true)})
public String cancelOrder(String key, String orderNumber) {
logger.debug("Canceling an order");
PoloniexTradingAPIClient tmpTradingAPIClient;
if (isUsingMultipleMarkets()) {
tmpTradingAPIClient = getMultiMarketTradingClient(key);
} else {
tmpTradingAPIClient = getTradingClient("random");
}
final PoloniexTradingAPIClient tradingAPIClient = tmpTradingAPIClient;
String result = Failsafe.with(retryPolicy)
.onFailedAttempt(this::handleException)
.get(() -> analyzeResult(tradingAPIClient.cancelOrder(orderNumber)));
return result;
}
@Caching(evict = {@CacheEvict(value = "openOrders", allEntries = true),
@CacheEvict(value = "completeBalances", allEntries = true)})
public synchronized String buyOrder(String key, String currencyPair, BigDecimal buyPrice, BigDecimal amount) {
return buyOrderWithProtection(key, currencyPair, buyPrice, amount);
}
@Cacheable(value = "buyOrderProtection", key = "#currencyPair")
@Caching(evict = {@CacheEvict(value = "openOrders", allEntries = true),
@CacheEvict(value = "completeBalances", allEntries = true)})
public synchronized String buyOrderWithProtection(String key, String currencyPair, BigDecimal buyPrice, BigDecimal amount) {
boolean testMode = Boolean.parseBoolean(util.getConfigurationProperty("testMode"));
boolean globalSellOnlyMode = Boolean.parseBoolean(util.getConfigurationProperty("sellOnlyMode"));
boolean pairSellOnlyMode = Boolean.parseBoolean(util.getConfigurationProperty(String.format("%s_sellOnlyMode", currencyPair)));
if (testMode) {
logger.info("Test mode: We bought {}", currencyPair);
return "";
}
if (globalSellOnlyMode || pairSellOnlyMode) {
JsonObject jsonObject = new JsonObject();
String message = String.format("You are not allowed to buy. Sell Only mode is active for %s", currencyPair);
jsonObject.addProperty("error", message);
logger.info(jsonObject.toString());
return jsonObject.toString();
}
PoloniexTradingAPIClient tmpTradingAPIClient;
if (isUsingMultipleMarkets()) {
tmpTradingAPIClient = getMultiMarketTradingClient(key);
} else {
tmpTradingAPIClient = getTradingClient("random");
}
final PoloniexTradingAPIClient tradingAPIClient = tmpTradingAPIClient;
final Boolean fillOrKill = Boolean.valueOf(util.getConfigurationProperty("buy_fillOrKill", "false"));
final Boolean immediateOrCancel = Boolean.valueOf(util.getConfigurationProperty("buy_immediateOrCancel", "false"));
String result = Failsafe.with(retryPolicy)
.onFailedAttempt(this::handleException)
.get(() -> analyzeResult(tradingAPIClient.buy(currencyPair, buyPrice, amount, fillOrKill, immediateOrCancel, false)));
logger.info(String.format("Buy order for %s -- %s", currencyPair, result));
return result;
}
@Caching(evict = {@CacheEvict(value = "openOrders", allEntries = true),
@CacheEvict(value = "completeBalances", allEntries = true)})
public synchronized String sellOrder(String key, String currencyPair, BigDecimal sellPrice, BigDecimal amount) {
boolean testMode = Boolean.parseBoolean(util.getConfigurationProperty("testMode"));
if (testMode) {
logger.info("Test mode: We sold {}", currencyPair);
return "";
}
PoloniexTradingAPIClient tmpTradingAPIClient;
if (isUsingMultipleMarkets()) {
tmpTradingAPIClient = getMultiMarketTradingClient(key);
} else {
tmpTradingAPIClient = getTradingClient("random");
}
final PoloniexTradingAPIClient tradingAPIClient = tmpTradingAPIClient;
final Boolean fillOrKill = Boolean.valueOf(util.getConfigurationProperty("sell_fillOrKill", "false"));
final Boolean immediateOrCancel = Boolean.valueOf(util.getConfigurationProperty("sell_immediateOrCancel", "false"));
String result = Failsafe.with(retryPolicy)
.onFailedAttempt(this::handleException)
.get(() -> analyzeResult(tradingAPIClient.sell(currencyPair, sellPrice, amount, fillOrKill, immediateOrCancel, false)));
logger.info(String.format("Sell order for %s -- %s", currencyPair, result));
return result;
}
private PoloniexTradingAPIClient getTradingClient(String currencyPair) {
String apiKey = util.getEnvProperty(currencyPair + "_apiKey");
if (apiKey != null) {
return poloniexTradingAPIClients.get(apiKey);
} else {
int random = (int) (Math.random() * 1) + poloniexTradingAPIClients.values().size() - 1;
return (PoloniexTradingAPIClient) poloniexTradingAPIClients.values().toArray()[random];
}
}
private PoloniexTradingAPIClient getMultiMarketTradingClient(String apiKey) {
return poloniexMultiMarketTradingAPIClients.get(apiKey);
}
private PoloniexTradingAPIClient getMarketDefaultTradingClient(String market) {
PoloniexTradingAPIClient tradingAPIClient = poloniexDefaultAPIClients.get(market);
if (tradingAPIClient == null) {
tradingAPIClient = poloniexDefaultAPIClients.get("default");
}
return tradingAPIClient;
}
public String analyzeResult(String result) {
if (result == null) {
throw new ProxyHandledException("No value was returned");
} else if (result.contains("Nonce")) {
throw new ProxyHandledException("nonce error: " + result);
} else if (result.contains("Invalid API")) {
throw new ProxyHandledException(result);
} else if (result.contains("Connection timed out")) {
throw new ProxyHandledException(result);
}
return result;
}
private void handleException(Throwable e) {
if (e instanceof ProxyHandledException) {
logger.debug(e.toString());
} else if (e instanceof NullPointerException) {
logger.error("Something is really wrong", e);
} else {
logger.error(e);
}
}
public boolean isActiveMarket(String market) {
return poloniexDefaultAPIClients.get(market) != null;
}
public boolean isUsingMultipleMarkets() {
if (poloniexDefaultAPIClients.get("ETH") != null) {
return true;
}
if (poloniexDefaultAPIClients.get("XMR") != null) {
return true;
}
if (poloniexDefaultAPIClients.get("USDT") != null) {
return true;
}
return false;
}
public String getMarket(String apiKey) {
String market = marketMapping.get(apiKey);
if (StringUtils.isEmpty(market)) {
throw new RuntimeException("It seems u are using multiple markets but have not setup this apiKey " + apiKey);
}
return market;
}
public String checkDefaultKey(String market) {
PoloniexTradingAPIClient tradingAPIClient = getMarketDefaultTradingClient(market);
return Failsafe.with(retryPolicy)
.onFailedAttempt(this::handleException)
.get(() -> analyzeResult(tradingAPIClient.returnOpenOrders("ALL")));
}
public String checkTradingKey(String apiKey) {
PoloniexTradingAPIClient tradingAPIClient = poloniexTradingAPIClients.get(apiKey);
return Failsafe.with(retryPolicy)
.onFailedAttempt(this::handleException)
.get(() -> analyzeResult(tradingAPIClient.returnOpenOrders("ALL")));
}
public String checkMultiMarketTradingKey(String apiKey) {
PoloniexTradingAPIClient tradingAPIClient = poloniexMultiMarketTradingAPIClients.get(apiKey);
return Failsafe.with(retryPolicy)
.onFailedAttempt(this::handleException)
.get(() -> analyzeResult(tradingAPIClient.returnOpenOrders("ALL")));
}
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) {
filteredObject.add(entry.getKey().toString(), element);
}
double approximatePrice = btcValue.doubleValue() / available.add(onOrders).doubleValue();
double availableValue = available.doubleValue() * approximatePrice;
if (!entry.getKey().equals("USDT") && availableValue < 0.00015) {
available = BigDecimal.ZERO;
} else if (entry.getKey().equals("USDT") && available.doubleValue() < 1) {
available = BigDecimal.ZERO;
}
PoloniexCompleteBalance balance = new PoloniexCompleteBalance(available, onOrders, btcValue);
filteredObject.add(entry.getKey().toString(), jsonParser.parse(balance.toString()));
}
return filteredObject.toString();
}
}

View File

@ -1,24 +0,0 @@
package nl.komtek.gpi.utils;
/**
* Created by Elroy on 13-7-2017.
*/
import java.util.Properties;
public class CaseLessProperties extends Properties {
public Object put(Object key, Object value) {
String lowercase = ((String) key).toLowerCase();
return super.put(lowercase, value);
}
public String getProperty(String key) {
String lowercase = key.toLowerCase();
return super.getProperty(lowercase);
}
public String getProperty(String key, String defaultValue) {
String lowercase = key.toLowerCase();
return super.getProperty(lowercase, defaultValue);
}
}

View File

@ -1,11 +0,0 @@
package nl.komtek.gpi.utils;
/**
* Created by Elroy on 05-7-2017.
*/
public class ProxyHandledException extends RuntimeException {
public ProxyHandledException(String message) {
super(message);
}
}

View File

@ -1,50 +0,0 @@
package nl.komtek.gpi.utils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.io.FileInputStream;
import java.io.InputStream;
/**
* Created by Elroy on 10-7-2017.
*/
@Component
public class Util {
@Autowired
private Environment environment;
private Logger logger = LogManager.getLogger(Util.class);
public String getEnvProperty(String key) {
String value = StringUtils.trimAllWhitespace(environment.getProperty(key));
return StringUtils.replace(value, "\"", "");
}
public String getEnvProperty(String key, String defaultValue) {
String value = getEnvProperty(key);
return (value == null) ? defaultValue : value;
}
public String getConfigurationProperty(String key, String defaultValue) {
String value = getConfigurationProperty(key);
return (value == null) ? defaultValue : value;
}
public String getConfigurationProperty(String key) {
CaseLessProperties prop = new CaseLessProperties();
String value = null;
try (InputStream input = new FileInputStream("configuration.properties")) {
prop.load(input);
value = prop.getProperty(key);
logger.debug(String.format("reading property key %s -- value %s", key, value));
} catch (Exception e) {
logger.debug("Error reading configuration file", e);
}
return value;
}
}

View File

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="900">
<Properties>
<Property name="baseDir">logs</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %p %c{1} - %m%n"/>
</Console>
<RollingFile name="RollingFile" fileName="${baseDir}/GunbotProxy.log"
filePattern="${baseDir}/$${date:yyyy-MM}/GunbotProxy-%d{yyyy-MM-dd}.log.gz">
<PatternLayout pattern="%d %p %c{1.} [%t] %m%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="50 MB"/>
</Policies>
<DefaultRolloverStrategy max="2"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="nl.komtek" level="info" additivity="false">
<AppenderRef ref="Console" level="info"/>
<AppenderRef ref="RollingFile" level="debug"/>
</Logger>
<Logger name="org.apache" level="error" additivity="false">
<AppenderRef ref="Console"/>
<AppenderRef ref="RollingFile"/>
</Logger>
<Root level="error">
<AppenderRef ref="Console"/>
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>

Binary file not shown.

View File

@ -1,62 +0,0 @@
<#setting number_format=",##0.00000000">
<#assign total=0>
<!DOCTYPE html>
<html lang="en">
<body>
Your BTC Balance = ${balance}
<br />
<#if !gunbotLocation>
You have not setup your gunbot location!
<#else>
<br />
<br />
<table border="1">
<thead>
<th>Market</th>
<th>In BTC</th>
<th>Buy/Bought</th>
<th>Sell/Sold</th>
<th>Last price</th>
<th>How's the price?</th>
<thead>
<#list monitoringDatas as monitoringData>
<tbody>
<tr>
<td>${monitoringData.market._pair}</td>
<#assign altBalance = monitoringData.altcoinBalance!0.0 >
<#if altBalance gt 0>
<#assign btc=altBalance * monitoringData.lastPrice>
<#assign total = total + btc>
<td>${btc}</td>
<#else>
<td>0.00000000</td>
</#if>
<#if altBalance gt 0>
<td>${monitoringData.boughtPrice!0.0}</td>
<#else>
<td>${monitoringData.priceToBuy!0.0}</td>
</#if>
<#if altBalance gt 0>
<td>${monitoringData.priceToSell!0.0}</td>
<#else>
<td>${monitoringData.soldPrice!0.0}</td>
</#if>
<td>${monitoringData.lastPrice!0.0}</td>
<td>${monitoringData.reason!""}</td>
</tr>
</tbody>
</#list>
<tr>
<td>Total</td>
<td>${total}</td>
</tr>
</table>
</#if>
</body>
</html>

View File

@ -1,20 +0,0 @@
<#setting number_format=",##0.00000000">
<#assign total=0>
<!DOCTYPE html>
<html lang="en">
<body>
<table border="1">
<#list setupData?keys as key>
<tbody>
<tr>
<td>${key}</td>
<td>${setupData[key]} </td>
</tr>
</tbody>
</#list>
</table>
</body>
</html>

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Context path=""/>