first commit
This commit is contained in:
3
comm/Hobi/WebContent/META-INF/MANIFEST.MF
Executable file
3
comm/Hobi/WebContent/META-INF/MANIFEST.MF
Executable file
@@ -0,0 +1,3 @@
|
||||
Manifest-Version: 1.0
|
||||
Class-Path:
|
||||
|
||||
172
comm/Hobi/WebContent/symbols_list.jsp
Executable file
172
comm/Hobi/WebContent/symbols_list.jsp
Executable file
@@ -0,0 +1,172 @@
|
||||
<%@ page language="java" pageEncoding="utf-8"%>
|
||||
<%@ include file="include/pagetop.jsp"%>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<%@ include file="include/head.jsp"%>
|
||||
</head>
|
||||
<body>
|
||||
<%@ include file="include/loading.jsp"%>
|
||||
<%@ include file="include/top.jsp"%>
|
||||
<%@ include file="include/menu_left.jsp"%>
|
||||
|
||||
<!-- //////////////////////////////////////////////////////////////////////////// -->
|
||||
<!-- START CONTENT -->
|
||||
<div class="content">
|
||||
|
||||
|
||||
|
||||
<!-- //////////////////////////////////////////////////////////////////////////// -->
|
||||
<!-- START CONTAINER -->
|
||||
<div class="container-default">
|
||||
<h3>可交易品种库</h3>
|
||||
<%@ include file="include/alert.jsp"%>
|
||||
|
||||
<!-- START queryForm -->
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="panel panel-default">
|
||||
|
||||
<div class="panel-title">查询条件</div>
|
||||
<div class="panel-body">
|
||||
|
||||
<form class="form-horizontal"
|
||||
action="<%=basePath%>normal/adminSymbolsAction!list.action"
|
||||
method="post" id="queryForm">
|
||||
<input type="hidden" name="pageNo" id="pageNo"
|
||||
value="${param.pageNo}">
|
||||
<div class="col-md-12 col-lg-8">
|
||||
<fieldset>
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<s:textfield id="quote_currency" name="quote_currency" cssClass="form-control " placeholder="报价币种"/>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="col-md-12 col-lg-2">
|
||||
<button type="submit" class="btn btn-light btn-block">查询</button>
|
||||
</div>
|
||||
</form>
|
||||
<sec:authorize ifAnyGranted="ROLE_ROOT,ROLE_ADMIN">
|
||||
<div class="col-md-12 col-lg-4" style="margin-top: 10px;">
|
||||
<div class="mailbox clearfix">
|
||||
<div class="mailbox-menu">
|
||||
<ul class="menu">
|
||||
<li>
|
||||
<button type="button" onclick="reload()" class="btn btn-default ">同步远程数据库</button></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</sec:authorize>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- END queryForm -->
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<!-- Start Panel -->
|
||||
<div class="panel panel-default">
|
||||
|
||||
<div class="panel-title">查询结果</div>
|
||||
<div class="panel-body">
|
||||
<table class="table table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>交易对</td>
|
||||
<td>基础币种</td>
|
||||
<td>报价币种</td>
|
||||
<td>报价精度(小数位)</td>
|
||||
<td>交易对杠杆最大倍数</td>
|
||||
<td>状态</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<s:iterator value="page.elements" status="stat">
|
||||
<tr>
|
||||
<td><s:property value="symbol" /></td>
|
||||
<td><s:property value="base_currency" /></td>
|
||||
<td><s:property value="quote_currency" /></td>
|
||||
<td><s:property value="price_precision" /></td>
|
||||
<td><s:property value="leverage_ratio" /></td>
|
||||
<td><s:property value="state" /></td>
|
||||
<td>
|
||||
<sec:authorize ifAnyGranted="ROLE_ROOT,ROLE_ADMIN">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-light">操作</button>
|
||||
<button type="button" class="btn btn-light dropdown-toggle"
|
||||
data-toggle="dropdown" aria-expanded="false">
|
||||
<span class="caret"></span> <span class="sr-only">Toggle
|
||||
Dropdown</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a
|
||||
href="<%=basePath%>normal/adminItemAction!toAdd.action?symbol_data=<s:property value="symbol" />&symbol=<s:property value="base_currency" />">添加到交易品种</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</sec:authorize>
|
||||
</td>
|
||||
</tr>
|
||||
</s:iterator>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<%@ include file="include/page_simple.jsp"%>
|
||||
<nav>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- End Panel -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- END CONTAINER -->
|
||||
<!-- //////////////////////////////////////////////////////////////////////////// -->
|
||||
|
||||
|
||||
<%@ include file="include/footer.jsp"%>
|
||||
|
||||
|
||||
</div>
|
||||
<!-- End Content -->
|
||||
<!-- //////////////////////////////////////////////////////////////////////////// -->
|
||||
|
||||
|
||||
|
||||
<%@ include file="include/js.jsp"%>
|
||||
|
||||
</body>
|
||||
<sec:authorize ifAnyGranted="ROLE_ADMIN,ROLE_ROOT">
|
||||
<form action="<%=basePath%>normal/adminSymbolsAction!reload.action" method="post"
|
||||
id="reload">
|
||||
</form>
|
||||
<script type="text/javascript">
|
||||
function reload() {
|
||||
swal({
|
||||
title : "是否同步远程数据库?",
|
||||
text : "",
|
||||
type : "warning",
|
||||
showCancelButton : true,
|
||||
confirmButtonColor : "#DD6B55",
|
||||
confirmButtonText : "确认",
|
||||
closeOnConfirm : false
|
||||
}, function() {
|
||||
document.getElementById("reload").submit();
|
||||
});
|
||||
|
||||
}
|
||||
</script>
|
||||
</sec:authorize>
|
||||
</html>
|
||||
39
comm/Hobi/build/classes/project/hobi/Realtime.hbm.xml
Executable file
39
comm/Hobi/build/classes/project/hobi/Realtime.hbm.xml
Executable file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
|
||||
<hibernate-mapping>
|
||||
<class name="project.data.Realtime" table="T_REALTIME">
|
||||
<id name="id" type="java.lang.String">
|
||||
<column name="UUID" />
|
||||
<generator class="uuid.hex" />
|
||||
</id>
|
||||
<property name="symbol" type="java.lang.String">
|
||||
<column name="SYMBOL" />
|
||||
</property>
|
||||
<property name="ts" type="int">
|
||||
<column name="TS" />
|
||||
</property>
|
||||
<property name="name" type="java.lang.String">
|
||||
<column name="NAME" />
|
||||
</property>
|
||||
<property name="open" type="double">
|
||||
<column name="OPEN" />
|
||||
</property>
|
||||
<property name="high" type="double">
|
||||
<column name="HIGH" />
|
||||
</property>
|
||||
<property name="low" type="double">
|
||||
<column name="LOW" />
|
||||
</property>
|
||||
<property name="close" type="double">
|
||||
<column name="CLOSE" />
|
||||
</property>
|
||||
<property name="volume" type="double">
|
||||
<column name="VOLUME" />
|
||||
</property>
|
||||
<property name="amount" type="double">
|
||||
<column name="AMOUNT" />
|
||||
</property>
|
||||
|
||||
</class>
|
||||
</hibernate-mapping>
|
||||
11
comm/Hobi/config/applicationContext-hibernate.xml
Executable file
11
comm/Hobi/config/applicationContext-hibernate.xml
Executable file
@@ -0,0 +1,11 @@
|
||||
|
||||
admin
|
||||
<!-- hobi -->
|
||||
<value>adminSymbolsService</value>
|
||||
<value>adminContractSymbolsService</value>
|
||||
|
||||
|
||||
data
|
||||
<!-- hobi -->
|
||||
<value>dataDBService</value>
|
||||
<value>klineService</value>
|
||||
22
comm/Hobi/config/applicationContext-hobi.xml
Executable file
22
comm/Hobi/config/applicationContext-hobi.xml
Executable file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://code.alibabatech.com/schema/dubbo
|
||||
http://code.alibabatech.com/schema/dubbo/dubbo.xsd ">
|
||||
|
||||
|
||||
|
||||
<bean id="dataService"
|
||||
class="project.data.internal.DataServiceImpl">
|
||||
<property name="remoteDataService" ref="remoteDataService" />
|
||||
</bean>
|
||||
|
||||
|
||||
<dubbo:reference id="remoteDataService"
|
||||
interface="project.data.DataService" check="false" />
|
||||
|
||||
|
||||
</beans>
|
||||
31
comm/Hobi/config/applicationContext-hobi_admin.xml
Executable file
31
comm/Hobi/config/applicationContext-hobi_admin.xml
Executable file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://code.alibabatech.com/schema/dubbo
|
||||
http://code.alibabatech.com/schema/dubbo/dubbo.xsd ">
|
||||
|
||||
|
||||
<dubbo:reference id="hobiDataService"
|
||||
interface="project.hobi.HobiDataService" check="false" />
|
||||
|
||||
<bean id="adminSymbolsService"
|
||||
class="project.hobi.internal.AdminSymbolsServiceImpl">
|
||||
<property name="hibernateTemplate" ref="hibernateTemplate" />
|
||||
<property name="pagedQueryDao" ref="pagedDao" />
|
||||
<property name="hobiDataService" ref="hobiDataService" />
|
||||
</bean>
|
||||
<bean id="adminContractSymbolsService"
|
||||
class="project.hobi.internal.AdminContractSymbolsServiceImpl">
|
||||
<property name="hibernateTemplate" ref="hibernateTemplate" />
|
||||
<property name="pagedQueryDao" ref="pagedDao" />
|
||||
<property name="hobiDataService" ref="hobiDataService" />
|
||||
<property name="jdbcTemplate" ref="jdbcTemplate" />
|
||||
</bean>
|
||||
|
||||
<dubbo:reference id="klineInitService"
|
||||
interface="project.data.internal.KlineInitService" check="false" />
|
||||
|
||||
</beans>
|
||||
123
comm/Hobi/config/applicationContext-hobi_data.xml
Executable file
123
comm/Hobi/config/applicationContext-hobi_data.xml
Executable file
@@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://code.alibabatech.com/schema/dubbo
|
||||
http://code.alibabatech.com/schema/dubbo/dubbo.xsd ">
|
||||
|
||||
|
||||
<bean id="klineInitService"
|
||||
class="project.data.internal.KlineInitServiceImpl">
|
||||
<property name="klineService" ref="klineService" />
|
||||
</bean>
|
||||
<dubbo:service
|
||||
interface="project.data.internal.KlineInitService"
|
||||
ref="klineInitService" />
|
||||
|
||||
<bean id="hobiDataService"
|
||||
class="project.hobi.internal.HobiDataServiceImpl">
|
||||
<property name="itemService" ref="itemService" />
|
||||
</bean>
|
||||
<dubbo:service interface="project.hobi.HobiDataService"
|
||||
ref="hobiDataService" />
|
||||
|
||||
|
||||
<bean id="cleanDataJob" class="project.data.job.CleanDataJob">
|
||||
<property name="itemService" ref="itemService" />
|
||||
<property name="dataDBService" ref="dataDBService" />
|
||||
<property name="klineService" ref="klineService" />
|
||||
|
||||
</bean>
|
||||
|
||||
|
||||
<bean id="dataDBService"
|
||||
class="project.data.internal.DataDBServiceImpl">
|
||||
<property name="hibernateTemplate" ref="hibernateTemplate" />
|
||||
<property name="namedParameterJdbcTemplate"
|
||||
ref="namedParameterJdbcTemplate" />
|
||||
<property name="sysparaService" ref="sysparaService" />
|
||||
<property name="pagedQueryDao" ref="pagedDao" />
|
||||
<property name="itemService" ref="itemService" />
|
||||
</bean>
|
||||
|
||||
<bean id="klineService"
|
||||
class="project.data.internal.KlineServiceImpl">
|
||||
<property name="itemService" ref="itemService" />
|
||||
<property name="hobiDataService" ref="hobiDataService" />
|
||||
<property name="hibernateTemplate" ref="hibernateTemplate" />
|
||||
<property name="sysparaService" ref="sysparaService" />
|
||||
<property name="pagedQueryDao" ref="pagedDao" />
|
||||
<property name="namedParameterJdbcTemplate"
|
||||
ref="namedParameterJdbcTemplate" />
|
||||
</bean>
|
||||
|
||||
|
||||
<bean id="klineCacheJob" class="project.data.job.KlineCacheJob">
|
||||
<property name="itemService" ref="itemService" />
|
||||
<property name="hobiDataService" ref="hobiDataService" />
|
||||
</bean>
|
||||
|
||||
|
||||
|
||||
<bean id="dataServer" class="project.data.job.DataServer">
|
||||
<property name="hobiDataService" ref="hobiDataService" />
|
||||
<property name="taskExecutor" ref="dataServerThreadPool" />
|
||||
</bean>
|
||||
|
||||
<bean id="dataServerThreadPool"
|
||||
class="kernel.concurrent.ThreadPoolTaskExecutor">
|
||||
<property name="corePoolSize" value="1" />
|
||||
<property name="keepAliveSeconds" value="60" />
|
||||
<property name="maxPoolSize" value="2" />
|
||||
<property name="queueCapacity" value="50" />
|
||||
<property name="rejectedExecutionHandler"
|
||||
ref="dataServerThreadRejectExecutingHandler" />
|
||||
</bean>
|
||||
|
||||
<bean id="dataServerThreadRejectExecutingHandler"
|
||||
class="kernel.util.RejectExecutionHandlerDelegator">
|
||||
<property name="rejectExecutionHandlers">
|
||||
<list>
|
||||
|
||||
<bean
|
||||
class="project.data.job.OffLineEventRejectExecutingHandler" />
|
||||
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="saveRealtimeServer"
|
||||
class="project.data.job.SaveRealtimeServer">
|
||||
<property name="dataDBService" ref="dataDBService" />
|
||||
</bean>
|
||||
|
||||
<bean id="dataFrequencyServer"
|
||||
class="project.data.job.DataFrequencyServer">
|
||||
<property name="itemService" ref="itemService" />
|
||||
<property name="hobiDataService" ref="hobiDataService" />
|
||||
</bean>
|
||||
|
||||
<bean id="adjustmentValueService"
|
||||
class="project.data.internal.AdjustmentValueServiceImpl">
|
||||
<property name="hibernateTemplate" ref="hibernateTemplate" />
|
||||
<property name="dataService" ref="dataService" />
|
||||
<property name="itemService" ref="itemService" />
|
||||
</bean>
|
||||
|
||||
<dubbo:service
|
||||
interface="project.data.AdjustmentValueService"
|
||||
ref="adjustmentValueService" />
|
||||
|
||||
<bean id="dataService"
|
||||
class="project.data.internal.RemoteDataServiceImpl">
|
||||
<property name="hibernateTemplate" ref="hibernateTemplate" />
|
||||
<property name="itemService" ref="itemService" />
|
||||
<property name="sysparaService" ref="sysparaService" />
|
||||
<property name="klineService" ref="klineService" />
|
||||
</bean>
|
||||
|
||||
<dubbo:service interface="project.data.DataService"
|
||||
ref="dataService" />
|
||||
</beans>
|
||||
23
comm/Hobi/config/struts2.xml
Executable file
23
comm/Hobi/config/struts2.xml
Executable file
@@ -0,0 +1,23 @@
|
||||
|
||||
admin
|
||||
<action name="adminSymbolsAction"
|
||||
class="project.hobi.web.AdminSymbolsAction">
|
||||
<result name="list">/symbols_list.jsp</result>
|
||||
</action>
|
||||
<action name="adminContractSymbolsAction"
|
||||
class="project.hobi.web.AdminContractSymbolsAction">
|
||||
<result name="list">/contract_manage_add_symbols_list.jsp</result>
|
||||
</action>
|
||||
api
|
||||
|
||||
<action name="realtime" class="project.api.RealtimeAction">
|
||||
</action>
|
||||
|
||||
<action name="trend" class="project.api.TrendAction">
|
||||
</action>
|
||||
<action name="depth" class="project.api.DepthAction">
|
||||
</action>
|
||||
<action name="trade" class="project.api.TradeAction">
|
||||
</action>
|
||||
<action name="kline" class="project.api.KlineAction">
|
||||
</action>
|
||||
48
comm/Hobi/dbscript/1.1/HOBI-DDL-MYSQL.SQL
Executable file
48
comm/Hobi/dbscript/1.1/HOBI-DDL-MYSQL.SQL
Executable file
@@ -0,0 +1,48 @@
|
||||
DROP TABLE IF EXISTS `T_REALTIME`;
|
||||
CREATE TABLE `T_REALTIME` (
|
||||
`UUID` varchar(32) NOT NULL COMMENT '<27><><EFBFBD><EFBFBD>',
|
||||
`SYMBOL` varchar(32) COMMENT '<27><><EFBFBD><EFBFBD>',
|
||||
`TS` bigint ,
|
||||
`NAME` varchar(64) ,
|
||||
`OPEN` double ,
|
||||
`HIGH` double ,
|
||||
`LOW` double ,
|
||||
`CLOSE` double ,
|
||||
`AMOUNT` double ,
|
||||
`VOLUME` double ,
|
||||
PRIMARY KEY (`UUID`),
|
||||
KEY `INDEX_REALTIME_TS` (`TS`),
|
||||
KEY `INDEX_REALTIME_SYMBOL` (`SYMBOL`,`TS`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `T_KLINE`;
|
||||
CREATE TABLE `T_KLINE` (
|
||||
`UUID` varchar(32) NOT NULL COMMENT '<27><><EFBFBD><EFBFBD>',
|
||||
`SYMBOL` varchar(32) COMMENT '<27><><EFBFBD><EFBFBD>',
|
||||
`TS` bigint ,
|
||||
`OPEN` double ,
|
||||
`HIGH` double ,
|
||||
`LOW` double ,
|
||||
`CLOSE` double ,
|
||||
`AMOUNT` double ,
|
||||
`VOLUME` double ,
|
||||
`PERIOD` varchar(64) ,
|
||||
PRIMARY KEY (`UUID`),
|
||||
KEY `INDEX_KLINE_TS` (`TS`),
|
||||
KEY `INDEX_KLINE_SYMBOL` (`SYMBOL`,`TS`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
DROP TABLE IF EXISTS `T_SYMBOLS`;
|
||||
CREATE TABLE `T_SYMBOLS` (
|
||||
`UUID` varchar(32) NOT NULL ,
|
||||
`SYMBOL` varchar(32) ,
|
||||
`BASE_CURRENCY` varchar(32) ,
|
||||
`QUOTE_CURRENCY` varchar(32) ,
|
||||
`PRICE_PRECISION` int(11) ,
|
||||
`STATE` varchar(32) ,
|
||||
`LEVERAGE_RATIO` double ,
|
||||
PRIMARY KEY (`UUID`),
|
||||
KEY `INDEX_SYMBOLS_SYMBOL` (`SYMBOL`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
24
comm/Hobi/src/project/data/AdjustmentValueCache.java
Executable file
24
comm/Hobi/src/project/data/AdjustmentValueCache.java
Executable file
@@ -0,0 +1,24 @@
|
||||
package project.data;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class AdjustmentValueCache {
|
||||
/**
|
||||
* 当前值
|
||||
*/
|
||||
private static volatile Map<String, Double> currentValue = new ConcurrentHashMap();
|
||||
/**
|
||||
* 延时值
|
||||
*/
|
||||
private static volatile Map<String, AdjustmentValue> delayValue = new ConcurrentHashMap();
|
||||
|
||||
public static Map<String, Double> getCurrentValue() {
|
||||
return currentValue;
|
||||
}
|
||||
|
||||
public static Map<String, AdjustmentValue> getDelayValue() {
|
||||
return delayValue;
|
||||
}
|
||||
|
||||
}
|
||||
121
comm/Hobi/src/project/data/DataCache.java
Executable file
121
comm/Hobi/src/project/data/DataCache.java
Executable file
@@ -0,0 +1,121 @@
|
||||
package project.data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import kernel.util.StringUtils;
|
||||
import project.data.internal.DepthTimeObject;
|
||||
import project.data.internal.KlineTimeObject;
|
||||
import project.data.internal.TradeTimeObject;
|
||||
import project.data.internal.TrendTimeObject;
|
||||
import project.data.model.Kline;
|
||||
import project.data.model.Realtime;
|
||||
|
||||
public class DataCache {
|
||||
/**
|
||||
* 分时
|
||||
*/
|
||||
private volatile static Map<String, TrendTimeObject> trend = new ConcurrentHashMap<String, TrendTimeObject>();
|
||||
|
||||
/**
|
||||
* K线
|
||||
*/
|
||||
private volatile static Map<String, KlineTimeObject> kline = new ConcurrentHashMap<String, KlineTimeObject>();
|
||||
|
||||
/**
|
||||
* 实时数据
|
||||
*/
|
||||
private volatile static Map<String, Realtime> realtime = new ConcurrentHashMap<String, Realtime>();
|
||||
|
||||
/**
|
||||
* 实时历史数据
|
||||
*/
|
||||
private volatile static Map<String, List<Realtime>> realtimeHistory = new ConcurrentHashMap<String, List<Realtime>>();
|
||||
/**
|
||||
* 最高最低
|
||||
*/
|
||||
private volatile static Map<String, Double> realtimeHigh = new ConcurrentHashMap<String, Double>();
|
||||
private volatile static Map<String, Double> realtimeLow = new ConcurrentHashMap<String, Double>();
|
||||
/**
|
||||
* 向前24小时时间点的开盘价
|
||||
*/
|
||||
private volatile static Map<String, Double> realtime24HBeforeOpen = new ConcurrentHashMap<String, Double>();
|
||||
|
||||
/**
|
||||
* 市场深度数据
|
||||
*/
|
||||
private volatile static Map<String, DepthTimeObject> depth = new ConcurrentHashMap<String, DepthTimeObject>();
|
||||
|
||||
/**
|
||||
* 近期交易记录
|
||||
*/
|
||||
private volatile static Map<String, TradeTimeObject> trade = new ConcurrentHashMap<String, TradeTimeObject>();
|
||||
|
||||
private volatile static Map<String, Kline> kline_hobi = new ConcurrentHashMap<String, Kline>();
|
||||
|
||||
public static TrendTimeObject getTrend(String symbol) {
|
||||
return trend.get(symbol);
|
||||
}
|
||||
|
||||
public static void putTrend(String symbol, TrendTimeObject model) {
|
||||
trend.put(symbol, model);
|
||||
}
|
||||
|
||||
public static KlineTimeObject getKline(String symbol, String line) {
|
||||
String key = symbol;
|
||||
if (!StringUtils.isNullOrEmpty(line)) {
|
||||
key = key + "_" + line;
|
||||
}
|
||||
return kline.get(key);
|
||||
}
|
||||
|
||||
public static void putKline(String symbol, String line, KlineTimeObject model) {
|
||||
String key = symbol;
|
||||
if (!StringUtils.isNullOrEmpty(line)) {
|
||||
key = key + "_" + line;
|
||||
}
|
||||
kline.put(key, model);
|
||||
}
|
||||
|
||||
public static Realtime getRealtime(String symbol) {
|
||||
return realtime.get(symbol);
|
||||
}
|
||||
|
||||
public static void putRealtime(String symbol, Realtime model) {
|
||||
realtime.put(symbol, model);
|
||||
}
|
||||
|
||||
public static Map<String, List<Realtime>> getRealtimeHistory() {
|
||||
return realtimeHistory;
|
||||
}
|
||||
|
||||
public static void setRealtimeHistory(Map<String, List<Realtime>> realtimeHistory) {
|
||||
DataCache.realtimeHistory = realtimeHistory;
|
||||
}
|
||||
|
||||
public static Map<String, Double> getRealtimeHigh() {
|
||||
return realtimeHigh;
|
||||
}
|
||||
|
||||
public static Map<String, Double> getRealtimeLow() {
|
||||
return realtimeLow;
|
||||
}
|
||||
|
||||
public static Map<String, DepthTimeObject> getDepth() {
|
||||
return depth;
|
||||
}
|
||||
|
||||
public static Map<String, TradeTimeObject> getTrade() {
|
||||
return trade;
|
||||
}
|
||||
|
||||
public static Map<String, Kline> getKline_hobi() {
|
||||
return kline_hobi;
|
||||
}
|
||||
|
||||
public static Map<String, Double> getRealtime24HBeforeOpen() {
|
||||
return realtime24HBeforeOpen;
|
||||
}
|
||||
|
||||
}
|
||||
32
comm/Hobi/src/project/data/DataDBService.java
Executable file
32
comm/Hobi/src/project/data/DataDBService.java
Executable file
@@ -0,0 +1,32 @@
|
||||
package project.data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import project.data.model.Realtime;
|
||||
|
||||
public interface DataDBService {
|
||||
/**
|
||||
* 异步保存
|
||||
*/
|
||||
public void saveAsyn(Realtime entity);
|
||||
|
||||
/**
|
||||
* 数据库最新的实时价格
|
||||
*/
|
||||
public Realtime get(String symbol);
|
||||
|
||||
/**
|
||||
* 批量保存
|
||||
*/
|
||||
public void saveBatch(List<Realtime> entities);
|
||||
|
||||
public List<Realtime> findRealtimeOneDay(String symbol);
|
||||
|
||||
/**
|
||||
* 删除数据库里Realtime
|
||||
*/
|
||||
public void deleteRealtime(int days);
|
||||
|
||||
public void updateOptimize(String table);
|
||||
|
||||
}
|
||||
80
comm/Hobi/src/project/data/internal/AdjustmentValueServiceImpl.java
Executable file
80
comm/Hobi/src/project/data/internal/AdjustmentValueServiceImpl.java
Executable file
@@ -0,0 +1,80 @@
|
||||
package project.data.internal;
|
||||
|
||||
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
|
||||
|
||||
import kernel.exception.BusinessException;
|
||||
import kernel.util.Arith;
|
||||
import project.data.AdjustmentValue;
|
||||
import project.data.AdjustmentValueCache;
|
||||
import project.data.AdjustmentValueService;
|
||||
import project.data.DataService;
|
||||
import project.data.model.Realtime;
|
||||
import project.item.ItemService;
|
||||
import project.item.model.Item;
|
||||
|
||||
public class AdjustmentValueServiceImpl extends HibernateDaoSupport implements AdjustmentValueService {
|
||||
|
||||
private DataService dataService;
|
||||
private ItemService itemService;
|
||||
|
||||
public void adjust(String symbol, double value, double second) {
|
||||
if (value == 0.0D) {
|
||||
return;
|
||||
}
|
||||
|
||||
Realtime realtime = dataService.realtime(symbol).get(0);
|
||||
double new_price = realtime.getClose();
|
||||
double plus = Math.abs(value);
|
||||
if (Arith.div(plus, new_price) > 0.1D) {
|
||||
throw new BusinessException("调整偏差过大,超过10%");
|
||||
}
|
||||
|
||||
if (second <= 0) {
|
||||
/**
|
||||
* 即时生效
|
||||
*/
|
||||
|
||||
Double currentValue = AdjustmentValueCache.getCurrentValue().get(symbol);
|
||||
|
||||
if (currentValue == null) {
|
||||
AdjustmentValueCache.getCurrentValue().put(symbol, value);
|
||||
} else {
|
||||
AdjustmentValueCache.getCurrentValue().put(symbol, Arith.add(currentValue, value));
|
||||
}
|
||||
/*
|
||||
* 持久化缓存
|
||||
*/
|
||||
Item item = this.itemService.cacheBySymbol(symbol, false);
|
||||
if (item.getAdjustment_value() != AdjustmentValueCache.getCurrentValue().get(symbol)) {
|
||||
item.setAdjustment_value(AdjustmentValueCache.getCurrentValue().get(symbol));
|
||||
itemService.update(item);
|
||||
}
|
||||
|
||||
} else {
|
||||
AdjustmentValue adjustmentValue = new AdjustmentValue();
|
||||
adjustmentValue.setSymbol(symbol);
|
||||
adjustmentValue.setValue(value);
|
||||
adjustmentValue.setSecond(second);
|
||||
AdjustmentValueCache.getDelayValue().put(symbol, adjustmentValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getCurrentValue(String symbol) {
|
||||
return AdjustmentValueCache.getCurrentValue().get(symbol);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdjustmentValue getDelayValue(String symbol) {
|
||||
return AdjustmentValueCache.getDelayValue().get(symbol);
|
||||
}
|
||||
|
||||
public void setDataService(DataService dataService) {
|
||||
this.dataService = dataService;
|
||||
}
|
||||
|
||||
public void setItemService(ItemService itemService) {
|
||||
this.itemService = itemService;
|
||||
}
|
||||
|
||||
}
|
||||
156
comm/Hobi/src/project/data/internal/DataDBServiceImpl.java
Executable file
156
comm/Hobi/src/project/data/internal/DataDBServiceImpl.java
Executable file
@@ -0,0 +1,156 @@
|
||||
package project.data.internal;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
|
||||
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
|
||||
|
||||
import kernel.util.Arith;
|
||||
import kernel.util.DateUtils;
|
||||
import kernel.web.PagedQueryDao;
|
||||
import project.data.DataCache;
|
||||
import project.data.DataDBService;
|
||||
import project.data.job.RealtimeQueue;
|
||||
import project.data.model.Realtime;
|
||||
import project.item.ItemService;
|
||||
import project.item.model.Item;
|
||||
import project.syspara.SysparaService;
|
||||
|
||||
public class DataDBServiceImpl extends HibernateDaoSupport implements DataDBService {
|
||||
private NamedParameterJdbcOperations namedParameterJdbcTemplate;
|
||||
private SysparaService sysparaService;
|
||||
private PagedQueryDao pagedQueryDao;
|
||||
private ItemService itemService;
|
||||
|
||||
@Override
|
||||
public void saveAsyn(Realtime entity) {
|
||||
|
||||
Realtime current = DataCache.getRealtime(entity.getSymbol());
|
||||
if (current == null || current.getTs() != entity.getTs()) {
|
||||
|
||||
Item item = itemService.cacheBySymbol(entity.getSymbol(), true);
|
||||
/**
|
||||
* 交易量倍数不为空或0时修改倍数
|
||||
*/
|
||||
if (item.getMultiple() > 0) {
|
||||
entity.setVolume(Arith.mul(entity.getVolume(), item.getMultiple()));
|
||||
entity.setAmount(Arith.mul(entity.getAmount(), item.getMultiple()));
|
||||
}
|
||||
|
||||
Double high = DataCache.getRealtimeHigh().get(entity.getSymbol());
|
||||
if (high != null && high >= entity.getClose()) {
|
||||
entity.setHigh(high);
|
||||
}
|
||||
|
||||
|
||||
Double low = DataCache.getRealtimeLow().get(entity.getSymbol());
|
||||
if (low != null && low <= entity.getClose()) {
|
||||
entity.setLow(low);
|
||||
}
|
||||
|
||||
|
||||
Double h24Before = DataCache.getRealtime24HBeforeOpen().get(entity.getSymbol());
|
||||
if (h24Before != null) {
|
||||
entity.setOpen(h24Before);
|
||||
}
|
||||
|
||||
/**
|
||||
* 时间有变化,才保存
|
||||
*/
|
||||
DataCache.putRealtime(entity.getSymbol(), entity);
|
||||
List<Realtime> list = DataCache.getRealtimeHistory().get(entity.getSymbol());
|
||||
if (list == null) {
|
||||
list = new LinkedList<Realtime>();
|
||||
|
||||
}
|
||||
if (entity.getLow() > 0) {
|
||||
/**
|
||||
* 修正最低为0的BUG,直接丢弃
|
||||
*/
|
||||
list.add(entity);
|
||||
|
||||
DataCache.getRealtimeHistory().put(entity.getSymbol(), list);
|
||||
|
||||
RealtimeQueue.add(entity);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveBatch(List<Realtime> entities) {
|
||||
for (int i = 0; i < entities.size(); i++) {
|
||||
this.getHibernateTemplate().saveOrUpdate(entities.get(i));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Realtime get(String symbol) {
|
||||
StringBuffer queryString = new StringBuffer(" FROM Realtime where 1=1 ");
|
||||
Map<String, Object> parameters = new HashMap();
|
||||
queryString.append(" and symbol = :symbol ");
|
||||
parameters.put("symbol", symbol);
|
||||
List<Realtime> list = this.pagedQueryDao.pagedQueryHql(0, 1, queryString.toString(), parameters).getElements();
|
||||
if (list.size() > 0) {
|
||||
return list.get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void deleteRealtime(int days) {
|
||||
Map<String, Object> parameters = new HashMap();
|
||||
Long ts = DateUtils.addDate(new Date(), days).getTime();
|
||||
parameters.put("ts", ts);
|
||||
this.namedParameterJdbcTemplate.update("DELETE FROM T_REALTIME WHERE ts < :ts", parameters);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateOptimize(String table) {
|
||||
Map<String, Object> parameters = new HashMap();
|
||||
this.namedParameterJdbcTemplate.update("optimize table " + table, parameters);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Realtime> findRealtimeOneDay(String symbol) {
|
||||
int interval = this.sysparaService.find("data_interval").getInteger().intValue() / 1000;
|
||||
int num = (24 * 60 * 60) / interval;
|
||||
|
||||
StringBuffer queryString = new StringBuffer(" FROM Realtime WHERE 1=1 ");
|
||||
|
||||
Map<String, Object> parameters = new HashMap();
|
||||
queryString.append(" and symbol = :symbol ");
|
||||
parameters.put("symbol", symbol);
|
||||
|
||||
queryString.append(" order by ts asc");
|
||||
List<Realtime> list = this.pagedQueryDao.pagedQueryHql(0, num, queryString.toString(), parameters)
|
||||
.getElements();
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setNamedParameterJdbcTemplate(NamedParameterJdbcOperations namedParameterJdbcTemplate) {
|
||||
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
|
||||
}
|
||||
|
||||
public void setSysparaService(SysparaService sysparaService) {
|
||||
this.sysparaService = sysparaService;
|
||||
}
|
||||
|
||||
public void setPagedQueryDao(PagedQueryDao pagedQueryDao) {
|
||||
this.pagedQueryDao = pagedQueryDao;
|
||||
}
|
||||
|
||||
public void setItemService(ItemService itemService) {
|
||||
this.itemService = itemService;
|
||||
}
|
||||
|
||||
}
|
||||
175
comm/Hobi/src/project/data/internal/DataServiceImpl.java
Executable file
175
comm/Hobi/src/project/data/internal/DataServiceImpl.java
Executable file
@@ -0,0 +1,175 @@
|
||||
package project.data.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
|
||||
|
||||
import kernel.util.DateUtils;
|
||||
import project.data.DataService;
|
||||
import project.data.model.Depth;
|
||||
import project.data.model.Kline;
|
||||
import project.data.model.Realtime;
|
||||
import project.data.model.Trade;
|
||||
import project.data.model.Trend;
|
||||
import project.syspara.SysparaService;
|
||||
|
||||
public class DataServiceImpl extends HibernateDaoSupport implements DataService {
|
||||
private volatile static Map<String, TimeObject> cache = new ConcurrentHashMap<String, TimeObject>();
|
||||
private DataService remoteDataService;
|
||||
private SysparaService sysparaService;
|
||||
|
||||
/**
|
||||
* 行情实时价格
|
||||
*/
|
||||
@Override
|
||||
public List<Realtime> realtime(String symbol) {
|
||||
String key = "realtime_" + symbol;
|
||||
List<Realtime> list = new ArrayList<Realtime>();
|
||||
TimeObject timeObject = cache.get(key);
|
||||
if (isRemote(timeObject)) {
|
||||
list = remoteDataService.realtime(symbol);
|
||||
RealtimeTimeObject realtimeTimeObject = new RealtimeTimeObject();
|
||||
realtimeTimeObject.setLastTime(new Date());
|
||||
realtimeTimeObject.setList(list);
|
||||
cache.put(key, realtimeTimeObject);
|
||||
} else {
|
||||
list = ((RealtimeTimeObject) timeObject).getList();
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分时图
|
||||
*/
|
||||
@Override
|
||||
public List<Trend> trend(String symbol) {
|
||||
String key = "trend_" + symbol;
|
||||
List<Trend> list = new ArrayList<Trend>();
|
||||
TimeObject timeObject = cache.get(key);
|
||||
if (isRemote(timeObject)) {
|
||||
list = remoteDataService.trend(symbol);
|
||||
TrendTimeObject trendTimeObject = new TrendTimeObject();
|
||||
trendTimeObject.setLastTime(new Date());
|
||||
trendTimeObject.setTrend(list);
|
||||
cache.put(key, trendTimeObject);
|
||||
} else {
|
||||
list = ((TrendTimeObject) timeObject).getTrend();
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kline
|
||||
*/
|
||||
@Override
|
||||
public List<Kline> kline(String symbol, String line) {
|
||||
|
||||
String key = "kline_" + symbol + "_" + line;
|
||||
List<Kline> list = new ArrayList<Kline>();
|
||||
TimeObject timeObject = cache.get(key);
|
||||
if (isRemote(timeObject)) {
|
||||
list = remoteDataService.kline(symbol, line);
|
||||
Collections.sort(list); // 按时间升序
|
||||
KlineTimeObject klineTimeObject = new KlineTimeObject();
|
||||
klineTimeObject.setLastTime(new Date());
|
||||
klineTimeObject.setKline(list);
|
||||
cache.put(key, klineTimeObject);
|
||||
} else {
|
||||
list = ((KlineTimeObject) timeObject).getKline();
|
||||
}
|
||||
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 深度数据
|
||||
*/
|
||||
@Override
|
||||
public Depth depth(String symbol) {
|
||||
String key = "depth_" + symbol;
|
||||
Depth depth = new Depth();
|
||||
TimeObject timeObject = cache.get(key);
|
||||
if (isRemote(timeObject)) {
|
||||
depth = remoteDataService.depth(symbol);
|
||||
DepthTimeObject depthTimeObject = new DepthTimeObject();
|
||||
depthTimeObject.setLastTime(new Date());
|
||||
depthTimeObject.setDepth(depth);
|
||||
cache.put(key, depthTimeObject);
|
||||
} else {
|
||||
depth = ((DepthTimeObject) timeObject).getDepth();
|
||||
}
|
||||
|
||||
return depth;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 近期交易记录
|
||||
*/
|
||||
@Override
|
||||
public Trade trade(String symbol) {
|
||||
|
||||
String key = "trade_" + symbol;
|
||||
Trade trade = new Trade();
|
||||
TimeObject timeObject = cache.get(key);
|
||||
if (isRemote(timeObject)) {
|
||||
trade = remoteDataService.trade(symbol);
|
||||
if(trade!=null) {
|
||||
TradeTimeObject tradeTimeObject = new TradeTimeObject();
|
||||
tradeTimeObject.setLastTime(new Date());
|
||||
tradeTimeObject.put(symbol, trade.getData());
|
||||
cache.put(key, tradeTimeObject);
|
||||
}
|
||||
|
||||
} else {
|
||||
trade = ((TradeTimeObject) timeObject).getTrade();
|
||||
}
|
||||
|
||||
return trade;
|
||||
}
|
||||
|
||||
private boolean isRemote(TimeObject timeObject) {
|
||||
if (timeObject == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否远程 读取数据,先完成3秒过期。后期补上非开盘时间不调用。
|
||||
*/
|
||||
Date timestamps = timeObject.getLastTime();
|
||||
|
||||
/**
|
||||
* 数据超时时间
|
||||
*/
|
||||
// 15秒
|
||||
//默认3秒
|
||||
double huobi_data_timeout = Double.valueOf(sysparaService.find("symbol_data_timeout").getValue());
|
||||
|
||||
//int timeout = 3;
|
||||
|
||||
int timeout = (int) huobi_data_timeout;
|
||||
if (DateUtils.addSecond(timestamps, timeout).before(new Date())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setRemoteDataService(DataService remoteDataService) {
|
||||
this.remoteDataService = remoteDataService;
|
||||
}
|
||||
|
||||
public void setSysparaService(SysparaService sysparaService) {
|
||||
this.sysparaService = sysparaService;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
23
comm/Hobi/src/project/data/internal/DepthTimeObject.java
Executable file
23
comm/Hobi/src/project/data/internal/DepthTimeObject.java
Executable file
@@ -0,0 +1,23 @@
|
||||
package project.data.internal;
|
||||
|
||||
import project.data.model.Depth;
|
||||
|
||||
public class DepthTimeObject extends TimeObject {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -6508793344391115053L;
|
||||
|
||||
|
||||
private Depth depth;
|
||||
|
||||
|
||||
public Depth getDepth() {
|
||||
return depth;
|
||||
}
|
||||
|
||||
public void setDepth(Depth depth) {
|
||||
this.depth = depth;
|
||||
}
|
||||
|
||||
}
|
||||
24
comm/Hobi/src/project/data/internal/HighLow.java
Executable file
24
comm/Hobi/src/project/data/internal/HighLow.java
Executable file
@@ -0,0 +1,24 @@
|
||||
package project.data.internal;
|
||||
|
||||
public class HighLow {
|
||||
private Double high;
|
||||
|
||||
private Double low;
|
||||
|
||||
public Double getHigh() {
|
||||
return high;
|
||||
}
|
||||
|
||||
public void setHigh(Double high) {
|
||||
this.high = high;
|
||||
}
|
||||
|
||||
public Double getLow() {
|
||||
return low;
|
||||
}
|
||||
|
||||
public void setLow(Double low) {
|
||||
this.low = low;
|
||||
}
|
||||
|
||||
}
|
||||
117
comm/Hobi/src/project/data/internal/HighLowHandle.java
Executable file
117
comm/Hobi/src/project/data/internal/HighLowHandle.java
Executable file
@@ -0,0 +1,117 @@
|
||||
package project.data.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import kernel.util.DateUtils;
|
||||
import project.data.DataCache;
|
||||
import project.data.model.Kline;
|
||||
import project.data.model.Realtime;
|
||||
|
||||
public class HighLowHandle {
|
||||
|
||||
public static HighLow get(String symbol, int num, int interval) {
|
||||
List<Realtime> history = bulidNum(DataCache.getRealtimeHistory().get(symbol), num);
|
||||
HighLow highLow = new HighLow();
|
||||
if (history == null || history.size() == 0) {
|
||||
return highLow;
|
||||
|
||||
}
|
||||
Double high = null;
|
||||
|
||||
Double low = null;
|
||||
|
||||
for (int j = 0; j < history.size(); j++) {
|
||||
Realtime realtime = history.get(j);
|
||||
/**
|
||||
* 停机过久导致的处理
|
||||
*/
|
||||
if (realtime.getTs() < DateUtils.addSecond(new Date(), 0 - num * interval).getTime()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (high == null || high < realtime.getClose()) {
|
||||
high = realtime.getClose();
|
||||
}
|
||||
|
||||
if (low == null || low > realtime.getClose()) {
|
||||
low = realtime.getClose();
|
||||
}
|
||||
}
|
||||
|
||||
highLow.setHigh(high);
|
||||
highLow.setLow(low);
|
||||
|
||||
return highLow;
|
||||
|
||||
}
|
||||
|
||||
public static List<Realtime> bulidNum(List<Realtime> cacheList, int num) {
|
||||
List<Realtime> list = new ArrayList<Realtime>();
|
||||
if (cacheList == null) {
|
||||
return list;
|
||||
}
|
||||
if (num > cacheList.size()) {
|
||||
num = cacheList.size();
|
||||
}
|
||||
|
||||
for (int i = cacheList.size() - num; i < cacheList.size(); i++) {
|
||||
list.add(cacheList.get(i));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public static HighLow getByDay(String symbol, int num) {
|
||||
|
||||
KlineTimeObject timeObject = DataCache.getKline(symbol, Kline.PERIOD_1DAY);
|
||||
HighLow highLow = new HighLow();
|
||||
if (timeObject == null) {
|
||||
return highLow;
|
||||
}
|
||||
|
||||
List<Kline> list = timeObject.getKline();
|
||||
List<Kline> history = new ArrayList<Kline>();
|
||||
if (num > list.size()) {
|
||||
num = list.size();
|
||||
}
|
||||
|
||||
for (int i = list.size() - num; i < list.size(); i++) {
|
||||
history.add(list.get(i));
|
||||
}
|
||||
|
||||
if (history == null || history.size() == 0) {
|
||||
return highLow;
|
||||
|
||||
}
|
||||
Double high = null;
|
||||
|
||||
Double low = null;
|
||||
|
||||
for (int j = 0; j < history.size(); j++) {
|
||||
Kline kline = history.get(j);
|
||||
/**
|
||||
* 停机过久导致的处理
|
||||
*/
|
||||
if (kline.getTs() < DateUtils.addDay(new Date(), 0 - num).getTime()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (high == null || high < kline.getClose()) {
|
||||
high = kline.getClose();
|
||||
}
|
||||
|
||||
if (low == null || low > kline.getClose()) {
|
||||
low = kline.getClose();
|
||||
}
|
||||
}
|
||||
|
||||
highLow.setHigh(high);
|
||||
highLow.setLow(low);
|
||||
|
||||
return highLow;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
10
comm/Hobi/src/project/data/internal/KlineInitService.java
Executable file
10
comm/Hobi/src/project/data/internal/KlineInitService.java
Executable file
@@ -0,0 +1,10 @@
|
||||
package project.data.internal;
|
||||
|
||||
public interface KlineInitService {
|
||||
/**
|
||||
* 初始化K线数据,初始化前会删除旧数据
|
||||
*
|
||||
* @param symbol 指定产品代码,多个用逗号分割
|
||||
*/
|
||||
public void klineInit(String symbols);
|
||||
}
|
||||
53
comm/Hobi/src/project/data/internal/KlineInitServiceImpl.java
Executable file
53
comm/Hobi/src/project/data/internal/KlineInitServiceImpl.java
Executable file
@@ -0,0 +1,53 @@
|
||||
package project.data.internal;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import project.data.KlineService;
|
||||
|
||||
public class KlineInitServiceImpl implements KlineInitService {
|
||||
private Logger logger = LogManager.getLogger(this.getClass().getName());
|
||||
|
||||
private KlineService klineService;
|
||||
|
||||
@Override
|
||||
public void klineInit(String symbols) {
|
||||
|
||||
DelayThread lockDelayThread = new DelayThread(symbols, klineService);
|
||||
Thread t = new Thread(lockDelayThread);
|
||||
t.start();
|
||||
}
|
||||
|
||||
public class DelayThread implements Runnable {
|
||||
private KlineService klineService;
|
||||
private String symbol;
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
if (symbol.indexOf(",") == -1) {
|
||||
klineService.saveInit(symbol);
|
||||
} else {
|
||||
String[] symbols = symbol.split(",");
|
||||
for (int i = 0; i < symbols.length; i++) {
|
||||
klineService.saveInit(symbols[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("error:", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public DelayThread(String symbol, KlineService klineService) {
|
||||
this.symbol = symbol;
|
||||
this.klineService = klineService;
|
||||
}
|
||||
}
|
||||
|
||||
public void setKlineService(KlineService klineService) {
|
||||
this.klineService = klineService;
|
||||
}
|
||||
|
||||
}
|
||||
217
comm/Hobi/src/project/data/internal/KlineServiceImpl.java
Executable file
217
comm/Hobi/src/project/data/internal/KlineServiceImpl.java
Executable file
@@ -0,0 +1,217 @@
|
||||
package project.data.internal;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
|
||||
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
|
||||
|
||||
import kernel.util.DateUtils;
|
||||
import kernel.web.PagedQueryDao;
|
||||
import project.data.DataCache;
|
||||
import project.data.KlineService;
|
||||
import project.data.model.Kline;
|
||||
import project.data.model.Realtime;
|
||||
import project.hobi.HobiDataService;
|
||||
import project.item.ItemService;
|
||||
import project.syspara.SysparaService;
|
||||
|
||||
public class KlineServiceImpl extends HibernateDaoSupport implements KlineService {
|
||||
private Logger logger = LogManager.getLogger(this.getClass().getName());
|
||||
|
||||
private HobiDataService hobiDataService;
|
||||
private ItemService itemService;
|
||||
private PagedQueryDao pagedQueryDao;
|
||||
private SysparaService sysparaService;
|
||||
|
||||
private NamedParameterJdbcOperations namedParameterJdbcTemplate;
|
||||
|
||||
@Override
|
||||
public void saveInit(String symbol) {
|
||||
Map<String, Object> parameters = new HashMap();
|
||||
parameters.put("symbol", symbol);
|
||||
this.namedParameterJdbcTemplate.update("DELETE FROM T_KLINE WHERE SYMBOL = :symbol", parameters);
|
||||
|
||||
this.bulidInit(symbol, Kline.PERIOD_1MIN);
|
||||
this.bulidInit(symbol, Kline.PERIOD_5MIN);
|
||||
this.bulidInit(symbol, Kline.PERIOD_15MIN);
|
||||
this.bulidInit(symbol, Kline.PERIOD_30MIN);
|
||||
this.bulidInit(symbol, Kline.PERIOD_60MIN);
|
||||
this.bulidInit(symbol, Kline.PERIOD_4HOUR);
|
||||
this.bulidInit(symbol, Kline.PERIOD_1DAY);
|
||||
this.bulidInit(symbol, Kline.PERIOD_1MON);
|
||||
this.bulidInit(symbol, Kline.PERIOD_1WEEK);
|
||||
|
||||
}
|
||||
|
||||
public void bulidInit(String symbol, String line) {
|
||||
List<Kline> list = hobiDataService.kline(itemService.cacheBySymbol(symbol, true).getSymbol_data(), line, null,
|
||||
0);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
this.getHibernateTemplate().saveOrUpdate(list.get(i));
|
||||
}
|
||||
KlineTimeObject model = new KlineTimeObject();
|
||||
Collections.sort(list); // 按时间升序
|
||||
model.setKline(list);
|
||||
model.setLastTime(new Date());
|
||||
DataCache.putKline(symbol, line, model);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveOne(String symbol, String line) {
|
||||
Realtime realtime = DataCache.getRealtime(symbol);
|
||||
if (realtime == null) {
|
||||
logger.error("saveOne error, realtime is null,symbol [" + symbol + "]");
|
||||
return;
|
||||
}
|
||||
|
||||
Kline lastOne = null;
|
||||
|
||||
List<Kline> list = this.find(symbol, line, 1);
|
||||
if (list.size() > 0) {
|
||||
lastOne = list.get(0);
|
||||
}
|
||||
|
||||
String key = symbol + "_" + line;
|
||||
Kline hobiOne = DataCache.getKline_hobi().get(key);
|
||||
if (hobiOne == null || lastOne == null) {
|
||||
// 取不到远程数据,直接退出
|
||||
return;
|
||||
}
|
||||
|
||||
Kline kline = this.bulidKline(realtime, lastOne, hobiOne, line);
|
||||
|
||||
kline.setPeriod(line);
|
||||
this.getHibernateTemplate().save(kline);
|
||||
|
||||
KlineTimeObject timeObject = DataCache.getKline(symbol, line);
|
||||
if (timeObject == null) {
|
||||
timeObject = new KlineTimeObject();
|
||||
}
|
||||
timeObject.getKline().add(kline);
|
||||
timeObject.setLastTime(new Date());
|
||||
DataCache.putKline(symbol, line, timeObject);
|
||||
}
|
||||
|
||||
public Kline bulidKline(Realtime realtime, Kline lastOne, Kline hobiOne, String line) {
|
||||
Kline kline = new Kline();
|
||||
kline.setSymbol(realtime.getSymbol());
|
||||
kline.setTs(realtime.getTs());
|
||||
kline.setOpen(realtime.getOpen());
|
||||
kline.setHigh(realtime.getHigh());
|
||||
kline.setLow(realtime.getLow());
|
||||
kline.setClose(realtime.getClose());
|
||||
/**
|
||||
* 新传回来的volume是固定的 需要除以Arith.div(realtime.getVolume(), 倍数)
|
||||
*/
|
||||
kline.setVolume(realtime.getVolume());
|
||||
|
||||
if (lastOne != null) {
|
||||
kline.setOpen(lastOne.getClose());
|
||||
}
|
||||
int interval = this.sysparaService.find("data_interval").getInteger().intValue() / 1000;
|
||||
|
||||
HighLow highLow = null;
|
||||
switch (line) {
|
||||
case "1min":
|
||||
highLow = HighLowHandle.get(realtime.getSymbol(), (60) / interval, interval);
|
||||
break;
|
||||
|
||||
case "5min":
|
||||
highLow = HighLowHandle.get(realtime.getSymbol(), (60 * 5) / interval, interval);
|
||||
break;
|
||||
case "15min":
|
||||
highLow = HighLowHandle.get(realtime.getSymbol(), (60 * 15) / interval, interval);
|
||||
break;
|
||||
case "30min":
|
||||
highLow = HighLowHandle.get(realtime.getSymbol(), (60 * 30) / interval, interval);
|
||||
break;
|
||||
|
||||
case "60min":
|
||||
highLow = HighLowHandle.get(realtime.getSymbol(), (60 * 60) / interval, interval);
|
||||
break;
|
||||
|
||||
case "4hour":
|
||||
highLow = HighLowHandle.get(realtime.getSymbol(), (60 * 60 * 4) / interval, interval);
|
||||
break;
|
||||
case "1day":
|
||||
highLow = HighLowHandle.get(realtime.getSymbol(), (60 * 60 * 24) / interval, interval);
|
||||
break;
|
||||
|
||||
case Kline.PERIOD_1WEEK:
|
||||
highLow = HighLowHandle.getByDay(realtime.getSymbol(), 7);
|
||||
break;
|
||||
|
||||
case Kline.PERIOD_1MON:
|
||||
highLow = HighLowHandle.getByDay(realtime.getSymbol(), 30);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (highLow != null && highLow.getHigh() != null) {
|
||||
kline.setHigh(highLow.getHigh());
|
||||
}
|
||||
if (highLow != null && highLow.getLow() != null) {
|
||||
kline.setLow(highLow.getLow());
|
||||
}
|
||||
|
||||
kline.setVolume(hobiOne.getVolume());
|
||||
|
||||
return kline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Kline> find(String symbol, String line, int pageSize) {
|
||||
|
||||
StringBuffer queryString = new StringBuffer(" FROM Kline WHERE 1=1 ");
|
||||
|
||||
Map<String, Object> parameters = new HashMap();
|
||||
queryString.append(" and symbol = :symbol ");
|
||||
parameters.put("symbol", symbol);
|
||||
|
||||
queryString.append(" and period = :period ");
|
||||
parameters.put("period", line);
|
||||
|
||||
queryString.append(" order by ts DESC ");
|
||||
List<Kline> list = this.pagedQueryDao.pagedQueryHql(0, pageSize, queryString.toString(), parameters)
|
||||
.getElements();
|
||||
Collections.sort(list); // 按时间升序
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(String line, int days) {
|
||||
Map<String, Object> parameters = new HashMap();
|
||||
Long ts = DateUtils.addDate(new Date(), days).getTime();
|
||||
parameters.put("line", line);
|
||||
parameters.put("ts", ts);
|
||||
this.namedParameterJdbcTemplate.update("DELETE FROM T_KLINE WHERE PERIOD=:line AND TS < :ts", parameters);
|
||||
|
||||
}
|
||||
|
||||
public void setHobiDataService(HobiDataService hobiDataService) {
|
||||
this.hobiDataService = hobiDataService;
|
||||
}
|
||||
|
||||
public void setItemService(ItemService itemService) {
|
||||
this.itemService = itemService;
|
||||
}
|
||||
|
||||
public void setPagedQueryDao(PagedQueryDao pagedQueryDao) {
|
||||
this.pagedQueryDao = pagedQueryDao;
|
||||
}
|
||||
|
||||
public void setSysparaService(SysparaService sysparaService) {
|
||||
this.sysparaService = sysparaService;
|
||||
}
|
||||
|
||||
public void setNamedParameterJdbcTemplate(NamedParameterJdbcOperations namedParameterJdbcTemplate) {
|
||||
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
|
||||
}
|
||||
|
||||
}
|
||||
33
comm/Hobi/src/project/data/internal/KlineTimeObject.java
Executable file
33
comm/Hobi/src/project/data/internal/KlineTimeObject.java
Executable file
@@ -0,0 +1,33 @@
|
||||
package project.data.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import project.data.model.Kline;
|
||||
|
||||
public class KlineTimeObject extends TimeObject {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -5777137609729197999L;
|
||||
|
||||
|
||||
private List<Kline> kline=new ArrayList<Kline>();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return the kline
|
||||
*/
|
||||
public List<Kline> getKline() {
|
||||
return kline;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param kline the kline to set
|
||||
*/
|
||||
public void setKline(List<Kline> kline) {
|
||||
this.kline = kline;
|
||||
}
|
||||
|
||||
}
|
||||
22
comm/Hobi/src/project/data/internal/RealtimeTimeObject.java
Executable file
22
comm/Hobi/src/project/data/internal/RealtimeTimeObject.java
Executable file
@@ -0,0 +1,22 @@
|
||||
package project.data.internal;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import project.data.model.Realtime;
|
||||
|
||||
public class RealtimeTimeObject extends TimeObject{
|
||||
|
||||
private static final long serialVersionUID = -597193064229646966L;
|
||||
|
||||
List<Realtime> list;
|
||||
|
||||
public List<Realtime> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<Realtime> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
352
comm/Hobi/src/project/data/internal/RemoteDataServiceImpl.java
Executable file
352
comm/Hobi/src/project/data/internal/RemoteDataServiceImpl.java
Executable file
@@ -0,0 +1,352 @@
|
||||
package project.data.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
|
||||
|
||||
import kernel.util.DateUtils;
|
||||
import project.data.DataCache;
|
||||
import project.data.DataService;
|
||||
import project.data.KlineService;
|
||||
import project.data.job.DataQueue;
|
||||
import project.data.job.HandleObject;
|
||||
import project.data.model.Depth;
|
||||
import project.data.model.Kline;
|
||||
import project.data.model.Realtime;
|
||||
import project.data.model.Trade;
|
||||
import project.data.model.Trend;
|
||||
import project.item.ItemService;
|
||||
import project.item.model.Item;
|
||||
import project.syspara.SysparaService;
|
||||
|
||||
public class RemoteDataServiceImpl extends HibernateDaoSupport implements DataService {
|
||||
|
||||
private ItemService itemService;
|
||||
|
||||
private SysparaService sysparaService;
|
||||
|
||||
private KlineService klineService;
|
||||
|
||||
@Override
|
||||
public List<Realtime> realtime(String symbol) {
|
||||
List<Realtime> list = new ArrayList<Realtime>();
|
||||
if (symbol.indexOf(",") == -1) {
|
||||
/**
|
||||
* 单个symbol
|
||||
*/
|
||||
Realtime realtime = DataCache.getRealtime(symbol);
|
||||
|
||||
if (realtime != null) {
|
||||
list.add(realtime);
|
||||
}
|
||||
|
||||
} else {
|
||||
/**
|
||||
* 多个symbol,用逗号分隔
|
||||
*/
|
||||
String[] symbols = symbol.split(",");
|
||||
for (int i = 0; i < symbols.length; i++) {
|
||||
String split = symbols[i];
|
||||
Realtime realtime = DataCache.getRealtime(split);
|
||||
|
||||
if (realtime != null) {
|
||||
list.add(realtime);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Trend> trend(String symbol) {
|
||||
TrendTimeObject trendTimeObject = DataCache.getTrend(symbol);
|
||||
trendTimeObject = this.loadTrend(symbol, trendTimeObject);
|
||||
if (trendTimeObject != null) {
|
||||
return trendTimeObject.getTrend();
|
||||
}
|
||||
return new ArrayList<Trend>();
|
||||
}
|
||||
|
||||
private TrendTimeObject loadTrend(String symbol, TrendTimeObject trendTimeObject) {
|
||||
|
||||
Item item = itemService.cacheBySymbol(symbol, true);
|
||||
|
||||
if (trendTimeObject == null || isRemoteTrend(item, trendTimeObject)) {
|
||||
/**
|
||||
* 秒
|
||||
*/
|
||||
int interval = this.sysparaService.find("data_interval").getInteger().intValue() / 1000;
|
||||
int num = (24 * 60 * 60) / interval;
|
||||
List<Trend> list = new ArrayList<Trend>();
|
||||
/**
|
||||
* 24小时的历史记录
|
||||
*/
|
||||
List<Realtime> history = bulidNum(DataCache.getRealtimeHistory().get(symbol), num);
|
||||
|
||||
history = this.take500(history);
|
||||
|
||||
if (history.size() > 500) {
|
||||
Collections.sort(history); // 按时间升序
|
||||
List<Realtime> history_500 = new ArrayList<Realtime>();
|
||||
for (int i = 0; i < 500; i++) {
|
||||
history_500.add(history.get(i));
|
||||
}
|
||||
history = history_500;
|
||||
}
|
||||
|
||||
for (int i = 0; i < history.size(); i++) {
|
||||
Realtime realtime = history.get(i);
|
||||
Trend trend = bulidTrend(realtime);
|
||||
list.add(trend);
|
||||
}
|
||||
Realtime realtime_last = DataCache.getRealtime(symbol);
|
||||
if (realtime_last != null) {
|
||||
list.add(bulidTrend(DataCache.getRealtime(symbol)));
|
||||
}
|
||||
|
||||
trendTimeObject = new TrendTimeObject();
|
||||
trendTimeObject.setTrend(list);
|
||||
trendTimeObject.setLastTime(new Date());
|
||||
DataCache.putTrend(symbol, trendTimeObject);
|
||||
}
|
||||
|
||||
return trendTimeObject;
|
||||
|
||||
}
|
||||
|
||||
private Trend bulidTrend(Realtime realtime) {
|
||||
Trend trend = new Trend();
|
||||
trend.setSymbol(realtime.getSymbol());
|
||||
trend.setTs(realtime.getTs());
|
||||
trend.setTrend(realtime.getClose());
|
||||
trend.setVolume(realtime.getVolume());
|
||||
trend.setAmount(realtime.getAmount());
|
||||
|
||||
return trend;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按平均频率取500个数据点
|
||||
*/
|
||||
private List<Realtime> take500(List<Realtime> history) {
|
||||
List<Realtime> list = new ArrayList<Realtime>();
|
||||
|
||||
int num = history.size() / 500;
|
||||
|
||||
if (num <= 0) {
|
||||
return history;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
while (true) {
|
||||
if (num >= 1.0D) {
|
||||
if (i % num == 0) {
|
||||
list.add(history.get(i));
|
||||
}
|
||||
} else {
|
||||
list.add(history.get(i));
|
||||
}
|
||||
|
||||
i++;
|
||||
if (i >= history.size()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private boolean isRemoteTrend(Item item, TrendTimeObject timeObject) {
|
||||
|
||||
/**
|
||||
* 判断是否远程 读取数据,先完成3秒过期。后期补上非开盘时间不调用。
|
||||
*/
|
||||
Date timestamps = timeObject.getLastTime();
|
||||
/**
|
||||
* 数据超时时间
|
||||
*/
|
||||
int timeout = 3;
|
||||
if (DateUtils.addSecond(timestamps, timeout).before(new Date())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private List<Realtime> bulidNum(List<Realtime> cacheList, int num) {
|
||||
List<Realtime> list = new ArrayList<Realtime>();
|
||||
if (cacheList == null) {
|
||||
return list;
|
||||
}
|
||||
if (num > cacheList.size()) {
|
||||
num = cacheList.size();
|
||||
}
|
||||
|
||||
for (int i = cacheList.size() - num; i < cacheList.size(); i++) {
|
||||
list.add(cacheList.get(i));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Kline> kline(String symbol, String line) {
|
||||
KlineTimeObject timeObject = DataCache.getKline(symbol, line);
|
||||
List<Kline> list = new ArrayList<Kline>();
|
||||
if (timeObject != null) {
|
||||
list = timeObject.getKline();
|
||||
}
|
||||
List<Kline> list_clone = new ArrayList<Kline>();
|
||||
try {
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Kline kline = (Kline) list.get(i).clone();
|
||||
list_clone.add(kline);
|
||||
}
|
||||
} catch (CloneNotSupportedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Realtime realtime = DataCache.getRealtime(symbol);
|
||||
Kline hobiOne = DataCache.getKline_hobi().get(symbol + "_" + line);
|
||||
|
||||
Kline lastOne = null;
|
||||
if (list != null && list.size() > 0) {
|
||||
lastOne = list.get(list.size() - 1);
|
||||
}
|
||||
if (realtime != null && hobiOne != null && lastOne != null) {
|
||||
list_clone.add(this.klineService.bulidKline(realtime, lastOne, hobiOne, line));
|
||||
}
|
||||
Collections.sort(list_clone); // 按时间升序
|
||||
return list_clone;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Depth depth(String symbol) {
|
||||
DepthTimeObject timeObject = DataCache.getDepth().get(symbol);
|
||||
this.loadDepth(symbol, timeObject);
|
||||
if (timeObject != null) {
|
||||
return timeObject.getDepth();
|
||||
}
|
||||
timeObject = new DepthTimeObject();
|
||||
Depth depth = new Depth();
|
||||
timeObject.setLastTime(new Date());
|
||||
timeObject.setDepth(depth);
|
||||
DataCache.getDepth().put(symbol, timeObject);
|
||||
return depth;
|
||||
|
||||
}
|
||||
|
||||
private void loadDepth(String symbol, DepthTimeObject timeObject) {
|
||||
|
||||
Item item = itemService.cacheBySymbol(symbol, true);
|
||||
|
||||
if (timeObject == null) {
|
||||
|
||||
HandleObject handleObject = new HandleObject();
|
||||
handleObject.setType(HandleObject.type_depth);
|
||||
handleObject.setItem(item);
|
||||
DataQueue.add(handleObject);
|
||||
|
||||
} else {
|
||||
if (isRemoteDepth(item, timeObject)) {
|
||||
HandleObject handleObject = new HandleObject();
|
||||
handleObject.setType(HandleObject.type_depth);
|
||||
handleObject.setItem(item);
|
||||
DataQueue.add(handleObject);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isRemoteDepth(Item item, DepthTimeObject timeObject) {
|
||||
|
||||
// 判断是否远程 读取数据,先完成3秒过期。后期补上非开盘时间不调用。
|
||||
Date timestamps = timeObject.getLastTime();
|
||||
|
||||
// 数据超时时间
|
||||
int timeout = 15;
|
||||
if (DateUtils.addSecond(timestamps, timeout).before(new Date())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 近期交易记录
|
||||
*/
|
||||
@Override
|
||||
public Trade trade(String symbol) {
|
||||
|
||||
TradeTimeObject timeObject = DataCache.getTrade().get(symbol);
|
||||
this.loadTrade(symbol, timeObject);
|
||||
if (timeObject != null) {
|
||||
return timeObject.getTrade();
|
||||
}
|
||||
|
||||
timeObject = new TradeTimeObject();
|
||||
timeObject.setLastTime(new Date());
|
||||
DataCache.getTrade().put(symbol, timeObject);
|
||||
return timeObject.getTrade();
|
||||
}
|
||||
|
||||
private void loadTrade(String symbol, TradeTimeObject timeObject) {
|
||||
|
||||
Item item = itemService.cacheBySymbol(symbol, true);
|
||||
|
||||
if (timeObject == null) {
|
||||
|
||||
HandleObject handleObject = new HandleObject();
|
||||
handleObject.setType(HandleObject.type_trade);
|
||||
handleObject.setItem(item);
|
||||
DataQueue.add(handleObject);
|
||||
|
||||
} else {
|
||||
if (isRemoteTrade(item, timeObject)) {
|
||||
HandleObject handleObject = new HandleObject();
|
||||
handleObject.setType(HandleObject.type_trade);
|
||||
handleObject.setItem(item);
|
||||
DataQueue.add(handleObject);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isRemoteTrade(Item item, TradeTimeObject timeObject) {
|
||||
|
||||
/**
|
||||
* 判断是否远程 读取数据,先完成3秒过期。后期补上非开盘时间不调用。
|
||||
*/
|
||||
Date timestamps = timeObject.getLastTime();
|
||||
|
||||
/**
|
||||
* 数据超时时间
|
||||
*/
|
||||
// 15秒
|
||||
int timeout = 15;
|
||||
if (DateUtils.addSecond(timestamps, timeout).before(new Date())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setItemService(ItemService itemService) {
|
||||
this.itemService = itemService;
|
||||
}
|
||||
|
||||
public void setSysparaService(SysparaService sysparaService) {
|
||||
this.sysparaService = sysparaService;
|
||||
}
|
||||
|
||||
public void setKlineService(KlineService klineService) {
|
||||
this.klineService = klineService;
|
||||
}
|
||||
|
||||
}
|
||||
23
comm/Hobi/src/project/data/internal/TimeObject.java
Executable file
23
comm/Hobi/src/project/data/internal/TimeObject.java
Executable file
@@ -0,0 +1,23 @@
|
||||
package project.data.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
public abstract class TimeObject implements Serializable {
|
||||
private static final long serialVersionUID = -7709770878909783696L;
|
||||
|
||||
/**
|
||||
* 最后读取远程数据时间
|
||||
*/
|
||||
private Date lastTime;
|
||||
|
||||
public Date getLastTime() {
|
||||
return lastTime;
|
||||
}
|
||||
|
||||
public void setLastTime(Date lastTime) {
|
||||
this.lastTime = lastTime;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
47
comm/Hobi/src/project/data/internal/TradeTimeObject.java
Executable file
47
comm/Hobi/src/project/data/internal/TradeTimeObject.java
Executable file
@@ -0,0 +1,47 @@
|
||||
package project.data.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import project.data.model.Trade;
|
||||
import project.data.model.TradeEntry;
|
||||
|
||||
public class TradeTimeObject extends TimeObject {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -8540786365761455345L;
|
||||
|
||||
|
||||
private Trade trade;
|
||||
|
||||
public void put(String symbol, List<TradeEntry> data) {
|
||||
if (trade == null) {
|
||||
trade = new Trade();
|
||||
trade.setSymbol(symbol);
|
||||
}
|
||||
|
||||
trade.getData().addAll(data);
|
||||
Collections.sort(trade.getData());
|
||||
|
||||
if (trade.getData().size() > 50) {
|
||||
List<TradeEntry> data_50 = new ArrayList<TradeEntry>();
|
||||
for (int i = 0; i < 50; i++) {
|
||||
data_50.add(trade.getData().get(i));
|
||||
}
|
||||
trade.setData(data_50);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Trade getTrade() {
|
||||
return trade;
|
||||
}
|
||||
|
||||
}
|
||||
25
comm/Hobi/src/project/data/internal/TrendTimeObject.java
Executable file
25
comm/Hobi/src/project/data/internal/TrendTimeObject.java
Executable file
@@ -0,0 +1,25 @@
|
||||
package project.data.internal;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import project.data.model.Trend;
|
||||
|
||||
public class TrendTimeObject extends TimeObject {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -4078190280148061255L;
|
||||
|
||||
|
||||
private List<Trend> trend;
|
||||
|
||||
|
||||
public List<Trend> getTrend() {
|
||||
return trend;
|
||||
}
|
||||
|
||||
public void setTrend(List<Trend> trend) {
|
||||
this.trend = trend;
|
||||
}
|
||||
|
||||
}
|
||||
76
comm/Hobi/src/project/data/job/CleanDataJob.java
Executable file
76
comm/Hobi/src/project/data/job/CleanDataJob.java
Executable file
@@ -0,0 +1,76 @@
|
||||
package project.data.job;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import kernel.util.ThreadUtils;
|
||||
import project.data.DataCache;
|
||||
import project.data.DataDBService;
|
||||
import project.data.KlineService;
|
||||
import project.data.model.Kline;
|
||||
import project.data.model.Realtime;
|
||||
import project.item.ItemService;
|
||||
import project.item.model.Item;
|
||||
|
||||
public class CleanDataJob {
|
||||
private DataDBService dataDBService;
|
||||
private ItemService itemService;
|
||||
|
||||
private KlineService klineService;
|
||||
|
||||
public void taskJob() {
|
||||
/**
|
||||
* 删除过期数据
|
||||
*/
|
||||
this.dataDBService.deleteRealtime(-1);
|
||||
this.dataDBService.updateOptimize("T_REALTIME");
|
||||
|
||||
this.klineService.delete(Kline.PERIOD_1MIN, -1);
|
||||
this.klineService.delete(Kline.PERIOD_5MIN, -2);
|
||||
this.klineService.delete(Kline.PERIOD_15MIN, -6);
|
||||
this.klineService.delete(Kline.PERIOD_30MIN, -12);
|
||||
this.klineService.delete(Kline.PERIOD_60MIN, -24);
|
||||
this.klineService.delete(Kline.PERIOD_4HOUR, -96);
|
||||
|
||||
this.dataDBService.updateOptimize("T_KLINE");
|
||||
|
||||
ThreadUtils.sleep(1000);
|
||||
|
||||
/**
|
||||
* 重置实时数据历史缓存
|
||||
*/
|
||||
List<Item> item_list = itemService.cacheGetAll();
|
||||
for (int i = 0; i < item_list.size(); i++) {
|
||||
Item item = item_list.get(i);
|
||||
List<Realtime> list = this.dataDBService.findRealtimeOneDay(item.getSymbol());
|
||||
DataCache.getRealtimeHistory().put(item.getSymbol(), list);
|
||||
|
||||
DataCache.getKline(item.getSymbol(), Kline.PERIOD_1MIN)
|
||||
.setKline(this.klineService.find(item.getSymbol(), Kline.PERIOD_1MIN, Integer.MAX_VALUE));
|
||||
DataCache.getKline(item.getSymbol(), Kline.PERIOD_5MIN)
|
||||
.setKline(this.klineService.find(item.getSymbol(), Kline.PERIOD_5MIN, Integer.MAX_VALUE));
|
||||
DataCache.getKline(item.getSymbol(), Kline.PERIOD_15MIN)
|
||||
.setKline(this.klineService.find(item.getSymbol(), Kline.PERIOD_15MIN, Integer.MAX_VALUE));
|
||||
DataCache.getKline(item.getSymbol(), Kline.PERIOD_30MIN)
|
||||
.setKline(this.klineService.find(item.getSymbol(), Kline.PERIOD_30MIN, Integer.MAX_VALUE));
|
||||
DataCache.getKline(item.getSymbol(), Kline.PERIOD_60MIN)
|
||||
.setKline(this.klineService.find(item.getSymbol(), Kline.PERIOD_60MIN, Integer.MAX_VALUE));
|
||||
DataCache.getKline(item.getSymbol(), Kline.PERIOD_4HOUR)
|
||||
.setKline(this.klineService.find(item.getSymbol(), Kline.PERIOD_4HOUR, Integer.MAX_VALUE));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setItemService(ItemService itemService) {
|
||||
this.itemService = itemService;
|
||||
}
|
||||
|
||||
public void setDataDBService(DataDBService dataDBService) {
|
||||
this.dataDBService = dataDBService;
|
||||
}
|
||||
|
||||
public void setKlineService(KlineService klineService) {
|
||||
this.klineService = klineService;
|
||||
}
|
||||
|
||||
}
|
||||
74
comm/Hobi/src/project/data/job/DataFrequencyServer.java
Executable file
74
comm/Hobi/src/project/data/job/DataFrequencyServer.java
Executable file
@@ -0,0 +1,74 @@
|
||||
package project.data.job;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import kernel.util.ThreadUtils;
|
||||
import project.data.DataCache;
|
||||
import project.data.internal.TradeTimeObject;
|
||||
import project.data.model.Trade;
|
||||
import project.hobi.HobiDataService;
|
||||
import project.item.ItemService;
|
||||
import project.item.model.Item;
|
||||
|
||||
public class DataFrequencyServer implements Runnable {
|
||||
private Logger logger = LogManager.getLogger(this.getClass().getName());
|
||||
private HobiDataService hobiDataService;
|
||||
private ItemService itemService;
|
||||
|
||||
public void start() {
|
||||
new Thread(this, "DataFrequencyServer").start();
|
||||
if (logger.isInfoEnabled())
|
||||
logger.info("启动DataFrequencyServer!");
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while (true) {
|
||||
try {
|
||||
List<Item> item_list = itemService.cacheGetAll();
|
||||
for (int i = 0; i < item_list.size(); i++) {
|
||||
try {
|
||||
Item item = item_list.get(i);
|
||||
this.trade(item);
|
||||
} catch (Exception e) {
|
||||
logger.error("trade fail", e);
|
||||
} finally {
|
||||
ThreadUtils.sleep(3000);
|
||||
}
|
||||
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
logger.error("DataFrequencyServer fail", e);
|
||||
} finally {
|
||||
ThreadUtils.sleep(1000 * 10);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void trade(Item item) {
|
||||
|
||||
Trade trade = hobiDataService.tradeDecorator(item.getSymbol_data(), 0);
|
||||
if (trade != null) {
|
||||
TradeTimeObject timeObject = DataCache.getTrade().get(item.getSymbol());
|
||||
if (timeObject == null) {
|
||||
timeObject = new TradeTimeObject();
|
||||
}
|
||||
timeObject.setLastTime(new Date());
|
||||
timeObject.put(item.getSymbol(), trade.getData());
|
||||
DataCache.getTrade().put(item.getSymbol(), timeObject);
|
||||
}
|
||||
}
|
||||
|
||||
public void setHobiDataService(HobiDataService hobiDataService) {
|
||||
this.hobiDataService = hobiDataService;
|
||||
}
|
||||
|
||||
public void setItemService(ItemService itemService) {
|
||||
this.itemService = itemService;
|
||||
}
|
||||
|
||||
}
|
||||
26
comm/Hobi/src/project/data/job/DataQueue.java
Executable file
26
comm/Hobi/src/project/data/job/DataQueue.java
Executable file
@@ -0,0 +1,26 @@
|
||||
package project.data.job;
|
||||
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public class DataQueue {
|
||||
|
||||
private static ConcurrentLinkedQueue<HandleObject> WORKING_EVENTS = new ConcurrentLinkedQueue<HandleObject>();
|
||||
|
||||
public static void add(HandleObject event) {
|
||||
try {
|
||||
WORKING_EVENTS.add(event);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static HandleObject poll() {
|
||||
HandleObject event = null;
|
||||
try {
|
||||
event = WORKING_EVENTS.poll();
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return event;
|
||||
}
|
||||
}
|
||||
110
comm/Hobi/src/project/data/job/DataServer.java
Executable file
110
comm/Hobi/src/project/data/job/DataServer.java
Executable file
@@ -0,0 +1,110 @@
|
||||
package project.data.job;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
|
||||
import kernel.util.ThreadUtils;
|
||||
import project.data.DataCache;
|
||||
import project.data.internal.DepthTimeObject;
|
||||
import project.data.internal.TradeTimeObject;
|
||||
import project.data.model.Depth;
|
||||
import project.data.model.Trade;
|
||||
import project.hobi.HobiDataService;
|
||||
import project.item.model.Item;
|
||||
|
||||
public class DataServer implements Runnable {
|
||||
private Logger logger = LogManager.getLogger(this.getClass().getName());
|
||||
private HobiDataService hobiDataService;
|
||||
|
||||
private TaskExecutor taskExecutor;
|
||||
|
||||
public void start() {
|
||||
new Thread(this, "DataServer").start();
|
||||
if (logger.isInfoEnabled())
|
||||
logger.info("启动DataServer!");
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
|
||||
HandleObject handleObject = DataQueue.poll();
|
||||
|
||||
if (handleObject != null) {
|
||||
this.taskExecutor.execute(new HandleRunner(handleObject, handleObject.getType()));
|
||||
} else {
|
||||
ThreadUtils.sleep(50);
|
||||
}
|
||||
|
||||
} catch (Throwable e) {
|
||||
logger.error("DataServer taskExecutor.execute() fail", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class HandleRunner implements Runnable {
|
||||
private String type;
|
||||
private HandleObject handle;
|
||||
|
||||
public HandleRunner(HandleObject handle, String type) {
|
||||
this.handle = handle;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
if (HandleObject.type_depth.equals(type)) {
|
||||
depth(handle);
|
||||
} else if (HandleObject.type_trade.equals(type)) {
|
||||
trade(handle);
|
||||
}
|
||||
|
||||
} catch (Throwable t) {
|
||||
logger.error("HandleRunner run fail ", t);
|
||||
}
|
||||
}
|
||||
|
||||
private void depth(HandleObject handle) {
|
||||
Item item = handle.getItem();
|
||||
Depth depth = hobiDataService.depthDecorator(item.getSymbol_data(), 0);
|
||||
if (depth != null) {
|
||||
DepthTimeObject timeObject = new DepthTimeObject();
|
||||
timeObject.setLastTime(new Date());
|
||||
|
||||
timeObject.setDepth(depth);
|
||||
DataCache.getDepth().put(item.getSymbol(), timeObject);
|
||||
}
|
||||
}
|
||||
|
||||
private void trade(HandleObject handle) {
|
||||
Item item = handle.getItem();
|
||||
Trade trade = hobiDataService.tradeDecorator(item.getSymbol_data(), 0);
|
||||
|
||||
if (trade != null) {
|
||||
TradeTimeObject timeObject = DataCache.getTrade().get(item.getSymbol());
|
||||
if (timeObject == null) {
|
||||
timeObject = new TradeTimeObject();
|
||||
}
|
||||
timeObject.setLastTime(new Date());
|
||||
|
||||
timeObject.put(item.getSymbol(), trade.getData());
|
||||
|
||||
DataCache.getTrade().put(item.getSymbol(), timeObject);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setTaskExecutor(TaskExecutor taskExecutor) {
|
||||
this.taskExecutor = taskExecutor;
|
||||
}
|
||||
|
||||
public void setHobiDataService(HobiDataService hobiDataService) {
|
||||
this.hobiDataService = hobiDataService;
|
||||
}
|
||||
|
||||
}
|
||||
160
comm/Hobi/src/project/data/job/GetDataJob.java
Executable file
160
comm/Hobi/src/project/data/job/GetDataJob.java
Executable file
@@ -0,0 +1,160 @@
|
||||
package project.data.job;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import kernel.util.Arith;
|
||||
import kernel.util.ThreadUtils;
|
||||
import project.data.AdjustmentValue;
|
||||
import project.data.AdjustmentValueCache;
|
||||
import project.data.DataCache;
|
||||
import project.data.DataDBService;
|
||||
import project.data.model.Realtime;
|
||||
import project.hobi.HobiDataService;
|
||||
import project.item.ItemService;
|
||||
import project.item.model.Item;
|
||||
import project.syspara.SysparaService;
|
||||
|
||||
public class GetDataJob implements Runnable {
|
||||
|
||||
private Logger logger = LogManager.getLogger(this.getClass().getName());
|
||||
/**
|
||||
* 数据接口调用间隔时长(毫秒)
|
||||
*/
|
||||
private int interval;
|
||||
public static boolean first = true;
|
||||
private SysparaService sysparaService;
|
||||
|
||||
private DataDBService dataDBService;
|
||||
|
||||
private HobiDataService hobiDataService;
|
||||
private ItemService itemService;
|
||||
|
||||
public void run() {
|
||||
|
||||
if (first) {
|
||||
/**
|
||||
* data数据保存间隔时长(毫秒)
|
||||
*/
|
||||
this.interval = this.sysparaService.find("data_interval").getInteger().intValue();
|
||||
|
||||
first = false;
|
||||
}
|
||||
while (true) {
|
||||
try {
|
||||
this.realtimeHandle();
|
||||
} catch (Exception e) {
|
||||
logger.error("run fail", e);
|
||||
} finally {
|
||||
ThreadUtils.sleep(this.interval);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void realtimeHandle() {
|
||||
/**
|
||||
* 取到数据
|
||||
*/
|
||||
List<Realtime> realtime_list = this.hobiDataService.realtime(0);
|
||||
for (int i = 0; i < realtime_list.size(); i++) {
|
||||
try {
|
||||
Realtime realtime = realtime_list.get(i);
|
||||
String symbol = realtime.getSymbol();
|
||||
|
||||
Double currentValue = AdjustmentValueCache.getCurrentValue().get(symbol);
|
||||
|
||||
AdjustmentValue delayValue = AdjustmentValueCache.getDelayValue().get(symbol);
|
||||
|
||||
if (delayValue != null) {
|
||||
/**
|
||||
* 延时几次
|
||||
*/
|
||||
double frequency = Arith.div(Arith.mul(delayValue.getSecond(), 1000.0D), this.interval);
|
||||
|
||||
if (frequency <= 1.0D) {
|
||||
if (currentValue == null) {
|
||||
AdjustmentValueCache.getCurrentValue().put(symbol, delayValue.getValue());
|
||||
} else {
|
||||
AdjustmentValueCache.getCurrentValue().put(symbol,
|
||||
Arith.add(delayValue.getValue(), currentValue));
|
||||
}
|
||||
Item item = this.itemService.cacheBySymbol(symbol, false);
|
||||
if (item.getAdjustment_value() != AdjustmentValueCache.getCurrentValue().get(symbol)) {
|
||||
item.setAdjustment_value(AdjustmentValueCache.getCurrentValue().get(symbol));
|
||||
itemService.update(item);
|
||||
}
|
||||
AdjustmentValueCache.getDelayValue().remove(symbol);
|
||||
} else {
|
||||
/**
|
||||
* 本次调整值
|
||||
*/
|
||||
double currentValue_frequency = Arith.div(delayValue.getValue(), frequency);
|
||||
|
||||
if (currentValue == null) {
|
||||
AdjustmentValueCache.getCurrentValue().put(symbol, currentValue_frequency);
|
||||
} else {
|
||||
AdjustmentValueCache.getCurrentValue().put(symbol,
|
||||
Arith.add(currentValue, currentValue_frequency));
|
||||
}
|
||||
|
||||
delayValue.setValue(Arith.sub(delayValue.getValue(), currentValue_frequency));
|
||||
delayValue.setSecond(Arith.sub(delayValue.getSecond(), Arith.div(this.interval, 1000.0D)));
|
||||
AdjustmentValueCache.getDelayValue().put(symbol, delayValue);
|
||||
|
||||
Item item = this.itemService.cacheBySymbol(symbol, false);
|
||||
if (item.getAdjustment_value() != AdjustmentValueCache.getCurrentValue().get(symbol)) {
|
||||
item.setAdjustment_value(AdjustmentValueCache.getCurrentValue().get(symbol));
|
||||
itemService.update(item);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
currentValue = AdjustmentValueCache.getCurrentValue().get(realtime.getSymbol());
|
||||
|
||||
if (currentValue != null && currentValue != 0) {
|
||||
realtime.setClose(Arith.add(realtime.getClose(), currentValue));
|
||||
realtime.setVolume(Arith.add(realtime.getVolume(),
|
||||
Arith.mul(Arith.div(currentValue, realtime.getClose()), realtime.getVolume())));
|
||||
realtime.setAmount(Arith.add(realtime.getAmount(),
|
||||
Arith.mul(Arith.div(currentValue, realtime.getClose()), realtime.getAmount())));
|
||||
|
||||
}
|
||||
|
||||
Double high = DataCache.getRealtimeHigh().get(symbol);
|
||||
Double low = DataCache.getRealtimeLow().get(symbol);
|
||||
|
||||
if (high == null || realtime.getClose() > high) {
|
||||
DataCache.getRealtimeHigh().put(symbol, realtime.getClose());
|
||||
}
|
||||
if ((low == null || realtime.getClose() < low) && realtime.getClose() > 0) {
|
||||
DataCache.getRealtimeLow().put(symbol, realtime.getClose());
|
||||
}
|
||||
|
||||
this.dataDBService.saveAsyn(realtime);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void setSysparaService(SysparaService sysparaService) {
|
||||
this.sysparaService = sysparaService;
|
||||
}
|
||||
|
||||
public void setDataDBService(DataDBService dataDBService) {
|
||||
this.dataDBService = dataDBService;
|
||||
}
|
||||
|
||||
public void setHobiDataService(HobiDataService hobiDataService) {
|
||||
this.hobiDataService = hobiDataService;
|
||||
}
|
||||
|
||||
public void setItemService(ItemService itemService) {
|
||||
this.itemService = itemService;
|
||||
}
|
||||
|
||||
}
|
||||
33
comm/Hobi/src/project/data/job/HandleObject.java
Executable file
33
comm/Hobi/src/project/data/job/HandleObject.java
Executable file
@@ -0,0 +1,33 @@
|
||||
package project.data.job;
|
||||
|
||||
import project.item.model.Item;
|
||||
|
||||
public class HandleObject {
|
||||
|
||||
public static String type_depth = "depth";
|
||||
public static String type_trade = "trade";
|
||||
/**
|
||||
*/
|
||||
private String type;
|
||||
private Item item;
|
||||
|
||||
/**
|
||||
* K线图的参数line
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Item getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
public void setItem(Item item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
}
|
||||
129
comm/Hobi/src/project/data/job/HighLowHandleJob.java
Executable file
129
comm/Hobi/src/project/data/job/HighLowHandleJob.java
Executable file
@@ -0,0 +1,129 @@
|
||||
package project.data.job;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import kernel.util.ThreadUtils;
|
||||
import project.data.DataCache;
|
||||
import project.data.model.Realtime;
|
||||
import project.item.ItemService;
|
||||
import project.item.model.Item;
|
||||
import project.syspara.SysparaService;
|
||||
|
||||
/**
|
||||
* 最高最低修正
|
||||
*
|
||||
*/
|
||||
public class HighLowHandleJob implements Runnable {
|
||||
private Logger logger = LogManager.getLogger(this.getClass().getName());
|
||||
private SysparaService sysparaService;
|
||||
private ItemService itemService;
|
||||
/**
|
||||
* 数据接口调用间隔时长(毫秒)
|
||||
*/
|
||||
private int interval;
|
||||
public static boolean first = true;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
ThreadUtils.sleep(1000 * 60 * 3);
|
||||
while (true) {
|
||||
bulidHighLow();
|
||||
ThreadUtils.sleep(1000 * 60 * 3);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void bulidHighLow() {
|
||||
try {
|
||||
|
||||
if (first) {
|
||||
/**
|
||||
* data数据保存间隔时长(毫秒)
|
||||
*/
|
||||
this.interval = this.sysparaService.find("data_interval").getInteger().intValue() / 1000;
|
||||
first = false;
|
||||
}
|
||||
/**
|
||||
* 秒
|
||||
*/
|
||||
int num = (24 * 60 * 60) / this.interval;
|
||||
List<Item> item_list = itemService.cacheGetAll();
|
||||
for (int i = 0; i < item_list.size(); i++) {
|
||||
Item item = item_list.get(i);
|
||||
try {
|
||||
|
||||
/**
|
||||
* 24小时的历史记录
|
||||
*/
|
||||
List<Realtime> history = bulidNum(DataCache.getRealtimeHistory().get(item.getSymbol()), num);
|
||||
if (history == null || history.size() == 0) {
|
||||
continue;
|
||||
}
|
||||
Double high = null;
|
||||
|
||||
Double low = null;
|
||||
|
||||
for (int j = 0; j < history.size(); j++) {
|
||||
Realtime realtime = history.get(j);
|
||||
|
||||
if (high == null || high < realtime.getClose()) {
|
||||
high = realtime.getClose();
|
||||
}
|
||||
|
||||
if ((low == null || low > realtime.getClose()) && realtime.getClose() > 0) {
|
||||
low = realtime.getClose();
|
||||
}
|
||||
}
|
||||
if (item == null || item.getSymbol() == null) {
|
||||
logger.error("run fail");
|
||||
}
|
||||
if (high != null) {
|
||||
DataCache.getRealtimeHigh().put(item.getSymbol(), high);
|
||||
}
|
||||
if (low != null && low > 0) {
|
||||
DataCache.getRealtimeLow().put(item.getSymbol(), low);
|
||||
}
|
||||
|
||||
Collections.sort(history);
|
||||
DataCache.getRealtime24HBeforeOpen().put(item.getSymbol(), history.get(0).getClose());
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("run fail", e);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("run fail", e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Realtime> bulidNum(List<Realtime> cacheList, int num) {
|
||||
List<Realtime> list = new ArrayList<Realtime>();
|
||||
if (cacheList == null) {
|
||||
return list;
|
||||
}
|
||||
if (num > cacheList.size()) {
|
||||
num = cacheList.size();
|
||||
}
|
||||
|
||||
for (int i = cacheList.size() - num; i < cacheList.size(); i++) {
|
||||
list.add(cacheList.get(i));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setSysparaService(SysparaService sysparaService) {
|
||||
this.sysparaService = sysparaService;
|
||||
}
|
||||
|
||||
public void setItemService(ItemService itemService) {
|
||||
this.itemService = itemService;
|
||||
}
|
||||
|
||||
}
|
||||
73
comm/Hobi/src/project/data/job/KlineCacheJob.java
Executable file
73
comm/Hobi/src/project/data/job/KlineCacheJob.java
Executable file
@@ -0,0 +1,73 @@
|
||||
package project.data.job;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import kernel.util.ThreadUtils;
|
||||
import project.data.DataCache;
|
||||
import project.data.model.Kline;
|
||||
import project.hobi.HobiDataService;
|
||||
import project.item.ItemService;
|
||||
import project.item.model.Item;
|
||||
|
||||
public class KlineCacheJob implements Runnable {
|
||||
|
||||
private Logger logger = LogManager.getLogger(this.getClass().getName());
|
||||
private HobiDataService hobiDataService;
|
||||
private ItemService itemService;
|
||||
|
||||
public void start() {
|
||||
new Thread(this, "KlineCacheJob").start();
|
||||
if (logger.isInfoEnabled())
|
||||
logger.info("启动KlineCacheJob!");
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while (true) {
|
||||
try {
|
||||
List<Item> item_list = itemService.cacheGetAll();
|
||||
for (int i = 0; i < item_list.size(); i++) {
|
||||
Item item = item_list.get(i);
|
||||
|
||||
this.addCache(item, Kline.PERIOD_1MIN);
|
||||
this.addCache(item, Kline.PERIOD_5MIN);
|
||||
this.addCache(item, Kline.PERIOD_15MIN);
|
||||
this.addCache(item, Kline.PERIOD_30MIN);
|
||||
this.addCache(item, Kline.PERIOD_60MIN);
|
||||
this.addCache(item, Kline.PERIOD_4HOUR);
|
||||
this.addCache(item, Kline.PERIOD_1DAY);
|
||||
this.addCache(item, Kline.PERIOD_1MON);
|
||||
this.addCache(item, Kline.PERIOD_1WEEK);
|
||||
|
||||
}
|
||||
|
||||
} catch (Throwable e) {
|
||||
logger.error("KlineCacheJob fail", e);
|
||||
} finally {
|
||||
ThreadUtils.sleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void addCache(Item item, String line) {
|
||||
List<Kline> hobikline_list = hobiDataService.kline(item.getSymbol_data(), line, 1, 0);
|
||||
if (hobikline_list != null && hobikline_list.size() > 0) {
|
||||
|
||||
String key = item.getSymbol() + "_" + line;
|
||||
DataCache.getKline_hobi().put(key, hobikline_list.get(0));
|
||||
}
|
||||
ThreadUtils.sleep(2000);
|
||||
}
|
||||
|
||||
public void setHobiDataService(HobiDataService hobiDataService) {
|
||||
this.hobiDataService = hobiDataService;
|
||||
}
|
||||
|
||||
public void setItemService(ItemService itemService) {
|
||||
this.itemService = itemService;
|
||||
}
|
||||
|
||||
}
|
||||
9
comm/Hobi/src/project/data/job/OffLineEventRejectExecutingHandler.java
Executable file
9
comm/Hobi/src/project/data/job/OffLineEventRejectExecutingHandler.java
Executable file
@@ -0,0 +1,9 @@
|
||||
package project.data.job;
|
||||
|
||||
import java.util.concurrent.RejectedExecutionHandler;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
public class OffLineEventRejectExecutingHandler implements RejectedExecutionHandler {
|
||||
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
|
||||
}
|
||||
}
|
||||
38
comm/Hobi/src/project/data/job/RealtimeQueue.java
Executable file
38
comm/Hobi/src/project/data/job/RealtimeQueue.java
Executable file
@@ -0,0 +1,38 @@
|
||||
package project.data.job;
|
||||
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import project.data.model.Realtime;
|
||||
|
||||
public class RealtimeQueue {
|
||||
private static Logger logger = LogManager.getLogger(RealtimeQueue.class);
|
||||
|
||||
private static ConcurrentLinkedQueue<Realtime> WORKING_EVENTS = new ConcurrentLinkedQueue<Realtime>();
|
||||
|
||||
public static void add(Realtime item) {
|
||||
Assert.notNull(item, "The item must not be null.");
|
||||
try {
|
||||
WORKING_EVENTS.add(item);
|
||||
} catch (Throwable e) {
|
||||
logger.error("add() fail : ", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static int size() {
|
||||
return WORKING_EVENTS.size();
|
||||
}
|
||||
|
||||
public static Realtime poll() {
|
||||
Realtime item = null;
|
||||
try {
|
||||
item = WORKING_EVENTS.poll();
|
||||
} catch (Throwable e) {
|
||||
logger.error("poll() fail : ", e);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
55
comm/Hobi/src/project/data/job/SaveRealtimeServer.java
Executable file
55
comm/Hobi/src/project/data/job/SaveRealtimeServer.java
Executable file
@@ -0,0 +1,55 @@
|
||||
package project.data.job;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import kernel.util.ThreadUtils;
|
||||
import project.data.DataDBService;
|
||||
import project.data.model.Realtime;
|
||||
|
||||
public class SaveRealtimeServer implements Runnable {
|
||||
private Logger logger = LogManager.getLogger(this.getClass().getName());
|
||||
private DataDBService dataDBService;
|
||||
|
||||
public void start() {
|
||||
new Thread(this, "SaveRealtimeServer").start();
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("启动SaveRealtimeServer!");
|
||||
}
|
||||
|
||||
}
|
||||
public void run() {
|
||||
while (true) {
|
||||
try {
|
||||
int size = RealtimeQueue.size();
|
||||
/**
|
||||
* 现量轮询一圈
|
||||
*/
|
||||
List<Realtime> list = new ArrayList<Realtime>();
|
||||
for (int i = 0; i < size; i++) {
|
||||
Realtime item = RealtimeQueue.poll();
|
||||
list.add(item);
|
||||
|
||||
}
|
||||
if (list.size() > 0) {
|
||||
dataDBService.saveBatch(list);
|
||||
}
|
||||
|
||||
} catch (Throwable e) {
|
||||
logger.error(" run fail", e);
|
||||
} finally {
|
||||
ThreadUtils.sleep(60 * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setDataDBService(DataDBService dataDBService) {
|
||||
this.dataDBService = dataDBService;
|
||||
}
|
||||
|
||||
}
|
||||
33
comm/Hobi/src/project/data/klinejob/Kline15MinuteJob.java
Executable file
33
comm/Hobi/src/project/data/klinejob/Kline15MinuteJob.java
Executable file
@@ -0,0 +1,33 @@
|
||||
package project.data.klinejob;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import project.data.KlineService;
|
||||
import project.data.model.Kline;
|
||||
import project.item.ItemService;
|
||||
import project.item.model.Item;
|
||||
|
||||
/**
|
||||
* 15分钟K线
|
||||
*/
|
||||
public class Kline15MinuteJob {
|
||||
private KlineService klineService;
|
||||
private ItemService itemService;
|
||||
|
||||
public void taskJob() {
|
||||
List<Item> item_list = itemService.cacheGetAll();
|
||||
for (int i = 0; i < item_list.size(); i++) {
|
||||
Item item = item_list.get(i);
|
||||
klineService.saveOne(item.getSymbol(), Kline.PERIOD_15MIN);
|
||||
}
|
||||
}
|
||||
|
||||
public void setKlineService(KlineService klineService) {
|
||||
this.klineService = klineService;
|
||||
}
|
||||
|
||||
public void setItemService(ItemService itemService) {
|
||||
this.itemService = itemService;
|
||||
}
|
||||
|
||||
}
|
||||
33
comm/Hobi/src/project/data/klinejob/Kline1DayJob.java
Executable file
33
comm/Hobi/src/project/data/klinejob/Kline1DayJob.java
Executable file
@@ -0,0 +1,33 @@
|
||||
package project.data.klinejob;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import project.data.KlineService;
|
||||
import project.data.model.Kline;
|
||||
import project.item.ItemService;
|
||||
import project.item.model.Item;
|
||||
|
||||
/**
|
||||
* 1天K线
|
||||
*/
|
||||
public class Kline1DayJob {
|
||||
private KlineService klineService;
|
||||
private ItemService itemService;
|
||||
|
||||
public void taskJob() {
|
||||
List<Item> item_list = itemService.cacheGetAll();
|
||||
for (int i = 0; i < item_list.size(); i++) {
|
||||
Item item = item_list.get(i);
|
||||
klineService.saveOne(item.getSymbol(), Kline.PERIOD_1DAY);
|
||||
}
|
||||
}
|
||||
|
||||
public void setKlineService(KlineService klineService) {
|
||||
this.klineService = klineService;
|
||||
}
|
||||
|
||||
public void setItemService(ItemService itemService) {
|
||||
this.itemService = itemService;
|
||||
}
|
||||
|
||||
}
|
||||
33
comm/Hobi/src/project/data/klinejob/Kline1MinuteJob.java
Executable file
33
comm/Hobi/src/project/data/klinejob/Kline1MinuteJob.java
Executable file
@@ -0,0 +1,33 @@
|
||||
package project.data.klinejob;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import project.data.KlineService;
|
||||
import project.data.model.Kline;
|
||||
import project.item.ItemService;
|
||||
import project.item.model.Item;
|
||||
|
||||
/**
|
||||
* 1分钟K线
|
||||
*/
|
||||
public class Kline1MinuteJob {
|
||||
private KlineService klineService;
|
||||
private ItemService itemService;
|
||||
|
||||
public void taskJob() {
|
||||
List<Item> item_list = itemService.cacheGetAll();
|
||||
for (int i = 0; i < item_list.size(); i++) {
|
||||
Item item = item_list.get(i);
|
||||
klineService.saveOne(item.getSymbol(), Kline.PERIOD_1MIN);
|
||||
}
|
||||
}
|
||||
|
||||
public void setKlineService(KlineService klineService) {
|
||||
this.klineService = klineService;
|
||||
}
|
||||
|
||||
public void setItemService(ItemService itemService) {
|
||||
this.itemService = itemService;
|
||||
}
|
||||
|
||||
}
|
||||
33
comm/Hobi/src/project/data/klinejob/Kline1MonJob.java
Executable file
33
comm/Hobi/src/project/data/klinejob/Kline1MonJob.java
Executable file
@@ -0,0 +1,33 @@
|
||||
package project.data.klinejob;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import project.data.KlineService;
|
||||
import project.data.model.Kline;
|
||||
import project.item.ItemService;
|
||||
import project.item.model.Item;
|
||||
|
||||
/**
|
||||
* 1个月K线
|
||||
*/
|
||||
public class Kline1MonJob {
|
||||
private KlineService klineService;
|
||||
private ItemService itemService;
|
||||
|
||||
public void taskJob() {
|
||||
List<Item> item_list = itemService.cacheGetAll();
|
||||
for (int i = 0; i < item_list.size(); i++) {
|
||||
Item item = item_list.get(i);
|
||||
klineService.saveOne(item.getSymbol(), Kline.PERIOD_1MON);
|
||||
}
|
||||
}
|
||||
|
||||
public void setKlineService(KlineService klineService) {
|
||||
this.klineService = klineService;
|
||||
}
|
||||
|
||||
public void setItemService(ItemService itemService) {
|
||||
this.itemService = itemService;
|
||||
}
|
||||
|
||||
}
|
||||
33
comm/Hobi/src/project/data/klinejob/Kline1WeekJob.java
Executable file
33
comm/Hobi/src/project/data/klinejob/Kline1WeekJob.java
Executable file
@@ -0,0 +1,33 @@
|
||||
package project.data.klinejob;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import project.data.KlineService;
|
||||
import project.data.model.Kline;
|
||||
import project.item.ItemService;
|
||||
import project.item.model.Item;
|
||||
|
||||
/**
|
||||
* 1周K线
|
||||
*/
|
||||
public class Kline1WeekJob {
|
||||
private KlineService klineService;
|
||||
private ItemService itemService;
|
||||
|
||||
public void taskJob() {
|
||||
List<Item> item_list = itemService.cacheGetAll();
|
||||
for (int i = 0; i < item_list.size(); i++) {
|
||||
Item item = item_list.get(i);
|
||||
klineService.saveOne(item.getSymbol(), Kline.PERIOD_1WEEK);
|
||||
}
|
||||
}
|
||||
|
||||
public void setKlineService(KlineService klineService) {
|
||||
this.klineService = klineService;
|
||||
}
|
||||
|
||||
public void setItemService(ItemService itemService) {
|
||||
this.itemService = itemService;
|
||||
}
|
||||
|
||||
}
|
||||
33
comm/Hobi/src/project/data/klinejob/Kline30MinuteJob.java
Executable file
33
comm/Hobi/src/project/data/klinejob/Kline30MinuteJob.java
Executable file
@@ -0,0 +1,33 @@
|
||||
package project.data.klinejob;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import project.data.KlineService;
|
||||
import project.data.model.Kline;
|
||||
import project.item.ItemService;
|
||||
import project.item.model.Item;
|
||||
|
||||
/**
|
||||
* 30分钟K线
|
||||
*/
|
||||
public class Kline30MinuteJob {
|
||||
private KlineService klineService;
|
||||
private ItemService itemService;
|
||||
|
||||
public void taskJob() {
|
||||
List<Item> item_list = itemService.cacheGetAll();
|
||||
for (int i = 0; i < item_list.size(); i++) {
|
||||
Item item = item_list.get(i);
|
||||
klineService.saveOne(item.getSymbol(), Kline.PERIOD_30MIN);
|
||||
}
|
||||
}
|
||||
|
||||
public void setKlineService(KlineService klineService) {
|
||||
this.klineService = klineService;
|
||||
}
|
||||
|
||||
public void setItemService(ItemService itemService) {
|
||||
this.itemService = itemService;
|
||||
}
|
||||
|
||||
}
|
||||
33
comm/Hobi/src/project/data/klinejob/Kline4HourJob.java
Executable file
33
comm/Hobi/src/project/data/klinejob/Kline4HourJob.java
Executable file
@@ -0,0 +1,33 @@
|
||||
package project.data.klinejob;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import project.data.KlineService;
|
||||
import project.data.model.Kline;
|
||||
import project.item.ItemService;
|
||||
import project.item.model.Item;
|
||||
|
||||
/**
|
||||
* 4小时K线
|
||||
*/
|
||||
public class Kline4HourJob {
|
||||
private KlineService klineService;
|
||||
private ItemService itemService;
|
||||
|
||||
public void taskJob() {
|
||||
List<Item> item_list = itemService.cacheGetAll();
|
||||
for (int i = 0; i < item_list.size(); i++) {
|
||||
Item item = item_list.get(i);
|
||||
klineService.saveOne(item.getSymbol(), Kline.PERIOD_4HOUR);
|
||||
}
|
||||
}
|
||||
|
||||
public void setKlineService(KlineService klineService) {
|
||||
this.klineService = klineService;
|
||||
}
|
||||
|
||||
public void setItemService(ItemService itemService) {
|
||||
this.itemService = itemService;
|
||||
}
|
||||
|
||||
}
|
||||
33
comm/Hobi/src/project/data/klinejob/Kline5MinuteJob.java
Executable file
33
comm/Hobi/src/project/data/klinejob/Kline5MinuteJob.java
Executable file
@@ -0,0 +1,33 @@
|
||||
package project.data.klinejob;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import project.data.KlineService;
|
||||
import project.data.model.Kline;
|
||||
import project.item.ItemService;
|
||||
import project.item.model.Item;
|
||||
|
||||
/**
|
||||
* 5分钟K线
|
||||
*/
|
||||
public class Kline5MinuteJob {
|
||||
private KlineService klineService;
|
||||
private ItemService itemService;
|
||||
|
||||
public void taskJob() {
|
||||
List<Item> item_list = itemService.cacheGetAll();
|
||||
for (int i = 0; i < item_list.size(); i++) {
|
||||
Item item = item_list.get(i);
|
||||
klineService.saveOne(item.getSymbol(), Kline.PERIOD_5MIN);
|
||||
}
|
||||
}
|
||||
|
||||
public void setKlineService(KlineService klineService) {
|
||||
this.klineService = klineService;
|
||||
}
|
||||
|
||||
public void setItemService(ItemService itemService) {
|
||||
this.itemService = itemService;
|
||||
}
|
||||
|
||||
}
|
||||
33
comm/Hobi/src/project/data/klinejob/Kline60MinuteJob.java
Executable file
33
comm/Hobi/src/project/data/klinejob/Kline60MinuteJob.java
Executable file
@@ -0,0 +1,33 @@
|
||||
package project.data.klinejob;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import project.data.KlineService;
|
||||
import project.data.model.Kline;
|
||||
import project.item.ItemService;
|
||||
import project.item.model.Item;
|
||||
|
||||
/**
|
||||
* 60分钟K线
|
||||
*/
|
||||
public class Kline60MinuteJob {
|
||||
private KlineService klineService;
|
||||
private ItemService itemService;
|
||||
|
||||
public void taskJob() {
|
||||
List<Item> item_list = itemService.cacheGetAll();
|
||||
for (int i = 0; i < item_list.size(); i++) {
|
||||
Item item = item_list.get(i);
|
||||
klineService.saveOne(item.getSymbol(), Kline.PERIOD_60MIN);
|
||||
}
|
||||
}
|
||||
|
||||
public void setKlineService(KlineService klineService) {
|
||||
this.klineService = klineService;
|
||||
}
|
||||
|
||||
public void setItemService(ItemService itemService) {
|
||||
this.itemService = itemService;
|
||||
}
|
||||
|
||||
}
|
||||
67
comm/Hobi/src/project/data/model/Depth.java
Executable file
67
comm/Hobi/src/project/data/model/Depth.java
Executable file
@@ -0,0 +1,67 @@
|
||||
package project.data.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 市场深度数据
|
||||
*
|
||||
*/
|
||||
public class Depth implements Serializable {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -6927860235289172991L;
|
||||
|
||||
/**
|
||||
* 产品代码
|
||||
*/
|
||||
private String symbol;
|
||||
|
||||
/**
|
||||
* 时间戳
|
||||
*/
|
||||
private Long ts;
|
||||
/**
|
||||
* 买单
|
||||
*/
|
||||
private List<DepthEntry> bids = new ArrayList<DepthEntry>();
|
||||
/**
|
||||
* 卖单
|
||||
*/
|
||||
private List<DepthEntry> asks = new ArrayList<DepthEntry>();
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public Long getTs() {
|
||||
return ts;
|
||||
}
|
||||
|
||||
public void setTs(Long ts) {
|
||||
this.ts = ts;
|
||||
}
|
||||
|
||||
public List<DepthEntry> getBids() {
|
||||
return bids;
|
||||
}
|
||||
|
||||
public void setBids(List<DepthEntry> bids) {
|
||||
this.bids = bids;
|
||||
}
|
||||
|
||||
public List<DepthEntry> getAsks() {
|
||||
return asks;
|
||||
}
|
||||
|
||||
public void setAsks(List<DepthEntry> asks) {
|
||||
this.asks = asks;
|
||||
}
|
||||
|
||||
}
|
||||
34
comm/Hobi/src/project/data/model/DepthEntry.java
Executable file
34
comm/Hobi/src/project/data/model/DepthEntry.java
Executable file
@@ -0,0 +1,34 @@
|
||||
package project.data.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* An depth entry consisting of price and amount.
|
||||
*/
|
||||
public class DepthEntry implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -2177789072570310524L;
|
||||
|
||||
private Double price;
|
||||
private Double amount;
|
||||
|
||||
public Double getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(Double price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public Double getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(Double amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
}
|
||||
35
comm/Hobi/src/project/data/model/Kline.hbm.xml
Executable file
35
comm/Hobi/src/project/data/model/Kline.hbm.xml
Executable file
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
|
||||
<hibernate-mapping>
|
||||
<class name="project.data.model.Kline" table="T_KLINE">
|
||||
<id name="id" type="java.lang.String">
|
||||
<column name="UUID" />
|
||||
<generator class="uuid.hex" />
|
||||
</id>
|
||||
<property name="symbol" type="java.lang.String">
|
||||
<column name="SYMBOL" />
|
||||
</property>
|
||||
<property name="ts" type="long">
|
||||
<column name="TS" />
|
||||
</property>
|
||||
<property name="open" type="double">
|
||||
<column name="OPEN" />
|
||||
</property>
|
||||
<property name="high" type="double">
|
||||
<column name="HIGH" />
|
||||
</property>
|
||||
<property name="low" type="double">
|
||||
<column name="LOW" />
|
||||
</property>
|
||||
<property name="close" type="double">
|
||||
<column name="CLOSE" />
|
||||
</property>
|
||||
<property name="volume" type="double">
|
||||
<column name="VOLUME" />
|
||||
</property>
|
||||
<property name="period" type="java.lang.String">
|
||||
<column name="PERIOD" />
|
||||
</property>
|
||||
</class>
|
||||
</hibernate-mapping>
|
||||
152
comm/Hobi/src/project/data/model/Kline.java
Executable file
152
comm/Hobi/src/project/data/model/Kline.java
Executable file
@@ -0,0 +1,152 @@
|
||||
package project.data.model;
|
||||
|
||||
import kernel.bo.EntityObject;
|
||||
|
||||
/**
|
||||
* K线图
|
||||
*/
|
||||
public class Kline extends EntityObject implements Comparable<Kline>, Cloneable {
|
||||
public final static String PERIOD_1MIN = "1min";
|
||||
public final static String PERIOD_5MIN = "5min";
|
||||
public final static String PERIOD_15MIN = "15min";
|
||||
public final static String PERIOD_30MIN = "30min";
|
||||
public final static String PERIOD_60MIN = "60min";
|
||||
public final static String PERIOD_4HOUR = "4hour";
|
||||
public final static String PERIOD_1DAY = "1day";
|
||||
public final static String PERIOD_1MON = "1mon";
|
||||
public final static String PERIOD_1WEEK = "1week";
|
||||
/**
|
||||
* Member Description
|
||||
*/
|
||||
|
||||
private static final long serialVersionUID = -6488478481677363147L;
|
||||
|
||||
/**
|
||||
* 产品代码
|
||||
*/
|
||||
private String symbol;
|
||||
/**
|
||||
* 时间戳
|
||||
*/
|
||||
private Long ts;
|
||||
/**
|
||||
* 时间戳的"yyyy-MM-dd HH:mm:ss"格式
|
||||
*/
|
||||
private String current_time;
|
||||
|
||||
/**
|
||||
* 开盘价
|
||||
*/
|
||||
private Double open;
|
||||
/**
|
||||
* 最高价
|
||||
*/
|
||||
private Double high;
|
||||
/**
|
||||
* 最低价
|
||||
*/
|
||||
private Double low;
|
||||
/**
|
||||
* 最新价
|
||||
*/
|
||||
private Double close;
|
||||
/**
|
||||
* 成交量
|
||||
*/
|
||||
private Double volume;
|
||||
|
||||
/**
|
||||
* 1min, 5min, 15min, 30min, 60min, 4hour, 1day, 1mon, 1week
|
||||
*/
|
||||
private String period;
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public Long getTs() {
|
||||
return ts;
|
||||
}
|
||||
|
||||
public void setTs(Long ts) {
|
||||
this.ts = ts;
|
||||
getCurrent_time();
|
||||
}
|
||||
|
||||
public Double getClose() {
|
||||
return close;
|
||||
}
|
||||
|
||||
public void setClose(Double close) {
|
||||
this.close = close;
|
||||
}
|
||||
|
||||
public Double getOpen() {
|
||||
return open;
|
||||
}
|
||||
|
||||
public void setOpen(Double open) {
|
||||
this.open = open;
|
||||
}
|
||||
|
||||
public Double getHigh() {
|
||||
return high;
|
||||
}
|
||||
|
||||
public void setHigh(Double high) {
|
||||
this.high = high;
|
||||
}
|
||||
|
||||
public Double getLow() {
|
||||
return low;
|
||||
}
|
||||
|
||||
public void setLow(Double low) {
|
||||
this.low = low;
|
||||
}
|
||||
|
||||
public Double getVolume() {
|
||||
return volume;
|
||||
}
|
||||
|
||||
public void setVolume(Double volume) {
|
||||
this.volume = volume;
|
||||
}
|
||||
|
||||
public String getCurrent_time() {
|
||||
return current_time;
|
||||
}
|
||||
|
||||
public void setCurrent_time(String current_time) {
|
||||
this.current_time = current_time;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Kline kline) {
|
||||
if (this.ts > kline.getTs()) {
|
||||
return 1;
|
||||
} else if (this.ts < kline.getTs()) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public String getPeriod() {
|
||||
return period;
|
||||
}
|
||||
|
||||
public void setPeriod(String period) {
|
||||
this.period = period;
|
||||
}
|
||||
@Override
|
||||
public Object clone() throws CloneNotSupportedException {
|
||||
return super.clone();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
39
comm/Hobi/src/project/data/model/Realtime.hbm.xml
Executable file
39
comm/Hobi/src/project/data/model/Realtime.hbm.xml
Executable file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
|
||||
<hibernate-mapping>
|
||||
<class name="project.data.model.Realtime" table="T_REALTIME">
|
||||
<id name="id" type="java.lang.String">
|
||||
<column name="UUID" />
|
||||
<generator class="uuid.hex" />
|
||||
</id>
|
||||
<property name="symbol" type="java.lang.String">
|
||||
<column name="SYMBOL" />
|
||||
</property>
|
||||
<property name="ts" type="long">
|
||||
<column name="TS" />
|
||||
</property>
|
||||
<property name="name" type="java.lang.String">
|
||||
<column name="NAME" />
|
||||
</property>
|
||||
<property name="open" type="double">
|
||||
<column name="OPEN" />
|
||||
</property>
|
||||
<property name="high" type="double">
|
||||
<column name="HIGH" />
|
||||
</property>
|
||||
<property name="low" type="double">
|
||||
<column name="LOW" />
|
||||
</property>
|
||||
<property name="close" type="double">
|
||||
<column name="CLOSE" />
|
||||
</property>
|
||||
<property name="volume" type="double">
|
||||
<column name="VOLUME" />
|
||||
</property>
|
||||
<property name="amount" type="double">
|
||||
<column name="AMOUNT" />
|
||||
</property>
|
||||
|
||||
</class>
|
||||
</hibernate-mapping>
|
||||
199
comm/Hobi/src/project/data/model/Realtime.java
Executable file
199
comm/Hobi/src/project/data/model/Realtime.java
Executable file
@@ -0,0 +1,199 @@
|
||||
package project.data.model;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import kernel.bo.EntityObject;
|
||||
import kernel.util.Arith;
|
||||
import kernel.util.DateUtils;
|
||||
|
||||
/**
|
||||
* 实时价格
|
||||
*
|
||||
*/
|
||||
public class Realtime extends EntityObject implements Comparable<Realtime>, Cloneable {
|
||||
private static final long serialVersionUID = -4957441549674121537L;
|
||||
/**
|
||||
* 产品代码
|
||||
*/
|
||||
private String symbol;
|
||||
/**
|
||||
* 时间戳
|
||||
*/
|
||||
private Long ts;
|
||||
/**
|
||||
* 时间戳的"yyyy-MM-dd HH:mm:ss"格式
|
||||
*/
|
||||
private String current_time;
|
||||
/**
|
||||
* 产品名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 开盘价
|
||||
*/
|
||||
private Double open;
|
||||
|
||||
/**
|
||||
* 最新价
|
||||
*/
|
||||
private Double close;
|
||||
/**
|
||||
* 最高价
|
||||
*/
|
||||
private Double high;
|
||||
/**
|
||||
* 最低价
|
||||
*/
|
||||
private Double low;
|
||||
/**
|
||||
**
|
||||
* 成交额 金额
|
||||
*/
|
||||
private Double volume;
|
||||
/**
|
||||
* 成交量 币个数
|
||||
*/
|
||||
private Double amount;
|
||||
|
||||
/**
|
||||
* 涨跌幅
|
||||
*/
|
||||
private double change_ratio;
|
||||
|
||||
public Double getChange_ratio() {
|
||||
change_ratio = Arith.div(Arith.sub(close, open), open);
|
||||
change_ratio = Arith.mul(change_ratio, 100);
|
||||
DecimalFormat df = new DecimalFormat("#.##");
|
||||
return Double.valueOf(df.format(change_ratio));
|
||||
}
|
||||
|
||||
/**
|
||||
* change_ratio,asc升序 desc 降序
|
||||
*/
|
||||
public String order;
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public Long getTs() {
|
||||
return ts;
|
||||
}
|
||||
|
||||
public void setTs(Long ts) {
|
||||
this.ts = ts;
|
||||
getCurrent_time();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Double getOpen() {
|
||||
return open;
|
||||
}
|
||||
|
||||
public void setOpen(Double open) {
|
||||
this.open = open;
|
||||
}
|
||||
|
||||
public Double getHigh() {
|
||||
return high;
|
||||
}
|
||||
|
||||
public void setHigh(Double high) {
|
||||
this.high = high;
|
||||
}
|
||||
|
||||
public Double getLow() {
|
||||
return low;
|
||||
}
|
||||
|
||||
public void setLow(Double low) {
|
||||
this.low = low;
|
||||
}
|
||||
|
||||
public Double getVolume() {
|
||||
return volume;
|
||||
}
|
||||
|
||||
public void setVolume(Double volume) {
|
||||
this.volume = volume;
|
||||
}
|
||||
|
||||
public Double getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(Double amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public static long getSerialversionuid() {
|
||||
return serialVersionUID;
|
||||
}
|
||||
|
||||
public String getCurrent_time() {
|
||||
|
||||
current_time = DateUtils.timeStamp2Date(String.valueOf(ts));
|
||||
return current_time;
|
||||
}
|
||||
|
||||
public Double getClose() {
|
||||
return close;
|
||||
}
|
||||
|
||||
public void setClose(Double close) {
|
||||
this.close = close;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Realtime realtime) {
|
||||
if ("asc".equals(order)) {
|
||||
if (this.getChange_ratio() == realtime.getChange_ratio()) {
|
||||
return 0;
|
||||
} else if (this.getChange_ratio() > realtime.getChange_ratio()) {
|
||||
return 1;
|
||||
} else if (this.getChange_ratio() < realtime.getChange_ratio()) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
} else if ("desc".equals(order)) {
|
||||
if (this.getChange_ratio() == realtime.getChange_ratio()) {
|
||||
return 0;
|
||||
} else if (this.getChange_ratio() < realtime.getChange_ratio()) {
|
||||
return 1;
|
||||
} else if (this.getChange_ratio() > realtime.getChange_ratio()) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (this.ts > realtime.getTs()) {
|
||||
return 1;
|
||||
} else if (this.ts < realtime.getTs()) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
public void setOrder(String order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() throws CloneNotSupportedException {
|
||||
return super.clone();
|
||||
}
|
||||
|
||||
}
|
||||
29
comm/Hobi/src/project/data/model/Symbols.hbm.xml
Executable file
29
comm/Hobi/src/project/data/model/Symbols.hbm.xml
Executable file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
|
||||
<hibernate-mapping>
|
||||
<class name="project.data.model.Symbols" table="T_SYMBOLS">
|
||||
<id name="id" type="java.lang.String">
|
||||
<column name="UUID" />
|
||||
<generator class="uuid.hex" />
|
||||
</id>
|
||||
<property name="symbol" type="java.lang.String">
|
||||
<column name="SYMBOL" />
|
||||
</property>
|
||||
<property name="base_currency" type="java.lang.String">
|
||||
<column name="BASE_CURRENCY" />
|
||||
</property>
|
||||
<property name="quote_currency" type="java.lang.String">
|
||||
<column name="QUOTE_CURRENCY" />
|
||||
</property>
|
||||
<property name="price_precision" type="int">
|
||||
<column name="PRICE_PRECISION" />
|
||||
</property>
|
||||
<property name="state" type="java.lang.String">
|
||||
<column name="STATE" />
|
||||
</property>
|
||||
<property name="leverage_ratio" type="double">
|
||||
<column name="LEVERAGE_RATIO" />
|
||||
</property>
|
||||
</class>
|
||||
</hibernate-mapping>
|
||||
87
comm/Hobi/src/project/data/model/Symbols.java
Executable file
87
comm/Hobi/src/project/data/model/Symbols.java
Executable file
@@ -0,0 +1,87 @@
|
||||
package project.data.model;
|
||||
|
||||
import kernel.bo.EntityObject;
|
||||
|
||||
public class Symbols extends EntityObject {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -6358871995039244069L;
|
||||
/**
|
||||
* 交易对中的基础币种
|
||||
*/
|
||||
private String base_currency;
|
||||
/**
|
||||
* 交易对中的报价币种
|
||||
*/
|
||||
private String quote_currency;
|
||||
|
||||
/**
|
||||
* 交易对报价的精度(小数点后位数)
|
||||
*/
|
||||
private int price_precision;
|
||||
|
||||
/**
|
||||
* 交易对
|
||||
*/
|
||||
private String symbol;
|
||||
|
||||
/**
|
||||
* 交易对状态;可能值: [online,offline,suspend] online - 已上线;offline -
|
||||
* 交易对已下线,不可交易;suspend -- 交易暂停
|
||||
*/
|
||||
private String state;
|
||||
/**
|
||||
* 交易对杠杆最大倍数
|
||||
*/
|
||||
private Double leverage_ratio;
|
||||
|
||||
public String getBase_currency() {
|
||||
return base_currency;
|
||||
}
|
||||
|
||||
public void setBase_currency(String base_currency) {
|
||||
this.base_currency = base_currency;
|
||||
}
|
||||
|
||||
public String getQuote_currency() {
|
||||
return quote_currency;
|
||||
}
|
||||
|
||||
public void setQuote_currency(String quote_currency) {
|
||||
this.quote_currency = quote_currency;
|
||||
}
|
||||
|
||||
public int getPrice_precision() {
|
||||
return price_precision;
|
||||
}
|
||||
|
||||
public void setPrice_precision(int price_precision) {
|
||||
this.price_precision = price_precision;
|
||||
}
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public Double getLeverage_ratio() {
|
||||
return leverage_ratio;
|
||||
}
|
||||
|
||||
public void setLeverage_ratio(Double leverage_ratio) {
|
||||
this.leverage_ratio = leverage_ratio;
|
||||
}
|
||||
|
||||
}
|
||||
48
comm/Hobi/src/project/data/model/Trade.java
Executable file
48
comm/Hobi/src/project/data/model/Trade.java
Executable file
@@ -0,0 +1,48 @@
|
||||
package project.data.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Trade implements Serializable {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1237970335128424556L;
|
||||
|
||||
/**
|
||||
* 产品代码
|
||||
*/
|
||||
private String symbol;
|
||||
|
||||
/**
|
||||
* 时间戳
|
||||
*/
|
||||
private Long ts;
|
||||
private List<TradeEntry> data = new ArrayList<TradeEntry>();
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public Long getTs() {
|
||||
return ts;
|
||||
}
|
||||
|
||||
public void setTs(Long ts) {
|
||||
this.ts = ts;
|
||||
}
|
||||
|
||||
public List<TradeEntry> getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(List<TradeEntry> data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
}
|
||||
83
comm/Hobi/src/project/data/model/TradeEntry.java
Executable file
83
comm/Hobi/src/project/data/model/TradeEntry.java
Executable file
@@ -0,0 +1,83 @@
|
||||
package project.data.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import project.hobi.util.DateUtils;
|
||||
|
||||
public class TradeEntry implements Comparable<TradeEntry>,Serializable {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 7342378765988828212L;
|
||||
/**
|
||||
* 以报价币种为单位的成交价格
|
||||
*/
|
||||
private Double price;
|
||||
/**
|
||||
* 以基础币种为单位的交易量
|
||||
*/
|
||||
private Double amount;
|
||||
/**
|
||||
* 交易方向:“buy” 或 “sell”, “buy” 即买,“sell” 即卖
|
||||
*/
|
||||
private String direction;
|
||||
|
||||
/**
|
||||
* 时间戳
|
||||
*/
|
||||
private Long ts;
|
||||
|
||||
/**
|
||||
* 时间戳的"yyyy-MM-dd HH:mm:ss"格式
|
||||
*/
|
||||
private String current_time;
|
||||
|
||||
public Double getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(Double price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public Double getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(Double amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public String getDirection() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
public void setDirection(String direction) {
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
public Long getTs() {
|
||||
return ts;
|
||||
}
|
||||
|
||||
public String getCurrent_time() {
|
||||
|
||||
current_time = DateUtils.timeStamp2Date(String.valueOf(ts), DateUtils.DF_HHmm);
|
||||
return current_time;
|
||||
}
|
||||
|
||||
public void setTs(Long ts) {
|
||||
this.ts = ts;
|
||||
getCurrent_time();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(TradeEntry model) {
|
||||
if (this.ts > model.getTs()) {
|
||||
return -1;
|
||||
} else if (this.ts < model.getTs()) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
102
comm/Hobi/src/project/data/model/Trend.java
Executable file
102
comm/Hobi/src/project/data/model/Trend.java
Executable file
@@ -0,0 +1,102 @@
|
||||
package project.data.model;
|
||||
|
||||
|
||||
import kernel.bo.EntityObject;
|
||||
import project.hobi.util.DateUtils;
|
||||
|
||||
/**
|
||||
* 分时图
|
||||
*
|
||||
*/
|
||||
public class Trend extends EntityObject implements Comparable<Trend> {
|
||||
|
||||
private static final long serialVersionUID = -783607185910260696L;
|
||||
/**
|
||||
* 产品代码
|
||||
*/
|
||||
private String symbol;
|
||||
/**
|
||||
* 时间戳
|
||||
*/
|
||||
private Long ts;
|
||||
|
||||
/**
|
||||
* 价格(白线)
|
||||
*/
|
||||
private Double trend;
|
||||
|
||||
/**
|
||||
* 成交额(以报价币种计量)
|
||||
*/
|
||||
private Double volume;
|
||||
/**
|
||||
* 成交量(以基础币种计量)
|
||||
*/
|
||||
private Double amount;
|
||||
|
||||
/**
|
||||
* 时间戳的"yyyy-MM-dd HH:mm:ss"格式
|
||||
*/
|
||||
private String current_time;
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public Double getTrend() {
|
||||
return trend;
|
||||
}
|
||||
|
||||
public void setTrend(Double trend) {
|
||||
this.trend = trend;
|
||||
}
|
||||
|
||||
public Double getVolume() {
|
||||
return volume;
|
||||
}
|
||||
|
||||
public void setVolume(Double volume) {
|
||||
this.volume = volume;
|
||||
}
|
||||
|
||||
public Double getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(Double amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public void setCurrent_time(String current_time) {
|
||||
this.current_time = current_time;
|
||||
}
|
||||
|
||||
public String getCurrent_time() {
|
||||
current_time = DateUtils.timeStamp2Date(String.valueOf(ts), "HH:mm");
|
||||
return current_time;
|
||||
}
|
||||
|
||||
public Long getTs() {
|
||||
return ts;
|
||||
}
|
||||
|
||||
public void setTs(Long ts) {
|
||||
this.ts = ts;
|
||||
getCurrent_time();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Trend trend) {
|
||||
|
||||
if (this.ts > trend.getTs()) {
|
||||
return 1;
|
||||
} else if (this.ts < trend.getTs()) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
14
comm/Hobi/src/project/hobi/AdminContractSymbolsService.java
Executable file
14
comm/Hobi/src/project/hobi/AdminContractSymbolsService.java
Executable file
@@ -0,0 +1,14 @@
|
||||
package project.hobi;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import kernel.web.Page;
|
||||
|
||||
public interface AdminContractSymbolsService {
|
||||
|
||||
public void saveReload();
|
||||
|
||||
public Page pagedQuery(int pageNo, int pageSize, String quote_currency, String base_currency);
|
||||
|
||||
public List<String> getQuoteList();
|
||||
}
|
||||
22
comm/Hobi/src/project/hobi/AdminSymbolsService.java
Executable file
22
comm/Hobi/src/project/hobi/AdminSymbolsService.java
Executable file
@@ -0,0 +1,22 @@
|
||||
package project.hobi;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import kernel.web.Page;
|
||||
import project.data.model.Symbols;
|
||||
|
||||
public interface AdminSymbolsService {
|
||||
|
||||
public void saveReload();
|
||||
|
||||
public Page pagedQuery(int pageNo, int pageSize, String quote_currency, String base_currency);
|
||||
public Page pagedQuery(int pageNo, int pageSize);
|
||||
|
||||
|
||||
/**
|
||||
* 查询报价单位
|
||||
*/
|
||||
public Page pagedQueryMap(int pageNo, int pageSize);
|
||||
|
||||
}
|
||||
32
comm/Hobi/src/project/hobi/Config.java
Executable file
32
comm/Hobi/src/project/hobi/Config.java
Executable file
@@ -0,0 +1,32 @@
|
||||
package project.hobi;
|
||||
|
||||
public class Config {
|
||||
|
||||
/**
|
||||
* API域名
|
||||
*/
|
||||
public static String url = "https://api.huobi.pro";
|
||||
|
||||
/**
|
||||
* 所有交易对的最新 Tickers
|
||||
*/
|
||||
public static String tickers = "/market/tickers";
|
||||
|
||||
/**
|
||||
* 市场深度数据
|
||||
*/
|
||||
public static String depth = "/market/depth";
|
||||
|
||||
/**
|
||||
* 最近市场成交记录
|
||||
*/
|
||||
public static String trade = "/market/trade";
|
||||
|
||||
/**
|
||||
* K 线数据(蜡烛图)
|
||||
*/
|
||||
public static String kline = "/market/history/kline";
|
||||
|
||||
public static String symbols = "/v1/common/symbols";
|
||||
|
||||
}
|
||||
54
comm/Hobi/src/project/hobi/HobiDataService.java
Executable file
54
comm/Hobi/src/project/hobi/HobiDataService.java
Executable file
@@ -0,0 +1,54 @@
|
||||
package project.hobi;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import project.data.model.Depth;
|
||||
import project.data.model.Kline;
|
||||
import project.data.model.Realtime;
|
||||
import project.data.model.Symbols;
|
||||
import project.data.model.Trade;
|
||||
|
||||
public interface HobiDataService {
|
||||
|
||||
/**
|
||||
* 实时价格。所有交易对的最新 Tickers
|
||||
*
|
||||
*/
|
||||
public List<Realtime> realtime(int maximum);
|
||||
|
||||
/**
|
||||
* K线
|
||||
*
|
||||
* @param period 1day, 1mon, 1week, 1year
|
||||
*
|
||||
*/
|
||||
public List<Kline> kline(String symbol, String period, Integer num, int maximum);
|
||||
|
||||
/**
|
||||
* 市场深度数据(20档)
|
||||
*/
|
||||
|
||||
public Depth depth(String symbol, int maximum);
|
||||
|
||||
/**
|
||||
* 市场深度数据(20档),包装,数据本地化处理
|
||||
*/
|
||||
public Depth depthDecorator(String symbol, int maximum);
|
||||
|
||||
/**
|
||||
* 获得近期交易记录
|
||||
*/
|
||||
public Trade trade(String symbol, int maximum);
|
||||
|
||||
/**
|
||||
* 获得近期交易记录,包装,数据本地化处理
|
||||
*/
|
||||
public Trade tradeDecorator(String symbol, int maximum);
|
||||
|
||||
public List<Symbols> symbols();
|
||||
|
||||
String getSymbolRealPrize(String symbol);
|
||||
|
||||
void putSymbolRealCache(String symbol,String val);
|
||||
|
||||
}
|
||||
341
comm/Hobi/src/project/hobi/http/HttpHelper.java
Executable file
341
comm/Hobi/src/project/hobi/http/HttpHelper.java
Executable file
@@ -0,0 +1,341 @@
|
||||
package project.hobi.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.CookieStore;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.HttpResponseException;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.client.protocol.HttpClientContext;
|
||||
import org.apache.http.client.utils.URLEncodedUtils;
|
||||
import org.apache.http.config.Registry;
|
||||
import org.apache.http.config.RegistryBuilder;
|
||||
import org.apache.http.conn.HttpConnectionFactory;
|
||||
import org.apache.http.conn.ManagedHttpClientConnection;
|
||||
import org.apache.http.conn.routing.HttpRoute;
|
||||
import org.apache.http.conn.socket.ConnectionSocketFactory;
|
||||
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
|
||||
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.cookie.Cookie;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.BasicCookieStore;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.conn.DefaultHttpResponseParserFactory;
|
||||
import org.apache.http.impl.conn.ManagedHttpClientConnectionFactory;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.apache.http.impl.conn.SystemDefaultDnsResolver;
|
||||
import org.apache.http.impl.io.DefaultHttpRequestWriterFactory;
|
||||
import org.apache.http.io.HttpMessageWriterFactory;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.apache.http.protocol.BasicHttpContext;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.ssl.SSLContexts;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
/**
|
||||
* <p/>
|
||||
* //请求信息类型MIME每种响应类型的输出(普通文本、html 和 XML,json)。允许的响应类型应当匹配资源类中生成的 MIME 类型
|
||||
* //资源类生成的 MIME 类型应当匹配一种可接受的 MIME 类型。如果生成的 MIME 类型和可接受的 MIME 类型不 匹配,那么将 //生成
|
||||
* com.sun.jersey.api.client.UniformInterfaceException。例如,将可接受的 MIME 类型设置为
|
||||
* text/xml,而将 //生成的 MIME 类型设置为 application/xml。将生成 UniformInterfaceException。
|
||||
* //代理: new HttpHost("10.0.0.172", 80, "http");
|
||||
* <p/>
|
||||
*/
|
||||
public class HttpHelper {
|
||||
private static Logger logger = LogManager.getLogger(HttpHelper.class);
|
||||
private static Map<String, List<Cookie>> cookiesMap = Collections
|
||||
.synchronizedMap(new HashMap<String, List<Cookie>>());
|
||||
static private HttpClient httpclient;
|
||||
private static Map<String, Map<String, String>> globalParam = new HashMap<String, Map<String, String>>(5);
|
||||
private static Map<String, String> headers = new HashMap<String, String>();
|
||||
|
||||
static {
|
||||
RequestConfig config = RequestConfig.copy(RequestConfig.DEFAULT).setConnectionRequestTimeout(30000)
|
||||
.setSocketTimeout(40000).build();
|
||||
SSLContext sslcontext = SSLContexts.createSystemDefault();
|
||||
HttpMessageWriterFactory<HttpRequest> requestWriterFactory = new DefaultHttpRequestWriterFactory();
|
||||
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
|
||||
.register("http", PlainConnectionSocketFactory.INSTANCE)
|
||||
.register("https", new SSLConnectionSocketFactory(sslcontext, NoopHostnameVerifier.INSTANCE)).build();
|
||||
HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connFactory = new ManagedHttpClientConnectionFactory(
|
||||
requestWriterFactory, new DefaultHttpResponseParserFactory());
|
||||
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry,
|
||||
connFactory, new SystemDefaultDnsResolver());
|
||||
connManager.setMaxTotal(100);
|
||||
connManager.setDefaultMaxPerRoute(100);
|
||||
httpclient = HttpClientBuilder.create().setConnectionManager(connManager).setDefaultRequestConfig(config)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过HTTP协议访问站点,并且将返回的数据转换成json对象 注意 对方返回的数据最外层对象必须是单个对象
|
||||
*
|
||||
* @param url
|
||||
* @param param
|
||||
* @param method
|
||||
* @return
|
||||
* @throws IOException
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String getJSONFromHttp(String url, Map<String, Object> param, HttpMethodType method)
|
||||
throws RuntimeException {
|
||||
String rs;
|
||||
switch (method) {
|
||||
case GET: {
|
||||
rs = sendGetHttp(url, param);
|
||||
break;
|
||||
}
|
||||
case POST: {
|
||||
rs = sendPostHttp(url, param, false);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
throw new IllegalArgumentException("HTTP访问方式设置有误");
|
||||
}
|
||||
}
|
||||
// logger.debug("return is:" + rs);
|
||||
return rs == null || "".equals(rs) ? null : rs;
|
||||
}
|
||||
|
||||
public static String sendHttp(String url, Map<String, Object> param, HttpMethodType method)
|
||||
throws RuntimeException {
|
||||
switch (method) {
|
||||
case GET: {
|
||||
return sendGetHttp(url, param);
|
||||
}
|
||||
case POST: {
|
||||
return sendPostHttp(url, param, false);
|
||||
}
|
||||
default:
|
||||
throw new IllegalArgumentException("参数中的HTTP访问方式有误,只支持GET、POST、FILE");
|
||||
}
|
||||
}
|
||||
|
||||
private static final Pattern paramPat = Pattern.compile("([^&]+)=([^&]+)");
|
||||
|
||||
/**
|
||||
* 发送一个HTTP协议的GET请求
|
||||
*
|
||||
* @param url
|
||||
* @param param
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String sendGetHttp(String url, Map<String, Object> param) throws RuntimeException {
|
||||
StringBuilder parmStr = new StringBuilder();
|
||||
if (null != param && !param.isEmpty()) {
|
||||
List<NameValuePair> parm = new ArrayList<NameValuePair>(param.size());
|
||||
for (Map.Entry<String, Object> paramEntity : param.entrySet()) {
|
||||
Object value = paramEntity.getValue();
|
||||
if (null != value && !StringUtils.isBlank(value.toString())) {
|
||||
parm.add(new BasicNameValuePair(paramEntity.getKey(), value.toString()));
|
||||
}
|
||||
}
|
||||
parmStr.append(URLEncodedUtils.format(parm, "UTF-8"));
|
||||
}
|
||||
return sendGetHttp(url, parmStr.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送一个HTTP协议的GET请求
|
||||
*
|
||||
* @param url
|
||||
* @param param
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String sendGetHttp(String url, String param) throws RuntimeException {
|
||||
HttpContext localContext = new BasicHttpContext();
|
||||
setCookie(localContext, url);
|
||||
if (!StringUtils.isBlank(param))
|
||||
url = url + ((url.indexOf("?") > 0) ? "&" + param : "?" + param);
|
||||
url = appendGlobalParam(url, param);
|
||||
// logger.debug("远程URL:{}", url);
|
||||
// 创建HttpGet对象
|
||||
HttpGet request = new HttpGet(url);
|
||||
setHeader(request);
|
||||
String result;
|
||||
try {
|
||||
HttpResponse response = httpclient.execute(request, localContext);
|
||||
result = responseProc(response);
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage());
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
request.reset();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String appendGlobalParam(String url, Object param) {
|
||||
for (Map.Entry<String, Map<String, String>> stringMapEntry : globalParam.entrySet()) {
|
||||
if (url.startsWith(stringMapEntry.getKey())) {
|
||||
for (Map.Entry<String, String> paramEntry : stringMapEntry.getValue().entrySet()) {
|
||||
logger.debug("HTTP处理过程发送了参数:" + paramEntry.getKey() + "|" + paramEntry.getValue());
|
||||
if (param instanceof List)
|
||||
((List) param).add(new BasicNameValuePair(paramEntry.getKey(), paramEntry.getValue()));
|
||||
else
|
||||
url += "&" + paramEntry.getKey() + "=" + paramEntry.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送一个HTTP协议的POST请求
|
||||
*
|
||||
* @param url
|
||||
* @param param
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String sendPostHttp(String url, Map<String, Object> param, boolean postTxtBody)
|
||||
throws RuntimeException {
|
||||
HttpContext localContext = new BasicHttpContext();
|
||||
setCookie(localContext, url);
|
||||
// logger.debug("远程URL:{}", url);
|
||||
HttpPost request = new HttpPost(url);
|
||||
List<NameValuePair> parm = new ArrayList<NameValuePair>();
|
||||
if (null != param && !param.isEmpty())
|
||||
for (Map.Entry<String, Object> paramEntity : param.entrySet()) {
|
||||
Object value = paramEntity.getValue();
|
||||
if (null != value && !StringUtils.isBlank(value.toString())) {
|
||||
logger.debug("HTTP处理过程发送了参数:" + paramEntity.getKey() + "|" + value);
|
||||
parm.add(new BasicNameValuePair(paramEntity.getKey(), value.toString()));
|
||||
}
|
||||
}
|
||||
appendGlobalParam(url, parm);
|
||||
HttpResponse response;
|
||||
try {
|
||||
request.setEntity(generyEntity(parm, "UTF-8", postTxtBody));
|
||||
setHeader(request);
|
||||
response = httpclient.execute(request, localContext);
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
String result;
|
||||
try {
|
||||
result = responseProc(response);
|
||||
} catch (IOException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
request.reset();
|
||||
}
|
||||
// logger.debug("return is:" + result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Pattern urlPrePat = Pattern.compile("https?://([^/]*)?/?");
|
||||
|
||||
private static String getUrlPerfix(String url) {
|
||||
Matcher mat = urlPrePat.matcher(url);
|
||||
if (mat.find())
|
||||
return mat.group(1);
|
||||
return "";
|
||||
}
|
||||
|
||||
private static void setCookie(HttpContext localContext, String url) {
|
||||
String urlPrefix = getUrlPerfix(url);
|
||||
CookieStore cookieStore = new BasicCookieStore();
|
||||
List<Cookie> cookieList = cookiesMap.get(urlPrefix);
|
||||
if (cookieList != null && cookieList.size() > 0) {
|
||||
for (Cookie cookie : cookiesMap.get(urlPrefix)) {
|
||||
cookieStore.addCookie(cookie);
|
||||
}
|
||||
localContext.setAttribute(HttpClientContext.COOKIE_STORE, cookieStore);
|
||||
}
|
||||
}
|
||||
|
||||
private static void parseCookie(HttpClientContext context, String url) {
|
||||
List<Cookie> cookies = context.getCookieStore().getCookies();
|
||||
String urlPrefix = getUrlPerfix(url);
|
||||
List<Cookie> oldCookies = cookiesMap.get(urlPrefix);
|
||||
if (oldCookies != null) {
|
||||
for (Cookie cookie : cookies) {
|
||||
for (Cookie oldCookie : oldCookies) {
|
||||
if (cookie.getName().equals(oldCookie.getName())) {
|
||||
oldCookies.remove(oldCookie);
|
||||
oldCookies.add(cookie);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
cookiesMap.put(urlPrefix, cookies);
|
||||
}
|
||||
|
||||
private static String responseProc(HttpResponse response) throws IOException {
|
||||
switch (response.getStatusLine().getStatusCode()) {
|
||||
case 200: {
|
||||
HttpEntity entity = response.getEntity();
|
||||
return EntityUtils.toString(entity, "UTF-8");
|
||||
}
|
||||
case 302: {
|
||||
return sendGetHttp(response.getFirstHeader("location").getValue(), "");
|
||||
}
|
||||
case 303:
|
||||
case 304: {
|
||||
Header[] headers = response.getAllHeaders();
|
||||
for (Header header : headers) {
|
||||
logger.debug(header.getName() + " : " + header.getValue());
|
||||
}
|
||||
}
|
||||
default:
|
||||
throw new HttpResponseException(response.getStatusLine().getStatusCode(),
|
||||
response.getStatusLine().getReasonPhrase());
|
||||
}
|
||||
}
|
||||
|
||||
public static void setHeader(HttpRequestBase request) {
|
||||
for (Map.Entry<String, String> headerEntry : headers.entrySet()) {
|
||||
request.setHeader(headerEntry.getKey(), headerEntry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public static HttpEntity generyEntity(List<NameValuePair> parm, String encode, boolean postTxtBody)
|
||||
throws Exception {
|
||||
if (postTxtBody && parm.size() > 0) {
|
||||
JSONObject paramJson = new JSONObject();
|
||||
for (NameValuePair nameValuePair : parm) {
|
||||
paramJson.put(nameValuePair.getName(), nameValuePair.getValue());
|
||||
}
|
||||
return (new StringEntity(paramJson.toString(), encode));
|
||||
} else
|
||||
return (new UrlEncodedFormEntity(parm, encode));
|
||||
}
|
||||
|
||||
// public static void main(String[] args) {
|
||||
// byte[] bytes = new byte[1];
|
||||
// if (bytes instanceof byte[]) {
|
||||
// System.out.println(1);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
5
comm/Hobi/src/project/hobi/http/HttpMethodType.java
Executable file
5
comm/Hobi/src/project/hobi/http/HttpMethodType.java
Executable file
@@ -0,0 +1,5 @@
|
||||
package project.hobi.http;
|
||||
|
||||
public enum HttpMethodType {
|
||||
GET, POST, FILE
|
||||
}
|
||||
90
comm/Hobi/src/project/hobi/internal/AdminContractSymbolsServiceImpl.java
Executable file
90
comm/Hobi/src/project/hobi/internal/AdminContractSymbolsServiceImpl.java
Executable file
@@ -0,0 +1,90 @@
|
||||
package project.hobi.internal;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
|
||||
|
||||
import kernel.util.StringUtils;
|
||||
import kernel.web.Page;
|
||||
import kernel.web.PagedQueryDao;
|
||||
import project.data.model.Symbols;
|
||||
import project.hobi.AdminContractSymbolsService;
|
||||
import project.hobi.HobiDataService;;
|
||||
|
||||
public class AdminContractSymbolsServiceImpl extends HibernateDaoSupport implements AdminContractSymbolsService {
|
||||
private HobiDataService hobiDataService;
|
||||
private PagedQueryDao pagedQueryDao;
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
@Override
|
||||
public void saveReload() {
|
||||
List<Symbols> list = hobiDataService.symbols();
|
||||
if (list.size() > 0) {
|
||||
this.delete(this.getAll());
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
this.getHibernateTemplate().saveOrUpdate(list.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<Symbols> getAll() {
|
||||
List<Symbols> list = (List<Symbols>) this.getHibernateTemplate().find("FROM Symbols ");
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page pagedQuery(int pageNo, int pageSize, String quote_currency, String base_currency) {
|
||||
StringBuffer queryString = new StringBuffer();
|
||||
queryString.append(" FROM Symbols where 1 = 1 ");
|
||||
|
||||
Map<String, Object> parameters = new HashMap();
|
||||
|
||||
if (!StringUtils.isNullOrEmpty(quote_currency)) {
|
||||
queryString.append(" and quote_currency = :quote_currency ");
|
||||
parameters.put("quote_currency", quote_currency);
|
||||
} else {
|
||||
String defaultQuote = jdbcTemplate.queryForObject("SELECT DISTINCT(QUOTE_CURRENCY) FROM T_SYMBOLS LIMIT 1",
|
||||
String.class);
|
||||
queryString.append(" and quote_currency =:quote_currency ");
|
||||
parameters.put("quote_currency", defaultQuote);
|
||||
}
|
||||
|
||||
if (!StringUtils.isNullOrEmpty(base_currency)) {
|
||||
queryString.append(" and base_currency like:base_currency ");
|
||||
parameters.put("base_currency", "%" + base_currency + "%");
|
||||
}
|
||||
|
||||
Page page = this.pagedQueryDao.pagedQueryHql(pageNo, pageSize, queryString.toString(), parameters);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
public List<String> getQuoteList() {
|
||||
List<String> result = (List<String>) this.getHibernateTemplate().find("SELECT DISTINCT(obj.quote_currency) FROM Symbols obj");
|
||||
return result;
|
||||
}
|
||||
|
||||
private void delete(List<Symbols> list) {
|
||||
this.getHibernateTemplate().deleteAll(list);
|
||||
}
|
||||
|
||||
public void setHobiDataService(HobiDataService hobiDataService) {
|
||||
this.hobiDataService = hobiDataService;
|
||||
}
|
||||
|
||||
public void setPagedQueryDao(PagedQueryDao pagedQueryDao) {
|
||||
this.pagedQueryDao = pagedQueryDao;
|
||||
}
|
||||
|
||||
public JdbcTemplate getJdbcTemplate() {
|
||||
return jdbcTemplate;
|
||||
}
|
||||
|
||||
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
|
||||
this.jdbcTemplate = jdbcTemplate;
|
||||
}
|
||||
|
||||
}
|
||||
96
comm/Hobi/src/project/hobi/internal/AdminSymbolsServiceImpl.java
Executable file
96
comm/Hobi/src/project/hobi/internal/AdminSymbolsServiceImpl.java
Executable file
@@ -0,0 +1,96 @@
|
||||
package project.hobi.internal;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
|
||||
|
||||
import kernel.util.StringUtils;
|
||||
import kernel.web.Page;
|
||||
import kernel.web.PagedQueryDao;
|
||||
import project.data.model.Symbols;
|
||||
import project.hobi.AdminSymbolsService;
|
||||
import project.hobi.HobiDataService;;
|
||||
|
||||
public class AdminSymbolsServiceImpl extends HibernateDaoSupport implements AdminSymbolsService {
|
||||
private HobiDataService hobiDataService;
|
||||
private PagedQueryDao pagedQueryDao;
|
||||
|
||||
@Override
|
||||
public void saveReload() {
|
||||
List<Symbols> list = hobiDataService.symbols();
|
||||
if (list.size() > 0) {
|
||||
this.delete(this.getAll());
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
this.getHibernateTemplate().saveOrUpdate(list.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<Symbols> getAll() {
|
||||
List<Symbols> list = (List<Symbols>) this.getHibernateTemplate().find("FROM Symbols ");
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page pagedQuery(int pageNo, int pageSize, String quote_currency, String base_currency) {
|
||||
StringBuffer queryString = new StringBuffer();
|
||||
queryString.append(" FROM Symbols where 1 = 1 ");
|
||||
|
||||
Map<String, Object> parameters = new HashMap();
|
||||
|
||||
if (!StringUtils.isNullOrEmpty(quote_currency)) {
|
||||
queryString.append(" and quote_currency = :quote_currency ");
|
||||
parameters.put("quote_currency", quote_currency);
|
||||
}
|
||||
|
||||
if (!StringUtils.isNullOrEmpty(base_currency)) {
|
||||
queryString.append(" and base_currency =:base_currency ");
|
||||
parameters.put("base_currency", base_currency);
|
||||
}
|
||||
|
||||
Page page = this.pagedQueryDao.pagedQueryHql(pageNo, pageSize, queryString.toString(), parameters);
|
||||
|
||||
return page;
|
||||
}
|
||||
@Override
|
||||
public Page pagedQuery(int pageNo, int pageSize) {
|
||||
StringBuffer queryString = new StringBuffer(" SELECT DISTINCT(QUOTE_CURRENCY) ");
|
||||
|
||||
queryString.append(
|
||||
" FROM T_SYMBOLS WHERE 1 = 1 ");
|
||||
|
||||
Map parameters = new HashMap();
|
||||
|
||||
Page page = this.pagedQueryDao.pagedQuerySQL(pageNo, pageSize, queryString.toString(), parameters);
|
||||
|
||||
return page;
|
||||
}
|
||||
@Override
|
||||
public Page pagedQueryMap(int pageNo, int pageSize) {
|
||||
StringBuffer queryString = new StringBuffer(" SELECT DISTINCT(QUOTE_CURRENCY) quote_currency ");
|
||||
|
||||
queryString.append(
|
||||
" FROM T_SYMBOLS WHERE 1 = 1 ");
|
||||
|
||||
Map parameters = new HashMap();
|
||||
|
||||
Page page = this.pagedQueryDao.pagedQuerySQL(pageNo, pageSize, queryString.toString(), parameters);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
private void delete(List<Symbols> list) {
|
||||
this.getHibernateTemplate().deleteAll(list);
|
||||
}
|
||||
|
||||
public void setHobiDataService(HobiDataService hobiDataService) {
|
||||
this.hobiDataService = hobiDataService;
|
||||
}
|
||||
|
||||
public void setPagedQueryDao(PagedQueryDao pagedQueryDao) {
|
||||
this.pagedQueryDao = pagedQueryDao;
|
||||
}
|
||||
|
||||
}
|
||||
474
comm/Hobi/src/project/hobi/internal/HobiDataServiceImpl.java
Executable file
474
comm/Hobi/src/project/hobi/internal/HobiDataServiceImpl.java
Executable file
@@ -0,0 +1,474 @@
|
||||
package project.hobi.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import kernel.util.Arith;
|
||||
import kernel.util.StringUtils;
|
||||
import kernel.util.ThreadUtils;
|
||||
import project.data.model.Depth;
|
||||
import project.data.model.DepthEntry;
|
||||
import project.data.model.Kline;
|
||||
import project.data.model.Realtime;
|
||||
import project.data.model.Symbols;
|
||||
import project.data.model.Trade;
|
||||
import project.data.model.TradeEntry;
|
||||
import project.hobi.Config;
|
||||
import project.hobi.HobiDataService;
|
||||
import project.hobi.http.HttpHelper;
|
||||
import project.hobi.http.HttpMethodType;
|
||||
import project.invest.InvestRedisKeys;
|
||||
import project.item.ItemService;
|
||||
import project.item.model.Item;
|
||||
import project.mall.MallRedisKeys;
|
||||
|
||||
public class HobiDataServiceImpl implements HobiDataService {
|
||||
|
||||
private Logger logger = LogManager.getLogger(this.getClass().getName());
|
||||
/**
|
||||
* 接口调用间隔(毫秒)
|
||||
*/
|
||||
private int interval = 100;
|
||||
private int sleep = 100;
|
||||
/**
|
||||
* 最后一次访问接口时间
|
||||
*/
|
||||
private volatile Date last_time = new Date();
|
||||
|
||||
private volatile boolean lock = false;
|
||||
|
||||
private ItemService itemService;
|
||||
|
||||
@Override
|
||||
public List<Realtime> realtime(int maximum) {
|
||||
List<Realtime> list = new ArrayList<Realtime>();
|
||||
boolean current_lock = false;
|
||||
if (lock || (new Date().getTime() - last_time.getTime()) < interval) {
|
||||
ThreadUtils.sleep(sleep);
|
||||
if (maximum >= 100) {
|
||||
logger.warn("---------> 超过 100 次的轮询,未能竞争到查询实时汇率的处理机会,返回空集合。");
|
||||
return list;
|
||||
} else {
|
||||
return realtime(++maximum);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
current_lock = true;
|
||||
lock = true;
|
||||
Map<String, Object> param = new HashMap<String, Object>();
|
||||
String result = HttpHelper.getJSONFromHttp(Config.url + Config.tickers, param, HttpMethodType.GET);
|
||||
JSONObject resultJson = JSON.parseObject(result);
|
||||
String status = resultJson.getString("status");
|
||||
if ("ok".equals(status)) {
|
||||
JSONArray dataArray = resultJson.getJSONArray("data");
|
||||
Long ts = resultJson.getLongValue("ts");
|
||||
for (int i = 0; i < dataArray.size(); i++) {
|
||||
JSONObject realtimeJson = dataArray.getJSONObject(i);
|
||||
Realtime realtime = new Realtime();
|
||||
Item item = itemService.cacheBySymbolData(realtimeJson.getString("symbol"));
|
||||
if (item == null) {
|
||||
continue;
|
||||
}
|
||||
realtime.setSymbol(item.getSymbol());
|
||||
realtime.setName(item.getName());
|
||||
realtime.setTs(ts);
|
||||
realtime.setOpen(realtimeJson.getDouble("open"));
|
||||
realtime.setClose(realtimeJson.getDouble("close"));
|
||||
realtime.setHigh(realtimeJson.getDouble("high"));
|
||||
realtime.setLow(realtimeJson.getDouble("low"));
|
||||
realtime.setAmount(realtimeJson.getDouble("amount"));
|
||||
realtime.setVolume(realtimeJson.getDouble("vol"));
|
||||
list.add(realtime);
|
||||
}
|
||||
} else {
|
||||
logger.error(" realtime()error, resultJson [ " + resultJson.toJSONString() + " ]");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("realtime error:", e);
|
||||
} finally {
|
||||
if (current_lock) {
|
||||
lock = false;
|
||||
last_time = new Date();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Kline> kline(String symbol, String period, Integer num, int maximum) {
|
||||
List<Kline> list = new ArrayList<Kline>();
|
||||
Item item = itemService.cacheBySymbolData(symbol);
|
||||
if (item == null) {
|
||||
return list;
|
||||
}
|
||||
boolean current_lock = false;
|
||||
if (lock || (new Date().getTime() - last_time.getTime()) < interval) {
|
||||
ThreadUtils.sleep(sleep);
|
||||
if (maximum >= 100) {
|
||||
return list;
|
||||
} else {
|
||||
return this.kline(symbol, period, num, ++maximum);
|
||||
}
|
||||
|
||||
} else {
|
||||
try {
|
||||
current_lock = true;
|
||||
lock = true;
|
||||
Map<String, Object> param = new HashMap<String, Object>();
|
||||
param.put("symbol", symbol);
|
||||
param.put("period", period);
|
||||
if (num == null) {
|
||||
if (Kline.PERIOD_1MIN.equals(period)) {
|
||||
param.put("size", 1440);
|
||||
}
|
||||
if (Kline.PERIOD_5MIN.equals(period)) {
|
||||
param.put("size", 576);
|
||||
}
|
||||
if (Kline.PERIOD_15MIN.equals(period)) {
|
||||
param.put("size", 576);
|
||||
}
|
||||
if (Kline.PERIOD_30MIN.equals(period)) {
|
||||
param.put("size", 576);
|
||||
}
|
||||
if (Kline.PERIOD_60MIN.equals(period)) {
|
||||
param.put("size", 576);
|
||||
}
|
||||
|
||||
if (Kline.PERIOD_4HOUR.equals(period)) {
|
||||
param.put("size", 576);
|
||||
}
|
||||
if (Kline.PERIOD_1DAY.equals(period)) {
|
||||
param.put("size", 500);
|
||||
}
|
||||
if (Kline.PERIOD_1MON.equals(period)) {
|
||||
param.put("size", 500);
|
||||
}
|
||||
if (Kline.PERIOD_1WEEK.equals(period)) {
|
||||
param.put("size", 500);
|
||||
}
|
||||
|
||||
} else {
|
||||
param.put("size", num);
|
||||
}
|
||||
|
||||
String result = HttpHelper.getJSONFromHttp(Config.url + Config.kline, param, HttpMethodType.GET);
|
||||
JSONObject resultJson = JSON.parseObject(result);
|
||||
String status = resultJson.getString("status");
|
||||
if ("ok".equals(status)) {
|
||||
JSONArray dataArray = resultJson.getJSONArray("data");
|
||||
/**
|
||||
* 丢弃第一行数据
|
||||
*/
|
||||
int start = 1;
|
||||
if (num != null && num == 1)
|
||||
start = 0;
|
||||
for (int i = start; i < dataArray.size(); i++) {
|
||||
JSONObject realtimeJson = dataArray.getJSONObject(i);
|
||||
Kline kline = new Kline();
|
||||
kline.setSymbol(item.getSymbol());
|
||||
kline.setPeriod(period);
|
||||
kline.setTs(Long.valueOf(realtimeJson.getString("id") + "000"));
|
||||
kline.setOpen(realtimeJson.getDouble("open"));
|
||||
kline.setClose(realtimeJson.getDouble("close"));
|
||||
kline.setHigh(realtimeJson.getDouble("high"));
|
||||
kline.setLow(realtimeJson.getDouble("low"));
|
||||
kline.setVolume(realtimeJson.getDouble("vol"));
|
||||
list.add(kline);
|
||||
}
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("error", e);
|
||||
} finally {
|
||||
if (current_lock) {
|
||||
lock = false;
|
||||
last_time = new Date();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 市场深度数据(20档),包装,数据本地化处理
|
||||
*/
|
||||
public Depth depthDecorator(String symbol, int maximum) {
|
||||
Depth depth = this.depth(symbol, maximum);
|
||||
Item item = itemService.cacheBySymbolData(symbol);
|
||||
item = itemService.cacheBySymbol(item.getSymbol(), false);
|
||||
if ((depth == null || item.getAdjustment_value() == null || item.getAdjustment_value() == 0) &&
|
||||
(item.getMultiple() == 0 || item.getMultiple() == 1)) {
|
||||
return depth;
|
||||
}
|
||||
|
||||
List<DepthEntry> asks = depth.getAsks();
|
||||
for (int i = 0; i < asks.size(); i++) {
|
||||
DepthEntry depthEntry = asks.get(i);
|
||||
|
||||
/**
|
||||
* 调整交易量倍数和 行情值
|
||||
*/
|
||||
if (item.getMultiple() > 0) {
|
||||
depthEntry.setAmount(Arith.mul(depthEntry.getAmount(), item.getMultiple()));
|
||||
}else {
|
||||
depthEntry.setAmount(depthEntry.getAmount());
|
||||
}
|
||||
depthEntry.setPrice(Arith.add(depthEntry.getPrice(), item.getAdjustment_value()));
|
||||
}
|
||||
|
||||
List<DepthEntry> bids = depth.getBids();
|
||||
for (int i = 0; i < bids.size(); i++) {
|
||||
DepthEntry depthEntry = bids.get(i);
|
||||
/**
|
||||
* 调整交易量倍数和 行情值
|
||||
*/
|
||||
if (item.getMultiple() > 0) {
|
||||
depthEntry.setAmount(Arith.mul(depthEntry.getAmount(), item.getMultiple()));
|
||||
}else {
|
||||
depthEntry.setAmount(depthEntry.getAmount());
|
||||
}
|
||||
depthEntry.setPrice(Arith.add(depthEntry.getPrice(), item.getAdjustment_value()));
|
||||
}
|
||||
|
||||
return depth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Depth depth(String symbol, int maximum) {
|
||||
boolean current_lock = false;
|
||||
if (StringUtils.isNullOrEmpty(symbol)) {
|
||||
return null;
|
||||
}
|
||||
if (lock || (new Date().getTime() - last_time.getTime()) < interval) {
|
||||
ThreadUtils.sleep(sleep);
|
||||
if (maximum >= 100) {
|
||||
return null;
|
||||
} else {
|
||||
return this.depth(symbol, ++maximum);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
current_lock = true;
|
||||
lock = true;
|
||||
Map<String, Object> param = new HashMap<String, Object>();
|
||||
param.put("symbol", symbol);
|
||||
param.put("type", "step2");
|
||||
|
||||
String result = HttpHelper.getJSONFromHttp(Config.url + Config.depth, param, HttpMethodType.GET);
|
||||
JSONObject resultJson = JSON.parseObject(result);
|
||||
String status = resultJson.getString("status");
|
||||
if ("ok".equals(status)) {
|
||||
JSONObject dataJson = resultJson.getJSONObject("tick");
|
||||
Long ts = resultJson.getLongValue("ts");
|
||||
Depth depth = new Depth();
|
||||
|
||||
Item item = itemService.cacheBySymbolData(symbol);
|
||||
if (item == null) {
|
||||
return null;
|
||||
}
|
||||
depth.setSymbol(item.getSymbol());
|
||||
depth.setTs(ts);
|
||||
|
||||
JSONArray bidsArray = dataJson.getJSONArray("bids");
|
||||
for (int i = 0; i < bidsArray.size(); i++) {
|
||||
|
||||
JSONArray object = (JSONArray) bidsArray.get(i);
|
||||
DepthEntry depthEntry = new DepthEntry();
|
||||
depthEntry.setPrice(object.getDouble(0));
|
||||
depthEntry.setAmount(object.getDouble(1));
|
||||
depth.getBids().add(depthEntry);
|
||||
|
||||
}
|
||||
|
||||
JSONArray asksArray = dataJson.getJSONArray("asks");
|
||||
for (int i = 0; i < asksArray.size(); i++) {
|
||||
JSONArray object = (JSONArray) asksArray.get(i);
|
||||
DepthEntry depthEntry = new DepthEntry();
|
||||
depthEntry.setPrice(object.getDouble(0));
|
||||
depthEntry.setAmount(object.getDouble(1));
|
||||
depth.getAsks().add(depthEntry);
|
||||
|
||||
}
|
||||
|
||||
return depth;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("error", e);
|
||||
} finally {
|
||||
if (current_lock) {
|
||||
lock = false;
|
||||
last_time = new Date();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得近期交易记录,包装,数据本地化处理
|
||||
*/
|
||||
public Trade tradeDecorator(String symbol, int maximum) {
|
||||
Trade trade = this.trade(symbol, maximum);
|
||||
Item item = itemService.cacheBySymbolData(symbol);
|
||||
item = itemService.cacheBySymbol(item.getSymbol(), false);
|
||||
if ((trade == null || item.getAdjustment_value() == null || item.getAdjustment_value() == 0) &&
|
||||
(item.getMultiple() == 0 || item.getMultiple() == 1)) {
|
||||
return trade;
|
||||
}
|
||||
List<TradeEntry> data = trade.getData();
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
TradeEntry tradeEntry = data.get(i);
|
||||
|
||||
/**
|
||||
* 调整交易量倍数和 行情值
|
||||
*/
|
||||
if (item.getMultiple() > 0) {
|
||||
tradeEntry.setAmount(Arith.mul(tradeEntry.getAmount(), item.getMultiple()));
|
||||
}else {
|
||||
tradeEntry.setAmount(tradeEntry.getAmount());
|
||||
}
|
||||
tradeEntry.setPrice(Arith.add(tradeEntry.getPrice(), item.getAdjustment_value()));
|
||||
}
|
||||
return trade;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trade trade(String symbol, int maximum) {
|
||||
boolean current_lock = false;
|
||||
if (StringUtils.isNullOrEmpty(symbol)) {
|
||||
return null;
|
||||
}
|
||||
if (lock || (new Date().getTime() - last_time.getTime()) < interval) {
|
||||
ThreadUtils.sleep(sleep);
|
||||
if (maximum >= 100) {
|
||||
|
||||
return null;
|
||||
} else {
|
||||
return this.trade(symbol, ++maximum);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
current_lock = true;
|
||||
lock = true;
|
||||
Map<String, Object> param = new HashMap<String, Object>();
|
||||
param.put("symbol", symbol);
|
||||
|
||||
String result = HttpHelper.getJSONFromHttp(Config.url + Config.trade, param, HttpMethodType.GET);
|
||||
JSONObject resultJson = JSON.parseObject(result);
|
||||
String status = resultJson.getString("status");
|
||||
if ("ok".equals(status)) {
|
||||
JSONObject dataJson = resultJson.getJSONObject("tick");
|
||||
Long ts = resultJson.getLongValue("ts");
|
||||
|
||||
Trade trade = new Trade();
|
||||
|
||||
Item item = itemService.cacheBySymbolData(symbol);
|
||||
if (item == null) {
|
||||
return null;
|
||||
}
|
||||
trade.setSymbol(item.getSymbol());
|
||||
trade.setTs(ts);
|
||||
|
||||
JSONArray dataArray = dataJson.getJSONArray("data");
|
||||
for (int i = 0; i < dataArray.size(); i++) {
|
||||
JSONObject object = dataArray.getJSONObject(i);
|
||||
TradeEntry tradeEntry = new TradeEntry();
|
||||
tradeEntry.setTs(object.getLong("ts"));
|
||||
tradeEntry.setPrice(object.getDouble("price"));
|
||||
tradeEntry.setAmount(object.getDouble("amount"));
|
||||
tradeEntry.setDirection(object.getString("direction"));
|
||||
trade.getData().add(tradeEntry);
|
||||
|
||||
}
|
||||
return trade;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("error", e);
|
||||
} finally {
|
||||
if (current_lock) {
|
||||
lock = false;
|
||||
last_time = new Date();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Symbols> symbols() {
|
||||
List<Symbols> list = new ArrayList<Symbols>();
|
||||
boolean current_lock = false;
|
||||
if (lock || (new Date().getTime() - last_time.getTime()) < interval) {
|
||||
|
||||
return list;
|
||||
} else {
|
||||
try {
|
||||
current_lock = true;
|
||||
lock = true;
|
||||
Map<String, Object> param = new HashMap<String, Object>();
|
||||
String result = HttpHelper.getJSONFromHttp(Config.url + Config.symbols, param, HttpMethodType.GET);
|
||||
JSONObject resultJson = JSON.parseObject(result);
|
||||
String status = resultJson.getString("status");
|
||||
if ("ok".equals(status)) {
|
||||
JSONArray dataArray = resultJson.getJSONArray("data");
|
||||
for (int i = 0; i < dataArray.size(); i++) {
|
||||
JSONObject realtimeJson = dataArray.getJSONObject(i);
|
||||
Symbols symbols = new Symbols();
|
||||
symbols.setBase_currency(realtimeJson.getString("base-currency"));
|
||||
symbols.setQuote_currency(realtimeJson.getString("quote-currency"));
|
||||
symbols.setLeverage_ratio(realtimeJson.getDouble("leverage-ratio"));
|
||||
symbols.setPrice_precision(realtimeJson.getIntValue("price-precision"));
|
||||
symbols.setState(realtimeJson.getString("state"));
|
||||
symbols.setSymbol(realtimeJson.getString("symbol"));
|
||||
list.add(symbols);
|
||||
}
|
||||
|
||||
} else {
|
||||
logger.error(" symbols()error, resultJson [ " + resultJson.toJSONString() + " ]");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("error", e);
|
||||
} finally {
|
||||
if (current_lock) {
|
||||
lock = false;
|
||||
last_time = new Date();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setItemService(ItemService itemService) {
|
||||
this.itemService = itemService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSymbolRealPrize(String symbol) {
|
||||
return itemService.getRedisHandler().getString(MallRedisKeys.BRUSH_VIRTUAL_CURRENCY_PRICE+symbol);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSymbolRealCache(String symbol, String val) {
|
||||
itemService.getRedisHandler().setSyncString(MallRedisKeys.BRUSH_VIRTUAL_CURRENCY_PRICE+symbol,val);
|
||||
}
|
||||
|
||||
}
|
||||
58
comm/Hobi/src/project/hobi/util/DateUtils.java
Executable file
58
comm/Hobi/src/project/hobi/util/DateUtils.java
Executable file
@@ -0,0 +1,58 @@
|
||||
package project.hobi.util;
|
||||
|
||||
import kernel.util.PropertiesUtil;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class DateUtils {
|
||||
|
||||
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
|
||||
|
||||
public static final String DEFAULT_TIME_ZONE = PropertiesUtil.getProperty("mall.default.time.zone");
|
||||
|
||||
public static final String NORMAL_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
public static final String DFS_MMdd = "MMdd";
|
||||
|
||||
public static final String DFS_yyyyMMdd = "yyyyMMdd";
|
||||
|
||||
public static final String DFS_yyMMdd = "yyMMdd";
|
||||
|
||||
public static final String DF_MMdd = "MM-dd";
|
||||
|
||||
public static final String DF_HHmm = "HH:mm";
|
||||
|
||||
public static final String DF_MMddHH = "MM-dd HH";
|
||||
|
||||
public static final String DF_yyyyMM = "yyyy-MM";
|
||||
|
||||
public static final String DF_yyyyMMdd = "yyyy-MM-dd";
|
||||
|
||||
public static final String DF_yyyyMMddHH = "yyyy-MM-dd HH";
|
||||
|
||||
public static final String DF_yyyyMMddHHmm = "yyyy-MM-dd HH:mm";
|
||||
|
||||
public static final String DF_yyyyMMddHHmmss = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
public static final String DF_yyyyMMddHHmmssS = "yyyy-MM-dd HH:mm:ss.SSS";
|
||||
public static final String DF_MMddyyyy = "MM/dd/yyyy";
|
||||
|
||||
public static String timeStamp2Date(String seconds, String format) {
|
||||
if (seconds == null || seconds.isEmpty() || seconds.equals("null")) {
|
||||
return "";
|
||||
}
|
||||
if (format == null || format.isEmpty()) {
|
||||
format = "yyyy-MM-dd HH:mm:ss";
|
||||
}
|
||||
TimeZone timeZone = TimeZone.getTimeZone(DEFAULT_TIME_ZONE);
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(format);
|
||||
sdf.setTimeZone(timeZone);
|
||||
return sdf.format(new Date(Long.valueOf(seconds)));
|
||||
}
|
||||
|
||||
}
|
||||
77
comm/Hobi/src/project/web/admin/adminContractSymbolsController.java
Executable file
77
comm/Hobi/src/project/web/admin/adminContractSymbolsController.java
Executable file
@@ -0,0 +1,77 @@
|
||||
package project.web.admin;
|
||||
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import kernel.exception.BusinessException;
|
||||
import kernel.util.PropertiesUtil;
|
||||
import kernel.web.PageActionSupport;
|
||||
import project.hobi.AdminContractSymbolsService;
|
||||
|
||||
@RestController
|
||||
public class adminContractSymbolsController extends PageActionSupport {
|
||||
|
||||
private Logger logger = LogManager.getLogger(adminContractSymbolsController.class);
|
||||
|
||||
@Autowired
|
||||
private AdminContractSymbolsService adminContractSymbolsService;
|
||||
|
||||
private final String action = "normal/adminContractSymbolsAction!";
|
||||
|
||||
@RequestMapping(action + "list.action")
|
||||
public ModelAndView list(HttpServletRequest request) {
|
||||
|
||||
// 交易对中的报价币种
|
||||
String quote_currency = request.getParameter("quote_currency");
|
||||
// 交易对中的基础币种
|
||||
String base_currency = request.getParameter("base_currency");
|
||||
|
||||
String basePath = PropertiesUtil.getProperty("admin_url");
|
||||
basePath = getPath(request);
|
||||
this.checkAndSetPageNo(request.getParameter("pageNo"));
|
||||
|
||||
this.pageSize = 7;
|
||||
this.page = this.adminContractSymbolsService.pagedQuery(this.pageNo, pageSize, quote_currency, base_currency);
|
||||
List<String> quoteList = this.adminContractSymbolsService.getQuoteList();
|
||||
|
||||
ModelAndView modelAndView = new ModelAndView();
|
||||
modelAndView.addObject("pageNo", this.pageNo);
|
||||
modelAndView.addObject("pageSize", this.pageSize);
|
||||
modelAndView.addObject("page", this.page);
|
||||
modelAndView.addObject("basePath", basePath);
|
||||
modelAndView.addObject("quoteList", quoteList);
|
||||
modelAndView.setViewName("contract_manage_add_symbols_list");
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
private String getPath(HttpServletRequest request) {
|
||||
return String.format("%s://%s:%s%s", request.getScheme(),request.getServerName()
|
||||
,request.getServerPort(),request.getContextPath());
|
||||
}
|
||||
|
||||
@RequestMapping(action + "reload.action")
|
||||
public ModelAndView reload() {
|
||||
String message = "";
|
||||
String error = "";
|
||||
try {
|
||||
adminContractSymbolsService.saveReload();
|
||||
message = "数据同步完成";
|
||||
} catch (BusinessException e) {
|
||||
error = e.getMessage();
|
||||
} catch (Exception e) {
|
||||
logger.error("error ", e);
|
||||
error = "程序错误";
|
||||
}
|
||||
ModelAndView modelAndView = new ModelAndView();
|
||||
modelAndView.addObject("message", message);
|
||||
modelAndView.addObject("error", error);
|
||||
modelAndView.setViewName("contract_manage_add_symbols_list");
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
}
|
||||
141
comm/Hobi/src/project/web/api/DepthController.java
Executable file
141
comm/Hobi/src/project/web/api/DepthController.java
Executable file
@@ -0,0 +1,141 @@
|
||||
package project.web.api;
|
||||
|
||||
import kernel.web.BaseAction;
|
||||
import java.math.RoundingMode;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import kernel.exception.BusinessException;
|
||||
import kernel.util.StringUtils;
|
||||
import kernel.web.ResultObject;
|
||||
import project.data.DataService;
|
||||
import project.data.model.Depth;
|
||||
import project.data.model.DepthEntry;
|
||||
import project.item.ItemService;
|
||||
import project.item.model.Item;
|
||||
|
||||
/**
|
||||
* 市场深度数据 20档深度,根据页面取5档或20档
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
@CrossOrigin
|
||||
public class DepthController extends BaseAction {
|
||||
|
||||
@Autowired
|
||||
private DataService dataService;
|
||||
@Autowired
|
||||
private ItemService itemService;
|
||||
|
||||
@RequestMapping("api/hobi!getDepth.action")
|
||||
public String getDepth(HttpServletRequest request) {
|
||||
ResultObject resultObject = new ResultObject();
|
||||
|
||||
try {
|
||||
String symbol = request.getParameter("symbol");
|
||||
if (StringUtils.isNullOrEmpty(symbol)) {
|
||||
resultObject.setCode("400");
|
||||
resultObject.setMsg("[symbol]参数为空");
|
||||
return JSON.toJSONString(resultObject);
|
||||
}
|
||||
|
||||
// 数据处理
|
||||
Depth data = this.dataService.depth(symbol);
|
||||
|
||||
resultObject.setData(revise(data));
|
||||
return JSONObject.toJSONString(resultObject);
|
||||
} catch (BusinessException e) {
|
||||
resultObject.setCode("402");
|
||||
resultObject.setMsg(e.getMessage());
|
||||
return JSONObject.toJSONString(resultObject);
|
||||
} catch (Throwable e) {
|
||||
resultObject.setCode("500");
|
||||
resultObject.setMsg("服务器错误(500)");
|
||||
|
||||
return JSONObject.toJSONString(resultObject);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Map<String, Object> revise(Depth data) {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("symbol", data.getSymbol());
|
||||
map.put("ts", data.getTs());
|
||||
Item item = this.itemService.cacheBySymbol(data.getSymbol(), true);
|
||||
List<Map<String, Object>> asks_list = new ArrayList<Map<String, Object>>();
|
||||
for (int i = 0; i < data.getAsks().size(); i++) {
|
||||
DepthEntry depthEntry = data.getAsks().get(i);
|
||||
Map<String, Object> asks_map = new HashMap<String, Object>();
|
||||
|
||||
if (item.getDecimals() == null || item.getDecimals() < 0) {
|
||||
asks_map.put("price", depthEntry.getPrice());
|
||||
asks_map.put("amount", depthEntry.getAmount());
|
||||
} else {
|
||||
String format = "";
|
||||
if (item.getDecimals() == 0) {
|
||||
format = "#";
|
||||
} else {
|
||||
format = "#.";
|
||||
for (int j = 0; j < item.getDecimals(); j++) {
|
||||
format = format + "#";
|
||||
}
|
||||
}
|
||||
|
||||
DecimalFormat df = new DecimalFormat(format);
|
||||
df.setRoundingMode(RoundingMode.FLOOR);// 向下取整
|
||||
|
||||
asks_map.put("price", df.format(depthEntry.getPrice()));
|
||||
asks_map.put("amount", df.format(depthEntry.getAmount()));
|
||||
|
||||
}
|
||||
asks_list.add(asks_map);
|
||||
|
||||
}
|
||||
map.put("asks", asks_list);
|
||||
List<Map<String, Object>> bids_list = new ArrayList<Map<String, Object>>();
|
||||
for (int i = 0; i < data.getBids().size(); i++) {
|
||||
DepthEntry depthEntry = data.getBids().get(i);
|
||||
Map<String, Object> bids_map = new HashMap<String, Object>();
|
||||
if (item.getDecimals() == null || item.getDecimals() < 0) {
|
||||
bids_map.put("price", depthEntry.getPrice());
|
||||
bids_map.put("amount", depthEntry.getAmount());
|
||||
} else {
|
||||
String format = "";
|
||||
if (item.getDecimals() == 0) {
|
||||
format = "#";
|
||||
} else {
|
||||
format = "#.";
|
||||
for (int j = 0; j < item.getDecimals(); j++) {
|
||||
format = format + "#";
|
||||
}
|
||||
}
|
||||
|
||||
DecimalFormat df = new DecimalFormat(format);
|
||||
|
||||
bids_map.put("price", df.format(depthEntry.getPrice()));
|
||||
bids_map.put("amount", df.format(depthEntry.getAmount()));
|
||||
|
||||
}
|
||||
bids_list.add(bids_map);
|
||||
|
||||
}
|
||||
|
||||
map.put("bids", bids_list);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
||||
138
comm/Hobi/src/project/web/api/KlineController.java
Executable file
138
comm/Hobi/src/project/web/api/KlineController.java
Executable file
@@ -0,0 +1,138 @@
|
||||
package project.web.api;
|
||||
|
||||
import java.math.RoundingMode;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import kernel.exception.BusinessException;
|
||||
import kernel.util.Arith;
|
||||
import kernel.util.StringUtils;
|
||||
import kernel.web.ResultObject;
|
||||
import project.data.DataService;
|
||||
import project.data.model.Kline;
|
||||
import project.hobi.util.DateUtils;
|
||||
import project.item.ItemService;
|
||||
import project.item.model.Item;
|
||||
|
||||
/**
|
||||
* K线图
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
@CrossOrigin
|
||||
public class KlineController {
|
||||
|
||||
private Logger logger = LogManager.getLogger(KlineController.class);
|
||||
|
||||
@Autowired
|
||||
private DataService dataService;
|
||||
|
||||
@Autowired
|
||||
private ItemService itemService;
|
||||
|
||||
@RequestMapping("api/hobi!getKline.action")
|
||||
public String getKline(HttpServletRequest request) {
|
||||
ResultObject resultObject = new ResultObject();
|
||||
String symbol = request.getParameter("symbol");
|
||||
// 1min, 5min, 15min, 30min, 60min, 4hour, 1day, 1mon, 1week
|
||||
String line = request.getParameter("line");
|
||||
try {
|
||||
if (StringUtils.isNullOrEmpty(symbol)) {
|
||||
resultObject.setCode("400");
|
||||
resultObject.setMsg("[symbol]参数为空");
|
||||
return JSON.toJSONString(resultObject);
|
||||
}
|
||||
|
||||
// 数据处理
|
||||
List<Kline> data = this.dataService.kline(symbol, line);
|
||||
if ("1day".equals(line) || "1mon".equals(line) || "1week".equals(line)) {
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
data.get(i).setCurrent_time(
|
||||
DateUtils.timeStamp2Date(String.valueOf(data.get(i).getTs()), "yyyy-MM-dd"));
|
||||
}
|
||||
} else if ("1min".equals(line)) {
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
data.get(i).setCurrent_time(DateUtils.timeStamp2Date(String.valueOf(data.get(i).getTs()), "HH:mm"));
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
data.get(i).setCurrent_time(
|
||||
DateUtils.timeStamp2Date(String.valueOf(data.get(i).getTs()), "MM-dd HH:mm"));
|
||||
}
|
||||
}
|
||||
resultObject.setData(this.revise(data, line));
|
||||
} catch (BusinessException e) {
|
||||
resultObject.setCode("402");
|
||||
resultObject.setMsg(e.getMessage());
|
||||
} catch (Throwable e) {
|
||||
resultObject.setCode("500");
|
||||
resultObject.setMsg("服务器错误(500)");
|
||||
logger.error("error:", e);
|
||||
}
|
||||
return JSONObject.toJSONString(resultObject);
|
||||
}
|
||||
|
||||
private List<Map<String, Object>> revise(List<Kline> data, String line) {
|
||||
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
|
||||
Item item = null;
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
Kline kline = data.get(i);
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("line", line);
|
||||
map.put("symbol", kline.getSymbol());
|
||||
map.put("ts", kline.getTs());
|
||||
map.put("current_time", kline.getCurrent_time());
|
||||
if (item == null) {
|
||||
item = this.itemService.cacheBySymbol(kline.getSymbol(), true);
|
||||
}
|
||||
if (item.getDecimals() == null || item.getDecimals() < 0) {
|
||||
map.put("open", kline.getOpen());
|
||||
map.put("close", kline.getClose());
|
||||
map.put("high", kline.getHigh());
|
||||
map.put("low", kline.getLow());
|
||||
map.put("volume", kline.getVolume());
|
||||
} else {
|
||||
String format = "";
|
||||
if (item.getDecimals() == 0) {
|
||||
format = "#";
|
||||
} else {
|
||||
format = "#.";
|
||||
for (int j = 0; j < item.getDecimals(); j++) {
|
||||
format = format + "#";
|
||||
}
|
||||
}
|
||||
|
||||
DecimalFormat df = new DecimalFormat(format);
|
||||
df.setRoundingMode(RoundingMode.FLOOR);// 向下取整
|
||||
|
||||
map.put("open", Double.valueOf(df.format(kline.getOpen())));
|
||||
map.put("close", Double.valueOf(df.format(kline.getClose())));
|
||||
map.put("high", Double.valueOf(df.format(kline.getHigh())));
|
||||
map.put("low", Double.valueOf(df.format(kline.getLow())));
|
||||
|
||||
if (item.getMultiple() > 0) {
|
||||
map.put("volume", Double.valueOf(df.format(Arith.mul(kline.getVolume(), item.getMultiple()))));
|
||||
}else {
|
||||
map.put("volume", Double.valueOf(df.format(kline.getVolume())));
|
||||
}
|
||||
}
|
||||
list.add(map);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
135
comm/Hobi/src/project/web/api/RealtimeController.java
Executable file
135
comm/Hobi/src/project/web/api/RealtimeController.java
Executable file
@@ -0,0 +1,135 @@
|
||||
package project.web.api;
|
||||
|
||||
import java.math.RoundingMode;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import kernel.exception.BusinessException;
|
||||
import kernel.util.StringUtils;
|
||||
import kernel.web.ResultObject;
|
||||
import project.data.DataService;
|
||||
import project.data.model.Realtime;
|
||||
import project.item.ItemService;
|
||||
import project.item.model.Item;
|
||||
|
||||
/**
|
||||
* 行情实时价格 http接口
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
@CrossOrigin
|
||||
public class RealtimeController {
|
||||
|
||||
private Logger logger = LogManager.getLogger(RealtimeController.class);
|
||||
|
||||
@Autowired
|
||||
private DataService dataService;
|
||||
|
||||
@Autowired
|
||||
private ItemService itemService;
|
||||
|
||||
@RequestMapping("api/hobi!getRealtime.action")
|
||||
public String getRealtime(HttpServletRequest request) {
|
||||
ResultObject resultObject = new ResultObject();
|
||||
String symbol = request.getParameter("symbol");
|
||||
// asc升序 desc 降序
|
||||
String order = request.getParameter("order");
|
||||
try {
|
||||
|
||||
if (StringUtils.isNullOrEmpty(symbol)) {
|
||||
resultObject.setCode("400");
|
||||
resultObject.setMsg("[symbol]参数为空");
|
||||
return JSON.toJSONString(resultObject);
|
||||
}
|
||||
|
||||
// 数据处理
|
||||
List<Realtime> data = this.dataService.realtime(symbol);
|
||||
|
||||
if (!StringUtils.isNullOrEmpty(order)) {
|
||||
List<Realtime> list_clone = new ArrayList<Realtime>();
|
||||
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
Realtime realtime = (Realtime) data.get(i).clone();
|
||||
realtime.setOrder(order);
|
||||
list_clone.add(realtime);
|
||||
}
|
||||
Collections.sort(list_clone);
|
||||
data = list_clone;
|
||||
}
|
||||
resultObject.setData(this.revise(data));
|
||||
return JSONObject.toJSONString(resultObject);
|
||||
} catch (BusinessException e) {
|
||||
resultObject.setCode("402");
|
||||
resultObject.setMsg(e.getMessage());
|
||||
return JSONObject.toJSONString(resultObject);
|
||||
} catch (Throwable e) {
|
||||
resultObject.setCode("500");
|
||||
resultObject.setMsg("服务器错误(500)");
|
||||
logger.error("error:", e);
|
||||
return JSONObject.toJSONString(resultObject);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Map<String, Object>> revise(List<Realtime> data) {
|
||||
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
Realtime realtime = data.get(i);
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("symbol", realtime.getSymbol());
|
||||
map.put("ts", realtime.getTs());
|
||||
map.put("current_time", realtime.getCurrent_time());
|
||||
map.put("name", realtime.getName());
|
||||
map.put("change_ratio", realtime.getChange_ratio());
|
||||
Item item = this.itemService.cacheBySymbol(realtime.getSymbol(), true);
|
||||
if (item.getDecimals() == null || item.getDecimals() < 0) {
|
||||
map.put("open", realtime.getOpen());
|
||||
map.put("close", realtime.getClose());
|
||||
map.put("high", realtime.getHigh());
|
||||
map.put("low", realtime.getLow());
|
||||
map.put("volume", realtime.getVolume());
|
||||
map.put("amount", realtime.getAmount());
|
||||
} else {
|
||||
String format = "";
|
||||
if (item.getDecimals() == 0) {
|
||||
format = "#";
|
||||
} else {
|
||||
format = "#.";
|
||||
for (int j = 0; j < item.getDecimals(); j++) {
|
||||
format = format + "#";
|
||||
}
|
||||
}
|
||||
|
||||
DecimalFormat df = new DecimalFormat(format);
|
||||
df.setRoundingMode(RoundingMode.FLOOR);// 向下取整
|
||||
|
||||
map.put("open", df.format(realtime.getOpen()));
|
||||
map.put("close", df.format(realtime.getClose()));
|
||||
map.put("high", df.format(realtime.getHigh()));
|
||||
map.put("low", df.format(realtime.getLow()));
|
||||
map.put("volume", df.format(realtime.getVolume()));
|
||||
map.put("amount", df.format(realtime.getAmount()));
|
||||
|
||||
}
|
||||
list.add(map);
|
||||
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
112
comm/Hobi/src/project/web/api/TradeController.java
Executable file
112
comm/Hobi/src/project/web/api/TradeController.java
Executable file
@@ -0,0 +1,112 @@
|
||||
package project.web.api;
|
||||
|
||||
import java.math.RoundingMode;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import kernel.exception.BusinessException;
|
||||
import kernel.util.StringUtils;
|
||||
import kernel.web.BaseAction;
|
||||
import kernel.web.ResultObject;
|
||||
import project.data.DataService;
|
||||
import project.data.model.Trade;
|
||||
import project.data.model.TradeEntry;
|
||||
import project.item.ItemService;
|
||||
import project.item.model.Item;
|
||||
|
||||
/**
|
||||
* 获得近期交易记录 页面保持20条,这个只能刷到最新的几条记录。
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
@CrossOrigin
|
||||
public class TradeController extends BaseAction {
|
||||
|
||||
@Autowired
|
||||
private DataService dataService;
|
||||
@Autowired
|
||||
private ItemService itemService;
|
||||
|
||||
@RequestMapping("api/hobi!getTrade.action")
|
||||
public String getTrade(HttpServletRequest request) {
|
||||
ResultObject resultObject = new ResultObject();
|
||||
|
||||
try {
|
||||
String symbol = request.getParameter("symbol");
|
||||
if (StringUtils.isNullOrEmpty(symbol)) {
|
||||
resultObject.setCode("400");
|
||||
resultObject.setMsg("[symbol]参数为空");
|
||||
return JSON.toJSONString(resultObject);
|
||||
}
|
||||
|
||||
// 数据处理
|
||||
Trade data = this.dataService.trade(symbol);
|
||||
if (data != null) {
|
||||
resultObject.setData(revise(data));
|
||||
}
|
||||
return JSONObject.toJSONString(resultObject);
|
||||
} catch (BusinessException e) {
|
||||
resultObject.setCode("402");
|
||||
resultObject.setMsg(e.getMessage());
|
||||
return JSONObject.toJSONString(resultObject);
|
||||
} catch (Throwable e) {
|
||||
resultObject.setCode("500");
|
||||
resultObject.setMsg("服务器错误(500)");
|
||||
return JSONObject.toJSONString(resultObject);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Object> revise(Trade data) {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("symbol", data.getSymbol());
|
||||
map.put("ts", data.getTs());
|
||||
Item item = this.itemService.cacheBySymbol(data.getSymbol(), true);
|
||||
List<Map<String, Object>> tradeEntry_list = new ArrayList<Map<String, Object>>();
|
||||
for (int i = 0; i < data.getData().size(); i++) {
|
||||
TradeEntry tradeEntry = data.getData().get(i);
|
||||
Map<String, Object> tradeEntry_map = new HashMap<String, Object>();
|
||||
tradeEntry_map.put("direction", tradeEntry.getDirection());
|
||||
tradeEntry_map.put("ts", tradeEntry.getTs());
|
||||
tradeEntry_map.put("current_time", tradeEntry.getCurrent_time());
|
||||
|
||||
if (item.getDecimals() == null || item.getDecimals() < 0) {
|
||||
tradeEntry_map.put("price", tradeEntry.getPrice());
|
||||
tradeEntry_map.put("amount", tradeEntry.getAmount());
|
||||
} else {
|
||||
String format = "";
|
||||
if (item.getDecimals() == 0) {
|
||||
format = "#";
|
||||
} else {
|
||||
format = "#.";
|
||||
for (int j = 0; j < item.getDecimals(); j++) {
|
||||
format = format + "#";
|
||||
}
|
||||
}
|
||||
|
||||
DecimalFormat df = new DecimalFormat(format);
|
||||
df.setRoundingMode(RoundingMode.FLOOR);// 向下取整
|
||||
|
||||
tradeEntry_map.put("price", df.format(tradeEntry.getPrice()));
|
||||
tradeEntry_map.put("amount", df.format(tradeEntry.getAmount()));
|
||||
|
||||
}
|
||||
tradeEntry_list.add(tradeEntry_map);
|
||||
|
||||
}
|
||||
map.put("data", tradeEntry_list);
|
||||
return map;
|
||||
}
|
||||
}
|
||||
112
comm/Hobi/src/project/web/api/TrendController.java
Executable file
112
comm/Hobi/src/project/web/api/TrendController.java
Executable file
@@ -0,0 +1,112 @@
|
||||
package project.web.api;
|
||||
|
||||
import java.math.RoundingMode;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import kernel.exception.BusinessException;
|
||||
import kernel.util.StringUtils;
|
||||
import kernel.web.ResultObject;
|
||||
import project.data.DataService;
|
||||
import project.data.model.Trend;
|
||||
import project.item.ItemService;
|
||||
import project.item.model.Item;
|
||||
|
||||
/**
|
||||
* 分时图
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
@CrossOrigin
|
||||
public class TrendController {
|
||||
|
||||
private Logger logger = LogManager.getLogger(KlineController.class);
|
||||
|
||||
@Autowired
|
||||
private DataService dataService;
|
||||
@Autowired
|
||||
private ItemService itemService;
|
||||
|
||||
@RequestMapping("api/hobi!getTrend.action")
|
||||
public String getTrend(HttpServletRequest request) {
|
||||
ResultObject resultObject = new ResultObject();
|
||||
|
||||
try {
|
||||
String symbol = request.getParameter("symbol");
|
||||
if (StringUtils.isNullOrEmpty(symbol)) {
|
||||
resultObject.setCode("400");
|
||||
resultObject.setMsg("[symbol]参数为空");
|
||||
return JSON.toJSONString(resultObject);
|
||||
}
|
||||
// 数据处理
|
||||
List<Trend> data = this.dataService.trend(symbol);
|
||||
if (data != null) {
|
||||
resultObject.setData(revise(data));
|
||||
}
|
||||
} catch (BusinessException e) {
|
||||
resultObject.setCode("402");
|
||||
resultObject.setMsg(e.getMessage());
|
||||
} catch (Throwable e) {
|
||||
resultObject.setCode("500");
|
||||
resultObject.setMsg("服务器错误(500)");
|
||||
logger.error("error:", e);
|
||||
}
|
||||
return JSONObject.toJSONString(resultObject);
|
||||
}
|
||||
|
||||
private List<Map<String, Object>> revise(List<Trend> data) {
|
||||
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
|
||||
Item item = null;
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
Trend trend = data.get(i);
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("symbol", trend.getSymbol());
|
||||
map.put("ts", trend.getTs());
|
||||
map.put("current_time", trend.getCurrent_time());
|
||||
if (item == null) {
|
||||
item = this.itemService.cacheBySymbol(trend.getSymbol(), true);
|
||||
}
|
||||
if (item.getDecimals() == null || item.getDecimals() < 0) {
|
||||
map.put("trend", trend.getTrend());
|
||||
map.put("volume", trend.getVolume());
|
||||
map.put("amount", trend.getAmount());
|
||||
} else {
|
||||
String format = "";
|
||||
if (item.getDecimals() == 0) {
|
||||
format = "#";
|
||||
} else {
|
||||
format = "#.";
|
||||
for (int j = 0; j < item.getDecimals(); j++) {
|
||||
format = format + "#";
|
||||
}
|
||||
}
|
||||
|
||||
DecimalFormat df = new DecimalFormat(format);
|
||||
df.setRoundingMode(RoundingMode.FLOOR);// 向下取整
|
||||
|
||||
map.put("trend", df.format(trend.getTrend()));
|
||||
map.put("volume", df.format(trend.getVolume()));
|
||||
map.put("amount", df.format(trend.getAmount()));
|
||||
|
||||
}
|
||||
list.add(map);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user