first commit

This commit is contained in:
Ray
2026-02-19 03:37:37 +08:00
commit ccfd8c79a4
2813 changed files with 453657 additions and 0 deletions

View 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;
}
}

View 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;
}
}

View 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);
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View File

@@ -0,0 +1,10 @@
package project.data.internal;
public interface KlineInitService {
/**
* 初始化K线数据初始化前会删除旧数据
*
* @param symbol 指定产品代码,多个用逗号分割
*/
public void klineInit(String symbols);
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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) {
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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>

View 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();
}
}

View 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>

View 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();
}
}

View 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>

View 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;
/**
* 交易对状态;可能值: [onlineoffline,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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}