├── server ├── src │ ├── main │ │ ├── resources │ │ │ ├── scripts │ │ │ │ ├── stop.sh │ │ │ │ ├── start.sh │ │ │ │ └── start_silent.sh │ │ │ ├── database.properties │ │ │ ├── query.json │ │ │ ├── message.properties │ │ │ └── logback-spring.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── lickhunter │ │ │ │ └── web │ │ │ │ ├── services │ │ │ │ ├── OrderService.java │ │ │ │ ├── NotificationService.java │ │ │ │ ├── WatchService.java │ │ │ │ ├── SentimentsService.java │ │ │ │ ├── FileService.java │ │ │ │ ├── LickHunterService.java │ │ │ │ ├── impl │ │ │ │ │ ├── OrderServiceImpl.java │ │ │ │ │ ├── TelegramServiceImpl.java │ │ │ │ │ ├── FileServiceImpl.java │ │ │ │ │ ├── DiscordServiceImpl.java │ │ │ │ │ ├── LickHunterServiceImpl.java │ │ │ │ │ ├── LongOffsetVWAPIndicator.java │ │ │ │ │ ├── ShortOffsetVWAPIndicator.java │ │ │ │ │ ├── SentimentsServiceImpl.java │ │ │ │ │ └── WatchServiceImpl.java │ │ │ │ ├── TechnicalIndicatorService.java │ │ │ │ ├── AccountService.java │ │ │ │ ├── TradeService.java │ │ │ │ └── MarketService.java │ │ │ │ ├── controllers │ │ │ │ ├── BaseController.java │ │ │ │ └── MarketController.java │ │ │ │ ├── constants │ │ │ │ ├── TradeConstants.java │ │ │ │ ├── ApplicationConstants.java │ │ │ │ ├── UserDataEventConstants.java │ │ │ │ └── ErrorCode.java │ │ │ │ ├── to │ │ │ │ ├── AbstractTO.java │ │ │ │ └── TickerQueryTO.java │ │ │ │ ├── events │ │ │ │ └── BinanceEvents.java │ │ │ │ ├── exceptions │ │ │ │ ├── ServiceException.java │ │ │ │ └── ExceptionTranslator.java │ │ │ │ ├── telegram │ │ │ │ └── Commands.java │ │ │ │ ├── factory │ │ │ │ └── JsonPropertySourceFactory.java │ │ │ │ ├── configs │ │ │ │ ├── ScheduledConfig.java │ │ │ │ ├── WebSettings.java │ │ │ │ ├── DcaRange.java │ │ │ │ ├── MessageConfig.java │ │ │ │ ├── DataSourceConfig.java │ │ │ │ ├── ApplicationConfig.java │ │ │ │ └── UserDefinedSettings.java │ │ │ │ ├── annotation │ │ │ │ └── Constraint.java │ │ │ │ ├── entities │ │ │ │ └── DefaultCatalog.java │ │ │ │ ├── models │ │ │ │ ├── liquidation │ │ │ │ │ ├── Liquidation.java │ │ │ │ │ └── Liquidations.java │ │ │ │ ├── Coins.java │ │ │ │ ├── sentiments │ │ │ │ │ ├── SentimentData.java │ │ │ │ │ └── Config.java │ │ │ │ ├── market │ │ │ │ │ └── RateLimit.java │ │ │ │ └── webhook │ │ │ │ │ └── DiscordWebhook.java │ │ │ │ ├── utils │ │ │ │ └── APIPreconditionsUtil.java │ │ │ │ ├── repositories │ │ │ │ └── TelegramRepository.java │ │ │ │ └── WebApplication.java │ │ └── assembly │ │ │ └── bin.xml │ └── test │ │ └── java │ │ └── com │ │ └── lickhunter │ │ └── web │ │ └── WebApplicationTests.java └── README.md ├── binance-sdk ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── binance │ │ │ │ └── client │ │ │ │ ├── model │ │ │ │ ├── enums │ │ │ │ │ ├── TransferType.java │ │ │ │ │ ├── NewOrderRespType.java │ │ │ │ │ ├── TimeInForce.java │ │ │ │ │ ├── OrderRespType.java │ │ │ │ │ ├── WorkingType.java │ │ │ │ │ ├── SideEffectType.java │ │ │ │ │ ├── CrossMarginTransferType.java │ │ │ │ │ ├── IncomeType.java │ │ │ │ │ ├── QuerySort.java │ │ │ │ │ ├── MarginTransferType.java │ │ │ │ │ ├── OrderSide.java │ │ │ │ │ ├── MBPLevelEnums.java │ │ │ │ │ ├── PositionSide.java │ │ │ │ │ ├── DepthStep.java │ │ │ │ │ ├── BalanceMode.java │ │ │ │ │ ├── DealRole.java │ │ │ │ │ ├── AccountChangeModeEnum.java │ │ │ │ │ ├── EtfSwapType.java │ │ │ │ │ ├── QueryDirection.java │ │ │ │ │ ├── AccountState.java │ │ │ │ │ ├── TradeDirection.java │ │ │ │ │ ├── SymbolState.java │ │ │ │ │ ├── EtfStatus.java │ │ │ │ │ ├── LoanOrderStates.java │ │ │ │ │ ├── BalanceType.java │ │ │ │ │ ├── DepositState.java │ │ │ │ │ ├── TransferFuturesDirection.java │ │ │ │ │ ├── TransferMasterType.java │ │ │ │ │ ├── AccountType.java │ │ │ │ │ ├── PeriodType.java │ │ │ │ │ ├── OrderState.java │ │ │ │ │ ├── OrderType.java │ │ │ │ │ ├── TransactType.java │ │ │ │ │ ├── StopOrderOperator.java │ │ │ │ │ ├── WithdrawState.java │ │ │ │ │ ├── OrderSource.java │ │ │ │ │ ├── CandlestickInterval.java │ │ │ │ │ └── AccountChangeType.java │ │ │ │ ├── market │ │ │ │ │ ├── OrderBookEntry.java │ │ │ │ │ ├── SymbolPrice.java │ │ │ │ │ ├── OrderBook.java │ │ │ │ │ ├── FundingRate.java │ │ │ │ │ ├── ExchangeFilter.java │ │ │ │ │ ├── TakerLongShortStat.java │ │ │ │ │ ├── RateLimit.java │ │ │ │ │ ├── OpenInterestStat.java │ │ │ │ │ ├── SymbolOrderBook.java │ │ │ │ │ ├── CommonLongShortRatio.java │ │ │ │ │ ├── MarkPrice.java │ │ │ │ │ ├── Trade.java │ │ │ │ │ ├── ExchangeInformation.java │ │ │ │ │ ├── AggregateTrade.java │ │ │ │ │ └── LiquidationOrder.java │ │ │ │ ├── user │ │ │ │ │ ├── AccountUpdate.java │ │ │ │ │ ├── BalanceUpdate.java │ │ │ │ │ ├── UserDataUpdateEvent.java │ │ │ │ │ └── PositionUpdate.java │ │ │ │ ├── ResponseResult.java │ │ │ │ ├── trade │ │ │ │ │ ├── Leverage.java │ │ │ │ │ ├── AccountBalance.java │ │ │ │ │ ├── Income.java │ │ │ │ │ └── WalletDeltaLog.java │ │ │ │ └── event │ │ │ │ │ ├── MarkPriceEvent.java │ │ │ │ │ └── SymbolBookTickerEvent.java │ │ │ │ ├── impl │ │ │ │ ├── utils │ │ │ │ │ ├── Handler.java │ │ │ │ │ ├── EnumLookup.java │ │ │ │ │ └── InternalUtils.java │ │ │ │ ├── RestApiRequest.java │ │ │ │ ├── RestApiJsonParser.java │ │ │ │ ├── ChannelParser.java │ │ │ │ ├── WebsocketRequest.java │ │ │ │ ├── BinanceApiInternalFactory.java │ │ │ │ ├── ApiSignature.java │ │ │ │ └── WebSocketWatchDog.java │ │ │ │ ├── SubscriptionErrorHandler.java │ │ │ │ ├── SubscriptionListener.java │ │ │ │ ├── ResponseCallback.java │ │ │ │ ├── RequestOptions.java │ │ │ │ ├── exception │ │ │ │ └── BinanceApiException.java │ │ │ │ └── constant │ │ │ │ └── BinanceApiConstants.java │ │ └── resources │ │ │ └── logback.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── binance │ │ │ └── client │ │ │ └── examples │ │ │ ├── constants │ │ │ └── PrivateConfig.java │ │ │ ├── websocket │ │ │ ├── SubscribeAllBookTicker.java │ │ │ ├── SubscribeAllMiniTicker.java │ │ │ ├── SubscribeAllLiquidationOrder.java │ │ │ ├── SubscribeAllTicker.java │ │ │ ├── SubscribeDiffDepth.java │ │ │ ├── SubscribeMarkPrice.java │ │ │ ├── SubscribeBookDepth.java │ │ │ ├── SubscribeSymbolTicker.java │ │ │ ├── SubscribeAggregateTrade.java │ │ │ ├── SubscribeSymbolBookTicker.java │ │ │ ├── SubscribeSymbolMiniTicker.java │ │ │ ├── SubscribeSymbolLiquidationOrder.java │ │ │ └── SubscribeCandlestick.java │ │ │ ├── market │ │ │ ├── GetMarkPrice.java │ │ │ ├── GetOldTrades.java │ │ │ ├── GetOrderBook.java │ │ │ ├── GetFundingRate.java │ │ │ ├── GetRecentTrades.java │ │ │ ├── GetAggregateTrades.java │ │ │ ├── GetLiquidationOrders.java │ │ │ ├── GetSymbolPriceTicker.java │ │ │ ├── GetExchangeInformation.java │ │ │ ├── Get24hrTickerPriceChange.java │ │ │ ├── GetSymbolOrderBookTicker.java │ │ │ ├── GetCandlestick.java │ │ │ ├── GetOpenInterestStat.java │ │ │ ├── GetGlobalAccountRatio.java │ │ │ ├── GetTakerLongShortRatio.java │ │ │ ├── GetTakerLongShortStat.java │ │ │ ├── GetTopTraderAccountRatio.java │ │ │ └── GetTopTraderPositionRatio.java │ │ │ ├── trade │ │ │ ├── GetBalance.java │ │ │ ├── GetPositionRisk.java │ │ │ ├── GetOrder.java │ │ │ ├── CancelOrder.java │ │ │ ├── GetAccountInformation.java │ │ │ ├── ChangeInitialLeverage.java │ │ │ ├── GetAccountTrades.java │ │ │ ├── GetIncomeHistory.java │ │ │ ├── GetOpenOrders.java │ │ │ ├── GetPositionSide.java │ │ │ ├── ChangePositionSide.java │ │ │ ├── CancelAllOpenOrders.java │ │ │ ├── GetAllOrders.java │ │ │ ├── ChangeMarginType.java │ │ │ ├── AddIsolatedPositionMargin.java │ │ │ ├── GetPositionMarginHistory.java │ │ │ ├── PostOrder.java │ │ │ ├── BatchCancelOrders.java │ │ │ └── BatchPlaceOrders.java │ │ │ └── user │ │ │ └── SubscribeUserData.java │ └── README.md └── README.md ├── .mvn └── wrapper │ └── maven-wrapper.properties ├── .gitignore ├── .github ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md └── workflows │ └── codeql-analysis.yml ├── pom.xml └── .gitattributes /server/src/main/resources/scripts/stop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | kill $(cat ./pid.file) -------------------------------------------------------------------------------- /server/src/main/resources/scripts/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | java -jar server-0.0.1-SNAPSHOT.jar & echo $! > ./pid.file & -------------------------------------------------------------------------------- /server/src/main/resources/scripts/start_silent.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | nohup ./start.sh > foo.out 2> foo.err < /dev/null & -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/services/OrderService.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.services; 2 | 3 | public interface OrderService { 4 | } 5 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/TransferType.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | public enum TransferType { 4 | ROLL_IN, 5 | ROLL_OUT 6 | } -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/NewOrderRespType.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | public enum NewOrderRespType { 4 | ACK, 5 | RESULT 6 | } 7 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/TimeInForce.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | public enum TimeInForce { 4 | GTC, 5 | IOC, 6 | FOK 7 | } 8 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/OrderRespType.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | public enum OrderRespType { 4 | ACK, 5 | RESULT, 6 | FULL 7 | } 8 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/WorkingType.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | public enum WorkingType { 4 | 5 | MARK_PRICE, 6 | CONTRACT_PRICE; 7 | 8 | } -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/impl/utils/Handler.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.impl.utils; 2 | 3 | @FunctionalInterface 4 | public interface Handler { 5 | 6 | void handle(T t); 7 | } 8 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/services/NotificationService.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.services; 2 | 3 | public interface NotificationService { 4 | void send(MESSAGE message); 5 | } 6 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/SideEffectType.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | 4 | public enum SideEffectType { 5 | NO_SIDE_EFFECT, 6 | MARGIN_BUY, 7 | AUTO_REPAY; 8 | } 9 | -------------------------------------------------------------------------------- /server/src/main/resources/database.properties: -------------------------------------------------------------------------------- 1 | #Database Configuration 2 | db.driver=org.sqlite.JDBC 3 | db.url=jdbc:sqlite:lickhunter.db 4 | db.username=sa 5 | db.password=password 6 | 7 | #SQL Dialect 8 | jooq.sql.dialect=SQLITE -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/services/WatchService.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.services; 2 | 3 | import java.io.IOException; 4 | 5 | public interface WatchService { 6 | void fileWatcher() throws IOException; 7 | } 8 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/CrossMarginTransferType.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | public enum CrossMarginTransferType { 4 | 5 | SUPER_MARGIN_TO_SPOT, 6 | SPOT_TO_SUPER_MARGIN; 7 | 8 | } 9 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/controllers/BaseController.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.controllers; 2 | 3 | public abstract class BaseController { 4 | //TODO set base URI for controllers 5 | public static final String BASE_URI = "/api"; 6 | } 7 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/impl/RestApiRequest.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.impl; 2 | 3 | import okhttp3.Request; 4 | 5 | public class RestApiRequest { 6 | 7 | public Request request; 8 | RestApiJsonParser jsonParser; 9 | } 10 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/services/SentimentsService.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.services; 2 | 3 | 4 | import com.lickhunter.web.models.sentiments.SentimentData; 5 | 6 | public interface SentimentsService { 7 | SentimentData getSentiments(String symbol); 8 | } 9 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/services/FileService.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.services; 2 | 3 | public interface FileService { 4 | FILE readFromFile(String path, String filename, Class classType); 5 | void writeToFile(String path, String filename, T t); 6 | } 7 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/impl/RestApiJsonParser.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.impl; 2 | 3 | import com.binance.client.impl.utils.JsonWrapper; 4 | 5 | @FunctionalInterface 6 | public interface RestApiJsonParser { 7 | 8 | T parseJson(JsonWrapper json); 9 | } 10 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/IncomeType.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | 4 | public enum IncomeType { 5 | TRANSFER, 6 | WELCOME_BONUS, 7 | REALIZED_PNL, 8 | FUNDING_FEE, 9 | COMMISSION, 10 | INSURANCE_CLEAR; 11 | } 12 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/constants/PrivateConfig.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.constants; 2 | 3 | public class PrivateConfig { 4 | 5 | public static final String API_KEY = "XXXXXX"; 6 | public static final String SECRET_KEY = "XXXXXX"; 7 | 8 | } 9 | -------------------------------------------------------------------------------- /server/src/test/java/com/lickhunter/web/WebApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class WebApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/SubscriptionErrorHandler.java: -------------------------------------------------------------------------------- 1 | package com.binance.client; 2 | 3 | import com.binance.client.exception.BinanceApiException; 4 | 5 | /** 6 | * The error handler for the subscription. 7 | */ 8 | @FunctionalInterface 9 | public interface SubscriptionErrorHandler { 10 | 11 | void onError(BinanceApiException exception); 12 | } 13 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/QuerySort.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | public enum QuerySort { 4 | 5 | ASC("asc"), 6 | DESC("desc"); 7 | 8 | private final String code; 9 | 10 | QuerySort(String code) { 11 | this.code = code; 12 | } 13 | 14 | public String getCode() { 15 | return code; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/constants/TradeConstants.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.constants; 2 | 3 | public enum TradeConstants { 4 | CROSSED("crossed"), 5 | ISOLATED("isolated"); 6 | 7 | private final String value; 8 | 9 | TradeConstants(String value) { 10 | this.value = value; 11 | } 12 | 13 | public String getValue() { 14 | return this.value; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/to/AbstractTO.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.to; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * This class represents a general request (transfer object) message. 9 | * It's the base class used for all client request and response parameters. 10 | */ 11 | @Slf4j 12 | public abstract class AbstractTO implements Serializable { 13 | } 14 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/MarginTransferType.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | 4 | public enum MarginTransferType { 5 | IN("1"), 6 | OUT("2"); 7 | 8 | private final String code; 9 | 10 | MarginTransferType(String code) { 11 | this.code = code; 12 | } 13 | 14 | @Override 15 | public String toString() { 16 | return code; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/OrderSide.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | /** 4 | * buy, sell, both. 5 | */ 6 | 7 | public enum OrderSide { 8 | BUY("BUY"), 9 | SELL("SELL"); 10 | 11 | private final String code; 12 | 13 | OrderSide(String side) { 14 | this.code = side; 15 | } 16 | 17 | @Override 18 | public String toString() { 19 | return code; 20 | } 21 | 22 | 23 | } -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/MBPLevelEnums.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | public enum MBPLevelEnums { 4 | 5 | 6 | LEVEL5(5), 7 | LEVEL10(10), 8 | LEVEL20(20), 9 | LEVEL150(150), 10 | 11 | ; 12 | 13 | private final int levels; 14 | 15 | MBPLevelEnums(int levels) { 16 | this.levels = levels; 17 | } 18 | 19 | public int getLevels() { 20 | return levels; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /server/README.md: -------------------------------------------------------------------------------- 1 | # lick-hunter-web 2 | Web Application for Lick Hunter 3 | 4 | ##Prerequisites 5 | 1. Clone https://github.com/Binance-docs/Binance_Futures_Java.git 6 | 2. Open maven project and execute: mvn install 7 | 8 | ##Build 9 | 1. mvn clean install 10 | 11 | ##Run 12 | 1. java -jar web-0.0.1-SNAPSHOT.jar 13 | 14 | ##Database 15 | 1. To access the console, got to http://localhost:8080/h2-console 16 | username and password located in database.properties -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/websocket/SubscribeAllBookTicker.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.websocket; 2 | 3 | import com.binance.client.SubscriptionClient; 4 | 5 | public class SubscribeAllBookTicker { 6 | 7 | public static void main(String[] args) { 8 | 9 | SubscriptionClient client = SubscriptionClient.create(); 10 | 11 | client.subscribeAllBookTickerEvent(System.out::println, null); 12 | 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/websocket/SubscribeAllMiniTicker.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.websocket; 2 | 3 | import com.binance.client.SubscriptionClient; 4 | 5 | public class SubscribeAllMiniTicker { 6 | 7 | public static void main(String[] args) { 8 | 9 | SubscriptionClient client = SubscriptionClient.create(); 10 | 11 | client.subscribeAllMiniTickerEvent(System.out::println, null); 12 | 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/events/BinanceEvents.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.events; 2 | 3 | import org.springframework.context.ApplicationEvent; 4 | 5 | public class BinanceEvents extends ApplicationEvent { 6 | private String message; 7 | 8 | public BinanceEvents(Object source, String message) { 9 | super(source); 10 | this.message = message; 11 | } 12 | 13 | public String getMessage() { 14 | return this.message; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/websocket/SubscribeAllLiquidationOrder.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.websocket; 2 | 3 | import com.binance.client.SubscriptionClient; 4 | 5 | public class SubscribeAllLiquidationOrder { 6 | 7 | public static void main(String[] args) { 8 | 9 | SubscriptionClient client = SubscriptionClient.create(); 10 | 11 | client.subscribeAllLiquidationOrderEvent(System.out::println, null); 12 | 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /server/src/main/resources/query.json: -------------------------------------------------------------------------------- 1 | { 2 | "symbol": null, 3 | "maxPriceChangePercent":null, 4 | "volumeUpperLimit":3000000000, 5 | "volumeLowerLimit":0, 6 | "minimumTradingAge":30, 7 | "percentageFromAllTimeHigh":5, 8 | "exclude":["DOGE","BTC","ETH","XRP"], 9 | "autoExclude": true, 10 | "autoExcludePercentage": 70, 11 | "bbStrategy": false, 12 | "bbTimeframe": "15m", 13 | "bbBarCount": 20, 14 | "cciStrategy": false, 15 | "cciBarCount": 20, 16 | "cciTimeframe": "15m", 17 | "minMarketCap": 0 18 | } -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/constants/ApplicationConstants.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.constants; 2 | 3 | public enum ApplicationConstants { 4 | 5 | SETTINGS("settings.json"), 6 | COINS("coins.json"), 7 | WEB_SETTINGS("web-settings.json"), 8 | TICKER_QUERY("query.json"); 9 | 10 | private final String value; 11 | 12 | ApplicationConstants(String value) { 13 | this.value = value; 14 | } 15 | 16 | public String getValue() { 17 | return this.value; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/exceptions/ServiceException.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.exceptions; 2 | 3 | public class ServiceException extends Exception { 4 | 5 | public ServiceException() { 6 | super(); 7 | } 8 | 9 | public ServiceException(String msg, Exception e) { 10 | super(msg, e); 11 | } 12 | 13 | public ServiceException(String msg) { 14 | super(msg); 15 | } 16 | 17 | public ServiceException(Throwable cause) { 18 | super(cause); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/services/LickHunterService.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.services; 2 | 3 | import com.lickhunter.web.configs.Settings; 4 | import com.lickhunter.web.configs.UserDefinedSettings; 5 | import com.lickhunter.web.configs.WebSettings; 6 | import com.lickhunter.web.to.TickerQueryTO; 7 | 8 | public interface LickHunterService { 9 | TickerQueryTO getQuery(); 10 | WebSettings getWebSettings(); 11 | UserDefinedSettings getActiveSettings(); 12 | Settings getLickHunterSettings(); 13 | } 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/PositionSide.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | /** 4 | * @author : wangwanlu 5 | * @since : 2020/3/25, Wed 6 | **/ 7 | public enum PositionSide { 8 | 9 | BOTH("BOTH"), 10 | 11 | SHORT("SHORT"), 12 | 13 | LONG("LONG"), 14 | ; 15 | 16 | private final String code; 17 | 18 | PositionSide(String side) { 19 | this.code = side; 20 | } 21 | 22 | @Override 23 | public String toString() { 24 | return code; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/websocket/SubscribeAllTicker.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.websocket; 2 | 3 | import com.binance.client.SubscriptionClient; 4 | 5 | public class SubscribeAllTicker { 6 | 7 | public static void main(String[] args) { 8 | 9 | SubscriptionClient client = SubscriptionClient.create(); 10 | 11 | client.subscribeAllTickerEvent(((event) -> { 12 | System.out.println(event); 13 | client.unsubscribeAll(); 14 | }), null); 15 | 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/impl/ChannelParser.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.impl; 2 | 3 | class ChannelParser { 4 | 5 | private String symbol = ""; 6 | 7 | ChannelParser(String input) { 8 | String[] fields = input.split("\\."); 9 | if (fields.length >= 2) { 10 | symbol = fields[1]; 11 | } 12 | String type = ""; 13 | if (fields.length > 3) { 14 | type = fields[2]; 15 | } 16 | if (type.equals("kline")) { 17 | 18 | } 19 | } 20 | 21 | public String getSymbol() { 22 | return symbol; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/websocket/SubscribeDiffDepth.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.websocket; 2 | 3 | import com.binance.client.SubscriptionClient; 4 | 5 | public class SubscribeDiffDepth { 6 | 7 | public static void main(String[] args) { 8 | 9 | SubscriptionClient client = SubscriptionClient.create(); 10 | 11 | client.subscribeDiffDepthEvent("btcusdt", ((event) -> { 12 | System.out.println(event); 13 | client.unsubscribeAll(); 14 | }), null); 15 | 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/websocket/SubscribeMarkPrice.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.websocket; 2 | 3 | import com.binance.client.SubscriptionClient; 4 | 5 | public class SubscribeMarkPrice { 6 | 7 | public static void main(String[] args) { 8 | 9 | SubscriptionClient client = SubscriptionClient.create(); 10 | 11 | client.subscribeMarkPriceEvent("btcusdt", ((event) -> { 12 | System.out.println(event); 13 | client.unsubscribeAll(); 14 | }), null); 15 | 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/websocket/SubscribeBookDepth.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.websocket; 2 | 3 | import com.binance.client.SubscriptionClient; 4 | 5 | public class SubscribeBookDepth { 6 | 7 | public static void main(String[] args) { 8 | 9 | SubscriptionClient client = SubscriptionClient.create(); 10 | 11 | client.subscribeBookDepthEvent("btcusdt", 5, ((event) -> { 12 | System.out.println(event); 13 | client.unsubscribeAll(); 14 | }), null); 15 | 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/services/impl/OrderServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.services.impl; 2 | 3 | import com.lickhunter.web.configs.Settings; 4 | import com.lickhunter.web.services.OrderService; 5 | import lombok.RequiredArgsConstructor; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.stereotype.Service; 8 | 9 | @Service 10 | @Slf4j 11 | @RequiredArgsConstructor 12 | public class OrderServiceImpl implements OrderService { 13 | 14 | private final Settings config; 15 | 16 | public void test() { 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/websocket/SubscribeSymbolTicker.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.websocket; 2 | 3 | import com.binance.client.SubscriptionClient; 4 | 5 | public class SubscribeSymbolTicker { 6 | 7 | public static void main(String[] args) { 8 | 9 | SubscriptionClient client = SubscriptionClient.create(); 10 | 11 | client.subscribeSymbolTickerEvent("btcusdt", ((event) -> { 12 | System.out.println(event); 13 | client.unsubscribeAll(); 14 | }), null); 15 | 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/websocket/SubscribeAggregateTrade.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.websocket; 2 | 3 | import com.binance.client.SubscriptionClient; 4 | 5 | public class SubscribeAggregateTrade { 6 | 7 | public static void main(String[] args) { 8 | 9 | SubscriptionClient client = SubscriptionClient.create(); 10 | 11 | client.subscribeAggregateTradeEvent("btcusdt", ((event) -> { 12 | System.out.println(event); 13 | client.unsubscribeAll(); 14 | }), null); 15 | 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/websocket/SubscribeSymbolBookTicker.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.websocket; 2 | 3 | import com.binance.client.SubscriptionClient; 4 | 5 | public class SubscribeSymbolBookTicker { 6 | 7 | public static void main(String[] args) { 8 | 9 | SubscriptionClient client = SubscriptionClient.create(); 10 | 11 | client.subscribeSymbolBookTickerEvent("btcusdt", ((event) -> { 12 | System.out.println(event); 13 | client.unsubscribeAll(); 14 | }), null); 15 | 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/websocket/SubscribeSymbolMiniTicker.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.websocket; 2 | 3 | import com.binance.client.SubscriptionClient; 4 | 5 | public class SubscribeSymbolMiniTicker { 6 | 7 | public static void main(String[] args) { 8 | 9 | SubscriptionClient client = SubscriptionClient.create(); 10 | 11 | client.subscribeSymbolMiniTickerEvent("btcusdt", ((event) -> { 12 | System.out.println(event); 13 | client.unsubscribeAll(); 14 | }), null); 15 | 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/DepthStep.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | 4 | /** 5 | * The aggregation depth type. 6 | */ 7 | public enum DepthStep { 8 | 9 | /** 10 | * step0,step1,step2,step3,step4,step5 11 | */ 12 | STEP0("step0"), 13 | STEP1("step1"), 14 | STEP2("step2"), 15 | STEP3("step3"), 16 | STEP4("step4"), 17 | STEP5("step5"), 18 | ; 19 | 20 | private final String step; 21 | 22 | DepthStep(String step) { 23 | this.step = step; 24 | } 25 | 26 | public String getStep() { 27 | return step; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/market/GetMarkPrice.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.market; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | 8 | public class GetMarkPrice { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/market/GetOldTrades.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.market; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | 8 | public class GetOldTrades { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/market/GetOrderBook.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.market; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | 8 | public class GetOrderBook { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/market/GetFundingRate.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.market; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | 8 | public class GetFundingRate { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/market/GetRecentTrades.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.market; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | 8 | public class GetRecentTrades { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/websocket/SubscribeSymbolLiquidationOrder.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.websocket; 2 | 3 | import com.binance.client.SubscriptionClient; 4 | 5 | public class SubscribeSymbolLiquidationOrder { 6 | 7 | public static void main(String[] args) { 8 | 9 | SubscriptionClient client = SubscriptionClient.create(); 10 | 11 | client.subscribeSymbolLiquidationOrderEvent("btcusdt", ((event) -> { 12 | System.out.println(event); 13 | client.unsubscribeAll(); 14 | }), null); 15 | 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/SubscriptionListener.java: -------------------------------------------------------------------------------- 1 | package com.binance.client; 2 | 3 | /** 4 | * You must implement the SubscriptionListener interface.
The server will push any update to 5 | * the client. if client get the update, the onReceive method will be called. 6 | * 7 | * @param The type of received data. 8 | */ 9 | @FunctionalInterface 10 | public interface SubscriptionListener { 11 | 12 | /** 13 | * onReceive will be called when get the data sent by server. 14 | * 15 | * @param data The data send by server. 16 | */ 17 | void onReceive(T data); 18 | } 19 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/market/GetAggregateTrades.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.market; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | 8 | public class GetAggregateTrades { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/market/GetLiquidationOrders.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.market; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | 8 | public class GetLiquidationOrders { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | } 14 | } -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/market/GetSymbolPriceTicker.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.market; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | 8 | public class GetSymbolPriceTicker { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/market/GetExchangeInformation.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.market; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | 8 | public class GetExchangeInformation { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/constants/UserDataEventConstants.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.constants; 2 | 3 | public enum UserDataEventConstants { 4 | 5 | ACCOUNT_UPDATE("ACCOUNT_UPDATE"), 6 | MARGIN_CALL("MARGIN_CALL"), 7 | ORDER_TRADE_UPDATE("ORDER_TRADE_UPDATE"), 8 | ACCOUNT_CONFIG_UPDATE("ACCOUNT_CONFIG_UPDATE"), 9 | LISTEN_KEY_EXPIRED("LISTEN_KEY_EXPIRED"); 10 | 11 | private final String value; 12 | 13 | UserDataEventConstants(String value) { 14 | this.value = value; 15 | } 16 | 17 | public String getValue() { 18 | return this.value; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/market/Get24hrTickerPriceChange.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.market; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | 8 | public class Get24hrTickerPriceChange { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/market/GetSymbolOrderBookTicker.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.market; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | 8 | public class GetSymbolOrderBookTicker { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/BalanceMode.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | /** 4 | * The balance mode used for subscribing the balance notification. 5 | */ 6 | public enum BalanceMode { 7 | 8 | /** 9 | * Subscribe available balance 10 | */ 11 | AVAILABLE("0"), 12 | 13 | /** 14 | * Subscribe TOTAL balance, total balance is the sum of available and frozen 15 | */ 16 | TOTAL("1"); 17 | 18 | private final String code; 19 | 20 | BalanceMode(String code) { 21 | this.code = code; 22 | } 23 | 24 | public String getCode() { 25 | return code; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/DealRole.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | public enum DealRole { 4 | 5 | /** 6 | * TAKER,MAKER 7 | */ 8 | 9 | TAKER("taker"), 10 | MAKER("maker") 11 | ; 12 | 13 | private final String role; 14 | 15 | DealRole(String role) { 16 | this.role = role; 17 | } 18 | 19 | public String getRole() { 20 | return role; 21 | } 22 | 23 | public static DealRole find(String role) { 24 | for (DealRole fr : DealRole.values()) { 25 | if (fr.getRole().equals(role)) { 26 | return fr; 27 | } 28 | } 29 | return null; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/trade/GetBalance.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.trade; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | 8 | public class GetBalance { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | System.out.println(syncRequestClient.getBalance()); 14 | } 15 | } -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/AccountChangeModeEnum.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | /** 4 | * The balance mode used for subscribing the balance notification. 5 | */ 6 | public enum AccountChangeModeEnum { 7 | 8 | /** 9 | * Subscribe balance change 10 | */ 11 | BALANCE("0"), 12 | 13 | /** 14 | * Subscribe TOTAL balance, total balance is the sum of available and frozen 15 | */ 16 | TOTAL("1"); 17 | 18 | private final String code; 19 | 20 | AccountChangeModeEnum(String code) { 21 | this.code = code; 22 | } 23 | 24 | public String getCode() { 25 | return code; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/EtfSwapType.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | import com.binance.client.impl.utils.EnumLookup; 4 | 5 | public enum EtfSwapType { 6 | ETF_SWAP_IN("1"), 7 | ETF_SWAP_OUT("2"); 8 | 9 | private final String code; 10 | 11 | EtfSwapType(String code) { 12 | this.code = code; 13 | } 14 | 15 | @Override 16 | public String toString() { 17 | return code; 18 | } 19 | 20 | private static final EnumLookup lookup = new EnumLookup<>(EtfSwapType.class); 21 | 22 | public static EtfSwapType lookup(String name) { 23 | return lookup.lookup(name); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/trade/GetPositionRisk.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.trade; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | 8 | public class GetPositionRisk { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | System.out.println(syncRequestClient.getPositionRisk()); 14 | } 15 | } -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/QueryDirection.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | import com.binance.client.impl.utils.EnumLookup; 4 | 5 | public enum QueryDirection { 6 | PREV("prev"), 7 | NEXT("next"); 8 | 9 | private final String code; 10 | 11 | QueryDirection(String code) { 12 | this.code = code; 13 | } 14 | 15 | @Override 16 | public String toString() { 17 | return code; 18 | } 19 | 20 | private static final EnumLookup lookup = new EnumLookup<>(QueryDirection.class); 21 | 22 | public static QueryDirection lookup(String name) { 23 | return lookup.lookup(name); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/trade/GetOrder.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.trade; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | 8 | public class GetOrder { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | System.out.println(syncRequestClient.getOrder("BTCUSDT", 37886301L, null)); 14 | } 15 | } -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/market/GetCandlestick.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.market; 2 | 3 | import com.binance.client.model.enums.CandlestickInterval; 4 | 5 | import com.binance.client.RequestOptions; 6 | import com.binance.client.SyncRequestClient; 7 | 8 | import com.binance.client.examples.constants.PrivateConfig; 9 | 10 | public class GetCandlestick { 11 | public static void main(String[] args) { 12 | RequestOptions options = new RequestOptions(); 13 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 14 | options); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/market/GetOpenInterestStat.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.market; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | import com.binance.client.examples.constants.PrivateConfig; 6 | import com.binance.client.model.enums.PeriodType; 7 | 8 | public class GetOpenInterestStat { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/market/GetGlobalAccountRatio.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.market; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | import com.binance.client.examples.constants.PrivateConfig; 6 | import com.binance.client.model.enums.PeriodType; 7 | 8 | public class GetGlobalAccountRatio { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/market/GetTakerLongShortRatio.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.market; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | import com.binance.client.examples.constants.PrivateConfig; 6 | import com.binance.client.model.enums.PeriodType; 7 | 8 | public class GetTakerLongShortRatio { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/market/GetTakerLongShortStat.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.market; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | import com.binance.client.examples.constants.PrivateConfig; 6 | import com.binance.client.model.enums.PeriodType; 7 | 8 | public class GetTakerLongShortStat { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/trade/CancelOrder.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.trade; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | 8 | public class CancelOrder { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | System.out.println(syncRequestClient.cancelOrder("BTCUSDT", 37886301L, null)); 14 | } 15 | } -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/market/GetTopTraderAccountRatio.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.market; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | import com.binance.client.examples.constants.PrivateConfig; 6 | import com.binance.client.model.enums.PeriodType; 7 | 8 | public class GetTopTraderAccountRatio { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/market/GetTopTraderPositionRatio.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.market; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | import com.binance.client.examples.constants.PrivateConfig; 6 | import com.binance.client.model.enums.PeriodType; 7 | 8 | public class GetTopTraderPositionRatio { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/trade/GetAccountInformation.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.trade; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | 8 | public class GetAccountInformation { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | System.out.println(syncRequestClient.getAccountInformation()); 14 | } 15 | } -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/constants/ErrorCode.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.constants; 2 | 3 | public enum ErrorCode { 4 | //TODO enhance exception handling and error message 5 | RESOURCE_NOT_FOUND(4000, "Resournce not found."), 6 | TOO_MANY_REQUESTS(4100, "Binance API requests limitation reached."); 7 | 8 | private final int code; 9 | private final String value; 10 | 11 | ErrorCode(int code, String value) { 12 | this.code = code; 13 | this.value = value; 14 | } 15 | 16 | public int getCode() { 17 | return this.code; 18 | } 19 | 20 | public String getValue() { 21 | return this.value; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/trade/ChangeInitialLeverage.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.trade; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | 8 | public class ChangeInitialLeverage { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | System.out.println(syncRequestClient.changeInitialLeverage("BTCUSDT", 1)); 14 | } 15 | } -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/AccountState.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | import com.binance.client.impl.utils.EnumLookup; 4 | 5 | /** 6 | * working, lock. 7 | */ 8 | public enum AccountState { 9 | WORKING("working"), 10 | LOCK("lock"); 11 | 12 | private final String code; 13 | 14 | AccountState(String code) { 15 | this.code = code; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return code; 21 | } 22 | 23 | private static final EnumLookup lookup = new EnumLookup<>(AccountState.class); 24 | 25 | public static AccountState lookup(String name) { 26 | return lookup.lookup(name); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/TradeDirection.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | import com.binance.client.impl.utils.EnumLookup; 4 | 5 | /** 6 | * buy, sell. 7 | */ 8 | public enum TradeDirection { 9 | BUY("buy"), 10 | SELL("sell"); 11 | 12 | private final String code; 13 | 14 | TradeDirection(String side) { 15 | this.code = side; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return code; 21 | } 22 | 23 | private static final EnumLookup lookup = new EnumLookup<>(TradeDirection.class); 24 | 25 | public static TradeDirection lookup(String name) { 26 | return lookup.lookup(name); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/trade/GetAccountTrades.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.trade; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | 8 | public class GetAccountTrades { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | System.out.println(syncRequestClient.getAccountTrades("BTCUSDT", null, null, null, null)); 14 | } 15 | } -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/trade/GetIncomeHistory.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.trade; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | 8 | public class GetIncomeHistory { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | System.out.println(syncRequestClient.getIncomeHistory("BTCUSDT", null, null, null, null)); 14 | } 15 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/websocket/SubscribeCandlestick.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.websocket; 2 | 3 | import com.binance.client.SubscriptionClient; 4 | import com.binance.client.model.enums.CandlestickInterval; 5 | 6 | import java.util.Arrays; 7 | 8 | public class SubscribeCandlestick { 9 | 10 | public static void main(String[] args) { 11 | 12 | SubscriptionClient client = SubscriptionClient.create(); 13 | 14 | client.subscribeCandlestickEvent(Arrays.asList("btcusdt"), CandlestickInterval.ONE_MINUTE, ((event) -> { 15 | System.out.println(event); 16 | client.unsubscribeAll(); 17 | }), null); 18 | 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/services/impl/TelegramServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.services.impl; 2 | 3 | import com.lickhunter.web.services.NotificationService; 4 | import com.lickhunter.web.telegram.TelegramBot; 5 | import lombok.RequiredArgsConstructor; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.stereotype.Service; 8 | 9 | @Service("telegramNotification") 10 | @Slf4j 11 | @RequiredArgsConstructor 12 | public class TelegramServiceImpl implements NotificationService { 13 | 14 | private final TelegramBot telegramBot; 15 | 16 | @Override 17 | public void send(String message) { 18 | telegramBot.sendNotification(message); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/SymbolState.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | public enum SymbolState { 4 | 5 | /** 6 | * ONLINE, OFFLINE, SUSPEND. 7 | */ 8 | ONLINE("online"), 9 | OFFLINE("offline"), 10 | SUSPEND("suspend") 11 | ; 12 | private final String state; 13 | 14 | SymbolState(String state) { 15 | this.state = state; 16 | } 17 | 18 | public String getState() { 19 | return state; 20 | } 21 | 22 | public static SymbolState find(String state) { 23 | for (SymbolState st : SymbolState.values()) { 24 | if (st.getState().equals(state)) { 25 | return st; 26 | } 27 | } 28 | return null; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/trade/GetOpenOrders.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.trade; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | 8 | public class GetOpenOrders { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | System.out.println(syncRequestClient.getOpenOrders("BTCUSDT")); 14 | // System.out.println(syncRequestClient.getOpenOrders(null)); 15 | } 16 | } -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/trade/GetPositionSide.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.trade; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | import com.binance.client.examples.constants.PrivateConfig; 6 | 7 | /** 8 | * @author : wangwanlu 9 | * @since : 2020/4/7, Tue 10 | **/ 11 | public class GetPositionSide { 12 | 13 | public static void main(String[] args) { 14 | RequestOptions options = new RequestOptions(); 15 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 16 | options); 17 | System.out.println(syncRequestClient.getPositionSide()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/services/TechnicalIndicatorService.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.services; 2 | 3 | import com.binance.client.model.enums.CandlestickInterval; 4 | import org.ta4j.core.BarSeries; 5 | import org.ta4j.core.Strategy; 6 | 7 | public interface TechnicalIndicatorService { 8 | BarSeries getBarSeries(String symbol, CandlestickInterval timeframe); 9 | Strategy bollingerBandsStrategy(BarSeries series, Double markprice, int barCount); 10 | Strategy cciCorrectionStrategy(BarSeries series, int barCount); 11 | Strategy vwapShortStrategy(BarSeries series, int barCount, Double shortOffset, Double price); 12 | Strategy vwapLongStrategy(BarSeries series, int barCount, Double longOffset, Double price); 13 | } 14 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/EtfStatus.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | import com.binance.client.impl.utils.EnumLookup; 4 | 5 | public enum EtfStatus { 6 | NORMAL("1"), 7 | REBALANCING_START("2"), 8 | CREATION_AND_REDEMPTION_SUSPEND("3"), 9 | CREATION_SUSPEND("4"), 10 | REDEMPTION_SUSPEND("5"); 11 | 12 | private final String code; 13 | 14 | EtfStatus(String code) { 15 | this.code = code; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return code; 21 | } 22 | 23 | private static final EnumLookup lookup = new EnumLookup<>(EtfStatus.class); 24 | 25 | public static EtfStatus lookup(String name) { 26 | return lookup.lookup(name); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/trade/ChangePositionSide.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.trade; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | import com.binance.client.examples.constants.PrivateConfig; 6 | 7 | /** 8 | * @author : wangwanlu 9 | * @since : 2020/3/25, Wed 10 | **/ 11 | public class ChangePositionSide { 12 | public static void main(String[] args) { 13 | RequestOptions options = new RequestOptions(); 14 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 15 | options); 16 | System.out.println(syncRequestClient.changePositionSide(true)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /binance-sdk/README.md: -------------------------------------------------------------------------------- 1 | # Binance Java SDK (beta version) 2 | 3 | This is Binance Java SDK, This is a lightweight Java library, you can import to your Java project and use this SDK to query all market data, trading and manage your account. 4 | 5 | The SDK supports both synchronous and asynchronous RESTful API invoking, and subscribe the market data from the Websocket connection. 6 | 7 | 8 | ## Table of Contents 9 | 10 | - [Beginning](#Beginning) 11 | - [Installation](#Installation) 12 | 13 | 14 | ## Beginning 15 | 16 | ### Installation 17 | 18 | *The SDK is compiled by Java8* 19 | 20 | For Beta version, please import the source code in java IDE (idea or eclipse) 21 | 22 | The example code is in binance-api-sdk/java/src/test/java/com/binance/client/examples. 23 | -------------------------------------------------------------------------------- /binance-sdk/src/README.md: -------------------------------------------------------------------------------- 1 | # Binance Java SDK (beta version) 2 | 3 | This is Binance Java SDK, This is a lightweight Java library, you can import to your Java project and use this SDK to query all market data, trading and manage your account. 4 | 5 | The SDK supports both synchronous and asynchronous RESTful API invoking, and subscribe the market data from the Websocket connection. 6 | 7 | 8 | ## Table of Contents 9 | 10 | - [Beginning](#Beginning) 11 | - [Installation](#Installation) 12 | 13 | 14 | ## Beginning 15 | 16 | ### Installation 17 | 18 | *The SDK is compiled by Java8* 19 | 20 | For Beta version, please import the source code in java IDE (idea or eclipse) 21 | 22 | The example code is in binance-api-sdk/java/src/test/java/com/binance/client/examples. 23 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/trade/CancelAllOpenOrders.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.trade; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | import com.binance.client.examples.constants.PrivateConfig; 6 | 7 | /** 8 | * @author : wangwanlu 9 | * @since : 2020/4/7, Tue 10 | **/ 11 | public class CancelAllOpenOrders { 12 | 13 | public static void main(String[] args) { 14 | RequestOptions options = new RequestOptions(); 15 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 16 | options); 17 | System.out.println(syncRequestClient.cancelAllOpenOrder("BTCUSDT")); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/trade/GetAllOrders.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.trade; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | 8 | public class GetAllOrders { 9 | public static void main(String[] args) { 10 | RequestOptions options = new RequestOptions(); 11 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 12 | options); 13 | System.out.println(syncRequestClient.getAllOrders("BTCUSDT", null, null, null, 10)); 14 | // System.out.println(syncRequestClient.getAllOrders("BTCUSDT", null, null, null, null)); 15 | } 16 | } -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/services/AccountService.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.services; 2 | 3 | import com.binance.client.model.enums.IncomeType; 4 | import com.binance.client.model.trade.AccountInformation; 5 | import com.binance.client.model.trade.Income; 6 | 7 | import java.math.BigDecimal; 8 | import java.util.List; 9 | 10 | public interface AccountService { 11 | 12 | AccountInformation getAccountInformation(); 13 | Boolean isOpenOrderIsolationActive(String key, Double isolationPercentage); 14 | Boolean isMaxOpenActive(String key, Long maxOpen); 15 | List getIncomeHistory(String symbol, IncomeType incomeType, Long startTime, Long endTime, Integer limit); 16 | BigDecimal getDailyPnl(); 17 | void futuresTransfer(String asset, Double amount, int type); 18 | } 19 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/telegram/Commands.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.telegram; 2 | 3 | public class Commands { 4 | public static final String commandInitChar = "/"; 5 | public static final String startCommand = commandInitChar + "start"; 6 | public static final String SETTINGS = commandInitChar + "settings"; 7 | public static final String PAUSE_BOT = commandInitChar + "pause"; 8 | public static final String RESUME_BOT = commandInitChar + "resume"; 9 | public static final String STATUS = commandInitChar + "status"; 10 | public static final String CLOSE_POSITION = commandInitChar + "close"; 11 | public static final String CLOSE_ALL_POSITIONS = commandInitChar + "close_all"; 12 | public static final String POSITIONS = commandInitChar + "positions"; 13 | } 14 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/LoanOrderStates.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | import com.binance.client.impl.utils.EnumLookup; 4 | 5 | /** 6 | * created, accrual, cleared, invalid. 7 | */ 8 | public enum LoanOrderStates { 9 | 10 | CREATED("created"), 11 | ACCRUAL("accrual"), 12 | CLEARED("cleared"), 13 | INVALID("invalid"); 14 | 15 | private final String code; 16 | 17 | LoanOrderStates(String state) { 18 | this.code = state; 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return code; 24 | } 25 | 26 | private static final EnumLookup lookup = new EnumLookup<>(LoanOrderStates.class); 27 | 28 | public static LoanOrderStates lookup(String name) { 29 | return lookup.lookup(name); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/BalanceType.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | import com.binance.client.impl.utils.EnumLookup; 4 | 5 | public enum BalanceType { 6 | TRADE("trade"), 7 | FROZEN("frozen"), 8 | LOAN("loan"), 9 | INTEREST("interest"), 10 | LOAN_AVAILABLE("loan-available"), 11 | TRANSFER_OUT_AVAILABLE("transfer-out-available"); 12 | 13 | 14 | 15 | private final String code; 16 | 17 | BalanceType(String code) { 18 | this.code = code; 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return code; 24 | } 25 | 26 | private static final EnumLookup lookup = new EnumLookup<>(BalanceType.class); 27 | 28 | public static BalanceType lookup(String name) { 29 | return lookup.lookup(name); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/DepositState.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | import com.binance.client.impl.utils.EnumLookup; 4 | 5 | 6 | /** 7 | * withdraw, deposit. 8 | */ 9 | public enum DepositState { 10 | 11 | UNKNOWN("unknown"), 12 | CONFIRMING("confirming"), 13 | SAFE("safe"), 14 | CONFIRMED("confirmed"), 15 | ORPHAN("orphan"); 16 | 17 | 18 | private final String code; 19 | 20 | DepositState(String code) { 21 | this.code = code; 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return code; 27 | } 28 | 29 | private static final EnumLookup lookup = new EnumLookup<>(DepositState.class); 30 | 31 | public static DepositState lookup(String name) { 32 | return lookup.lookup(name); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/ResponseCallback.java: -------------------------------------------------------------------------------- 1 | package com.binance.client; 2 | 3 | /** 4 | * The interface for define asynchronous invoking callback.
If you want to ues the asynchronous 5 | * invoking, you must implement the ResponseCallback yourself.
The onResponse method is 6 | * mandatory, when the asynchronous invoking completed, this method will be called.
You should 7 | * check the AsyncResult to know whether the asynchronous invoking is successful or not, and get the 8 | * response data from AsyncResult. 9 | */ 10 | @FunctionalInterface 11 | public interface ResponseCallback { 12 | 13 | /** 14 | * Be called when the request successful. 15 | * 16 | * @param response The {@link AsyncResult} of the asynchronous invoking. 17 | */ 18 | void onResponse(T response); 19 | } 20 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/trade/ChangeMarginType.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.trade; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | import com.binance.client.examples.constants.PrivateConfig; 6 | 7 | /** 8 | * @author : wangwanlu 9 | * @since : 2020/4/23, Thu 10 | **/ 11 | public class ChangeMarginType { 12 | 13 | public static void main(String[] args) { 14 | RequestOptions options = new RequestOptions(); 15 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 16 | options); 17 | 18 | // margin type: ISOLATED, CROSSED 19 | System.out.println(syncRequestClient.changeMarginType("BTCUSDT", "ISOLATED")); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/impl/WebsocketRequest.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.impl; 2 | 3 | import com.binance.client.SubscriptionErrorHandler; 4 | import com.binance.client.SubscriptionListener; 5 | import com.binance.client.impl.utils.Handler; 6 | 7 | class WebsocketRequest { 8 | 9 | WebsocketRequest(SubscriptionListener listener, SubscriptionErrorHandler errorHandler) { 10 | this.updateCallback = listener; 11 | this.errorHandler = errorHandler; 12 | } 13 | 14 | String signatureVersion = "2"; 15 | String name; 16 | Handler connectionHandler; 17 | Handler authHandler = null; 18 | final SubscriptionListener updateCallback; 19 | RestApiJsonParser jsonParser; 20 | final SubscriptionErrorHandler errorHandler; 21 | } 22 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/TransferFuturesDirection.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | 4 | public enum TransferFuturesDirection { 5 | 6 | /** 7 | * FUTURES_TO_PRO,PRO_TO_FUTURES 8 | */ 9 | FUTURES_TO_PRO("futures-to-pro"), 10 | PRO_TO_FUTURES("pro-to-futures") 11 | ; 12 | 13 | private String direction; 14 | 15 | TransferFuturesDirection(String direction) { 16 | this.direction = direction; 17 | } 18 | 19 | public String getDirection() { 20 | return direction; 21 | } 22 | 23 | public static TransferFuturesDirection find(String direction){ 24 | for (TransferFuturesDirection d : TransferFuturesDirection.values()) { 25 | if (d.getDirection().equals(direction)) { 26 | return d; 27 | } 28 | } 29 | return null; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/trade/AddIsolatedPositionMargin.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.trade; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | import com.binance.client.examples.constants.PrivateConfig; 6 | import com.binance.client.model.enums.PositionSide; 7 | 8 | /** 9 | * @author : wangwanlu 10 | * @since : 2020/4/23, Thu 11 | **/ 12 | public class AddIsolatedPositionMargin { 13 | 14 | static int INCREASE_MARGIN_TYPE = 1; 15 | static int DECREASE_MARGIN_TYPE = 2; 16 | 17 | public static void main(String[] args) { 18 | RequestOptions options = new RequestOptions(); 19 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 20 | options); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/exceptions/ExceptionTranslator.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.exceptions; 2 | 3 | import org.jooq.ExecuteContext; 4 | import org.jooq.SQLDialect; 5 | import org.jooq.impl.DefaultExecuteListener; 6 | import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator; 7 | import org.springframework.jdbc.support.SQLExceptionTranslator; 8 | 9 | public class ExceptionTranslator extends DefaultExecuteListener { 10 | 11 | @Override 12 | public void exception(ExecuteContext context) { 13 | SQLDialect dialect = context.configuration().dialect(); 14 | SQLExceptionTranslator translator = new SQLErrorCodeSQLExceptionTranslator(dialect.thirdParty().springDbName()); 15 | 16 | context.exception(translator.translate("Access database using jOOQ", context.sql(), context.sqlException())); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/TransferMasterType.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | import com.binance.client.impl.utils.EnumLookup; 4 | 5 | public enum TransferMasterType { 6 | 7 | 8 | MASTER_TRANSFER_IN("master-transfer-in"), 9 | MASTER_TRANSFER_OUT("master-transfer-out"), 10 | MASTER_POINT_TRANSFER_IN("master-point-transfer-in"), 11 | MASTER_POINT_TRANSFER_OUT("master-point-transfer-out"); 12 | private final String code; 13 | 14 | TransferMasterType(String side) { 15 | this.code = side; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return code; 21 | } 22 | 23 | private static final EnumLookup lookup = new EnumLookup<>(TransferMasterType.class); 24 | 25 | public static TransferMasterType lookup(String name) { 26 | return lookup.lookup(name); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/AccountType.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | import com.binance.client.impl.utils.EnumLookup; 4 | 5 | /** 6 | * SPOT, MARGIN, OTC, POINT, UNKNOWN. 7 | */ 8 | public enum AccountType { 9 | SPOT("spot"), 10 | MARGIN("margin"), 11 | OTC("otc"), 12 | POINT("point"), 13 | SUPER_MARGIN("super-margin"), 14 | MINEPOOL("minepool"), 15 | ETF( "etf"), 16 | AGENCY( "agency"), 17 | UNKNOWN("unknown"); 18 | 19 | private final String code; 20 | 21 | AccountType(String code) { 22 | this.code = code; 23 | } 24 | 25 | @Override 26 | public String toString() { 27 | return code; 28 | } 29 | 30 | private static final EnumLookup lookup = new EnumLookup<>(AccountType.class); 31 | 32 | public static AccountType lookup(String name) { 33 | return lookup.lookup(name); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/PeriodType.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | import com.binance.client.impl.utils.EnumLookup; 4 | 5 | public enum PeriodType { 6 | _5m("5m"), 7 | _15m("15m"), 8 | _30m("30m"), 9 | _1h("1h"), 10 | _2h("2h"), 11 | _4h("4h"), 12 | _6h("6h"), 13 | _12h("12h"), 14 | _1d("1d"); 15 | 16 | private final String code; 17 | 18 | PeriodType(String code) { 19 | this.code = code; 20 | } 21 | 22 | 23 | public String getCode() { 24 | return code; 25 | } 26 | 27 | @Override 28 | public String toString() { 29 | return code; 30 | } 31 | 32 | private static final EnumLookup lookup = new EnumLookup<>(PeriodType.class); 33 | 34 | public static PeriodType lookup(String name) { 35 | return lookup.lookup(name); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /server/src/main/resources/message.properties: -------------------------------------------------------------------------------- 1 | notification.margin-threshold=Margin Threshold reached %s percent. Margin: %s. Balance: %s 2 | notification.balance=Balance: %s \nUnrealized Profit: %s \nRisk Ratio: %s%%\nPositions: %s\nToday's PNL: %s\nToday's %%: %s%% 3 | notification.start-websocket=Start Websocket successful 4 | notification.stop-websocket=Stop Websocket successful 5 | notification.telegram-commands=/balance - Check balance\n/settings - Change settings of lick hunter server\n/pause - Pause Bot\n/resume - Resume Bot\n/status - Check the status of the Bot 6 | notification.social-volume-alerts=Social Volume increased %s%% from %s to %s\n\nAlert Configuration: If %s Social Volume increased %s%% from the previous hour, alert me! 7 | notification.twitter-volume-alerts=Number of Tweets increased %s%% from %s to %s\n\nAlert Configuration: If %s Number of Tweets increased %s%% from the previous hour, alert me! -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/impl/utils/EnumLookup.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.impl.utils; 2 | 3 | import java.util.EnumSet; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | public class EnumLookup> { 11 | 12 | 13 | Logger logger = LoggerFactory.getLogger(EnumLookup.class); 14 | 15 | private final Map map = new HashMap<>(); 16 | private final String enumName; 17 | 18 | public EnumLookup(Class clazz) { 19 | enumName = clazz.getName(); 20 | for (T item : EnumSet.allOf(clazz)) { 21 | map.put(item.toString(), item); 22 | } 23 | } 24 | 25 | public T lookup(String name) { 26 | if (!map.containsKey(name)) { 27 | logger.error("[Enum] Cannot found " + name + " in Enum " + enumName); 28 | return null; 29 | } 30 | return map.get(name); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/factory/JsonPropertySourceFactory.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.factory; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import org.springframework.core.env.MapPropertySource; 5 | import org.springframework.core.env.PropertySource; 6 | import org.springframework.core.io.support.EncodedResource; 7 | import org.springframework.core.io.support.PropertySourceFactory; 8 | 9 | import java.io.IOException; 10 | import java.util.Map; 11 | 12 | public class JsonPropertySourceFactory implements PropertySourceFactory { 13 | 14 | @Override 15 | public PropertySource createPropertySource( 16 | String name, EncodedResource resource) 17 | throws IOException { 18 | Map readValue = new ObjectMapper() 19 | .readValue(resource.getInputStream(), Map.class); 20 | return new MapPropertySource("json-property", readValue); 21 | } 22 | } -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/OrderState.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | import com.binance.client.impl.utils.EnumLookup; 4 | 5 | /** 6 | * SUBMITTED, PARTIALFILLED, CANCELLING. PARTIALCANCELED FILLED CANCELED CREATED 7 | */ 8 | public enum OrderState { 9 | SUBMITTED("submitted"), 10 | CREATED("created"), 11 | PARTIALFILLED("partial-filled"), 12 | CANCELLING("cancelling"), 13 | PARTIALCANCELED("partial-canceled"), 14 | FILLED("filled"), 15 | CANCELED("canceled"); 16 | 17 | 18 | private final String code; 19 | 20 | OrderState(String code) { 21 | this.code = code; 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return code; 27 | } 28 | 29 | private static final EnumLookup lookup = new EnumLookup<>(OrderState.class); 30 | 31 | public static OrderState lookup(String name) { 32 | return lookup.lookup(name); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/trade/GetPositionMarginHistory.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.trade; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | import com.binance.client.examples.constants.PrivateConfig; 6 | 7 | /** 8 | * @author : wangwanlu 9 | * @since : 2020/4/23, Thu 10 | **/ 11 | public class GetPositionMarginHistory { 12 | 13 | static int INCREASE_MARGIN_TYPE = 1; 14 | static int DECREASE_MARGIN_TYPE = 2; 15 | 16 | public static void main(String[] args) { 17 | RequestOptions options = new RequestOptions(); 18 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 19 | options); 20 | 21 | long endTime = System.currentTimeMillis(); 22 | long startTime = endTime - (24 * 60 * 60 * 1000); 23 | int limit = 500; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/configs/ScheduledConfig.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.configs; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.scheduling.annotation.EnableScheduling; 6 | import org.springframework.scheduling.annotation.SchedulingConfigurer; 7 | import org.springframework.scheduling.config.ScheduledTaskRegistrar; 8 | 9 | import java.util.concurrent.Executor; 10 | import java.util.concurrent.Executors; 11 | 12 | @Configuration 13 | @EnableScheduling 14 | public class ScheduledConfig implements SchedulingConfigurer { 15 | 16 | @Override 17 | public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { 18 | taskRegistrar.setScheduler(taskExecutor()); 19 | } 20 | 21 | @Bean(destroyMethod="shutdown") 22 | public Executor taskExecutor() { 23 | return Executors.newScheduledThreadPool(100); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/OrderType.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | import com.binance.client.impl.utils.EnumLookup; 4 | 5 | /** 6 | * buy-market, sell-market, buy-limit, buy-ioc, sell-ioc, 7 | * buy-limit-maker, sell-limit-maker, buy-stop-limit, sell-stop-limit. 8 | */ 9 | public enum OrderType { 10 | LIMIT("LIMIT"), 11 | MARKET("MARKET"), 12 | STOP("STOP"), 13 | STOP_MARKET("STOP_MARKET"), 14 | TAKE_PROFIT("TAKE_PROFIT"), 15 | TAKE_PROFIT_MARKET("TAKE_PROFIT_MARKET"), 16 | INVALID(null); 17 | 18 | private final String code; 19 | 20 | OrderType(String code) { 21 | this.code = code; 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return code; 27 | } 28 | 29 | private static final EnumLookup lookup = new EnumLookup<>(OrderType.class); 30 | 31 | public static OrderType lookup(String name) { 32 | return lookup.lookup(name); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/market/OrderBookEntry.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.market; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | 6 | import java.math.BigDecimal; 7 | 8 | public class OrderBookEntry { 9 | 10 | private BigDecimal price; 11 | 12 | private BigDecimal qty; 13 | 14 | public BigDecimal getPrice() { 15 | return price; 16 | } 17 | 18 | public void setPrice(BigDecimal price) { 19 | this.price = price; 20 | } 21 | 22 | public BigDecimal getQty() { 23 | return qty; 24 | } 25 | 26 | public void setQty(BigDecimal qty) { 27 | this.qty = qty; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE).append("price", price) 33 | .append("qty", qty).toString(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/market/SymbolPrice.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.market; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | 6 | import java.math.BigDecimal; 7 | 8 | public class SymbolPrice { 9 | 10 | private String symbol; 11 | 12 | private BigDecimal price; 13 | 14 | public String getSymbol() { 15 | return symbol; 16 | } 17 | 18 | public void setSymbol(String symbol) { 19 | this.symbol = symbol; 20 | } 21 | 22 | public BigDecimal getPrice() { 23 | return price; 24 | } 25 | 26 | public void setPrice(BigDecimal price) { 27 | this.price = price; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE).append("symbol", symbol) 33 | .append("price", price).toString(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/TransactType.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | public enum TransactType { 4 | 5 | TRADE("trade"), 6 | ETF("etf"), 7 | TRANSACT_FEE("transact-fee"), 8 | FEE_DEDUCTION("fee-deduction"), 9 | TRANSFER("transfer"), 10 | CREDIT("credit"), 11 | LIQUIDATION("liquidation"), 12 | INTEREST("interest"), 13 | DEPOSIT("deposit"), 14 | WITHDRAW("withdraw"), 15 | WITHDRAW_FEE("withdraw-fee"), 16 | EXCHANGE("exchange"), 17 | OTHER_TYPES("other-types") 18 | 19 | ; 20 | private final String code; 21 | 22 | TransactType(String code) { 23 | this.code = code; 24 | } 25 | 26 | public String getCode() { 27 | return code; 28 | } 29 | 30 | public static TransactType find(String code) { 31 | for (TransactType transactType : TransactType.values()) { 32 | if (transactType.getCode().equals(code)) { 33 | return transactType; 34 | } 35 | } 36 | return null; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/StopOrderOperator.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | public enum StopOrderOperator { 4 | /** 5 | * GTE,greater than and equal (>=) ,LTE less than and equal (<=) 6 | */ 7 | GTE("gte", "greater than and equal (>=)"), LTE("lte", "less than and equal (<=)"); 8 | 9 | private String operator; 10 | 11 | private String desc; 12 | 13 | StopOrderOperator(String operator, String desc) { 14 | this.operator = operator; 15 | this.desc = desc; 16 | } 17 | 18 | public String getOperator() { 19 | return operator; 20 | } 21 | 22 | public String getDesc() { 23 | return desc; 24 | } 25 | 26 | public static StopOrderOperator find(String operator) { 27 | for (StopOrderOperator op : StopOrderOperator.values()) { 28 | if (op.getOperator().equals(operator)) { 29 | return op; 30 | } 31 | } 32 | return null; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/WithdrawState.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | import com.binance.client.impl.utils.EnumLookup; 4 | 5 | 6 | /** 7 | * withdraw, deposit. 8 | */ 9 | public enum WithdrawState { 10 | 11 | 12 | SUBMITTED("submitted"), 13 | REEXAMINE("reexamine"), 14 | CANCELED("canceled"), 15 | PASS("pass"), 16 | REJECT("reject"), 17 | PRETRANSFER("pre-transfer"), 18 | WALLETTRANSFER("wallet-transfer"), 19 | WALEETREJECT("wallet-reject"), 20 | CONFIRMED("confirmed"), 21 | CONFIRMERROR("confirm-error"), 22 | REPEALED("repealed"); 23 | 24 | 25 | private final String code; 26 | 27 | WithdrawState(String code) { 28 | this.code = code; 29 | } 30 | 31 | @Override 32 | public String toString() { 33 | return code; 34 | } 35 | 36 | private static final EnumLookup lookup = new EnumLookup<>(WithdrawState.class); 37 | 38 | public static WithdrawState lookup(String name) { 39 | return lookup.lookup(name); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/configs/WebSettings.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.configs; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import lombok.With; 8 | 9 | import java.math.BigDecimal; 10 | import java.util.HashMap; 11 | import java.util.Map; 12 | 13 | @With 14 | @Data 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class WebSettings { 18 | 19 | @JsonProperty("vwapTimeframe") 20 | private String vwapTimeframe; 21 | @JsonProperty("vwapLength") 22 | private Integer vwapLength; 23 | @JsonProperty("active") 24 | private String active; 25 | @JsonProperty("defaultSettings") 26 | private String defaultSettings; 27 | @JsonProperty("dailyReinvestment") 28 | private BigDecimal dailyReinvestment; 29 | @JsonProperty("safe") 30 | private String safe; 31 | @JsonProperty("userDefinedSettings") 32 | private Map userDefinedSettings = new HashMap<>(); 33 | 34 | } -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/configs/DcaRange.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.configs; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | import lombok.With; 10 | 11 | import java.math.BigDecimal; 12 | 13 | @With 14 | @Data 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | @JsonInclude(JsonInclude.Include.NON_NULL) 18 | @JsonPropertyOrder({ 19 | "percentFromAverage", 20 | "percentTakeProfit", 21 | "percentBuy", 22 | "numberOfBuys" 23 | }) 24 | public class DcaRange { 25 | @JsonProperty("percentFromAverage") 26 | private BigDecimal percentFromAverage; 27 | @JsonProperty("percentTakeProfit") 28 | private BigDecimal percentTakeProfit; 29 | @JsonProperty("percentBuy") 30 | private BigDecimal percentBuy; 31 | @JsonProperty("numberOfBuys") 32 | private String numberOfBuys; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/user/AccountUpdate.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.user; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | 6 | import java.util.List; 7 | 8 | public class AccountUpdate { 9 | 10 | private List balances; 11 | 12 | private List positions; 13 | 14 | public List getBalances() { 15 | return balances; 16 | } 17 | 18 | public void setBalances(List balances) { 19 | this.balances = balances; 20 | } 21 | 22 | public List getPositions() { 23 | return positions; 24 | } 25 | 26 | public void setPositions(List positions) { 27 | this.positions = positions; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE).append("balances", balances) 33 | .append("positions", positions).toString(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | pom 6 | 7 | binance-sdk 8 | server 9 | 10 | 11 | org.springframework.boot 12 | spring-boot-starter-parent 13 | 2.4.3 14 | 15 | 16 | com.lickhunter 17 | web 18 | 0.0.1-SNAPSHOT 19 | web 20 | Web Application for Lick Hunter 21 | 22 | 23 | 24 | github 25 | GitHub OWNER Apache Maven Packages 26 | https://maven.pkg.github.com/ebaloaloa/lick-hunter-server 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/RequestOptions.java: -------------------------------------------------------------------------------- 1 | package com.binance.client; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import com.binance.client.exception.BinanceApiException; 5 | import java.net.URL; 6 | 7 | /** 8 | * The configuration for the request APIs 9 | */ 10 | public class RequestOptions { 11 | 12 | private String url = BinanceApiConstants.API_BASE_URL; 13 | 14 | public RequestOptions() { 15 | } 16 | 17 | public RequestOptions(RequestOptions option) { 18 | this.url = option.url; 19 | } 20 | 21 | /** 22 | * Set the URL for request. 23 | * 24 | * @param url The URL name like "https://fapi.binance.com". 25 | */ 26 | public void setUrl(String url) { 27 | try { 28 | URL u = new URL(url); 29 | this.url = u.toString(); 30 | } catch (Exception e) { 31 | throw new BinanceApiException(BinanceApiException.INPUT_ERROR, "The URI is incorrect: " + e.getMessage()); 32 | } 33 | this.url = url; 34 | } 35 | 36 | public String getUrl() { 37 | return url; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/ResponseResult.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | 6 | /** 7 | * @author : wangwanlu 8 | * @since : 2020/3/25, Wed 9 | **/ 10 | public class ResponseResult { 11 | 12 | private int code; 13 | 14 | private String msg; 15 | 16 | public ResponseResult() { 17 | } 18 | 19 | public ResponseResult(int code, String msg) { 20 | this.code = code; 21 | this.msg = msg; 22 | } 23 | 24 | public int getCode() { 25 | return code; 26 | } 27 | 28 | public void setCode(int code) { 29 | this.code = code; 30 | } 31 | 32 | public String getMsg() { 33 | return msg; 34 | } 35 | 36 | public void setMsg(String msg) { 37 | this.msg = msg; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE).append("code", code) 43 | .append("msg", msg).toString(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/services/TradeService.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.services; 2 | 3 | import com.binance.client.model.ResponseResult; 4 | import com.binance.client.model.enums.OrderSide; 5 | import com.binance.client.model.enums.OrderType; 6 | import com.binance.client.model.enums.TimeInForce; 7 | import com.binance.client.model.trade.Leverage; 8 | import com.binance.client.model.user.OrderUpdate; 9 | import com.lickhunter.web.entities.tables.records.SymbolRecord; 10 | 11 | public interface TradeService { 12 | ResponseResult marginType(String symbol, String marginType) throws Exception; 13 | void changeAllMarginType(); 14 | void changeAllLeverage(); 15 | Leverage changeInitialLeverage(String symbol, int leverage); 16 | void takeProfitLimitOrders(OrderUpdate orderUpdate); 17 | void newOrder(String symbol, OrderSide orderSide, OrderType orderType, TimeInForce timeInForce, String qty, String price, Boolean reduceOnly, Boolean closePosition); 18 | void closeAllPositions(); 19 | void closePosition(SymbolRecord symbolRecord); 20 | void stopLoss(); 21 | void createTakeProfitOrders(); 22 | } 23 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/annotation/Constraint.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Annotation to check the constraint of the web service input parameters. 10 | */ 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Target(value = {ElementType.FIELD, ElementType.PARAMETER}) 13 | public @interface Constraint { 14 | 15 | /** 16 | * true if the parameter can be null. default is false. 17 | * 18 | * @return true if the parameter can be null. 19 | */ 20 | boolean nullable() default false; 21 | 22 | /** 23 | * true if the list can be empty. default is false. 24 | * 25 | * @return true if the list can be empty. 26 | */ 27 | boolean emptyList() default false; 28 | 29 | /** 30 | * @return an exampl value of the parameter. 31 | */ 32 | String example() default ""; 33 | } 34 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/controllers/MarketController.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.controllers; 2 | 3 | import com.lickhunter.web.entities.tables.records.SymbolRecord; 4 | import com.lickhunter.web.services.MarketService; 5 | import com.lickhunter.web.to.TickerQueryTO; 6 | import lombok.RequiredArgsConstructor; 7 | import org.springframework.http.ResponseEntity; 8 | import org.springframework.web.bind.annotation.*; 9 | 10 | import java.util.List; 11 | 12 | @RestController 13 | @RequestMapping("/api") 14 | @RequiredArgsConstructor 15 | public class MarketController { 16 | 17 | private final MarketService marketService; 18 | 19 | @PostMapping("/ticker") 20 | public ResponseEntity getTickerByQuery(@RequestBody TickerQueryTO query) throws Exception { 21 | List priceChangeTickerList = marketService.getTickerByQuery(query); 22 | return ResponseEntity.ok(priceChangeTickerList); 23 | } 24 | 25 | @GetMapping("/liquidation") 26 | public ResponseEntity getLiquidation() throws Exception { 27 | marketService.getLiquidations(); 28 | return ResponseEntity.ok(null); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/OrderSource.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | import com.binance.client.impl.utils.EnumLookup; 4 | 5 | /** 6 | * sys, web, api, app. 7 | */ 8 | public enum OrderSource { 9 | SYS("sys"), 10 | WEB("web"), 11 | API("api"), 12 | APP("app"), 13 | FLSYS("fl-sys"), 14 | FLMGT("fl-mgt"), 15 | SPOTWEB("spot-web"), 16 | SPOTAPI("spot-api"), 17 | SPOTAPP("spot-app"), 18 | MARGINAPI("margin-api"), 19 | MARGINWEB("margin-web"), 20 | MARGINAPP("margin-app"), 21 | SUPERMARGINAPI("super_margin_api"), 22 | SUPERMARGINAPP("super_margin_app"), 23 | SUPERMARGINWEB("super_margin_web"), 24 | SUPERMARGINFLSYS("super_margin_fl_sys"), 25 | SUPERMARGINFLMGT("super_margin_fl_mgt"); 26 | 27 | private final String code; 28 | 29 | OrderSource(String code) { 30 | this.code = code; 31 | } 32 | 33 | @Override 34 | public String toString() { 35 | return code; 36 | } 37 | 38 | private static final EnumLookup lookup = new EnumLookup<>(OrderSource.class); 39 | 40 | public static OrderSource lookup(String name) { 41 | return lookup.lookup(name); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/configs/MessageConfig.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.configs; 2 | 3 | import lombok.*; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.context.annotation.PropertySource; 7 | import org.springframework.context.annotation.PropertySources; 8 | 9 | @Configuration 10 | @ConfigurationProperties(prefix = "notification") 11 | @PropertySources({ 12 | @PropertySource(value = "classpath:message.properties", ignoreResourceNotFound = true), 13 | @PropertySource(value = "file:message.properties", ignoreResourceNotFound = true) 14 | }) 15 | @With 16 | @Getter 17 | @Setter 18 | @AllArgsConstructor 19 | @RequiredArgsConstructor 20 | public class MessageConfig { 21 | private String marginThreshold; 22 | private String balance; 23 | private String startProfit; 24 | private String stopProfit; 25 | private String startWebsocket; 26 | private String stopWebsocket; 27 | private String telegramCommands; 28 | private String socialVolumeAlerts; 29 | private String twitterVolumeAlerts; 30 | } 31 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/exception/BinanceApiException.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.exception; 2 | 3 | public class BinanceApiException extends RuntimeException { 4 | 5 | /** 6 | * 7 | */ 8 | private static final long serialVersionUID = 4360108982268949009L; 9 | public static final String RUNTIME_ERROR = "RuntimeError"; 10 | public static final String INPUT_ERROR = "InputError"; 11 | public static final String KEY_MISSING = "KeyMissing"; 12 | public static final String SYS_ERROR = "SysError"; 13 | public static final String SUBSCRIPTION_ERROR = "SubscriptionError"; 14 | public static final String ENV_ERROR = "EnvironmentError"; 15 | public static final String EXEC_ERROR = "ExecuteError"; 16 | private final String errCode; 17 | 18 | public BinanceApiException(String errType, String errMsg) { 19 | super(errMsg); 20 | this.errCode = errType; 21 | } 22 | 23 | public BinanceApiException(String errType, String errMsg, Throwable e) { 24 | super(errMsg, e); 25 | this.errCode = errType; 26 | } 27 | 28 | public String getErrType() { 29 | return this.errCode; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/entities/DefaultCatalog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is generated by jOOQ. 3 | */ 4 | package com.lickhunter.web.entities; 5 | 6 | 7 | import java.util.Arrays; 8 | import java.util.List; 9 | 10 | import org.jooq.Schema; 11 | import org.jooq.impl.CatalogImpl; 12 | 13 | 14 | /** 15 | * This class is generated by jOOQ. 16 | */ 17 | @SuppressWarnings({ "all", "unchecked", "rawtypes" }) 18 | public class DefaultCatalog extends CatalogImpl { 19 | 20 | private static final long serialVersionUID = 1L; 21 | 22 | /** 23 | * The reference instance of DEFAULT_CATALOG 24 | */ 25 | public static final DefaultCatalog DEFAULT_CATALOG = new DefaultCatalog(); 26 | 27 | /** 28 | * The schema DEFAULT_SCHEMA. 29 | */ 30 | public final DefaultSchema DEFAULT_SCHEMA = DefaultSchema.DEFAULT_SCHEMA; 31 | 32 | /** 33 | * No further instances allowed 34 | */ 35 | private DefaultCatalog() { 36 | super(""); 37 | } 38 | 39 | @Override 40 | public final List getSchemas() { 41 | return Arrays.asList( 42 | DefaultSchema.DEFAULT_SCHEMA); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /binance-sdk/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | %d{yyyy-MM-dd HH:mm:ss} [%level] - %m%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | logs/%d{yyyy-MM-dd}.log 17 | 18 | 19 | 20 | 30 21 | 22 | 23 | %d{yyyy-MM-dd HH:mm:ss} [%level] - %m%n 24 | 25 | 26 | 28 | 5MB 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/trade/PostOrder.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.trade; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | import com.binance.client.model.enums.*; 8 | 9 | public class PostOrder { 10 | public static void main(String[] args) { 11 | RequestOptions options = new RequestOptions(); 12 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 13 | options); 14 | // System.out.println(syncRequestClient.postOrder("BTCUSDT", OrderSide.SELL, PositionSide.BOTH, OrderType.LIMIT, TimeInForce.GTC, 15 | // "1", "1", null, null, null, null)); 16 | 17 | // place dual position side order. 18 | // Switch between dual or both position side, call: com.binance.client.examples.trade.ChangePositionSide 19 | System.out.println(syncRequestClient.postOrder("BTCUSDT", OrderSide.SELL, PositionSide.SHORT, OrderType.LIMIT, TimeInForce.GTC, 20 | "1", "9000", null, null, null, null, NewOrderRespType.RESULT, null)); 21 | } 22 | } -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/user/SubscribeUserData.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.user; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | import com.binance.client.SubscriptionClient; 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | 8 | public class SubscribeUserData { 9 | 10 | public static void main(String[] args) { 11 | 12 | RequestOptions options = new RequestOptions(); 13 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 14 | options); 15 | 16 | // Start user data stream 17 | String listenKey = syncRequestClient.startUserDataStream(); 18 | System.out.println("listenKey: " + listenKey); 19 | 20 | // Keep user data stream 21 | syncRequestClient.keepUserDataStream(listenKey); 22 | 23 | // Close user data stream 24 | syncRequestClient.closeUserDataStream(listenKey); 25 | 26 | SubscriptionClient client = SubscriptionClient.create(); 27 | 28 | 29 | client.subscribeUserDataEvent(listenKey, System.out::println, null); 30 | 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/models/liquidation/Liquidation.java: -------------------------------------------------------------------------------- 1 | 2 | package com.lickhunter.web.models.liquidation; 3 | 4 | import com.fasterxml.jackson.annotation.*; 5 | 6 | import javax.annotation.Generated; 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | @JsonInclude(JsonInclude.Include.NON_NULL) 12 | @JsonPropertyOrder({ 13 | "data" 14 | }) 15 | @Generated("jsonschema2pojo") 16 | public class Liquidation { 17 | 18 | @JsonProperty("data") 19 | private List data = null; 20 | @JsonIgnore 21 | private Map additionalProperties = new HashMap(); 22 | 23 | @JsonProperty("data") 24 | public List getData() { 25 | return data; 26 | } 27 | 28 | @JsonProperty("data") 29 | public void setData(List data) { 30 | this.data = data; 31 | } 32 | 33 | @JsonAnyGetter 34 | public Map getAdditionalProperties() { 35 | return this.additionalProperties; 36 | } 37 | 38 | @JsonAnySetter 39 | public void setAdditionalProperty(String name, Object value) { 40 | this.additionalProperties.put(name, value); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/models/liquidation/Liquidations.java: -------------------------------------------------------------------------------- 1 | 2 | package com.lickhunter.web.models.liquidation; 3 | 4 | import com.fasterxml.jackson.annotation.*; 5 | 6 | import javax.annotation.Generated; 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | @JsonInclude(JsonInclude.Include.NON_NULL) 12 | @JsonPropertyOrder({ 13 | "data" 14 | }) 15 | @Generated("jsonschema2pojo") 16 | public class Liquidations { 17 | 18 | @JsonProperty("data") 19 | private List data = null; 20 | @JsonIgnore 21 | private Map additionalProperties = new HashMap(); 22 | 23 | @JsonProperty("data") 24 | public List getData() { 25 | return data; 26 | } 27 | 28 | @JsonProperty("data") 29 | public void setData(List data) { 30 | this.data = data; 31 | } 32 | 33 | @JsonAnyGetter 34 | public Map getAdditionalProperties() { 35 | return this.additionalProperties; 36 | } 37 | 38 | @JsonAnySetter 39 | public void setAdditionalProperty(String name, Object value) { 40 | this.additionalProperties.put(name, value); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/trade/BatchCancelOrders.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.trade; 2 | 3 | import com.alibaba.fastjson.JSONArray; 4 | import com.binance.client.RequestOptions; 5 | import com.binance.client.SyncRequestClient; 6 | import com.binance.client.examples.constants.PrivateConfig; 7 | 8 | 9 | /** 10 | * @author : wangwanlu 11 | * @since : 2020/4/7, Tue 12 | **/ 13 | public class BatchCancelOrders { 14 | 15 | public static void main(String[] args) { 16 | RequestOptions options = new RequestOptions(); 17 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 18 | options); 19 | 20 | // batch cancel by order ids 21 | JSONArray orderIds = new JSONArray(); 22 | orderIds.add(180L); 23 | orderIds.add(181L); 24 | 25 | // batch cancel by client order ids 26 | // JSONArray origClientOrderIds = new JSONArray(); 27 | // origClientOrderIds.add("cli_order_001"); 28 | // origClientOrderIds.add("cli_order_002"); 29 | // System.out.println(syncRequestClient.batchCancelOrders("BTCUSDT", null, origClientOrderIds.toJSONString())); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/CandlestickInterval.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | /** 4 | * 1min, 5min, 15min, 30min, 60min, 1day, 1mon, 1week, 1year 5 | */ 6 | public enum CandlestickInterval { 7 | ONE_MINUTE("1m"), 8 | THREE_MINUTES("3m"), 9 | FIVE_MINUTES("5m"), 10 | FIFTEEN_MINUTES("15m"), 11 | HALF_HOURLY("30m"), 12 | HOURLY("1h"), 13 | TWO_HOURLY("2h"), 14 | FOUR_HOURLY("4h"), 15 | SIX_HOURLY("6h"), 16 | EIGHT_HOURLY("8h"), 17 | TWELVE_HOURLY("12h"), 18 | DAILY("1d"), 19 | THREE_DAILY("3d"), 20 | WEEKLY("1w"), 21 | MONTHLY("1M"); 22 | 23 | private String code; 24 | 25 | CandlestickInterval(String code) { 26 | this.code = code; 27 | } 28 | 29 | public static CandlestickInterval of(String code) { 30 | for(CandlestickInterval candlestickInterval: CandlestickInterval.values()) { 31 | if(candlestickInterval.getCode().equalsIgnoreCase(code)) { 32 | return candlestickInterval; 33 | } 34 | } 35 | return null; 36 | } 37 | 38 | public String getCode() { 39 | return this.code; 40 | } 41 | @Override 42 | public String toString() { 43 | return code; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/market/OrderBook.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.market; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | 6 | import java.util.List; 7 | 8 | public class OrderBook { 9 | 10 | private Long lastUpdateId; 11 | 12 | private List bids; 13 | 14 | private List asks; 15 | 16 | public Long getLastUpdateId() { 17 | return lastUpdateId; 18 | } 19 | 20 | public void setLastUpdateId(Long lastUpdateId) { 21 | this.lastUpdateId = lastUpdateId; 22 | } 23 | 24 | public List getBids() { 25 | return bids; 26 | } 27 | 28 | public void setBids(List bids) { 29 | this.bids = bids; 30 | } 31 | 32 | public List getAsks() { 33 | return asks; 34 | } 35 | 36 | public void setAsks(List asks) { 37 | this.asks = asks; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) 43 | .append("lastUpdateId", lastUpdateId).append("bids", bids).append("asks", asks).toString(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/market/FundingRate.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.market; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | 6 | import java.math.BigDecimal; 7 | 8 | public class FundingRate { 9 | 10 | private String symbol; 11 | 12 | private BigDecimal fundingRate; 13 | 14 | private Long fundingTime; 15 | 16 | public String getSymbol() { 17 | return symbol; 18 | } 19 | 20 | public void setSymbol(String symbol) { 21 | this.symbol = symbol; 22 | } 23 | 24 | public BigDecimal getFundingRate() { 25 | return fundingRate; 26 | } 27 | 28 | public void setFundingRate(BigDecimal fundingRate) { 29 | this.fundingRate = fundingRate; 30 | } 31 | 32 | public Long getFundingTime() { 33 | return fundingTime; 34 | } 35 | 36 | public void setFundingTime(Long fundingTime) { 37 | this.fundingTime = fundingTime; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE).append("symbol", symbol) 43 | .append("fundingRate", fundingRate).append("fundingTime", fundingTime).toString(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/trade/Leverage.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.trade; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | 6 | import java.math.BigDecimal; 7 | 8 | public class Leverage { 9 | 10 | private BigDecimal leverage; 11 | 12 | private Double maxNotionalValue; 13 | 14 | private String symbol; 15 | 16 | public BigDecimal getLeverage() { 17 | return leverage; 18 | } 19 | 20 | public void setLeverage(BigDecimal leverage) { 21 | this.leverage = leverage; 22 | } 23 | 24 | public Double getMaxNotionalValue() { 25 | return maxNotionalValue; 26 | } 27 | 28 | public void setMaxNotionalValue(Double maxNotionalValue) { 29 | this.maxNotionalValue = maxNotionalValue; 30 | } 31 | 32 | public String getSymbol() { 33 | return symbol; 34 | } 35 | 36 | public void setSymbol(String symbol) { 37 | this.symbol = symbol; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE).append("leverage", leverage) 43 | .append("maxNotionalValue", maxNotionalValue).append("symbol", symbol).toString(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/trade/AccountBalance.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.trade; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | 6 | import java.math.BigDecimal; 7 | 8 | public class AccountBalance { 9 | 10 | private String asset; 11 | 12 | private BigDecimal balance; 13 | 14 | private BigDecimal withdrawAvailable; 15 | 16 | public String getAsset() { 17 | return asset; 18 | } 19 | 20 | public void setAsset(String asset) { 21 | this.asset = asset; 22 | } 23 | 24 | public BigDecimal getBalance() { 25 | return balance; 26 | } 27 | 28 | public void setBalance(BigDecimal balance) { 29 | this.balance = balance; 30 | } 31 | 32 | public BigDecimal getWithdrawAvailable() { 33 | return withdrawAvailable; 34 | } 35 | 36 | public void setWithdrawAvailable(BigDecimal withdrawAvailable) { 37 | this.withdrawAvailable = withdrawAvailable; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE).append("asset", asset) 43 | .append("balance", balance).append("withdrawAvailable", withdrawAvailable).toString(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/market/ExchangeFilter.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.market; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | 6 | public class ExchangeFilter { 7 | 8 | private String filterType; 9 | 10 | private Long maxNumOrders; 11 | 12 | private Long maxNumAlgoOrders; 13 | 14 | public String getFilterType() { 15 | return filterType; 16 | } 17 | 18 | public void setFilterType(String filterType) { 19 | this.filterType = filterType; 20 | } 21 | 22 | public Long getMaxNumOrders() { 23 | return maxNumOrders; 24 | } 25 | 26 | public void setMaxNumOrders(Long maxNumOrders) { 27 | this.maxNumOrders = maxNumOrders; 28 | } 29 | 30 | public Long getMaxNumAlgoOrders() { 31 | return maxNumAlgoOrders; 32 | } 33 | 34 | public void setMaxNumAlgoOrders(Long maxNumAlgoOrders) { 35 | this.maxNumAlgoOrders = maxNumAlgoOrders; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE).append("filterType", filterType) 41 | .append("maxNumOrders", maxNumOrders).append("maxNumAlgoOrders", maxNumAlgoOrders).toString(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/services/impl/FileServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.services.impl; 2 | 3 | import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import com.fasterxml.jackson.databind.ObjectWriter; 6 | import com.fasterxml.jackson.databind.SerializationFeature; 7 | import com.lickhunter.web.services.FileService; 8 | import lombok.SneakyThrows; 9 | import org.springframework.context.annotation.Primary; 10 | import org.springframework.stereotype.Service; 11 | 12 | import java.io.File; 13 | import java.nio.file.Paths; 14 | 15 | @Primary 16 | @Service("fileServiceImpl") 17 | public class FileServiceImpl implements FileService { 18 | 19 | @SneakyThrows 20 | public FILE readFromFile(String path, String filename, Class classType) { 21 | ObjectMapper mapper = new ObjectMapper(); 22 | return (FILE) mapper.readValue(new File(path.concat(filename)), classType); 23 | } 24 | 25 | @SneakyThrows 26 | public void writeToFile(String path, String filename, T t) { 27 | ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); 28 | ObjectWriter writer = mapper.writer(new DefaultPrettyPrinter()); 29 | writer.writeValue(Paths.get(path.concat(filename)).toFile(), t); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/utils/APIPreconditionsUtil.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.utils; 2 | 3 | import com.lickhunter.web.constants.ErrorCode; 4 | import com.lickhunter.web.exceptions.ServiceException; 5 | 6 | public class APIPreconditionsUtil { 7 | 8 | private APIPreconditionsUtil() {} 9 | 10 | /** 11 | * Check if some value was found, otherwise throw exception 12 | * 13 | * @param expression 14 | * has value true if found, otherwise false 15 | * @throws ServiceException 16 | * if expression is false, value is not found 17 | */ 18 | public static void checkFound(final boolean expression) throws ServiceException { 19 | if (!expression) { 20 | throw new ServiceException(ErrorCode.RESOURCE_NOT_FOUND.getValue()); 21 | } 22 | } 23 | 24 | /** 25 | * Check if some value was found, otherwise throw exception 26 | * 27 | * @param resource 28 | * has value true if found, otherwise false 29 | * @throws ServiceException 30 | * if expression is false, value is not found 31 | */ 32 | public static T checkFound(final T resource) throws ServiceException { 33 | if (resource == null) { 34 | throw new ServiceException(ErrorCode.RESOURCE_NOT_FOUND.getValue()); 35 | } 36 | return resource; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/user/BalanceUpdate.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.user; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | 6 | import java.math.BigDecimal; 7 | 8 | public class BalanceUpdate { 9 | 10 | private String asset; 11 | 12 | private BigDecimal walletBalance; 13 | 14 | private BigDecimal crossWalletBalance; 15 | 16 | public String getAsset() { 17 | return asset; 18 | } 19 | 20 | public void setAsset(String asset) { 21 | this.asset = asset; 22 | } 23 | 24 | public BigDecimal getWalletBalance() { 25 | return walletBalance; 26 | } 27 | 28 | public void setWalletBalance(BigDecimal walletBalance) { 29 | this.walletBalance = walletBalance; 30 | } 31 | 32 | public BigDecimal getCrossWalletBalance() { 33 | return crossWalletBalance; 34 | } 35 | 36 | public void setCrossWalletBalance(BigDecimal crossWalletBalance) { 37 | this.crossWalletBalance = crossWalletBalance; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE).append("asset", asset) 43 | .append("walletBalance", walletBalance).append("crossWalletBalance", crossWalletBalance).toString(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/impl/utils/InternalUtils.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.impl.utils; 2 | 3 | import com.binance.client.exception.BinanceApiException; 4 | import java.io.ByteArrayInputStream; 5 | import java.io.ByteArrayOutputStream; 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.io.OutputStream; 9 | import java.util.zip.GZIPInputStream; 10 | 11 | public abstract class InternalUtils { 12 | 13 | public static byte[] decode(byte[] data) throws IOException { 14 | ByteArrayInputStream bais = new ByteArrayInputStream(data); 15 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 16 | decompress(bais, baos); 17 | baos.flush(); 18 | baos.close(); 19 | bais.close(); 20 | return baos.toByteArray(); 21 | } 22 | 23 | private static void decompress(InputStream is, OutputStream os) throws IOException { 24 | GZIPInputStream gis = new GZIPInputStream(is); 25 | int count; 26 | byte[] data = new byte[1024]; 27 | while ((count = gis.read(data, 0, 1024)) != -1) { 28 | os.write(data, 0, count); 29 | } 30 | gis.close(); 31 | } 32 | 33 | public static void await(long n) throws BinanceApiException { 34 | try { 35 | Thread.sleep(n); 36 | } catch (InterruptedException e) { 37 | throw new BinanceApiException(BinanceApiException.SYS_ERROR, "Error when sleep", e); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/market/TakerLongShortStat.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.market; 2 | 3 | import java.math.BigDecimal; 4 | 5 | public class TakerLongShortStat { 6 | 7 | private BigDecimal buySellRatio; 8 | private BigDecimal sellVol; 9 | private BigDecimal buyVol; 10 | private Long timestamp; 11 | 12 | public BigDecimal getBuySellRatio() { 13 | return buySellRatio; 14 | } 15 | 16 | public void setBuySellRatio(BigDecimal buySellRatio) { 17 | this.buySellRatio = buySellRatio; 18 | } 19 | 20 | public BigDecimal getSellVol() { 21 | return sellVol; 22 | } 23 | 24 | public void setSellVol(BigDecimal sellVol) { 25 | this.sellVol = sellVol; 26 | } 27 | 28 | public BigDecimal getBuyVol() { 29 | return buyVol; 30 | } 31 | 32 | public void setBuyVol(BigDecimal buyVol) { 33 | this.buyVol = buyVol; 34 | } 35 | 36 | public Long getTimestamp() { 37 | return timestamp; 38 | } 39 | 40 | public void setTimestamp(Long timestamp) { 41 | this.timestamp = timestamp; 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return "TakerLongShortStat{" + 47 | "buySellRatio=" + buySellRatio + 48 | ", sellVol=" + sellVol + 49 | ", buyVol=" + buyVol + 50 | ", timestamp=" + timestamp + 51 | '}'; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/enums/AccountChangeType.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.enums; 2 | 3 | import com.binance.client.impl.utils.EnumLookup; 4 | 5 | /** 6 | * The event that Asset Change Notification Related ,for example : create order (order.place) , 7 | * commit order (order.match),order refunds(order.refund),order canceled (order.cancel) ,card 8 | * deducts transaction fee (order.fee-refund),lever account transfer(margin.transfer),loan 9 | * principal(margin.loan),loan interest (margin.interest),return loan interest(margin.repay),other 10 | * asset change(other) 11 | */ 12 | public enum AccountChangeType { 13 | 14 | 15 | NEWORDER("order.place"), 16 | 17 | TRADE("order.match"), 18 | 19 | REFUND("order.refund"), 20 | 21 | CANCELORDER("order.cancel"), 22 | 23 | FEE("order.fee-refund"), 24 | 25 | TRANSFER("margin.transfer"), 26 | 27 | LOAN("margin.loan"), 28 | 29 | INTEREST("margin.interest"), 30 | 31 | REPAY("margin.repay"), 32 | 33 | OTHER("other"), 34 | 35 | INVALID("INVALID"); 36 | 37 | private final String code; 38 | 39 | AccountChangeType(String code) { 40 | this.code = code; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return code; 46 | } 47 | 48 | private static final EnumLookup lookup = new EnumLookup<>( 49 | AccountChangeType.class); 50 | 51 | public static AccountChangeType lookup(String name) { 52 | return lookup.lookup(name); 53 | } 54 | 55 | 56 | } 57 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/market/RateLimit.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.market; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | 6 | public class RateLimit { 7 | 8 | private String rateLimitType; 9 | 10 | private String interval; 11 | 12 | private Long intervalNum; 13 | 14 | private Long limit; 15 | 16 | public String getRateLimitType() { 17 | return rateLimitType; 18 | } 19 | 20 | public void setRateLimitType(String rateLimitType) { 21 | this.rateLimitType = rateLimitType; 22 | } 23 | 24 | public String getInterval() { 25 | return interval; 26 | } 27 | 28 | public void setInterval(String interval) { 29 | this.interval = interval; 30 | } 31 | 32 | public Long getIntervalNum() { 33 | return intervalNum; 34 | } 35 | 36 | public void setIntervalNum(Long intervalNum) { 37 | this.intervalNum = intervalNum; 38 | } 39 | 40 | public Long getLimit() { 41 | return limit; 42 | } 43 | 44 | public void setLimit(Long limit) { 45 | this.limit = limit; 46 | } 47 | 48 | @Override 49 | public String toString() { 50 | return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) 51 | .append("rateLimitType", rateLimitType).append("interval", interval).append("intervalNum", intervalNum) 52 | .append("limit", limit).toString(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /binance-sdk/src/test/java/com/binance/client/examples/trade/BatchPlaceOrders.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.examples.trade; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SyncRequestClient; 5 | import com.binance.client.examples.constants.PrivateConfig; 6 | 7 | /** 8 | * @author : wangwanlu 9 | * @since : 2020/3/26, Thu 10 | **/ 11 | public class BatchPlaceOrders { 12 | public static void main(String[] args) { 13 | RequestOptions options = new RequestOptions(); 14 | SyncRequestClient syncRequestClient = SyncRequestClient.create(PrivateConfig.API_KEY, PrivateConfig.SECRET_KEY, 15 | options); 16 | 17 | // place dual position side orders. 18 | // Switch between dual or both position side, call: com.binance.client.examples.trade.ChangePositionSide 19 | System.out.println(syncRequestClient.postBatchOrders( 20 | "[{\"symbol\": \"BTCUSDT\",\"side\":\"BUY\",\"positionSide\":\"LONG\",\"type\":\"LIMIT\",\"newClientOrderId\":\"wanlu_dev_0324\",\"quantity\":\"1\",\"price\": \"8000\",\"timeInForce\":\"GTC\"},\n" + 21 | "{\"symbol\": \"BTCUSDT\",\"side\":\"BUY\",\"positionSide\":\"SHORT\",\"type\":\"LIMIT\",\"newClientOrderId\":\"wanlu_dev_0325\",\"quantity\":\"1\",\"price\": \"8000\",\"timeInForce\":\"GTC\"},\n" + 22 | "{\"symbol\": \"BTCUSDT\",\"side\":\"BUY\",\"type\":\"LIMIT\",\"newClientOrderId\":\"wanlu_dev_0320\",\"quantity\":\"1\",\"price\": \"8000\",\"timeInForce\":\"GTC\"}]" 23 | 24 | )); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /server/src/main/assembly/bin.xml: -------------------------------------------------------------------------------- 1 | 4 | distribution 5 | 6 | zip 7 | 8 | 9 | 10 | ${project.parent.basedir} 11 | / 12 | 13 | lickhunter.db 14 | 15 | 16 | 17 | ${project.build.directory}/classes/scripts 18 | / 19 | 20 | *.sh 21 | 22 | 23 | 24 | src/main/resources 25 | / 26 | 27 | *.properties 28 | *.json 29 | *.xml 30 | 31 | 32 | 33 | ${project.build.directory} 34 | / 35 | 36 | *.jar 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/market/OpenInterestStat.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.market; 2 | 3 | import java.math.BigDecimal; 4 | 5 | public class OpenInterestStat { 6 | 7 | private String symbol; 8 | private BigDecimal sumOpenInterest; 9 | private BigDecimal sumOpenInterestValue; 10 | private Long timestamp; 11 | 12 | public String getSymbol() { 13 | return symbol; 14 | } 15 | 16 | public void setSymbol(String symbol) { 17 | this.symbol = symbol; 18 | } 19 | 20 | public BigDecimal getSumOpenInterest() { 21 | return sumOpenInterest; 22 | } 23 | 24 | public void setSumOpenInterest(BigDecimal sumOpenInterest) { 25 | this.sumOpenInterest = sumOpenInterest; 26 | } 27 | 28 | public BigDecimal getSumOpenInterestValue() { 29 | return sumOpenInterestValue; 30 | } 31 | 32 | public void setSumOpenInterestValue(BigDecimal sumOpenInterestValue) { 33 | this.sumOpenInterestValue = sumOpenInterestValue; 34 | } 35 | 36 | public Long getTimestamp() { 37 | return timestamp; 38 | } 39 | 40 | public void setTimestamp(Long timestamp) { 41 | this.timestamp = timestamp; 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return "OpenInterestStat{" + 47 | "symbol='" + symbol + '\'' + 48 | ", sumOpenInterest=" + sumOpenInterest + 49 | ", sumOpenInterestValue=" + sumOpenInterestValue + 50 | ", timestamp=" + timestamp + 51 | '}'; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/impl/BinanceApiInternalFactory.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.impl; 2 | 3 | import com.binance.client.RequestOptions; 4 | import com.binance.client.SubscriptionClient; 5 | import com.binance.client.SubscriptionOptions; 6 | import com.binance.client.SyncRequestClient; 7 | import java.net.URI; 8 | 9 | public final class BinanceApiInternalFactory { 10 | 11 | private static final BinanceApiInternalFactory instance = new BinanceApiInternalFactory(); 12 | 13 | public static BinanceApiInternalFactory getInstance() { 14 | return instance; 15 | } 16 | 17 | private BinanceApiInternalFactory() { 18 | } 19 | 20 | public SyncRequestClient createSyncRequestClient(String apiKey, String secretKey, RequestOptions options) { 21 | RequestOptions requestOptions = new RequestOptions(options); 22 | RestApiRequestImpl requestImpl = new RestApiRequestImpl(apiKey, secretKey, requestOptions); 23 | return new SyncRequestImpl(requestImpl); 24 | } 25 | 26 | public SubscriptionClient createSubscriptionClient(SubscriptionOptions options) { 27 | SubscriptionOptions subscriptionOptions = new SubscriptionOptions(options); 28 | RequestOptions requestOptions = new RequestOptions(); 29 | try { 30 | String host = new URI(options.getUri()).getHost(); 31 | requestOptions.setUrl("https://" + host); 32 | } catch (Exception e) { 33 | 34 | } 35 | SubscriptionClient webSocketStreamClient = new WebSocketStreamClientImpl(subscriptionOptions); 36 | return webSocketStreamClient; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/trade/Income.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.trade; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | 6 | import java.math.BigDecimal; 7 | 8 | public class Income { 9 | 10 | private String symbol; 11 | 12 | private String incomeType; 13 | 14 | private BigDecimal income; 15 | 16 | private String asset; 17 | 18 | private Long time; 19 | 20 | public String getSymbol() { 21 | return symbol; 22 | } 23 | 24 | public void setSymbol(String symbol) { 25 | this.symbol = symbol; 26 | } 27 | 28 | public String getIncomeType() { 29 | return incomeType; 30 | } 31 | 32 | public void setIncomeType(String incomeType) { 33 | this.incomeType = incomeType; 34 | } 35 | 36 | public BigDecimal getIncome() { 37 | return income; 38 | } 39 | 40 | public void setIncome(BigDecimal income) { 41 | this.income = income; 42 | } 43 | 44 | public String getAsset() { 45 | return asset; 46 | } 47 | 48 | public void setAsset(String asset) { 49 | this.asset = asset; 50 | } 51 | 52 | public Long getTime() { 53 | return time; 54 | } 55 | 56 | public void setTime(Long time) { 57 | this.time = time; 58 | } 59 | 60 | @Override 61 | public String toString() { 62 | return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE).append("symbol", symbol) 63 | .append("incomeType", incomeType).append("income", income).append("asset", asset).append("time", time) 64 | .toString(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/constant/BinanceApiConstants.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.constant; 2 | 3 | import org.apache.commons.lang3.builder.ToStringStyle; 4 | 5 | /** 6 | * Constants used throughout Binance's API. 7 | */ 8 | public class BinanceApiConstants { 9 | 10 | /** 11 | * REST API base URL. 12 | */ 13 | public static final String API_BASE_URL = "https://fapi.binance.com"; 14 | 15 | /** 16 | * Streaming API base URL. 17 | */ 18 | public static final String WS_API_BASE_URL = "wss://fstream.binance.com/ws"; 19 | 20 | /** 21 | * HTTP Header to be used for API-KEY authentication. 22 | */ 23 | public static final String API_KEY_HEADER = "X-MBX-APIKEY"; 24 | 25 | /** 26 | * Decorator to indicate that an endpoint requires an API key. 27 | */ 28 | public static final String ENDPOINT_SECURITY_TYPE_APIKEY = "APIKEY"; 29 | public static final String ENDPOINT_SECURITY_TYPE_APIKEY_HEADER = ENDPOINT_SECURITY_TYPE_APIKEY + ": #"; 30 | 31 | /** 32 | * Decorator to indicate that an endpoint requires a signature. 33 | */ 34 | public static final String ENDPOINT_SECURITY_TYPE_SIGNED = "SIGNED"; 35 | public static final String ENDPOINT_SECURITY_TYPE_SIGNED_HEADER = ENDPOINT_SECURITY_TYPE_SIGNED + ": #"; 36 | 37 | /** 38 | * Default receiving window. 39 | */ 40 | public static final long DEFAULT_RECEIVING_WINDOW = 60_000L; 41 | 42 | /** 43 | * Default ToStringStyle used by toString methods. Override this to change the 44 | * output format of the overridden toString methods. - Example 45 | * ToStringStyle.JSON_STYLE 46 | */ 47 | public static ToStringStyle TO_STRING_BUILDER_STYLE = ToStringStyle.SHORT_PREFIX_STYLE; 48 | } 49 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/market/SymbolOrderBook.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.market; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | 6 | import java.math.BigDecimal; 7 | 8 | public class SymbolOrderBook { 9 | 10 | private String symbol; 11 | 12 | private BigDecimal bidPrice; 13 | 14 | private BigDecimal bidQty; 15 | 16 | private BigDecimal askPrice; 17 | 18 | private BigDecimal askQty; 19 | 20 | public String getSymbol() { 21 | return symbol; 22 | } 23 | 24 | public void setSymbol(String symbol) { 25 | this.symbol = symbol; 26 | } 27 | 28 | public BigDecimal getBidPrice() { 29 | return bidPrice; 30 | } 31 | 32 | public void setBidPrice(BigDecimal bidPrice) { 33 | this.bidPrice = bidPrice; 34 | } 35 | 36 | public BigDecimal getBidQty() { 37 | return bidQty; 38 | } 39 | 40 | public void setBidQty(BigDecimal bidQty) { 41 | this.bidQty = bidQty; 42 | } 43 | 44 | public BigDecimal getAskPrice() { 45 | return askPrice; 46 | } 47 | 48 | public void setAskPrice(BigDecimal askPrice) { 49 | this.askPrice = askPrice; 50 | } 51 | 52 | public BigDecimal getAskQty() { 53 | return askQty; 54 | } 55 | 56 | public void setAskQty(BigDecimal askQty) { 57 | this.askQty = askQty; 58 | } 59 | 60 | @Override 61 | public String toString() { 62 | return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE).append("symbol", symbol) 63 | .append("bidPrice", bidPrice).append("bidQty", bidQty).append("askPrice", askPrice) 64 | .append("askQty", askQty).toString(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/models/Coins.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.models; 2 | 3 | import com.fasterxml.jackson.annotation.*; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | @JsonInclude(JsonInclude.Include.NON_NULL) 9 | @JsonPropertyOrder({ 10 | "symbol", 11 | "longoffset", 12 | "shortoffset" 13 | }) 14 | public class Coins { 15 | @JsonProperty("symbol") 16 | private String symbol; 17 | @JsonProperty("longoffset") 18 | private String longoffset; 19 | @JsonProperty("shortoffset") 20 | private String shortoffset; 21 | @JsonIgnore 22 | private Map additionalProperties = new HashMap(); 23 | 24 | @JsonProperty("symbol") 25 | public String getSymbol() { 26 | return symbol; 27 | } 28 | 29 | @JsonProperty("symbol") 30 | public void setSymbol(String symbol) { 31 | this.symbol = symbol; 32 | } 33 | 34 | @JsonProperty("longoffset") 35 | public String getLongoffset() { 36 | return longoffset; 37 | } 38 | 39 | @JsonProperty("longoffset") 40 | public void setLongoffset(String longoffset) { 41 | this.longoffset = longoffset; 42 | } 43 | 44 | @JsonProperty("shortoffset") 45 | public String getShortoffset() { 46 | return shortoffset; 47 | } 48 | 49 | @JsonProperty("shortoffset") 50 | public void setShortoffset(String shortoffset) { 51 | this.shortoffset = shortoffset; 52 | } 53 | 54 | @JsonAnyGetter 55 | public Map getAdditionalProperties() { 56 | return this.additionalProperties; 57 | } 58 | 59 | @JsonAnySetter 60 | public void setAdditionalProperty(String name, Object value) { 61 | this.additionalProperties.put(name, value); 62 | } 63 | } -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/models/sentiments/SentimentData.java: -------------------------------------------------------------------------------- 1 | 2 | package com.lickhunter.web.models.sentiments; 3 | 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | import javax.annotation.Generated; 8 | import com.fasterxml.jackson.annotation.JsonAnyGetter; 9 | import com.fasterxml.jackson.annotation.JsonAnySetter; 10 | import com.fasterxml.jackson.annotation.JsonIgnore; 11 | import com.fasterxml.jackson.annotation.JsonInclude; 12 | import com.fasterxml.jackson.annotation.JsonProperty; 13 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 14 | 15 | @JsonInclude(JsonInclude.Include.NON_NULL) 16 | @JsonPropertyOrder({ 17 | "config", 18 | "data" 19 | }) 20 | @Generated("jsonschema2pojo") 21 | public class SentimentData { 22 | 23 | @JsonProperty("config") 24 | private Config config; 25 | @JsonProperty("data") 26 | private List data = null; 27 | @JsonIgnore 28 | private Map additionalProperties = new HashMap(); 29 | 30 | @JsonProperty("config") 31 | public Config getConfig() { 32 | return config; 33 | } 34 | 35 | @JsonProperty("config") 36 | public void setConfig(Config config) { 37 | this.config = config; 38 | } 39 | 40 | @JsonProperty("data") 41 | public List getData() { 42 | return data; 43 | } 44 | 45 | @JsonProperty("data") 46 | public void setData(List data) { 47 | this.data = data; 48 | } 49 | 50 | @JsonAnyGetter 51 | public Map getAdditionalProperties() { 52 | return this.additionalProperties; 53 | } 54 | 55 | @JsonAnySetter 56 | public void setAdditionalProperty(String name, Object value) { 57 | this.additionalProperties.put(name, value); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/services/impl/DiscordServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.services.impl; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.lickhunter.web.configs.Settings; 5 | import com.lickhunter.web.constants.ApplicationConstants; 6 | import com.lickhunter.web.models.webhook.DiscordWebhook; 7 | import com.lickhunter.web.services.FileService; 8 | import com.lickhunter.web.services.NotificationService; 9 | import lombok.RequiredArgsConstructor; 10 | import lombok.SneakyThrows; 11 | import lombok.extern.slf4j.Slf4j; 12 | import org.springframework.http.HttpEntity; 13 | import org.springframework.http.HttpHeaders; 14 | import org.springframework.http.HttpMethod; 15 | import org.springframework.http.MediaType; 16 | import org.springframework.stereotype.Service; 17 | import org.springframework.web.client.RestTemplate; 18 | 19 | import java.util.Objects; 20 | 21 | @Service("discordNotification") 22 | @Slf4j 23 | @RequiredArgsConstructor 24 | public class DiscordServiceImpl implements NotificationService { 25 | 26 | private final FileService fileService; 27 | 28 | @SneakyThrows 29 | public void send(DiscordWebhook webhook) { 30 | Settings settings = (Settings) fileService.readFromFile("./", ApplicationConstants.SETTINGS.getValue(), Settings.class); 31 | RestTemplate restTemplate = new RestTemplate(); 32 | HttpHeaders headers = new HttpHeaders(); 33 | headers.setContentType(MediaType.APPLICATION_JSON); 34 | headers.add("user-agent", "PostmanRuntime/7.26.8"); 35 | HttpEntity entity = new HttpEntity<>(JSON.toJSONString(webhook), headers); 36 | if(Objects.nonNull(settings.getDiscordwebhook())) { 37 | restTemplate.exchange(webhook.getWebhook(), HttpMethod.POST, entity, String.class); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/market/CommonLongShortRatio.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.market; 2 | 3 | import java.math.BigDecimal; 4 | 5 | public class CommonLongShortRatio { 6 | 7 | private String symbol; 8 | private BigDecimal longAccount; 9 | private BigDecimal longShortRatio; 10 | private BigDecimal shortAccount; 11 | private Long timestamp; 12 | 13 | public String getSymbol() { 14 | return symbol; 15 | } 16 | 17 | public void setSymbol(String symbol) { 18 | this.symbol = symbol; 19 | } 20 | 21 | public BigDecimal getLongAccount() { 22 | return longAccount; 23 | } 24 | 25 | public void setLongAccount(BigDecimal longAccount) { 26 | this.longAccount = longAccount; 27 | } 28 | 29 | public BigDecimal getLongShortRatio() { 30 | return longShortRatio; 31 | } 32 | 33 | public void setLongShortRatio(BigDecimal longShortRatio) { 34 | this.longShortRatio = longShortRatio; 35 | } 36 | 37 | public BigDecimal getShortAccount() { 38 | return shortAccount; 39 | } 40 | 41 | public void setShortAccount(BigDecimal shortAccount) { 42 | this.shortAccount = shortAccount; 43 | } 44 | 45 | public Long getTimestamp() { 46 | return timestamp; 47 | } 48 | 49 | public void setTimestamp(Long timestamp) { 50 | this.timestamp = timestamp; 51 | } 52 | 53 | @Override 54 | public String toString() { 55 | return "CommonLongShortRatio{" + 56 | "symbol='" + symbol + '\'' + 57 | ", longAccount=" + longAccount + 58 | ", longShortRatio=" + longShortRatio + 59 | ", shortAccount=" + shortAccount + 60 | ", timestamp=" + timestamp + 61 | '}'; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/market/MarkPrice.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.market; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | 6 | import java.math.BigDecimal; 7 | 8 | public class MarkPrice { 9 | 10 | private String symbol; 11 | 12 | private BigDecimal markPrice; 13 | 14 | private BigDecimal lastFundingRate; 15 | 16 | private Long nextFundingTime; 17 | 18 | private Long time; 19 | 20 | public String getSymbol() { 21 | return symbol; 22 | } 23 | 24 | public void setSymbol(String symbol) { 25 | this.symbol = symbol; 26 | } 27 | 28 | public BigDecimal getMarkPrice() { 29 | return markPrice; 30 | } 31 | 32 | public void setMarkPrice(BigDecimal markPrice) { 33 | this.markPrice = markPrice; 34 | } 35 | 36 | public BigDecimal getLastFundingRate() { 37 | return lastFundingRate; 38 | } 39 | 40 | public void setLastFundingRate(BigDecimal lastFundingRate) { 41 | this.lastFundingRate = lastFundingRate; 42 | } 43 | 44 | public Long getNextFundingTime() { 45 | return nextFundingTime; 46 | } 47 | 48 | public void setNextFundingTime(Long nextFundingTime) { 49 | this.nextFundingTime = nextFundingTime; 50 | } 51 | 52 | public Long getTime() { 53 | return time; 54 | } 55 | 56 | public void setTime(Long time) { 57 | this.time = time; 58 | } 59 | 60 | @Override 61 | public String toString() { 62 | return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE).append("symbol", symbol) 63 | .append("markPrice", markPrice).append("lastFundingRate", lastFundingRate) 64 | .append("nextFundingTime", nextFundingTime).append("time", time).toString(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/configs/DataSourceConfig.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.configs; 2 | 3 | import com.zaxxer.hikari.HikariConfig; 4 | import com.zaxxer.hikari.HikariDataSource; 5 | import org.springframework.beans.factory.annotation.Value; 6 | import org.springframework.boot.context.properties.ConfigurationProperties; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.sqlite.SQLiteConfig; 10 | import org.sqlite.SQLiteOpenMode; 11 | 12 | import javax.sql.DataSource; 13 | 14 | @Configuration 15 | public class DataSourceConfig { 16 | @Value("${spring.datasource.driver-class-name}") 17 | private String driverName; 18 | @Value("${spring.datasource.url}") 19 | private String url; 20 | 21 | /** 22 | * 23 | * @return DataSource 24 | */ 25 | @Bean("masterDataSource") 26 | @ConfigurationProperties("spring.datasource.master") 27 | public DataSource masterDataSource() { 28 | HikariConfig hikariConfig = new HikariConfig(); 29 | hikariConfig.setDriverClassName(driverName); 30 | hikariConfig.setJdbcUrl(url); 31 | hikariConfig.setMaximumPoolSize(1); 32 | hikariConfig.setConnectionTestQuery("SELECT 1"); 33 | SQLiteConfig config= new SQLiteConfig(); 34 | config.setOpenMode(SQLiteOpenMode.OPEN_URI); 35 | config.setOpenMode(SQLiteOpenMode.FULLMUTEX); 36 | config.setBusyTimeout("10000"); 37 | hikariConfig.setPoolName("springHikariCP"); 38 | hikariConfig.addDataSourceProperty(SQLiteConfig.Pragma.OPEN_MODE.pragmaName, config.getOpenModeFlags()); 39 | hikariConfig.addDataSourceProperty(SQLiteConfig.Pragma.JOURNAL_MODE.pragmaName, SQLiteConfig.JournalMode.WAL ); 40 | HikariDataSource dataSource = new HikariDataSource(hikariConfig); 41 | return dataSource; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/user/UserDataUpdateEvent.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.user; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | 6 | public class UserDataUpdateEvent { 7 | 8 | private String eventType; 9 | 10 | private Long eventTime; 11 | 12 | private Long transactionTime; 13 | 14 | private AccountUpdate accountUpdate; 15 | 16 | private OrderUpdate orderUpdate; 17 | 18 | public String getEventType() { 19 | return eventType; 20 | } 21 | 22 | public void setEventType(String eventType) { 23 | this.eventType = eventType; 24 | } 25 | 26 | public Long getEventTime() { 27 | return eventTime; 28 | } 29 | 30 | public void setEventTime(Long eventTime) { 31 | this.eventTime = eventTime; 32 | } 33 | 34 | public Long getTransactionTime() { 35 | return transactionTime; 36 | } 37 | 38 | public void setTransactionTime(Long transactionTime) { 39 | this.transactionTime = transactionTime; 40 | } 41 | 42 | public AccountUpdate getAccountUpdate() { 43 | return accountUpdate; 44 | } 45 | 46 | public void setAccountUpdate(AccountUpdate accountUpdate) { 47 | this.accountUpdate = accountUpdate; 48 | } 49 | 50 | public OrderUpdate getOrderUpdate() { 51 | return orderUpdate; 52 | } 53 | 54 | public void setOrderUpdate(OrderUpdate orderUpdate) { 55 | this.orderUpdate = orderUpdate; 56 | } 57 | 58 | @Override 59 | public String toString() { 60 | return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE).append("eventType", eventType) 61 | .append("eventTime", eventTime).append("accountUpdate", accountUpdate) 62 | .append("orderUpdate", orderUpdate).toString(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /server/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable 11 | 12 | 13 | 14 | 15 | 17 | ${LOGS}/spring-boot-logger.log 18 | 20 | %d %p %C{1.} [%t] %m%n 21 | 22 | 23 | 25 | 26 | ${LOGS}/archived/spring-boot-logger-%d{yyyy-MM-dd}.%i.log 27 | 28 | 30 | 10MB 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/services/impl/LickHunterServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.services.impl; 2 | 3 | import com.lickhunter.web.configs.MessageConfig; 4 | import com.lickhunter.web.configs.Settings; 5 | import com.lickhunter.web.configs.UserDefinedSettings; 6 | import com.lickhunter.web.configs.WebSettings; 7 | import com.lickhunter.web.constants.ApplicationConstants; 8 | import com.lickhunter.web.services.FileService; 9 | import com.lickhunter.web.services.LickHunterService; 10 | import com.lickhunter.web.to.TickerQueryTO; 11 | import lombok.RequiredArgsConstructor; 12 | import lombok.extern.slf4j.Slf4j; 13 | import org.springframework.stereotype.Service; 14 | 15 | @Service 16 | @RequiredArgsConstructor 17 | @Slf4j 18 | public class LickHunterServiceImpl implements LickHunterService { 19 | 20 | private final MessageConfig messageConfig; 21 | private final FileService fileService; 22 | 23 | public TickerQueryTO getQuery() { 24 | TickerQueryTO tickerQueryTO = (TickerQueryTO) fileService.readFromFile("./", ApplicationConstants.TICKER_QUERY.getValue(), TickerQueryTO.class); 25 | return tickerQueryTO; 26 | } 27 | 28 | @Override 29 | public WebSettings getWebSettings() { 30 | WebSettings webSettings = (WebSettings) fileService.readFromFile("./", ApplicationConstants.WEB_SETTINGS.getValue(), WebSettings.class); 31 | return webSettings; 32 | } 33 | 34 | public UserDefinedSettings getActiveSettings() { 35 | WebSettings webSettings = (WebSettings) fileService.readFromFile("./", ApplicationConstants.WEB_SETTINGS.getValue(), WebSettings.class); 36 | return webSettings.getUserDefinedSettings().get(webSettings.getActive()); 37 | } 38 | 39 | public Settings getLickHunterSettings() { 40 | Settings settings = (Settings) fileService.readFromFile("./", ApplicationConstants.SETTINGS.getValue(), Settings.class); 41 | return settings; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/market/Trade.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.market; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | 6 | import java.math.BigDecimal; 7 | 8 | public class Trade { 9 | 10 | private Long id; 11 | 12 | private BigDecimal price; 13 | 14 | private BigDecimal qty; 15 | 16 | private BigDecimal quoteQty; 17 | 18 | private Long time; 19 | 20 | private Boolean isBuyerMaker; 21 | 22 | public Long getId() { 23 | return id; 24 | } 25 | 26 | public void setId(Long id) { 27 | this.id = id; 28 | } 29 | 30 | public BigDecimal getPrice() { 31 | return price; 32 | } 33 | 34 | public void setPrice(BigDecimal price) { 35 | this.price = price; 36 | } 37 | 38 | public BigDecimal getQty() { 39 | return qty; 40 | } 41 | 42 | public void setQty(BigDecimal qty) { 43 | this.qty = qty; 44 | } 45 | 46 | public BigDecimal getQuoteQty() { 47 | return quoteQty; 48 | } 49 | 50 | public void setQuoteQty(BigDecimal quoteQty) { 51 | this.quoteQty = quoteQty; 52 | } 53 | 54 | public Long getTime() { 55 | return time; 56 | } 57 | 58 | public void setTime(Long time) { 59 | this.time = time; 60 | } 61 | 62 | public Boolean getIsBuyerMaker() { 63 | return isBuyerMaker; 64 | } 65 | 66 | public void setIsBuyerMaker(Boolean isBuyerMaker) { 67 | this.isBuyerMaker = isBuyerMaker; 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE).append("id", id) 73 | .append("price", price).append("qty", qty).append("quoteQty", quoteQty).append("time", time) 74 | .append("isBuyerMaker", isBuyerMaker).toString(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/services/impl/LongOffsetVWAPIndicator.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.services.impl; 2 | 3 | import org.ta4j.core.BarSeries; 4 | import org.ta4j.core.Indicator; 5 | import org.ta4j.core.indicators.helpers.TypicalPriceIndicator; 6 | import org.ta4j.core.indicators.helpers.VolumeIndicator; 7 | import org.ta4j.core.indicators.volume.VWAPIndicator; 8 | import org.ta4j.core.num.Num; 9 | 10 | public class LongOffsetVWAPIndicator extends VWAPIndicator { 11 | 12 | private final int barCount; 13 | private final Indicator typicalPrice; 14 | private final Indicator volume; 15 | private final Num zero; 16 | private final Num offset; 17 | 18 | /** 19 | * Constructor. 20 | * @param series the series 21 | * @param barCount the time frame 22 | */ 23 | public LongOffsetVWAPIndicator(BarSeries series, int barCount, double offset) { 24 | super(series, barCount); 25 | this.barCount = barCount; 26 | this.typicalPrice = new TypicalPriceIndicator(series); 27 | this.volume = new VolumeIndicator(series); 28 | this.zero = numOf(0); 29 | this.offset = numOf(offset); 30 | } 31 | 32 | @Override 33 | protected Num calculate(int index) { 34 | if (index <= 0) { 35 | return this.typicalPrice.getValue(index); 36 | } 37 | int startIndex = Math.max(0, index - barCount + 1); 38 | Num cumulativeTPV = zero; 39 | Num cumulativeVolume = zero; 40 | for (int i = startIndex; i <= index; i++) { 41 | Num currentVolume = volume.getValue(i); 42 | cumulativeTPV = cumulativeTPV.plus(typicalPrice.getValue(i).multipliedBy(currentVolume)); 43 | cumulativeVolume = cumulativeVolume.plus(currentVolume); 44 | } 45 | Num vwap = cumulativeTPV.dividedBy(cumulativeVolume); 46 | return vwap.minus(vwap.multipliedBy(offset).dividedBy(numOf(100))); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/services/impl/ShortOffsetVWAPIndicator.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.services.impl; 2 | 3 | import org.ta4j.core.BarSeries; 4 | import org.ta4j.core.Indicator; 5 | import org.ta4j.core.indicators.helpers.TypicalPriceIndicator; 6 | import org.ta4j.core.indicators.helpers.VolumeIndicator; 7 | import org.ta4j.core.indicators.volume.VWAPIndicator; 8 | import org.ta4j.core.num.Num; 9 | 10 | public class ShortOffsetVWAPIndicator extends VWAPIndicator { 11 | 12 | private final int barCount; 13 | private final Indicator typicalPrice; 14 | private final Indicator volume; 15 | private final Num zero; 16 | private final Num offset; 17 | 18 | /** 19 | * Constructor. 20 | * @param series the series 21 | * @param barCount the time frame 22 | */ 23 | public ShortOffsetVWAPIndicator(BarSeries series, int barCount, double offset) { 24 | super(series, barCount); 25 | this.barCount = barCount; 26 | this.typicalPrice = new TypicalPriceIndicator(series); 27 | this.volume = new VolumeIndicator(series); 28 | this.zero = numOf(0); 29 | this.offset = numOf(offset); 30 | } 31 | 32 | @Override 33 | protected Num calculate(int index) { 34 | if (index <= 0) { 35 | return this.typicalPrice.getValue(index); 36 | } 37 | int startIndex = Math.max(0, index - barCount + 1); 38 | Num cumulativeTPV = zero; 39 | Num cumulativeVolume = zero; 40 | for (int i = startIndex; i <= index; i++) { 41 | Num currentVolume = volume.getValue(i); 42 | cumulativeTPV = cumulativeTPV.plus(typicalPrice.getValue(i).multipliedBy(currentVolume)); 43 | cumulativeVolume = cumulativeVolume.plus(currentVolume); 44 | } 45 | Num vwap = cumulativeTPV.dividedBy(cumulativeVolume); 46 | return vwap.plus(vwap.multipliedBy(offset.dividedBy(numOf(100)))); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/repositories/TelegramRepository.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.repositories; 2 | 3 | import com.lickhunter.web.entities.tables.records.TelegramUsersRecord; 4 | import lombok.RequiredArgsConstructor; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.jooq.DSLContext; 7 | import org.springframework.stereotype.Component; 8 | import org.springframework.transaction.annotation.Transactional; 9 | 10 | import java.util.Optional; 11 | 12 | import static com.lickhunter.web.entities.tables.TelegramUsers.TELEGRAM_USERS; 13 | 14 | @RequiredArgsConstructor 15 | @Transactional(transactionManager = "transactionManager") 16 | @Component 17 | @Slf4j 18 | public class TelegramRepository { 19 | 20 | private final DSLContext dsl; 21 | 22 | public void insertOrUpdate(String username, Long chatId) { 23 | Optional record = dsl.selectFrom(TELEGRAM_USERS) 24 | .where(TELEGRAM_USERS.USERNAME.in(username)) 25 | .fetchOptional(); 26 | if(record.isPresent()) { 27 | this.update(username, chatId); 28 | } else { 29 | this.insert(username, chatId); 30 | } 31 | } 32 | 33 | public void update(String username, Long chatId) { 34 | dsl.update(TELEGRAM_USERS) 35 | .set(TELEGRAM_USERS.CHAT_ID, chatId) 36 | .where(TELEGRAM_USERS.USERNAME.in(username)) 37 | .execute(); 38 | } 39 | 40 | public void insert(String username, Long chatId) { 41 | dsl.insertInto(TELEGRAM_USERS) 42 | .set(TELEGRAM_USERS.USERNAME, username) 43 | .set(TELEGRAM_USERS.CHAT_ID, chatId) 44 | .execute(); 45 | } 46 | 47 | public Optional findByUsername(String username) { 48 | return dsl.selectFrom(TELEGRAM_USERS) 49 | .where(TELEGRAM_USERS.USERNAME.eq(username)) 50 | .fetchOptional(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/trade/WalletDeltaLog.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.trade; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | 6 | /** 7 | * @author : wangwanlu 8 | * @since : 2020/4/24, Fri 9 | **/ 10 | public class WalletDeltaLog { 11 | 12 | private String symbol; 13 | private int type; 14 | private String amount; 15 | private String asset; 16 | private Long time; 17 | private String positionSide; 18 | 19 | public String getSymbol() { 20 | return symbol; 21 | } 22 | 23 | public void setSymbol(String symbol) { 24 | this.symbol = symbol; 25 | } 26 | 27 | public int getType() { 28 | return type; 29 | } 30 | 31 | public void setType(int type) { 32 | this.type = type; 33 | } 34 | 35 | public String getAmount() { 36 | return amount; 37 | } 38 | 39 | public void setAmount(String amount) { 40 | this.amount = amount; 41 | } 42 | 43 | public String getAsset() { 44 | return asset; 45 | } 46 | 47 | public void setAsset(String asset) { 48 | this.asset = asset; 49 | } 50 | 51 | public Long getTime() { 52 | return time; 53 | } 54 | 55 | public void setTime(Long time) { 56 | this.time = time; 57 | } 58 | 59 | public String getPositionSide() { 60 | return positionSide; 61 | } 62 | 63 | public void setPositionSide(String positionSide) { 64 | this.positionSide = positionSide; 65 | } 66 | 67 | @Override 68 | public String toString() { 69 | return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) 70 | .append("symbol", symbol).append("type", type).append("amount", amount) 71 | .append("asset", asset).append("time", time) 72 | .append("positionSide", positionSide).toString(); 73 | } 74 | } -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/market/ExchangeInformation.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.market; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | 6 | import java.util.List; 7 | 8 | public class ExchangeInformation { 9 | 10 | private String timezone; 11 | 12 | private Long serverTime; 13 | 14 | private List rateLimits; 15 | 16 | private List exchangeFilters; 17 | 18 | private List symbols; 19 | 20 | public String getTimezone() { 21 | return timezone; 22 | } 23 | 24 | public void setTimezone(String timezone) { 25 | this.timezone = timezone; 26 | } 27 | 28 | public Long getServerTime() { 29 | return serverTime; 30 | } 31 | 32 | public void setServerTime(Long serverTime) { 33 | this.serverTime = serverTime; 34 | } 35 | 36 | public List getRateLimits() { 37 | return rateLimits; 38 | } 39 | 40 | public void setRateLimits(List rateLimits) { 41 | this.rateLimits = rateLimits; 42 | } 43 | 44 | public List getExchangeFilters() { 45 | return exchangeFilters; 46 | } 47 | 48 | public void setExchangeFilters(List exchangeFilters) { 49 | this.exchangeFilters = exchangeFilters; 50 | } 51 | 52 | public List getSymbols() { 53 | return symbols; 54 | } 55 | 56 | public void setSymbols(List symbols) { 57 | this.symbols = symbols; 58 | } 59 | 60 | @Override 61 | public String toString() { 62 | return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE).append("timezone", timezone) 63 | .append("serverTime", serverTime).append("rateLimits", rateLimits) 64 | .append("exchangeFilters", exchangeFilters).append("symbols", symbols).toString(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/configs/ApplicationConfig.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.configs; 2 | 3 | import lombok.Getter; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.context.annotation.PropertySource; 7 | import org.springframework.context.annotation.PropertySources; 8 | import org.springframework.retry.annotation.EnableRetry; 9 | 10 | @Configuration 11 | @PropertySources({ 12 | @PropertySource(value = "classpath:application.properties", ignoreResourceNotFound = true), 13 | @PropertySource(value = "file:application.properties", ignoreResourceNotFound = true) 14 | }) 15 | @Getter 16 | @EnableRetry 17 | public class ApplicationConfig { 18 | @Value("${server.port}") 19 | private String serverPort; 20 | 21 | @Value("${api.liquidation}") 22 | private String liquidation; 23 | 24 | @Value("${sentiments.api}") 25 | private String sentimentsApi; 26 | 27 | @Value("${sentiments.social-volume-percentage}") 28 | private Double socialVolumePercentage; 29 | 30 | @Value("${sentiments.twitter-volume-percentage}") 31 | private Double twitterVolumePercentage; 32 | 33 | @Value("${sentiments.pause-bot-enable:false}") 34 | private Boolean pauseBotEnable; 35 | 36 | @Value("${sentiments.change-settings-enable:false}") 37 | private Boolean changeSettingsEnable; 38 | 39 | @Value("${sentiments.change-settings-volatility}") 40 | private Double changeSettingsVolatility; 41 | 42 | @Value("${sentiments.pause-bot}") 43 | private Integer pauseBotHours; 44 | 45 | @Value("${sentiments.enable:false}") 46 | private Boolean sentimentsEnable; 47 | 48 | @Value("${sentiments.discord-alerts}") 49 | private String sentimentsDiscordAlertsWebhook; 50 | 51 | @Value("${sentiments.discord-enable:false}") 52 | private Boolean sentimentsDiscordEnable; 53 | 54 | @Value("${sentiments.change-settings-enable}") 55 | private Boolean sentimentsChangeSettingsEnable; 56 | } 57 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/event/MarkPriceEvent.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.event; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | 6 | import java.math.BigDecimal; 7 | 8 | public class MarkPriceEvent { 9 | 10 | private String eventType; 11 | 12 | private Long eventTime; 13 | 14 | private String symbol; 15 | 16 | private BigDecimal markPrice; 17 | 18 | private BigDecimal fundingRate; 19 | 20 | private Long nextFundingTime; 21 | 22 | public String getEventType() { 23 | return eventType; 24 | } 25 | 26 | public void setEventType(String eventType) { 27 | this.eventType = eventType; 28 | } 29 | 30 | public Long getEventTime() { 31 | return eventTime; 32 | } 33 | 34 | public void setEventTime(Long eventTime) { 35 | this.eventTime = eventTime; 36 | } 37 | 38 | public String getSymbol() { 39 | return symbol; 40 | } 41 | 42 | public void setSymbol(String symbol) { 43 | this.symbol = symbol; 44 | } 45 | 46 | public BigDecimal getMarkPrice() { 47 | return markPrice; 48 | } 49 | 50 | public void setMarkPrice(BigDecimal markPrice) { 51 | this.markPrice = markPrice; 52 | } 53 | 54 | public BigDecimal getFundingRate() { 55 | return fundingRate; 56 | } 57 | 58 | public void setFundingRate(BigDecimal fundingRate) { 59 | this.fundingRate = fundingRate; 60 | } 61 | 62 | public Long getNextFundingTime() { 63 | return nextFundingTime; 64 | } 65 | 66 | public void setNextFundingTime(Long nextFundingTime) { 67 | this.nextFundingTime = nextFundingTime; 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE).append("eventType", eventType) 73 | .append("eventTime", eventTime).append("symbol", symbol).append("markPrice", markPrice) 74 | .append("fundingRate", fundingRate).append("nextFundingTime", nextFundingTime).toString(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/market/AggregateTrade.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.market; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | 6 | import java.math.BigDecimal; 7 | 8 | public class AggregateTrade { 9 | 10 | private Long id; 11 | 12 | private BigDecimal price; 13 | 14 | private BigDecimal qty; 15 | 16 | private Long firstId; 17 | 18 | private Long lastId; 19 | 20 | private Long time; 21 | 22 | private Boolean isBuyerMaker; 23 | 24 | public Long getId() { 25 | return id; 26 | } 27 | 28 | public void setId(Long id) { 29 | this.id = id; 30 | } 31 | 32 | public BigDecimal getPrice() { 33 | return price; 34 | } 35 | 36 | public void setPrice(BigDecimal price) { 37 | this.price = price; 38 | } 39 | 40 | public BigDecimal getQty() { 41 | return qty; 42 | } 43 | 44 | public void setQty(BigDecimal qty) { 45 | this.qty = qty; 46 | } 47 | 48 | public Long getFirstId() { 49 | return firstId; 50 | } 51 | 52 | public void setFirstId(Long firstId) { 53 | this.firstId = firstId; 54 | } 55 | 56 | public Long getLastId() { 57 | return lastId; 58 | } 59 | 60 | public void setLastId(Long lastId) { 61 | this.lastId = lastId; 62 | } 63 | 64 | public Long getTime() { 65 | return time; 66 | } 67 | 68 | public void setTime(Long time) { 69 | this.time = time; 70 | } 71 | 72 | public Boolean getIsBuyerMaker() { 73 | return isBuyerMaker; 74 | } 75 | 76 | public void setIsBuyerMaker(Boolean isBuyerMaker) { 77 | this.isBuyerMaker = isBuyerMaker; 78 | } 79 | 80 | @Override 81 | public String toString() { 82 | return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE).append("id", id) 83 | .append("price", price).append("qty", qty).append("firstId", firstId).append("lastId", lastId) 84 | .append("time", time).append("isBuyerMaker", isBuyerMaker).toString(); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/impl/ApiSignature.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.impl; 2 | 3 | import com.binance.client.exception.BinanceApiException; 4 | import com.binance.client.constant.BinanceApiConstants; 5 | import com.binance.client.impl.utils.UrlParamsBuilder; 6 | import java.security.InvalidKeyException; 7 | import java.security.NoSuchAlgorithmException; 8 | import javax.crypto.Mac; 9 | import javax.crypto.spec.SecretKeySpec; 10 | import org.apache.commons.codec.binary.Hex; 11 | 12 | class ApiSignature { 13 | 14 | static final String op = "op"; 15 | static final String opValue = "auth"; 16 | private static final String signatureMethodValue = "HmacSHA256"; 17 | public static final String signatureVersionValue = "2"; 18 | 19 | void createSignature(String accessKey, String secretKey, UrlParamsBuilder builder) { 20 | 21 | if (accessKey == null || "".equals(accessKey) || secretKey == null || "".equals(secretKey)) { 22 | throw new BinanceApiException(BinanceApiException.KEY_MISSING, "API key and secret key are required"); 23 | } 24 | 25 | builder.putToUrl("recvWindow", Long.toString(BinanceApiConstants.DEFAULT_RECEIVING_WINDOW)) 26 | .putToUrl("timestamp", Long.toString(System.currentTimeMillis())); 27 | 28 | Mac hmacSha256; 29 | try { 30 | hmacSha256 = Mac.getInstance(signatureMethodValue); 31 | SecretKeySpec secKey = new SecretKeySpec(secretKey.getBytes(), signatureMethodValue); 32 | hmacSha256.init(secKey); 33 | } catch (NoSuchAlgorithmException e) { 34 | throw new BinanceApiException(BinanceApiException.RUNTIME_ERROR, 35 | "[Signature] No such algorithm: " + e.getMessage()); 36 | } catch (InvalidKeyException e) { 37 | throw new BinanceApiException(BinanceApiException.RUNTIME_ERROR, 38 | "[Signature] Invalid key: " + e.getMessage()); 39 | } 40 | String payload = builder.buildSignature(); 41 | String actualSign = new String(Hex.encodeHex(hmacSha256.doFinal(payload.getBytes()))); 42 | 43 | builder.putToUrl("signature", actualSign); 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/models/market/RateLimit.java: -------------------------------------------------------------------------------- 1 | 2 | package com.lickhunter.web.models.market; 3 | 4 | import com.fasterxml.jackson.annotation.*; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | @JsonInclude(JsonInclude.Include.NON_NULL) 10 | @JsonPropertyOrder({ 11 | "rateLimitType", 12 | "interval", 13 | "intervalNum", 14 | "limit" 15 | }) 16 | public class RateLimit { 17 | 18 | @JsonProperty("rateLimitType") 19 | private String rateLimitType; 20 | @JsonProperty("interval") 21 | private String interval; 22 | @JsonProperty("intervalNum") 23 | private Integer intervalNum; 24 | @JsonProperty("limit") 25 | private Integer limit; 26 | @JsonIgnore 27 | private Map additionalProperties = new HashMap(); 28 | 29 | @JsonProperty("rateLimitType") 30 | public String getRateLimitType() { 31 | return rateLimitType; 32 | } 33 | 34 | @JsonProperty("rateLimitType") 35 | public void setRateLimitType(String rateLimitType) { 36 | this.rateLimitType = rateLimitType; 37 | } 38 | 39 | @JsonProperty("interval") 40 | public String getInterval() { 41 | return interval; 42 | } 43 | 44 | @JsonProperty("interval") 45 | public void setInterval(String interval) { 46 | this.interval = interval; 47 | } 48 | 49 | @JsonProperty("intervalNum") 50 | public Integer getIntervalNum() { 51 | return intervalNum; 52 | } 53 | 54 | @JsonProperty("intervalNum") 55 | public void setIntervalNum(Integer intervalNum) { 56 | this.intervalNum = intervalNum; 57 | } 58 | 59 | @JsonProperty("limit") 60 | public Integer getLimit() { 61 | return limit; 62 | } 63 | 64 | @JsonProperty("limit") 65 | public void setLimit(Integer limit) { 66 | this.limit = limit; 67 | } 68 | 69 | @JsonAnyGetter 70 | public Map getAdditionalProperties() { 71 | return this.additionalProperties; 72 | } 73 | 74 | @JsonAnySetter 75 | public void setAdditionalProperty(String name, Object value) { 76 | this.additionalProperties.put(name, value); 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/configs/UserDefinedSettings.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.configs; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import lombok.With; 8 | 9 | import java.math.BigDecimal; 10 | 11 | @With 12 | @Data 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | public class UserDefinedSettings { 16 | @JsonProperty("maxOpen") 17 | private Integer maxOpen; 18 | @JsonProperty("maxPos") 19 | private BigDecimal maxPos; 20 | @JsonProperty("openOrderIsolationPercentage") 21 | private Double openOrderIsolationPercentage; 22 | @JsonProperty("longOffset") 23 | private Double longOffset; 24 | @JsonProperty("shortOffset") 25 | private Double shortOffset; 26 | @JsonProperty("lickValue") 27 | private Integer lickValue; 28 | @JsonProperty("marginPercentNotification") 29 | private Integer marginPercentNotification; 30 | @JsonProperty("marginType") 31 | private String marginType; 32 | @JsonProperty("leverage") 33 | private Integer leverage; 34 | @JsonProperty("autoLickValue") 35 | private String autoLickValue; 36 | @JsonProperty("autoOffset") 37 | private Boolean autoOffset; 38 | @JsonProperty("offsetOne") 39 | private Double offsetOne; 40 | @JsonProperty("offsetVolatilityOne") 41 | private Double offsetVolatilityOne; 42 | @JsonProperty("offsetTwo") 43 | private Double offsetTwo; 44 | @JsonProperty("offsetVolatilityTwo") 45 | private Double offsetVolatilityTwo; 46 | @JsonProperty("offsetThree") 47 | private Double offsetThree; 48 | @JsonProperty("offsetVolatilityThree") 49 | private Double offsetVolatilityThree; 50 | @JsonProperty("dcaStart") 51 | private BigDecimal dcaStart; 52 | @JsonProperty("rangeOne") 53 | private DcaRange rangeOne; 54 | @JsonProperty("rangeTwo") 55 | private DcaRange rangeTwo; 56 | @JsonProperty("rangeThree") 57 | private DcaRange rangeThree; 58 | @JsonProperty("rangeFour") 59 | private DcaRange rangeFour; 60 | @JsonProperty("rangeFive") 61 | private DcaRange rangeFive; 62 | @JsonProperty("rangeSix") 63 | private DcaRange rangeSix; 64 | } 65 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/event/SymbolBookTickerEvent.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.event; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | 6 | import java.math.BigDecimal; 7 | 8 | public class SymbolBookTickerEvent { 9 | 10 | private Long orderBookUpdateId; 11 | 12 | private String symbol; 13 | 14 | private BigDecimal bestBidPrice; 15 | 16 | private BigDecimal bestBidQty; 17 | 18 | private BigDecimal bestAskPrice; 19 | 20 | private BigDecimal bestAskQty; 21 | 22 | public Long getOrderBookUpdateId() { 23 | return orderBookUpdateId; 24 | } 25 | 26 | public void setOrderBookUpdateId(Long orderBookUpdateId) { 27 | this.orderBookUpdateId = orderBookUpdateId; 28 | } 29 | 30 | public String getSymbol() { 31 | return symbol; 32 | } 33 | 34 | public void setSymbol(String symbol) { 35 | this.symbol = symbol; 36 | } 37 | 38 | public BigDecimal getBestBidPrice() { 39 | return bestBidPrice; 40 | } 41 | 42 | public void setBestBidPrice(BigDecimal bestBidPrice) { 43 | this.bestBidPrice = bestBidPrice; 44 | } 45 | 46 | public BigDecimal getBestBidQty() { 47 | return bestBidQty; 48 | } 49 | 50 | public void setBestBidQty(BigDecimal bestBidQty) { 51 | this.bestBidQty = bestBidQty; 52 | } 53 | 54 | public BigDecimal getBestAskPrice() { 55 | return bestAskPrice; 56 | } 57 | 58 | public void setBestAskPrice(BigDecimal bestAskPrice) { 59 | this.bestAskPrice = bestAskPrice; 60 | } 61 | 62 | public BigDecimal getBestAskQty() { 63 | return bestAskQty; 64 | } 65 | 66 | public void setBestAskQty(BigDecimal bestAskQty) { 67 | this.bestAskQty = bestAskQty; 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) 73 | .append("orderBookUpdateId", orderBookUpdateId).append("symbol", symbol) 74 | .append("bestBidPrice", bestBidPrice).append("bestBidQty", bestBidQty) 75 | .append("bestAskPrice", bestAskPrice).append("bestAskQty", bestAskQty).toString(); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/models/webhook/DiscordWebhook.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.models.webhook; 2 | 3 | import com.fasterxml.jackson.annotation.*; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | @JsonInclude(JsonInclude.Include.NON_NULL) 9 | @JsonPropertyOrder({ 10 | "webhook", 11 | "content", 12 | "username", 13 | "avatar_url" 14 | }) 15 | public class DiscordWebhook { 16 | 17 | @JsonProperty("webhook") 18 | private String webhook; 19 | @JsonProperty("content") 20 | private String content; 21 | @JsonProperty("username") 22 | private String username; 23 | @JsonProperty("avatar_url") 24 | private String avatarUrl; 25 | @JsonIgnore 26 | private Map additionalProperties = new HashMap(); 27 | 28 | @JsonProperty("webhook") 29 | public String getWebhook() { 30 | return webhook; 31 | } 32 | 33 | @JsonProperty("webhook") 34 | public void setWebhook(String webhook) { 35 | this.webhook = webhook; 36 | } 37 | 38 | @JsonProperty("content") 39 | public String getContent() { 40 | return content; 41 | } 42 | 43 | @JsonProperty("content") 44 | public void setContent(String content) { 45 | this.content = content; 46 | } 47 | 48 | @JsonProperty("username") 49 | public String getUsername() { 50 | return username; 51 | } 52 | 53 | @JsonProperty("username") 54 | public void setUsername(String username) { 55 | this.username = username; 56 | } 57 | 58 | @JsonProperty("avatar_url") 59 | public String getAvatarUrl() { 60 | return avatarUrl; 61 | } 62 | 63 | @JsonProperty("avatar_url") 64 | public void setAvatarUrl(String avatarUrl) { 65 | this.avatarUrl = avatarUrl; 66 | } 67 | 68 | public void setAdditionalProperties(Map additionalProperties) { 69 | this.additionalProperties = additionalProperties; 70 | } 71 | 72 | @JsonAnyGetter 73 | public Map getAdditionalProperties() { 74 | return this.additionalProperties; 75 | } 76 | 77 | @JsonAnySetter 78 | public void setAdditionalProperty(String name, Object value) { 79 | this.additionalProperties.put(name, value); 80 | } 81 | 82 | } -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/services/impl/SentimentsServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.services.impl; 2 | 3 | import com.lickhunter.web.configs.ApplicationConfig; 4 | import com.lickhunter.web.models.sentiments.SentimentData; 5 | import com.lickhunter.web.services.SentimentsService; 6 | import lombok.RequiredArgsConstructor; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.http.*; 10 | import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; 11 | import org.springframework.stereotype.Service; 12 | import org.springframework.web.client.RestTemplate; 13 | import org.springframework.web.util.UriComponentsBuilder; 14 | 15 | import java.util.Arrays; 16 | 17 | @Service 18 | @Slf4j 19 | @RequiredArgsConstructor 20 | public class SentimentsServiceImpl implements SentimentsService { 21 | 22 | private final ApplicationConfig applicationConfig; 23 | @Value("${sentiments.key}") 24 | private String key; 25 | 26 | public SentimentData getSentiments(String symbol) { 27 | SentimentData result = null; 28 | try { 29 | RestTemplate restTemplate = new RestTemplate(); 30 | MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(); 31 | mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN)); 32 | restTemplate.getMessageConverters().add(mappingJackson2HttpMessageConverter); 33 | HttpHeaders headers = new HttpHeaders(); 34 | headers.setContentType(MediaType.APPLICATION_JSON); 35 | HttpEntity entity = new HttpEntity<>(headers); 36 | UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(applicationConfig.getSentimentsApi()) 37 | .queryParam("data", "assets") 38 | .queryParam("symbol", symbol); 39 | ResponseEntity res = restTemplate.exchange(builder.toUriString(), HttpMethod.GET, entity, SentimentData.class); 40 | result = res.getBody(); 41 | } catch (Exception e) { 42 | log.error(String.format("Failed to retrieve sentiments. %s", e.getMessage())); 43 | } 44 | return result; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/models/sentiments/Config.java: -------------------------------------------------------------------------------- 1 | 2 | package com.lickhunter.web.models.sentiments; 3 | 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | import javax.annotation.Generated; 7 | import com.fasterxml.jackson.annotation.JsonAnyGetter; 8 | import com.fasterxml.jackson.annotation.JsonAnySetter; 9 | import com.fasterxml.jackson.annotation.JsonIgnore; 10 | import com.fasterxml.jackson.annotation.JsonInclude; 11 | import com.fasterxml.jackson.annotation.JsonProperty; 12 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 13 | 14 | @JsonInclude(JsonInclude.Include.NON_NULL) 15 | @JsonPropertyOrder({ 16 | "data", 17 | "symbol", 18 | "interval", 19 | "data_points" 20 | }) 21 | @Generated("jsonschema2pojo") 22 | public class Config { 23 | 24 | @JsonProperty("data") 25 | private String data; 26 | @JsonProperty("symbol") 27 | private String symbol; 28 | @JsonProperty("interval") 29 | private String interval; 30 | @JsonProperty("data_points") 31 | private Integer dataPoints; 32 | @JsonIgnore 33 | private Map additionalProperties = new HashMap(); 34 | 35 | @JsonProperty("data") 36 | public String getData() { 37 | return data; 38 | } 39 | 40 | @JsonProperty("data") 41 | public void setData(String data) { 42 | this.data = data; 43 | } 44 | 45 | @JsonProperty("symbol") 46 | public String getSymbol() { 47 | return symbol; 48 | } 49 | 50 | @JsonProperty("symbol") 51 | public void setSymbol(String symbol) { 52 | this.symbol = symbol; 53 | } 54 | 55 | @JsonProperty("interval") 56 | public String getInterval() { 57 | return interval; 58 | } 59 | 60 | @JsonProperty("interval") 61 | public void setInterval(String interval) { 62 | this.interval = interval; 63 | } 64 | 65 | @JsonProperty("data_points") 66 | public Integer getDataPoints() { 67 | return dataPoints; 68 | } 69 | 70 | @JsonProperty("data_points") 71 | public void setDataPoints(Integer dataPoints) { 72 | this.dataPoints = dataPoints; 73 | } 74 | 75 | @JsonAnyGetter 76 | public Map getAdditionalProperties() { 77 | return this.additionalProperties; 78 | } 79 | 80 | @JsonAnySetter 81 | public void setAdditionalProperty(String name, Object value) { 82 | this.additionalProperties.put(name, value); 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/services/MarketService.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.services; 2 | 3 | import com.binance.client.model.enums.CandlestickInterval; 4 | import com.lickhunter.web.entities.tables.records.SymbolRecord; 5 | import com.lickhunter.web.exceptions.ServiceException; 6 | import com.lickhunter.web.to.TickerQueryTO; 7 | 8 | import java.util.List; 9 | 10 | public interface MarketService { 11 | /** 12 | * Retrieves price change statistics by specifying query. 13 | * If symbol is set, tickers for that specific symbol will be returned. 14 | * Specify maxPriceChangePercentage to return records below that limit 15 | * Set volumeUpperLimit and volumeLowerLimit to return list symbols within that volume range. 16 | * 17 | * @param query symbol, maxPriceChangePercent, volumeUpperLimit, volumeLowerLimit 18 | * @return List of PriceChangeTicker 19 | * @throws ServiceException 20 | */ 21 | List getTickerByQuery(TickerQueryTO query); 22 | 23 | /** 24 | * Current exchange trading rules and symbol information 25 | * @return ExchangeInformation 26 | * @throws ServiceException 27 | */ 28 | void getExchangeInformation() throws ServiceException; 29 | 30 | /** 31 | * Retrieves the rolling 24h price ticker 32 | * @throws ServiceException 33 | */ 34 | void get24hrTickerPriceChange() throws Exception; 35 | /** 36 | * Manually retrieve candlestick data 37 | * @param interval 38 | * ONE_MINUTE("1m"), 39 | * THREE_MINUTES("3m"), 40 | * FIVE_MINUTES("5m"), 41 | * FIFTEEN_MINUTES("15m"), 42 | * HALF_HOURLY("30m"), 43 | * HOURLY("1h"), 44 | * TWO_HOURLY("2h"), 45 | * FOUR_HOURLY("4h"), 46 | * SIX_HOURLY("6h"), 47 | * EIGHT_HOURLY("8h"), 48 | * TWELVE_HOURLY("12h"), 49 | * DAILY("1d"), 50 | * THREE_DAILY("3d"), 51 | * WEEKLY("1w"), 52 | * MONTHLY("1M"); 53 | * @param limit identifies the number of bars to be retrieved 54 | * @throws ServiceException 55 | */ 56 | void getCandleStickData(CandlestickInterval interval, int limit) throws Exception; 57 | 58 | /** 59 | * Retrieves Mark Price Data 60 | * @throws ServiceException 61 | */ 62 | List getMarkPriceData() throws Exception; 63 | 64 | /** 65 | * Retrieves Liquidation Data 66 | * @throws Exception 67 | */ 68 | void getLiquidations() throws Exception; 69 | } 70 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/impl/WebSocketWatchDog.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.impl; 2 | 3 | import com.binance.client.SubscriptionOptions; 4 | import com.binance.client.impl.WebSocketConnection.ConnectionState; 5 | import java.util.Objects; 6 | import java.util.concurrent.CopyOnWriteArrayList; 7 | import java.util.concurrent.Executors; 8 | import java.util.concurrent.ScheduledExecutorService; 9 | import java.util.concurrent.TimeUnit; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | class WebSocketWatchDog { 14 | 15 | private final CopyOnWriteArrayList TIME_HELPER = new CopyOnWriteArrayList<>(); 16 | private final SubscriptionOptions options; 17 | private static final Logger log = LoggerFactory.getLogger(WebSocketConnection.class); 18 | 19 | WebSocketWatchDog(SubscriptionOptions subscriptionOptions) { 20 | this.options = Objects.requireNonNull(subscriptionOptions); 21 | long t = 1_000; 22 | ScheduledExecutorService exec = Executors.newScheduledThreadPool(1); 23 | exec.scheduleAtFixedRate(() -> { 24 | TIME_HELPER.forEach(connection -> { 25 | if (connection.getState() == ConnectionState.CONNECTED) { 26 | // Check response 27 | if (options.isAutoReconnect()) { 28 | long ts = System.currentTimeMillis() - connection.getLastReceivedTime(); 29 | if (ts > options.getReceiveLimitMs()) { 30 | log.warn("[Sub][" + connection.getConnectionId() + "] No response from server"); 31 | connection.reConnect(options.getConnectionDelayOnFailure()); 32 | } 33 | } 34 | } else if (connection.getState() == ConnectionState.DELAY_CONNECT) { 35 | connection.reConnect(); 36 | } else if (connection.getState() == ConnectionState.CLOSED_ON_ERROR) { 37 | if (options.isAutoReconnect()) { 38 | connection.reConnect(options.getConnectionDelayOnFailure()); 39 | } 40 | } 41 | }); 42 | }, t, t, TimeUnit.MILLISECONDS); 43 | Runtime.getRuntime().addShutdownHook(new Thread(exec::shutdown)); 44 | } 45 | 46 | void onConnectionCreated(WebSocketConnection connection) { 47 | TIME_HELPER.addIfAbsent(connection); 48 | } 49 | 50 | void onClosedNormally(WebSocketConnection connection) { 51 | TIME_HELPER.remove(connection); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/services/impl/WatchServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.services.impl; 2 | 3 | import com.lickhunter.web.constants.ApplicationConstants; 4 | import com.lickhunter.web.scheduler.LickHunterScheduledTasks; 5 | import com.lickhunter.web.services.LickHunterService; 6 | import com.lickhunter.web.services.WatchService; 7 | import lombok.RequiredArgsConstructor; 8 | import lombok.SneakyThrows; 9 | import lombok.extern.slf4j.Slf4j; 10 | import org.springframework.stereotype.Service; 11 | 12 | import java.nio.file.*; 13 | 14 | @Service 15 | @RequiredArgsConstructor 16 | @Slf4j 17 | public class WatchServiceImpl implements WatchService { 18 | 19 | private final LickHunterScheduledTasks lickHunterScheduledTasks; 20 | private final LickHunterService lickHunterService; 21 | 22 | @SneakyThrows 23 | public void fileWatcher() { 24 | final Path path = FileSystems.getDefault().getPath("./"); 25 | 26 | try (final java.nio.file.WatchService watchService = FileSystems.getDefault().newWatchService()) { 27 | final WatchKey watchKey = path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE); 28 | while (true) { 29 | final WatchKey wk = watchService.take(); 30 | for (WatchEvent event : wk.pollEvents()) { 31 | final Path changed = (Path) event.context(); 32 | if (event.kind().name().equalsIgnoreCase(StandardWatchEventKinds.ENTRY_MODIFY.name()) 33 | && (changed.endsWith(ApplicationConstants.SETTINGS.getValue()) 34 | || changed.endsWith(ApplicationConstants.WEB_SETTINGS.getValue()) 35 | || changed.endsWith(ApplicationConstants.TICKER_QUERY.getValue()))) { 36 | log.info("File changed:" + changed); 37 | lickHunterScheduledTasks.writeToCoinsJson(); 38 | } 39 | if (event.kind().name().equalsIgnoreCase(StandardWatchEventKinds.ENTRY_DELETE.name()) 40 | && changed.endsWith(ApplicationConstants.COINS.getValue())) { 41 | log.info("File deleted:" + changed); 42 | lickHunterScheduledTasks.writeToCoinsJson(); 43 | } 44 | } 45 | // reset the key 46 | boolean valid = wk.reset(); 47 | if (!valid) { 48 | System.out.println("Key has been unregistered"); 49 | } 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ master ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ master ] 20 | schedule: 21 | - cron: '26 20 * * 4' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'java' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] 37 | # Learn more: 38 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed 39 | 40 | steps: 41 | - name: Checkout repository 42 | uses: actions/checkout@v2 43 | 44 | # Initializes the CodeQL tools for scanning. 45 | - name: Initialize CodeQL 46 | uses: github/codeql-action/init@v1 47 | with: 48 | languages: ${{ matrix.language }} 49 | # If you wish to specify custom queries, you can do so here or in a config file. 50 | # By default, queries listed here will override any specified in a config file. 51 | # Prefix the list here with "+" to use these queries and those in the config file. 52 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 53 | 54 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 55 | # If this step fails, then you should remove it and run the build manually (see below) 56 | - name: Autobuild 57 | uses: github/codeql-action/autobuild@v1 58 | 59 | # ℹ️ Command-line programs to run using the OS shell. 60 | # 📚 https://git.io/JvXDl 61 | 62 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 63 | # and modify them (or add more) to build your code if your project 64 | # uses a compiled language 65 | 66 | #- run: | 67 | # make bootstrap 68 | # make release 69 | 70 | - name: Perform CodeQL Analysis 71 | uses: github/codeql-action/analyze@v1 72 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/user/PositionUpdate.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.user; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | import java.math.BigDecimal; 6 | 7 | public class PositionUpdate { 8 | 9 | private String symbol; 10 | 11 | private BigDecimal amount; 12 | 13 | private BigDecimal entryPrice; 14 | 15 | private BigDecimal preFee; 16 | 17 | private BigDecimal unrealizedPnl; 18 | 19 | private String marginType; 20 | 21 | private BigDecimal isolatedWallet; 22 | 23 | private String positionSide; 24 | 25 | 26 | public String getSymbol() { 27 | return symbol; 28 | } 29 | 30 | public void setSymbol(String symbol) { 31 | this.symbol = symbol; 32 | } 33 | 34 | public BigDecimal getAmount() { 35 | return amount; 36 | } 37 | 38 | public void setAmount(BigDecimal amount) { 39 | this.amount = amount; 40 | } 41 | 42 | public BigDecimal getEntryPrice() { 43 | return entryPrice; 44 | } 45 | 46 | public void setEntryPrice(BigDecimal entryPrice) { 47 | this.entryPrice = entryPrice; 48 | } 49 | 50 | public BigDecimal getPreFee() { 51 | return preFee; 52 | } 53 | 54 | public void setPreFee(BigDecimal preFee) { 55 | this.preFee = preFee; 56 | } 57 | 58 | public BigDecimal getUnrealizedPnl() { 59 | return unrealizedPnl; 60 | } 61 | 62 | public void setUnrealizedPnl(BigDecimal unrealizedPnl) { 63 | this.unrealizedPnl = unrealizedPnl; 64 | } 65 | 66 | public String getMarginType() { 67 | return marginType; 68 | } 69 | 70 | public void setMarginType(String marginType) { 71 | this.marginType = marginType; 72 | } 73 | 74 | public BigDecimal getIsolatedWallet() { 75 | return isolatedWallet; 76 | } 77 | 78 | public void setIsolatedWallet(BigDecimal isolatedWallet) { 79 | this.isolatedWallet = isolatedWallet; 80 | } 81 | 82 | public String getPositionSide() { 83 | return positionSide; 84 | } 85 | 86 | public void setPositionSide(String positionSide) { 87 | this.positionSide = positionSide; 88 | } 89 | 90 | @Override 91 | public String toString() { 92 | return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE).append("symbol", symbol) 93 | .append("amount", amount).append("entryPrice", entryPrice).append("preFee", preFee) 94 | .append("unrealizedPnl", unrealizedPnl).append("marginType", marginType).append("isolatedWallet", isolatedWallet) 95 | .append("positionSide", positionSide).toString(); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/to/TickerQueryTO.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web.to; 2 | 3 | 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import lombok.With; 8 | 9 | import javax.validation.constraints.Min; 10 | import javax.validation.constraints.NotNull; 11 | import java.math.BigDecimal; 12 | import java.util.List; 13 | 14 | /** 15 | * A representation of the Ticker query object 16 | */ 17 | @With 18 | @Data 19 | @NoArgsConstructor 20 | @AllArgsConstructor 21 | public class TickerQueryTO extends AbstractTO { 22 | 23 | /** 24 | * The symbol of the currency 25 | */ 26 | private List symbol; 27 | 28 | /** 29 | * The price percentage change of the symbol 30 | */ 31 | private BigDecimal maxPriceChangePercent; 32 | 33 | /** 34 | * The upper limit of trading volume in USD 35 | */ 36 | private BigDecimal volumeUpperLimit; 37 | 38 | /** 39 | * The lower limit of trading volume in USD 40 | */ 41 | @Min(value = 0, message = "Volume Lower Limit should not be less than 0") 42 | private BigDecimal volumeLowerLimit; 43 | 44 | /** 45 | * Minimum trading age of symbol. 46 | */ 47 | @NotNull(message = "Minimum Trading Age cannot be null") 48 | private int minimumTradingAge; 49 | 50 | /** 51 | * Include symbols nearing all time high 52 | */ 53 | @Min(value = 0, message = "Percentage From All Time High should not be less than 0") 54 | private Long percentageFromAllTimeHigh; 55 | 56 | /** 57 | * Exclude symbols from query 58 | */ 59 | private List exclude; 60 | 61 | /** 62 | * Enables automatic exclusion of coins based on percentage change within 24H. 63 | */ 64 | private Boolean autoExclude; 65 | 66 | /** 67 | * Sets the percentage change for automatic exclusion. 68 | */ 69 | private BigDecimal autoExcludePercentage; 70 | 71 | /** 72 | * Enables the Bollinger Bands Strategy 73 | */ 74 | private Boolean bbStrategy; 75 | 76 | /** 77 | * Timeframe to be used for Bollinger Bands 78 | */ 79 | private String bbTimeframe; 80 | 81 | /** 82 | * Length or number of bars for Bollinger Bands 83 | */ 84 | private int bbBarCount; 85 | 86 | /** 87 | * Enables the CCI Correction Strategy 88 | */ 89 | private Boolean cciStrategy; 90 | 91 | /** 92 | * Length or number of bars for CCI 93 | */ 94 | private int cciBarCount; 95 | 96 | /** 97 | * Timeframe to be used for CCI 98 | */ 99 | private String cciTimeframe; 100 | 101 | /** 102 | * Minim market cap allowed 103 | */ 104 | private Long minMarketCap; 105 | } 106 | -------------------------------------------------------------------------------- /binance-sdk/src/main/java/com/binance/client/model/market/LiquidationOrder.java: -------------------------------------------------------------------------------- 1 | package com.binance.client.model.market; 2 | 3 | import com.binance.client.constant.BinanceApiConstants; 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | 6 | import java.math.BigDecimal; 7 | 8 | public class LiquidationOrder { 9 | 10 | private String symbol; 11 | 12 | private BigDecimal price; 13 | 14 | private BigDecimal origQty; 15 | 16 | private BigDecimal executedQty; 17 | 18 | private BigDecimal averagePrice; 19 | 20 | private String timeInForce; 21 | 22 | private String type; 23 | 24 | private String side; 25 | 26 | private Long time; 27 | 28 | public String getSymbol() { 29 | return symbol; 30 | } 31 | 32 | public void setSymbol(String symbol) { 33 | this.symbol = symbol; 34 | } 35 | 36 | public BigDecimal getPrice() { 37 | return price; 38 | } 39 | 40 | public void setPrice(BigDecimal price) { 41 | this.price = price; 42 | } 43 | 44 | public BigDecimal getOrigQty() { 45 | return origQty; 46 | } 47 | 48 | public void setOrigQty(BigDecimal origQty) { 49 | this.origQty = origQty; 50 | } 51 | 52 | public BigDecimal getExecutedQty() { 53 | return executedQty; 54 | } 55 | 56 | public void setExecutedQty(BigDecimal executedQty) { 57 | this.executedQty = executedQty; 58 | } 59 | 60 | public BigDecimal getAveragePrice() { 61 | return averagePrice; 62 | } 63 | 64 | public void setAveragePrice(BigDecimal averagePrice) { 65 | this.averagePrice = averagePrice; 66 | } 67 | 68 | public String getTimeInForce() { 69 | return timeInForce; 70 | } 71 | 72 | public void setTimeInForce(String timeInForce) { 73 | this.timeInForce = timeInForce; 74 | } 75 | 76 | public String getType() { 77 | return type; 78 | } 79 | 80 | public void setType(String type) { 81 | this.type = type; 82 | } 83 | 84 | public String getSide() { 85 | return side; 86 | } 87 | 88 | public void setSide(String side) { 89 | this.side = side; 90 | } 91 | 92 | public Long getTime() { 93 | return time; 94 | } 95 | 96 | public void setTime(Long time) { 97 | this.time = time; 98 | } 99 | 100 | @Override 101 | public String toString() { 102 | return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE).append("symbol", symbol) 103 | .append("price", price).append("origQty", origQty).append("executedQty", executedQty) 104 | .append("averagePrice", averagePrice).append("timeInForce", timeInForce).append("type", type) 105 | .append("side", side).append("time", time).toString(); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /server/src/main/java/com/lickhunter/web/WebApplication.java: -------------------------------------------------------------------------------- 1 | package com.lickhunter.web; 2 | 3 | import com.binance.client.model.enums.CandlestickInterval; 4 | import com.binance.client.model.enums.IncomeType; 5 | import com.lickhunter.web.controllers.ApplicationController; 6 | import com.lickhunter.web.scheduler.LickHunterScheduledTasks; 7 | import com.lickhunter.web.services.*; 8 | import com.lickhunter.web.websockets.BinanceSubscription; 9 | import lombok.SneakyThrows; 10 | import lombok.extern.slf4j.Slf4j; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.boot.SpringApplication; 13 | import org.springframework.boot.autoconfigure.SpringBootApplication; 14 | import org.springframework.boot.context.event.ApplicationReadyEvent; 15 | import org.springframework.context.event.EventListener; 16 | 17 | import javax.annotation.PostConstruct; 18 | import java.util.Arrays; 19 | 20 | @SpringBootApplication 21 | @Slf4j 22 | public class WebApplication { 23 | 24 | @Autowired 25 | private AccountService accountService; 26 | 27 | @Autowired 28 | private MarketService marketService; 29 | 30 | @Autowired 31 | private LickHunterScheduledTasks lickHunterScheduledTasks; 32 | 33 | @Autowired 34 | private ApplicationController applicationController; 35 | 36 | @Autowired 37 | private LickHunterService lickHunterService; 38 | 39 | @Autowired 40 | private WatchService watchService; 41 | 42 | @Autowired 43 | private BinanceSubscription binanceSubscription; 44 | 45 | @Autowired 46 | private TechnicalIndicatorService technicalIndicatorService; 47 | 48 | public static void main(String[] args) { 49 | SpringApplication.run(WebApplication.class, args); 50 | } 51 | 52 | @PostConstruct 53 | public void initProcess() throws Exception { 54 | accountService.getAccountInformation(); 55 | marketService.getExchangeInformation(); 56 | marketService.get24hrTickerPriceChange(); 57 | // applicationController.subscribeCandleStickData(); 58 | applicationController.subscribeMarkPrice(); 59 | applicationController.subscribeUserData(); 60 | marketService.getLiquidations(); 61 | Arrays.stream(IncomeType.values()) 62 | .forEach(incomeType -> { 63 | try { 64 | accountService.getIncomeHistory(null, 65 | incomeType, 66 | null, 67 | null, 68 | 1000); 69 | } catch (Exception e) { 70 | e.printStackTrace(); 71 | } 72 | }); 73 | lickHunterScheduledTasks.checkSentiments(); 74 | marketService.getCandleStickData(CandlestickInterval.MONTHLY, 200); 75 | marketService.getCandleStickData(CandlestickInterval.FIFTEEN_MINUTES, 30); 76 | marketService.getCandleStickData(CandlestickInterval.HOURLY, 30); 77 | lickHunterScheduledTasks.writeToCoinsJson(); 78 | binanceSubscription.subscribeLiquidation(); 79 | } 80 | 81 | @EventListener(ApplicationReadyEvent.class) 82 | @SneakyThrows 83 | public void startWatcher() { 84 | watchService.fileWatcher(); 85 | } 86 | } 87 | --------------------------------------------------------------------------------