Java 股票K線邏輯 程式碼
阿新 • • 發佈:2019-02-03
package com.gustoboard.bm.rtdg.service.impl; import com.gustoboard.bm.rtdg.mapper.TradeMapper; import com.gustoboard.bm.rtdg.model.KTrade; import com.gustoboard.bm.rtdg.model.Market; import com.gustoboard.bm.rtdg.util.DateUtils; import com.gustoboard.bm.rtdg.util.JacksonUtils; import com.gustoboard.bm.rtdg.util.RedisEnum; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.text.ParseException; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.concurrent.TimeUnit; /** * 後期優化處理 通過 jprofile 調優後發現cpu利用率偏高 整體專案線上%12 左右有峰值 * 對於 15分鐘內k線 的只需存入10天左右的資料 如果使用者拖動到10天以後通過查詢拼接5天一檔 * 啟動定時器執行緒來單獨執行K線方法資料 錯開其他統計定時器 * 這裡提供程式碼邏輯 */ @Service public class KLineService { @Autowired private TradeMapper tradeMapper; @Autowired private RedisTemplate<String, String> redisTemplate; private final static Logger logger = LoggerFactory.getLogger(KLineService.class); // 1 5 15 30 60 2 4 6個 12 一天 3天 7天 private static final int[] time = {1, 5, 15, 30, 60, 120, 240, 360, 720, 1440, 4320, 10080}; /** * 30秒輪詢一次 */ @Scheduled(fixedRate = 30000) public void TradeKLine() { //redis 獲取股票的id 和初始時間初始價格 String marketRedis = redisTemplate.opsForValue().get(RedisEnum.GUSTO.getDesc() + "market"); List<Market> integers = null; if (null != marketRedis) { integers = JacksonUtils.getObjectFromJson(marketRedis, ArrayList.class, Market.class); } else { integers = tradeMapper.listMarket(); } //迴圈股票 for (int i = 0; i < integers.size(); i++) { Market market = integers.get(i); //初始最後價格 BigDecimal priceslasts = new BigDecimal("0"); //迴圈時間 for (int j = 0; j < time.length; j++) { String memberRedis = redisTemplate.opsForValue().get(RedisEnum.GUSTO.getDesc() + market.getId() + ":k:" + time[j]); Date openingDate = null; ArrayList<ArrayList> objectFromJson = null; if (null != memberRedis) { objectFromJson = JacksonUtils.getObjectFromJson(memberRedis, ArrayList.class, Object.class); //獲取redis最後的時間搓 Long endDate = (Long) objectFromJson.get(objectFromJson.size() - 1).get(0); openingDate = DateUtils.dateParse(endDate, null); //獲取最後的價格 priceslasts = new BigDecimal(objectFromJson.get(objectFromJson.size() - 1).get(4).toString()); } else { //獲取債捲髮行的時間 openingDate = market.getOpeningDate(); //獲取債捲髮行價格 priceslasts = market.getIssuePrice().setScale(2, BigDecimal.ROUND_HALF_UP); } //獲取發行 Date date = null; try { date = DateUtils.dateParse(DateUtils.dateFormat(openingDate, null), null); } catch (ParseException e) { e.printStackTrace(); } //獲取當前時間至 redis 最後一個時間 的分鐘數 long distanceTimes = DateUtils.getDistanceTimes(new Date(), date); String listStirng = null; ArrayList<ArrayList> lists = new ArrayList<ArrayList>(); int sum = 0; for (int k = 0; k < distanceTimes; k++) { if (k % time[j] == 0) { //上次最後一個的價格 Date dateEnd = DateUtils.dateAddSeconds(date, (sum * time[j]) * 60); //刪除掉最後一個 if(dateEnd.getTime()==date.getTime()&& objectFromJson!=null){ objectFromJson.remove(objectFromJson.size()-1); } Date dateStrat = DateUtils.dateAddSeconds(date, ((sum + 1) * time[j]) * 60); sum = sum + 1; KTrade trade = new KTrade(); trade.setMarketId(market.getId()); trade.setCreatedAtEnd(dateEnd); trade.setCreatedAtStart(dateStrat); KTrade kTrades = tradeMapper.listHistoryCurrency(trade); ArrayList list = new ArrayList(6); if (null != kTrades) { //時間搓 list.add(dateEnd.getTime()); //當前時間區間的第一個價格 list.add(kTrades.getPriceFirst()); //當前時間區間最高價格 list.add(kTrades.getPriceMax()); //當前時間區間最低 list.add(kTrades.getPriceMin()); //當前時間區間最後 list.add(kTrades.getPriceLast()); //當前時間數量 list.add(kTrades.getVolumeSum()); priceslasts = kTrades.getPriceLast().setScale(2, BigDecimal.ROUND_HALF_UP); } else { list.add(dateEnd.getTime()); list.add(priceslasts); list.add(priceslasts); list.add(priceslasts); list.add(priceslasts); list.add(0); } lists.add(list); } } if (null != objectFromJson) { objectFromJson.addAll(lists); listStirng = JacksonUtils.getJsonObject(objectFromJson); } else { listStirng = JacksonUtils.getJsonObject(lists); } redisTemplate.opsForValue().set(RedisEnum.GUSTO.getDesc() + market.getId() + ":k:" + time[j], listStirng, 1500, TimeUnit.MINUTES); lists.clear(); } //儲存 每月 的 K線openingDate 這個時間 為第一個月 ArrayList<ArrayList> listMonth = new ArrayList<ArrayList>(); int monthDifference = DateUtils.getMonthDifference(market.getOpeningDate(), new Date()); for (int j = 0; j < monthDifference; j++) { //上次最後一個的價格 Date monthOne = DateUtils.getMonthOne(market.getOpeningDate(), j); Date monthLast = DateUtils.getMonthLast(market.getOpeningDate(), j); KTrade trade = new KTrade(); trade.setMarketId(market.getId()); trade.setCreatedAtEnd(monthOne); trade.setCreatedAtStart(monthLast); KTrade kTrades = tradeMapper.listHistoryCurrency(trade); ArrayList list = new ArrayList(6); if (null != kTrades) { list.add(monthLast.getTime()); list.add(kTrades.getPriceFirst()); list.add(kTrades.getPriceMax()); list.add(kTrades.getPriceMin()); list.add(kTrades.getPriceLast()); list.add(kTrades.getVolumeSum()); priceslasts = kTrades.getPriceLast().setScale(2, BigDecimal.ROUND_HALF_UP); } else { list.add(monthLast.getTime()); list.add(priceslasts); list.add(priceslasts); list.add(priceslasts); list.add(priceslasts); list.add(0); } listMonth.add(list); } redisTemplate.opsForValue().set(RedisEnum.GUSTO.getDesc() + market.getId() + ":k:month", JacksonUtils.getJsonObject(listMonth), 1500, TimeUnit.MINUTES); /** * if period == 1 * # 24*60 = 1440 * if point = @r.lindex(key(market, 1), -1441) * Rails.cache.write "peatio:#{market}:ticker:open", JSON.parse(point)[4] * end * end * end * 獲取24小時之前的最後一筆價格 */ String kRedis1 = redisTemplate.opsForValue().get(RedisEnum.GUSTO.getDesc() + market.getId() + ":k:" + time[0]); if (null != kRedis1) { ArrayList<ArrayList> objectFromJson = JacksonUtils.getObjectFromJson(kRedis1, ArrayList.class, Object.class); int low = (objectFromJson.size() - 1441); if (low >= 0) { ArrayList arrayList = objectFromJson.get(low); String lastprices = arrayList.get(4).toString(); redisTemplate.opsForValue().set(RedisEnum.GUSTO.getDesc() + market.getId() + ":ticker:open", lastprices, 1500, TimeUnit.MINUTES); } } } } }