unterstein / binance-trader Goto Github PK
View Code? Open in Web Editor NEWExperimental trading bot for crypto currency on Binance.com
License: Apache License 2.0
Experimental trading bot for crypto currency on Binance.com
License: Apache License 2.0
` :: Spring Boot :: (v1.4.3.RELEASE)
2018-01-10 22:41:31.198 INFO 8112 --- [ main] i.g.unterstein.BinanceBotApplication : Starting BinanceBotApplication on ShadowZ-PC with PID 8112 (C:\Windows\System32\binance-trader\target\classes started by theep in C:\Windows\System32\binance-trader)
2018-01-10 22:41:31.201 INFO 8112 --- [ main] i.g.unterstein.BinanceBotApplication : No active profile set, falling back to default profiles: default
2018-01-10 22:41:31.248 INFO 8112 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@76817f45: startup date [Wed Jan 10 22:41:31 GMT-05:00 2018]; root of context hierarchy
2018-01-10 22:41:32.332 INFO 8112 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2018-01-10 22:41:32.346 INFO 8112 --- [ main] o.apache.catalina.core.StandardService : Starting service Tomcat
2018-01-10 22:41:32.349 INFO 8112 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.6
2018-01-10 22:41:32.427 INFO 8112 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2018-01-10 22:41:32.427 INFO 8112 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1183 ms
2018-01-10 22:41:32.523 INFO 8112 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2018-01-10 22:41:32.526 INFO 8112 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/]
2018-01-10 22:41:32.526 INFO 8112 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/]
2018-01-10 22:41:32.527 INFO 8112 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/]
2018-01-10 22:41:32.527 INFO 8112 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/]
2018-01-10 22:41:32.557 INFO 8112 --- [ main] i.g.unterstein.BinanceBotApplication : Starting app with diff=0.00000001, profit=1.30000000 amount=150 base=ETH trade=XVG
2018-01-10 22:41:34.207 INFO 8112 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@76817f45: startup date [Wed Jan 10 22:41:31 GMT-05:00 2018]; root of context hierarchy
2018-01-10 22:41:34.266 INFO 8112 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/]}" onto public java.util.List<com.binance.api.client.domain.account.AssetBalance> io.github.unterstein.BinanceBotApplication.getBalances()
2018-01-10 22:41:34.269 INFO 8112 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2018-01-10 22:41:34.270 INFO 8112 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2018-01-10 22:41:34.288 INFO 8112 --- [ main] o.s.w.s.h.BeanNameUrlHandlerMapping : Root mapping to handler '/'
2018-01-10 22:41:34.297 INFO 8112 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-01-10 22:41:34.301 INFO 8112 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-01-10 22:41:34.335 INFO 8112 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-01-10 22:41:34.447 INFO 8112 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2018-01-10 22:41:34.459 INFO 8112 --- [ main] s.a.ScheduledAnnotationBeanPostProcessor : No TaskScheduler/ScheduledExecutorService bean found for scheduled processing
2018-01-10 22:41:34.508 INFO 8112 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2018-01-10 22:41:34.514 INFO 8112 --- [ main] i.g.unterstein.BinanceBotApplication : Started BinanceBotApplication in 3.631 seconds (JVM running for 5.788)
2018-01-10 22:41:35.301 ERROR 8112 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : Unable to perform ticker
com.binance.api.client.exception.BinanceApiException: Timestamp for this request was 1000ms ahead of the server's time.
at com.binance.api.client.impl.BinanceApiServiceGenerator.executeSync(BinanceApiServiceGenerator.java:57) ~[binance-api-client-1.0.0.jar:na]
at com.binance.api.client.impl.BinanceApiRestClientImpl.getAccount(BinanceApiRestClientImpl.java:145) ~[binance-api-client-1.0.0.jar:na]
at com.binance.api.client.impl.BinanceApiRestClientImpl.getAccount(BinanceApiRestClientImpl.java:150) ~[binance-api-client-1.0.0.jar:na]
at io.github.unterstein.TradingClient.getTradingBalance(TradingClient.java:48) ~[classes/:na]
at io.github.unterstein.BinanceTrader.tick(BinanceTrader.java:42) ~[classes/:na]
at io.github.unterstein.BinanceBotApplication.schedule(BinanceBotApplication.java:57) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_151]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_151]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_151]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_151]
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65) [spring-context-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) [spring-context-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_151]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [na:1.8.0_151]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_151]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_151]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_151]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_151]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_151]`
Hi. I am new and just trying how this all works.
I assume data is real market data.
Is it possible to use this code to read from a test platform where dummy trades can be done?
2018-01-04 20:19:40.516 ERROR 10008 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [No adapter for handler [io.github.unterstein.BinanceBotApplication$$EnhancerBySpringCGLIB$$defe096a@6a758ad9]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler] with root cause
javax.servlet.ServletException: No adapter for handler [io.github.unterstein.BinanceBotApplication$$EnhancerBySpringCGLIB$$defe096a@6a758ad9]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler
at org.springframework.web.servlet.DispatcherServlet.getHandlerAdapter(DispatcherServlet.java:1173) ~[spring-webmvc-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943) ~[spring-webmvc-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) ~[spring-webmvc-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) ~[spring-webmvc-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) ~[tomcat-embed-core-8.5.6.jar:8.5.6]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230) ~[tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.6.jar:8.5.6]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.6.jar:8.5.6]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.6.jar:8.5.6]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:89) ~[spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.6.jar:8.5.6]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) ~[spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.6.jar:8.5.6]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108) [tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) [tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) [tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:784) [tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:802) [tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1410) [tomcat-embed-core-8.5.6.jar:8.5.6]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.6.jar:8.5.6]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_144]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_144]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.6.jar:8.5.6]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_144]
2018-01-04 20:19:40.653 INFO 10008 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : Tradingbalance: AssetBalance[asset=DNT,free=0.80000000,locked=0.00000000]
2018-01-04 20:19:40.653 INFO 10008 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : order still new, time 4
Running the docker image, whenever a buy occurs, it basically has 10 seconds to fill the sell order, if it doesn't, it panic sells.
I get WHY it does that but it would be great to be able to configure it to wait longer or wait-until-sold.
Hi
The bot bought 500 XVG
When he tries to sell I get :
2018-01-04 20:13:26.570 INFO 15 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : Tradingbalance: AssetBalance[asset=XVG,free=499.50000000,locked=0.00000000]
2018-01-04 20:13:26.570 INFO 15 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : Order filled, let`s sell!
2018-01-04 20:13:26.570 INFO 15 --- [pool-1-thread-1] io.github.unterstein.TradingClient : Selling 500 for 0.00017219
2018-01-04 20:13:27.962 ERROR 15 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : Unable to perform ticker
com.binance.api.client.exception.BinanceApiException: Account has insufficient balance for requested action.
I am running your code via docker on my mac. When bot decides to buy there is an error that says Unable to perform ticker and an exception like the issue title. How can I fix this?
Thanks
Dependency 'com.binance.api:binance-api-client:1.0.0' not found less... (Ctrl+F1)
Inspects a Maven model for resolution problems.
My IDEA can't import the jar.what is your Maven's mirror?
I having trouble with this error.
com.binance.api.client.exception.BinanceApiException: Filter failure: PRICE_FILTER at com.binance.api.client.impl.BinanceApiServiceGenerator.executeSync(BinanceApiServiceGenerator.java:57) ~[binance-api-client-1.0.0.jar!/:na] at com.binance.api.client.impl.BinanceApiRestClientImpl.newOrder(BinanceApiRestClientImpl.java:103) ~[binance-api-client-1.0.0.jar!/:na] at io.github.unterstein.TradingClient.buy(TradingClient.java:66) ~[classes!/:0.0.1-SNAPSHOT] at io.github.unterstein.BinanceTrader.tick(BinanceTrader.java:55) ~[classes!/:0.0.1-SNAPSHOT] at io.github.unterstein.BinanceBotApplication.schedule(BinanceBotApplication.java:53) [classes!/:0.0.1-SNAPSHOT]
i research an find out this page. However i cant understand how to fix it.
https://support.binance.com/hc/en-us/articles/115000594711-Trading-Rule
https://www.reddit.com/r/binance/comments/7941mc/binance_api_error/
Command example:
TRADE_PROFIT='1.3'
TRADE_AMOUNT='40'
BASE_CURRENCY='BNB'
TRADE_CURRENCY='RCN'
BNB Balance: 2.25157165
Can you help me?
Hello together, I have a problem and hope you can help me (I hope that it is ok to ask here :))
I want to calculate the MACD indicator, but I´m a noob and it doesn´t work :(
I would be great, if the trader is able to get the closing price of the last 2 days. I think it´s enough for me to know how to get out the closing price of the last hour and rest i can do my own. (First I only want to print the last closing price)
What I´ve done yet:
I saw at https://github.com/joaopsilva/binance-java-api the example of the Candlestick.
List<Candlestick> candlesticks = client.getCandlestickBars("NEOETH", CandlestickInterval.WEEKLY); System.out.println(candlesticks);
My changes in the code of TradingClient.java:
I added after line 14:
import com.binance.api.client.domain.market.Candlestick; import com.binance.api.client.domain.market.CandlestickInterval;
and after new line 73:
public List<Candlestick> getCandlestickBars() { //OrderRequest request = new OrderRequest(symbol); return client.getCandlestickBars("NEOETH", CandlestickInterval.WEEKLY); }
In BinanceTrader.java:
I added after line 6:
import com.binance.api.client.domain.market.Candlestick; import com.binance.api.client.domain.market.CandlestickInterval;
and after new line 42:
Candlestick candlestick = client.getCandlestickBars(); logger.info("candlestick: " + candlestick);
When I trie to start the trader I got the following message:
/root/binance-trader/src/main/java/io/github/unterstein/BinanceTrader.java:[43,58] incompatible types: java.util.List<com.binance.api.client.domain.market.Candlestick> cannot be converted to com.binance.api.client.domain.market.Candlestick
Here the complete code of my changes:
BinanceTrader.java:
`package io.github.unterstein;
import com.binance.api.client.domain.OrderStatus;
import com.binance.api.client.domain.account.AssetBalance;
import com.binance.api.client.domain.account.Order;
import com.binance.api.client.domain.market.OrderBook;
import com.binance.api.client.domain.market.Candlestick;
import com.binance.api.client.domain.market.CandlestickInterval;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
public class BinanceTrader {
private static Logger logger = LoggerFactory.getLogger(BinanceTrader.class);
private TradingClient client;
private final double tradeDifference;
private final double tradeProfit;
private final int tradeAmount;
private Double currentlyBoughtPrice;
private Long orderId;
private int panicBuyCounter;
private int panicSellCounter;
private double trackingLastPrice;
BinanceTrader(double tradeDifference, double tradeProfit, int tradeAmount, String baseCurrency, String tradeCurrency, String key, String secret) {
client = new TradingClient(baseCurrency, tradeCurrency, key, secret);
trackingLastPrice = client.lastPrice();
this.tradeAmount = tradeAmount;
this.tradeProfit = tradeProfit;
this.tradeDifference = tradeDifference;
clear();
}
void tick() {
double lastPrice = 0;
try {
OrderBook orderBook = client.getOrderBook();
Candlestick candlestick = client.getCandlestickBars();
logger.info("candlestick: " + candlestick);
lastPrice = client.lastPrice();
AssetBalance tradingBalance = client.getTradingBalance();
double lastKnownTradingBalance = client.getAllTradingBalance();
double lastBid = Double.valueOf(orderBook.getBids().get(0).getPrice());
double lastAsk = Double.valueOf(orderBook.getAsks().get(0).getPrice());
double buyPrice = lastBid + tradeDifference;
double sellPrice = lastAsk - tradeDifference;
double profitablePrice = buyPrice + (buyPrice * tradeProfit / 100);
logger.info(String.format("buyPrice:%.8f sellPrice:%.8f bid:%.8f ask:%.8f price:%.8f profit:%.8f diff:%.8f\n", buyPrice, sellPrice, lastAsk, lastAsk, lastPrice, profitablePrice, (lastAsk - profitablePrice)));
if (orderId == null) {
logger.info("nothing bought, let`s check");
// find a burst to buy
// but make sure price is ascending!
if (lastAsk >= profitablePrice) {
if (lastPrice > trackingLastPrice) {
logger.info("Buy burst detected");
currentlyBoughtPrice = profitablePrice;
orderId = client.buy(tradeAmount, buyPrice).getOrderId();
panicBuyCounter = 0;
panicSellCounter = 0;
} else {
logger.warn("woooops, price is falling?!? don`t do something!");
panicSellForCondition(lastPrice, lastKnownTradingBalance, client.tradingBalanceAvailable(tradingBalance));
}
} else {
logger.info(String.format("No profit detected, difference %.8f\n", lastAsk - profitablePrice));
currentlyBoughtPrice = null;
panicSellForCondition(lastPrice, lastKnownTradingBalance, client.tradingBalanceAvailable(tradingBalance));
}
} else {
Order order = client.getOrder(orderId);
OrderStatus status = order.getStatus();
if (status != OrderStatus.CANCELED) {
// not new and not canceled, check for profit
logger.info("Tradingbalance: " + tradingBalance);
if ("0".equals("" + tradingBalance.getLocked().charAt(0)) &&
lastAsk >= currentlyBoughtPrice) {
if (status == OrderStatus.NEW) {
// nothing happened here, maybe cancel as well?
panicBuyCounter++;
logger.info(String.format("order still new, time %d\n", panicBuyCounter));
if (panicBuyCounter > 4) {
client.cancelOrder(orderId);
clear();
}
} else {
if ("0".equals("" + tradingBalance.getFree().charAt(0))) {
logger.warn("no balance in trading money, clearing out");
clear();
} else if (status == OrderStatus.PARTIALLY_FILLED || status == OrderStatus.FILLED) {
logger.info("Order filled with status " + status);
if (lastAsk >= profitablePrice) {
logger.info("still gaining profitable profits HODL!!");
} else {
logger.info("Not gaining enough profit anymore, let`s sell");
logger.info(String.format("Bought %d for %.8f and sell it for %.8f, this is %.8f coins profit", tradeAmount, currentlyBoughtPrice, sellPrice, (1.0 * currentlyBoughtPrice - sellPrice) * tradeAmount));
client.sell(tradeAmount, sellPrice);
}
} else {
// WTF?!
logger.error("DETECTED WTF!!!!!");
logger.error("Order: " + order + " , Order-Status: " + status);
client.panicSell(lastKnownTradingBalance, lastPrice);
clear();
}
}
} else {
panicSellCounter++;
logger.info(String.format("sell request not successful, increasing time %d\n", panicSellCounter));
panicSellForCondition(lastPrice, lastKnownTradingBalance, panicSellCounter > 3);
}
} else {
logger.warn("Order was canceled, cleaning up.");
clear(); // Order was canceled, so clear and go on
}
}
} catch (Exception e) {
logger.error("Unable to perform ticker", e);
}
trackingLastPrice = lastPrice;
}
private void panicSellForCondition(double lastPrice, double lastKnownTradingBalance, boolean condition) {
if (condition) {
logger.info("panicSellForCondition");
client.panicSell(lastKnownTradingBalance, lastPrice);
clear();
}
}
private void clear() {
panicBuyCounter = 0;
panicSellCounter = 0;
orderId = null;
currentlyBoughtPrice = null;
}
List getBalances() {
return client.getBalances();
}
}
TradingClient.java:
package io.github.unterstein;
import com.binance.api.client.BinanceApiClientFactory;
import com.binance.api.client.BinanceApiRestClient;
import com.binance.api.client.domain.OrderSide;
import com.binance.api.client.domain.OrderType;
import com.binance.api.client.domain.TimeInForce;
import com.binance.api.client.domain.account.AssetBalance;
import com.binance.api.client.domain.account.NewOrder;
import com.binance.api.client.domain.account.NewOrderResponse;
import com.binance.api.client.domain.account.Order;
import com.binance.api.client.domain.account.request.CancelOrderRequest;
import com.binance.api.client.domain.account.request.OrderRequest;
import com.binance.api.client.domain.account.request.OrderStatusRequest;
import com.binance.api.client.domain.market.Candlestick;
import com.binance.api.client.domain.market.CandlestickInterval;
import com.binance.api.client.domain.market.OrderBook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
public class TradingClient {
private static Logger logger = LoggerFactory.getLogger(TradingClient.class);
private BinanceApiRestClient client;
private String baseCurrency;
private String tradeCurrency;
private String symbol;
TradingClient(String baseCurrency, String tradeCurrency, String key, String secret) {
this.baseCurrency = baseCurrency;
this.tradeCurrency = tradeCurrency;
BinanceApiClientFactory factory = BinanceApiClientFactory.newInstance(key, secret);
client = factory.newRestClient();
symbol = tradeCurrency + baseCurrency;
}
// The bid price represents the maximum price that a buyer is willing to pay for a security.
// The ask price represents the minimum price that a seller is willing to receive.
public OrderBook getOrderBook() {
return client.getOrderBook(symbol, 5);
}
public AssetBalance getBaseBalance() {
return client.getAccount().getAssetBalance(baseCurrency);
}
public AssetBalance getTradingBalance() {
return client.getAccount().getAssetBalance(tradeCurrency);
}
public double assetBalanceToDouble(AssetBalance balance) {
return Double.valueOf(balance.getFree()) + Double.valueOf(balance.getLocked());
}
public double getAllTradingBalance() {
AssetBalance tradingBalance = getTradingBalance();
return assetBalanceToDouble(tradingBalance);
}
public boolean tradingBalanceAvailable(AssetBalance tradingBalance) {
return assetBalanceToDouble(tradingBalance) > 1;
}
public List getBalances() {
return client.getAccount().getBalances();
}
public List getOpenOrders() {
OrderRequest request = new OrderRequest(symbol);
return client.getOpenOrders(request);
}
public List getCandlestickBars() {
//OrderRequest request = new OrderRequest(symbol);
return client.getCandlestickBars("NEOETH", CandlestickInterval.WEEKLY);
}
public void cancelAllOrders() {
getOpenOrders().forEach(order -> client.cancelOrder(new CancelOrderRequest(symbol, order.getOrderId())));
}
// * GTC (Good-Til-Canceled) orders are effective until they are executed or canceled.
// * IOC (Immediate or Cancel) orders fills all or part of an order immediately and cancels the remaining part of the order.
public NewOrderResponse buy(int quantity, double price) {
String priceString = String.format("%.8f", price).replace(",", ".");
logger.info(String.format("Buying %d for %s\n", quantity, priceString));
NewOrder order = new NewOrder(symbol, OrderSide.BUY, OrderType.LIMIT, TimeInForce.GTC, "" + quantity, priceString);
return client.newOrder(order);
}
public void sell(int quantity, double price) {
String priceString = String.format("%.8f", price).replace(",", ".");
logger.info(String.format("Selling %d for %s\n", quantity, priceString));
NewOrder order = new NewOrder(symbol, OrderSide.SELL, OrderType.LIMIT, TimeInForce.GTC, "" + quantity, priceString);
client.newOrder(order);
}
public void sellMarket(int quantity) {
if (quantity > 0) {
logger.info("Selling to MARKET with quantity " + quantity);
NewOrder order = new NewOrder(symbol, OrderSide.SELL, OrderType.MARKET, null, "" + quantity);
client.newOrder(order);
} else {
logger.info("not executing - 0 quantity sell");
}
}
public Order getOrder(long orderId) {
return client.getOrderStatus(new OrderStatusRequest(symbol, orderId));
}
public double lastPrice() {
return Double.valueOf(client.get24HrPriceStatistics(symbol).getLastPrice());
}
public void cancelOrder(long orderId) {
logger.info("Cancelling order " + orderId);
client.cancelOrder(new CancelOrderRequest(symbol, orderId));
}
public void panicSell(double lastKnownAmount, double lastKnownPrice) {
logger.error("!!!! PANIC SELL !!!!");
logger.warn(String.format("Probably selling %.8f for %.8f", lastKnownAmount, lastKnownPrice));
cancelAllOrders();
sellMarket(Double.valueOf(getTradingBalance().getFree()).intValue());
}
}
`
I'll preface this by saying that I'm not a Java guy, so I'm lodging this as a simple end-user.
So far I've had nothing but frustration from this bot because it seems to inexplicably do random things. Like randomly set a market(!?) order to panic sell all holdings at a very low rate for no explained reason :/
Suggestions:
(1) Yes I understand losses happen in trading, yes I know when the bot gets confused it attempts to panic sell all of your holdings.
Running on MacOS 10.13, Java 1.8.0_151
mvn spring-boot:run -DAPI_KEY='mykey' -DAPI_SECRET='mysecret' \
-DTRADE_PROFIT='1.3' -DTRADE_AMOUNT='75' \
-DBASE_CURRENCY='ETH' -DTRADE_CURRENCY='POE'
results in the following exception after a while
2017-12-30 13:56:40.877 INFO 8056 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : Tradingbalance: AssetBalance[asset=POE,free=149.85000000,locked=0.00000000]
2017-12-30 13:56:40.877 INFO 8056 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : Order filled
2017-12-30 13:56:40.877 INFO 8056 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : Not gaining enough profit anymore, lets sell
2017-12-30 13:56:40.878 ERROR 8056 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : Unable to perform ticker
java.util.MissingFormatArgumentException: Format specifier '%.8f'
at java.util.Formatter.format(Formatter.java:2519) ~[na:1.8.0_151]
at java.util.Formatter.format(Formatter.java:2455) ~[na:1.8.0_151]
at java.lang.String.format(String.java:2940) ~[na:1.8.0_151]
at io.github.unterstein.BinanceTrader.tick(BinanceTrader.java:97) ~[classes/:na]
I guess there is a parameter missing in the log info (sellPrice). If I find some time will provide a PR.
Anyway, great work. Will check out the bot performance ;)
When I try to run the mvn command it throws this.
Could not resolve dependencies for project io.github.unterstein:binancebot:jar:0.0.1-SNAPSHOT: Failure to find com.binance.api:binance-api-client:jar:1.0.0 in https://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced
Hi there,
I am trying to get this working on a raspberry pi with docker. I get the following error when trying to run the image:
standard_init_linux.go:195: exec user process caused "exec format error"
Do you have any idea what could cause this problem?
I want to try the git clone way. On my Server i cant run docker :/
Here is the output:
Administrator@WIN-7SM163QVH8B MINGW64 ~/Desktop
$ git clone [email protected]:binance-exchange/binance-java-api.git
Cloning into 'binance-java-api'...
The authenticity of host 'github.com (192.30.253.112)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'github.com,192.30.253.112' (RSA) to the list of known hosts.
[email protected]: Permission denied (publickey).
fatal: Could not read from remote repository.Please make sure you have the correct access rights
and the repository exists.
is this an error?
greetings
An error happening when I try with other coin like ETH , and when i try with a litlle amount .
And i can't see the difference on my binance acount when your bot work and didn't work . Can you help me to fix it ?
Hello i have installed your bot with docker its ok but no place order or sell i wait reply thanks you
nothing bought, let`s check
2018-01-15 11:26:55.852 INFO 15 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : Buy detected
2018-01-15 11:26:55.852 INFO 15 --- [pool-1-thread-1] io.github.unterstein.TradingClient : Buying 110 for 0.00009706
2018-01-15 11:26:58.856 INFO 15 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : buyPrice:0.00009707 sellPrice:0.00009821 bid:0.00009822 ask:0.00009822 price:0.00009792 profit:0.00009814 diff:0.00000008
2018-01-15 11:26:59.622 INFO 15 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : Tradingbalance: AssetBalance[asset=XVG,free=0.00000000,locked=0.00000000]
2018-01-15 11:26:59.623 INFO 15 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : order still new, time 1
2018-01-15 11:27:01.839 INFO 15 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : buyPrice:0.00009707 sellPrice:0.00009831 bid:0.00009832 ask:0.00009832 price:0.00009832 profit:0.00009814 diff:0.00000018
2018-01-15 11:27:02.416 INFO 15 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : Tradingbalance: AssetBalance[asset=XVG,free=0.00000000,locked=0.00000000]
2018-01-15 11:27:02.416 INFO 15 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : order still new, time 2
2018-01-15 11:27:04.850 INFO 15 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : buyPrice:0.00009707 sellPrice:0.00009829 bid:0.00009830 ask:0.00009830 price:0.00009832 profit:0.00009814 diff:0.00000016
2018-01-15 11:27:05.450 INFO 15 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : Tradingbalance: AssetBalance[asset=XVG,free=0.00000000,locked=0.00000000]
2018-01-15 11:27:05.450 INFO 15 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : order still new, time 3
2018-01-15 11:27:07.853 INFO 15 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : buyPrice:0.00009707 sellPrice:0.00009828 bid:0.00009829 ask:0.00009829 price:0.00009832 profit:0.00009814 diff:0.00000015
2018-01-15 11:27:08.447 INFO 15 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : Tradingbalance: AssetBalance[asset=XVG,free=0.00000000,locked=0.00000000]
2018-01-15 11:27:08.448 INFO 15 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : order still new, time 4
2018-01-15 11:27:10.836 INFO 15 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : buyPrice:0.00009707 sellPrice:0.00009827 bid:0.00009828 ask:0.00009828 price:0.00009829 profit:0.00009814 diff:0.00000014
2018-01-15 11:27:11.436 INFO 15 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : Tradingbalance: AssetBalance[asset=XVG,free=0.00000000,locked=0.00000000]
2018-01-15 11:27:11.436 INFO 15 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : order still new, time 5
2018-01-15 11:27:11.436 INFO 15 --- [pool-1-thread-1] io.github.unterstein.TradingClient : Cancelling order 7688776
2018-01-15 11:27:13.855 INFO 15 --- [pool-1-thread-1] io.github.unterstein.BinanceTrader : buyPrice:0.00009707 sellPrice:0.00009826 bid:0.00009827 ask:0.00009827 price:0.00009827 profit:0.00009814 diff:0.00000013
It tries to buy 5 times and then cancels the order? Do I need to do something in my binance account? I have ETH and some BNB for Fees.
Hey i'm in France , and i don't know how to change the order-date . Can you tell me how ?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.