fundvaluation2/src/com/pingan/rbpfunval/Process
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.slf4j.LoggerFactory;
import com.pingan.rbpfundval2.dao.fundDao;
import com.pingan.rbpfundval2.model.DatasourceStatus;
import com.pingan.rbpfundval2.model.FundDeviError;
import com.pingan.rbpfundval2.model.FundDividend;
import com.pingan.rbpfundval2.model.FundTop10Config;
import com.pingan.rbpfundval2.model.FundValDeviation;
import com.pingan.rbpfundval2.model.FundValError;
import com.pingan.rbpfundval2.model.FundValGlobalError;
import com.pingan.rbpfundval2.model.FundValuation;
import com.pingan.rbpfundval2.model.StockRealtime;
public class Process {
private static Logger logger = LoggerFactory.getLogger(Process.class);
private static SqlSession session;
private static fundDao fd;
private static String resource = "mybatis-config.xml";
private static String datasource = "PA";
private static String version = "";
private static String currentDate = "";
private static String preTradeday = "";
// 滿足條件的TOP10基金列表
private static List<FundTop10Qualification> fundTop10QualifiedList = null;
// 全部股混型基金前十股票配置
private static List<FundTop10Config> fundTop10ConfigList = null;
// 全部股混型基金前十股票配置, 按基金代號歸類
private static Map<String, List<FundTop10Config>> fundTop10ConfigMap = null;
//基金分紅信息
private static Map<String, FundDividend> fundDividendMap = null;
private static String loggerPrefix = "";
static {
try {
Properties properties = new Properties();
//測試
String userPath = System.getProperty("user.home");
userPath = userPath + "/java/fundvaluation2/";
String appFilePath = userPath + "application.properties";
//本地
//userPath = "D:\\work\\fundValuation2_WS\\fundValuation2\\src";
//appFilePath = userPath + "\\application.properties";
logger.info("user.home:" + userPath);
logger.info("appFilePath:" + appFilePath);
BufferedReader bufferedReader = new BufferedReader(new FileReader(appFilePath));
properties.load(bufferedReader);
version = properties.getProperty("version");
logger.info("version:" + properties.getProperty("version"));
} catch (IOException e) {
logger.error(e.getMessage());
}
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
boolean isSupplemented = false;
int iprocessType = 0;
// 0-正常流程, 計算當前時間兩分鐘前估值
// 1-補算缺失的top10實時估值數據
// 2-全局補算top10估值數據, 和全局補算基金實時偏離度
// 3-補算錯誤表中基金實時偏離度
if (args.length > 0) {
if (args[0].equals("0")) {
iprocessType = 0;
isSupplemented = false;
} else if (args[0].equals("1")) {
iprocessType = 1;
isSupplemented = true;
} else if (args[0].equals("2")) {
iprocessType = 2;
isSupplemented = true;
} else if (args[0].equals("3")) {
iprocessType = 3;
isSupplemented = true;
}
else if (args[0].equals("9")) { // 測試流程
iprocessType = 9;
}
} else {
logger.info("Lack of parameters! ");
return;
}
loggerPrefix = "[process " + iprocessType + "] - ";
init();
// currentDate = "20180928";
// 如果當前時間是交易日,則返回當前時間,否則返回空
String currentTradeDay = fd.getTradeDay(currentDate);
if (currentTradeDay == null) {
logger.info(loggerPrefix + "Current day is not trade day! ");
releaseResource();
return;
}
// 獲取當前時間的2分鐘前的時間
long time = 2 * 60 * 1000;// 2分鐘
Date beforeDate = new Date(new Date().getTime() - time);// 2分鐘前的時間
String valuationTime = new SimpleDateFormat("yyyyMMddHHmm").format(beforeDate);
//valuationTime = "201810101430";
// 獲取前一個交易日
preTradeday = fd.getPreTradeDay(currentDate);
logger.info(loggerPrefix + "preTradeday: " + preTradeday);
logger.info(loggerPrefix + "valuationTime: " + valuationTime);
logger.info(loggerPrefix + " time1: " + new Date());
fundTop10QualifiedList = fd.getFundTop10Qualification(currentDate, preTradeday);
logger.info(loggerPrefix + "fundTop10QualifiedList size: " + fundTop10QualifiedList.size());
fundTop10ConfigList = fd.getFundTop10Config(currentDate);
logger.info(loggerPrefix + "fundTop10ConfigList size: " + fundTop10ConfigList.size());
logger.info(loggerPrefix + " time2: " + new Date());
if (fundTop10QualifiedList == null || fundTop10QualifiedList.size() == 0 || fundTop10ConfigList == null
|| fundTop10ConfigList.size() == 0) {
logger.info(loggerPrefix + "Fund config information is empty!");
// 如果走正常流程基金配置表沒數據,寫入全局錯誤表
if (iprocessType == 0) {
fd.insertFundValGlobalError(new FundValGlobalError(currentDate, valuationTime, "01", "TOP10基金配置表無數據",
new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())));
session.commit();
}
releaseResource();
return;
}
fundTop10ConfigMap = new HashMap<String, List<FundTop10Config>>();
for (FundTop10Config ftc : fundTop10ConfigList) {
String fundId = ftc.getSymbolOf();
if (fundTop10ConfigMap.containsKey(fundId)) {
List<FundTop10Config> fundList = fundTop10ConfigMap.get(fundId);
fundList.add(ftc);
} else {
List<FundTop10Config> fundList = new ArrayList<FundTop10Config>();
fundList.add(ftc);
fundTop10ConfigMap.put(fundId, fundList);
}
}
logger.info(loggerPrefix + " time3: " + new Date());
logger.info(loggerPrefix + "fundTop10ConfigMap size: " + fundTop10ConfigMap.size());
// List<FundValuation> valuationList = new ArrayList<>();
// 獲取當前數據源的狀態
DatasourceStatus ds = fd.getDatasourceStatus(currentDate);
if (ds == null)
datasource = "PA";
else if (ds.getJqStatus().equals("1") && ds.getPaStatus().equals("0"))
datasource = "JQ";
else
datasource = "PA";
// datasource = "JQ";
logger.info(loggerPrefix + "當前數據源: " + datasource);
//初始化基金分紅信息
initFundDividendMap(currentDate);
if (iprocessType == 0) {
logger.info(loggerPrefix + "start process 0...");
boolean result = produceValuationData(valuationTime, isSupplemented, iprocessType);
if(result){
try{
Thread.sleep(10000);
}catch(InterruptedException e){
logger.error(e.getMessage());
}
produceDeviationData(valuationTime, isSupplemented, iprocessType);
}
logger.info(loggerPrefix + "end process 0...");
} else if (iprocessType == 1) {
logger.info(loggerPrefix + "start process 1...");
List<String> timeList = fd.getDistinctErrorTimeList(currentDate);
if (timeList != null && timeList.size() > 0) {
logger.info(loggerPrefix + " There are errors in fund_realtime_valuation_error table.");
logger.info(loggerPrefix + " total timeList size: " + timeList.size());
List<String> shortTimeList = timeList.subList(0, timeList.size()>8?8:timeList.size());
fd.markErrorProcessing(shortTimeList);
session.commit();
logger.info(loggerPrefix + "markErrorProcessing "+shortTimeList);
try {
for (String strTime : shortTimeList) {
if (strTime.trim().length() > 12)
strTime = strTime.substring(0, 12);
logger.info(loggerPrefix + " current time: " + strTime);
logger.info(loggerPrefix + " processing timeList: "+shortTimeList);
boolean result = addValuationData(strTime);
logger.info(loggerPrefix + "addValuationData result is " + result);
}
} catch (Exception e) {
logger.error(e.getMessage());
logger.info(loggerPrefix +"error message: "+e.toString());
return;
} finally {
logger.info(loggerPrefix + "releaseErrorProcessing " + shortTimeList);
fd.releaseErrorProcessing(shortTimeList);
session.commit();
releaseResource();
}
} else {
logger.info(loggerPrefix + " There is no new error in fund_realtime_valuation_error table.");
}
logger.info(loggerPrefix + "end process 1...");
}
else if (iprocessType == 2) {
logger.info(loggerPrefix + "start process 2...");
List<FundValGlobalError> fvgeList = fd.getFundValGlobalErrorList(currentDate);
if (fvgeList == null || fvgeList.size() == 0) {
releaseResource();
logger.info(loggerPrefix + "There is no error in fund_realtime_valuation_global_error_top10.");
return;
}
List<String> idList = fvgeList.stream().map(f -> f.getErrorId()).collect(Collectors.toList());
// 狀態加鎖
fd.markGlobalErrorProcessing(idList);
session.commit();
logger.info(loggerPrefix + "markGlobalErrorProcessing");
try {
// 循環取錯誤信息
for (FundValGlobalError fvge : fvgeList) {
String valtime = fvge.getValuationTime().trim();
boolean result = produceValuationData(valtime, isSupplemented, iprocessType);
if (result) {
fvge.setProcessCount(fvge.getProcessCount() + 1);
fvge.setReprocessOk("1");
fd.updateGlobalError(fvge);
session.commit();
try{
Thread.sleep(5000);
}catch(InterruptedException e){
logger.error(e.getMessage());
}
produceDeviationData(valtime, isSupplemented, iprocessType);
}
}
} catch (Exception e) {
logger.error(loggerPrefix+"raise process 2 exception...");
logger.error(e.getMessage());
return;
} finally {
// 狀態解鎖
logger.info(loggerPrefix + "releaseGlobalErrorProcessing");
fd.releaseGlobalErrorProcessing(idList);
session.commit();
releaseResource();
}
logger.info(loggerPrefix + "end process 2...");
}else if (iprocessType == 3){
logger.info(loggerPrefix + "start process 3...");
List<String> timeList = fd.getDistinctDeviErrorTimeList(currentDate);
if (timeList != null && timeList.size() > 0) {
logger.info(loggerPrefix + " There are errors in fund_realtime_valuation_devi_error_top10 table.");
logger.info(loggerPrefix + " total timeList size: " + timeList.size());
List<String> shortTimeList = timeList.subList(0, timeList.size()>8?8:timeList.size());
fd.markDeviErrorProcessing(shortTimeList);
session.commit();
logger.info(loggerPrefix + "markDeviErrorProcessing "+shortTimeList);
try {
for (String strTime : shortTimeList) {
if (strTime.trim().length() > 12)
strTime = strTime.substring(0, 12);
logger.info(loggerPrefix + " current time: " + strTime);
logger.info(loggerPrefix + " processing timeList: "+shortTimeList);
addDeviationData(strTime+"00");
}
} catch (Exception e) {
logger.error(e.getMessage());
logger.info(loggerPrefix +"error message: "+e.toString());
return;
} finally {
logger.info(loggerPrefix + "releaseDeviErrorProcessing " + shortTimeList);
fd.releaseDeviErrorProcessing(shortTimeList);
session.commit();
releaseResource();
}
} else {
logger.info(loggerPrefix + " There is no new error in fund_realtime_valuation_devi_error_top10 table.");
}
logger.info(loggerPrefix + "end process 3...");
}else if (iprocessType == 9){
//valuationTime = "201810160958";
//produceDeviationData(valuationTime, isSupplemented, iprocessType);
String strDate = currentDate;
logger.error(loggerPrefix + "error test");
/* for(int i=30; i <60; i++){
String strTime = strDate+"09"+i;
fd.insertFundValGlobalError(new FundValGlobalError(currentDate, strTime, "01", "TOP10基金配置表無數據",
new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())));
}
for(int i=0; i <60; i++){
String strMin="";
if(i<10) strMin="0"+i;
else strMin=""+i;
String strTime = strDate+"10"+strMin;
fd.insertFundValGlobalError(new FundValGlobalError(currentDate, strTime, "01", "TOP10基金配置表無數據",
new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())));
}
for(int i=0; i <=30; i++){
String strMin="";
if(i<10) strMin="0"+i;
else strMin=""+i;
String strTime = strDate+"11"+strMin;
fd.insertFundValGlobalError(new FundValGlobalError(currentDate, strTime, "01", "TOP10基金配置表無數據",
new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())));
}
for(int i=0; i <60; i++){
String strMin="";
if(i<10) strMin="0"+i;
else strMin=""+i;
String strTime = strDate+"13"+strMin;
fd.insertFundValGlobalError(new FundValGlobalError(currentDate, strTime, "01", "TOP10基金配置表無數據",
new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())));
}
for(int i=0; i <60; i++){
String strMin="";
if(i<10) strMin="0"+i;
else strMin=""+i;
String strTime = strDate+"14"+strMin;
fd.insertFundValGlobalError(new FundValGlobalError(currentDate, strTime, "01", "TOP10基金配置表無數據",
new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())));
}
fd.insertFundValGlobalError(new FundValGlobalError(currentDate, strDate+"1500", "01", "TOP10基金配置表無數據",
new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())));
session.commit();*/
}
releaseResource();
}
// 正常每分鐘計算基金估值的流程。交易時間段每分鐘觸發一次,取當前時間兩分鐘前的指數和股票實時數據,結合TOP10配置計算符合異動條件的基金估值並插入數據庫。
private static boolean produceValuationData(String valuationTime, boolean isSupplemented, int iprocessType) {
logger.info(loggerPrefix + "start produceValuationData... ");
String batchid = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
List<FundValuation> fundValList = new ArrayList<FundValuation>();
List<FundValError> valErrorList = new ArrayList<FundValError>();
logger.info(loggerPrefix + "valuationTime: " + valuationTime);
// logger.info(loggerPrefix + "batchid=" + batchid + " time1: " + new
// Date());
List<StockRealtime> stockRealTimes = new ArrayList<>();
Map<String, StockRealtime> mapAllStockRealTime = new HashMap<String, StockRealtime>();
if ("PA".equals(datasource)) {
logger.info(loggerPrefix + "batchid=" + batchid + " current data source is PA");
stockRealTimes = fd.getStockRealtimeByTime(valuationTime + "00");
} else if ("JQ".equals(datasource)) {
logger.info(loggerPrefix + "batchid=" + batchid + " current data source is JQ");
stockRealTimes = fd.getStockRealtimeJQByTime(valuationTime + "00");
}
logger.info(loggerPrefix + "stockRealTime size : " + stockRealTimes.size());
if (stockRealTimes == null || stockRealTimes.size() == 0) {
if(iprocessType == 0){
fd.insertFundValGlobalError(new FundValGlobalError(currentDate, valuationTime, "02", "全市場股票數據缺失",
new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())));
session.commit();
logger.info(loggerPrefix + "全市場股票數據缺失, 寫入全局錯誤表... ");
}else if(iprocessType == 2){
logger.info(loggerPrefix + "batchid=" + batchid + " 全市場股票數據缺失, 更新全局錯誤表... ");
FundValGlobalError globalError = fd.getFundValGlobalErrorByTime(valuationTime);
if (globalError == null) {
fd.insertFundValGlobalError(new FundValGlobalError(currentDate, valuationTime, "02",
"全市場股票數據缺失,無法計算基金估值", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())));
} else {
globalError.setProcessCount(globalError.getProcessCount() + 1);
fd.updateGlobalError(globalError);
}
session.commit();
}
logger.info(loggerPrefix + "end produceValuationData... ");
return false;
}
mapAllStockRealTime = stockRealTimes.stream()
.collect(Collectors.toMap(StockRealtime::getSymbol, Function.identity()));
// logger.info(loggerPrefix + "batchid=" + batchid + " indexRealtimes: "
// + indexRealtimes.size());
logger.info(loggerPrefix + "batchid=" + batchid + " stockRealTimes: " + stockRealTimes.size());
logger.info(loggerPrefix + "batchid=" + batchid + " mapAllStockRealTime: " + mapAllStockRealTime.size());
// logger.info(loggerPrefix + "batchid=" + batchid + " time2: " + new
// Date());
int i = 0;
for (FundTop10Qualification ftq : fundTop10QualifiedList) {
i++;
String symbol = ftq.getSymbolOf();
Double muFactor = ftq.getMuFactor();
Double nav = ftq.getNav();
List<FundTop10Config> fundconfList = fundTop10ConfigMap.get(symbol);
double retSum = 0;
double ret = 0;
// System.out.println(loggerPrefix +"
// ----------------"+i+"-------------------");
// System.out.println(loggerPrefix +" symbol="+ symbol);
int j = 0;
String lackStockIds = "";
boolean isLack = false;
for (FundTop10Config ftc : fundconfList) {
j++;
// System.out.println(loggerPrefix +"
// ----------------"+i+"-------------------"+j);
String stockId = ftc.getEsymbol();
// 測試代碼
// if(stockId.equals("000568")||stockId.equals("601336"))
// stockId=stockId+".OA";
// 測試代碼
Double sholding7 = ftc.getSholding7() / 100;
StockRealtime srt = mapAllStockRealTime.get(stockId);
if (srt == null)
srt = mapAllStockRealTime.get(stockId + ".SH");
if (srt == null)
srt = mapAllStockRealTime.get(stockId + ".SZ");
if (srt == null) {
System.out.println(loggerPrefix + "基金下的股票無實時數據. symbol=" + symbol + ", stockId=" + stockId);
isLack = true;
if (lackStockIds.equals(""))
lackStockIds = stockId;
else
lackStockIds = lackStockIds + "," + stockId;
continue;
}
Double lastPrice = srt.getLastPrice();
Double preClose = srt.getPreCloseprice();
if (Double.doubleToLongBits(lastPrice) == Double.doubleToLongBits(0)) {
lastPrice = srt.getPreCloseprice();
// System.out.println(loggerPrefix +"基金"+symbol+"下的股票停牌:"+
// stockId+",股票停牌前價格:"+ lastPrice);
}
ret = ((lastPrice - preClose) / preClose) * sholding7 * muFactor;
retSum = retSum + ret;
/ if (symbol.equals("000011.OF")) {
logger.error(loggerPrefix + " ----------------" + j + "-------------------"+valuationTime);
logger.error(loggerPrefix + " stockId=" + stockId);
logger.error(loggerPrefix + " sholding7=" + sholding7);
logger.error(loggerPrefix + " lastPrice=" + lastPrice);
logger.error(loggerPrefix + " preClose=" + preClose);
logger.error(loggerPrefix + " muFactor=" + muFactor);
logger.error(loggerPrefix + " ret=" + ret);
logger.error(loggerPrefix + " symbol=" + symbol + ", retSum=" + retSum);
}/
}
if (isLack) {//if(symbol.equals("000011.OF")){logger.error(loggerPrefix +"000011.OF 股票沒有實時數據 stockId="+lackStockIds);}
FundValError error = new FundValError();
error.setBatchId(batchid);
error.setCreateTime(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
error.setDescription("股票沒有實時數據");
error.setErrorCode("99");
error.setFundId(symbol);
error.setValuationDate(currentDate);
error.setValuationTime(valuationTime + "00");
error.setStockId(lackStockIds);
valErrorList.add(error);
continue;
}
//分紅
double fundDividendVal = 0;
FundDividend fundDividend = fundDividendMap.get(symbol.length()>6? symbol.substring(0, 6): symbol);
if(fundDividend!=null){
fundDividendVal = fundDividend.getDividendValue();
}
//
double retValue = (retSum + 1) * (nav - fundDividendVal);
/ if(symbol.equals("000011.OF")){
logger.error("000011.OF nav = " + nav);
logger.error("000011.OF retValue = " + retValue);
logger.error("000011.OF valuationTime = " + valuationTime);
logger.error(loggerPrefix + "#####################################################################");
}/
FundValuation fv = new FundValuation();
fv.setBatchId(batchid);
fv.setCreatetime(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
fv.setFundId(symbol);
fv.setIsSupplemented(isSupplemented ? "1" : "0");
fv.setPreValuation(nav);
fv.setValuation(retValue);
fv.setValuationDate(currentDate);
fv.setValuationTime(valuationTime + "00");
fundValList.add(fv);
}
// logger.info(loggerPrefix + "batchid=" + " time3: " + new Date());
logger.info(loggerPrefix + "batchid=" + batchid + " valuationList: " + fundValList.size());
if (fundValList != null && fundValList.size() > 0) {
batchInsertValuation(fundValList, 2000);
}
if (valErrorList != null && valErrorList.size() > 0) {
batchInsertError(valErrorList, 2000);
}
// logger.info(loggerPrefix + "batchid=" + batchid + " time4: " + new
// Date());
logger.info(loggerPrefix + "end produceValuationData... ");
return true;
}
//產生TOP10實時背離數據
private static void produceDeviationData(String valuationTime, boolean isSupplemented, int iprocessType){
logger.info(loggerPrefix + "start produceDeviationData... ");
List<FundValDeviation> deviList = null;
List<FundValDeviation> validDeviList = new ArrayList<FundValDeviation>();
List<FundDeviError> errorList = new ArrayList<FundDeviError>();
//logger.info(loggerPrefix + "before getDeviationList... ");
deviList = fd.getDeviationList(valuationTime+"00", valuationTime.substring(0,8), preTradeday, version);
//logger.info(loggerPrefix + "after getDeviationList... ");
for(FundValDeviation fvd: deviList){
String fundId = fvd.getFundId();
Double value1 = fvd.getValuation1();
Double value2 = fvd.getValuation2();
String valTime = fvd.getValuationTime();
fvd.setValuationDate(valTime.substring(0,8));
fvd.setIsSupplemented(isSupplemented ? "1" : "0");
//Double deviPercent = fvd.getDeviPercent();
if(value1==null
|| value2==null
|| Double.doubleToLongBits(value1)==Double.doubleToLongBits(0)
|| Double.doubleToLongBits(value2)==Double.doubleToLongBits(0))
{
//logger.info(loggerPrefix + " lackage of value1 or value2...");
FundDeviError deviError = new FundDeviError();
deviError.setFundId(fundId);
deviError.setValuationDate(valTime.substring(0,8));
deviError.setValuationTime(valTime);
errorList.add(deviError);
}else
validDeviList.add(fvd);
}
logger.info(loggerPrefix + " valuationTime = " + valuationTime+"00");
logger.info(loggerPrefix + " total deviation size = " + deviList.size());
logger.info(loggerPrefix + " valid deviation data size= " + validDeviList.size());
logger.info(loggerPrefix + " missing deviation data size= " + errorList.size());
if(validDeviList!=null && validDeviList.size()>0){
fd.insertFundDeviMinTop10(validDeviList);
session.commit();
}
if(errorList!=null && errorList.size()>0){
fd.insertFundDeviErrorTop10(errorList);
session.commit();
}
logger.info(loggerPrefix + "end produceDeviationData... ");
}
// 補發數據流程2。 對於由於股票實時數據缺失而沒有計算出基金估值的數據,進行重算補發。
private static boolean addValuationData(String valTime) {
String batchid = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
logger.info(loggerPrefix + "batchid=" + batchid + " start addValuationData... " + new Date());
List<FundValuation> valuationList = new ArrayList<FundValuation>();
List<String> successList = new ArrayList<String>();
List<FundValError> valErrorList = new ArrayList<>();
// logger.info(loggerPrefix + "batchid=" + batchid + " time1: " + new Date());
List<StockRealtime> stockRealTimes = null;
List<FundValError> fundValErrors = null;
Map<String, StockRealtime> mapAllStockRealTime = new HashMap<String, StockRealtime>();
// logger.info(loggerPrefix + "batchid=" + batchid +" time2: " + new
// Date());
fundValErrors = fd.getFundValErrorListByMin(valTime + "00");
if (fundValErrors == null || fundValErrors.size() == 0) {
logger.info(loggerPrefix + "batchid=" + batchid + " Error list is empty!");
return false;
}
// logger.info(loggerPrefix + "batchid=" + batchid + " time3: " + new
// Date());
logger.info("fundValErrors: " + fundValErrors.size());
if ("PA".equals(datasource)) {
stockRealTimes = fd.getStockRealtimeByTime(valTime + "00");
} else if ("JQ".equals(datasource)) {
stockRealTimes = fd.getStockRealtimeJQByTime(valTime + "00");
}
// logger.info(loggerPrefix + "batchid=" + batchid + " time5: " + new
// Date());
logger.info(loggerPrefix + "batchid=" + batchid + " stockRealTimes size: " + stockRealTimes.size());
if ( (stockRealTimes == null || stockRealTimes.size() == 0)) {
logger.info(loggerPrefix + "batchid=" + batchid + " stockRealTimes is empty!");
return false;
}
mapAllStockRealTime = stockRealTimes.stream()
.collect(Collectors.toMap(StockRealtime::getSymbol, Function.identity()));
Map<String, FundTop10Qualification> mapAllTop10Qualification = fundTop10QualifiedList.stream()
.collect(Collectors.toMap(FundTop10Qualification::getSymbolOf, Function.identity()));
// logger.info(loggerPrefix + "batchid=" + batchid + " time6: " + new
// Date());
//double nav = 0.0;
for (FundValError fve : fundValErrors) {
String fundid = fve.getFundId();
FundTop10Qualification ftq = mapAllTop10Qualification.get(fundid);
Double muFactor = ftq.getMuFactor();
Double nav = ftq.getNav();
List<FundTop10Config> fundconfList = fundTop10ConfigMap.get(fundid);
double retSum = 0;
double ret = 0;
// System.out.println(loggerPrefix +"
// ----------------"+i+"-------------------");
// System.out.println(loggerPrefix +" symbol="+ symbol);
int j = 0;
String lackStockIds = "";
boolean isLack = false;
for (FundTop10Config ftc : fundconfList) {
j++;
// System.out.println(loggerPrefix +"
// ----------------"+i+"-------------------"+j);
String stockId = ftc.getEsymbol();
// 測試代碼
// if(stockId.equals("000568")||stockId.equals("601336"))
// stockId=stockId+".OA";
// 測試代碼
Double sholding7 = ftc.getSholding7() / 100;
StockRealtime srt = mapAllStockRealTime.get(stockId);
if (srt == null)
srt = mapAllStockRealTime.get(stockId + ".SH");
if (srt == null)
srt = mapAllStockRealTime.get(stockId + ".SZ");
if (srt == null) {
System.out.println(loggerPrefix + "基金下的股票無實時數據. symbol=" + fundid + ", stockId=" + stockId);
isLack = true;
if (lackStockIds.equals(""))
lackStockIds = stockId;
else
lackStockIds = lackStockIds + "," + stockId;
continue;
}
Double lastPrice = srt.getLastPrice();
Double preClose = srt.getPreCloseprice();
if (Double.doubleToLongBits(lastPrice) == Double.doubleToLongBits(0)) {
lastPrice = srt.getPreCloseprice();
// System.out.println(loggerPrefix +"基金"+symbol+"下的股票停牌:"+
// stockId+",股票停牌前價格:"+ lastPrice);
}
ret = ((lastPrice - preClose) / preClose) * sholding7 * muFactor;
retSum = retSum + ret;
}
if (isLack) {
FundValError error = new FundValError();
error.setErrorId(fve.getErrorId());
error.setBatchId(batchid);
error.setCreateTime(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
error.setDescription("股票沒有實時數據");
error.setErrorCode("99");
error.setFundId(fundid);
error.setValuationDate(fve.getValuationDate());
error.setValuationTime(fve.getValuationTime());
error.setStockId(lackStockIds);
valErrorList.add(error);
continue;
}
//分紅
double fundDividendVal = 0;
FundDividend fundDividend = fundDividendMap.get(fundid.length()>6? fundid.substring(0, 6): fundid);
if(fundDividend!=null){
fundDividendVal = fundDividend.getDividendValue();
}
double retValue = (retSum + 1) * (nav - fundDividendVal);
FundValuation fv = new FundValuation();
fv.setBatchId(batchid);
fv.setCreatetime(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
fv.setFundId(fundid);
fv.setIsSupplemented("0");
fv.setPreValuation(nav);
fv.setValuation(retValue);
fv.setValuationDate(fve.getValuationDate());
fv.setValuationTime(fve.getValuationTime());
valuationList.add(fv);
successList.add(fve.getErrorId());
}
// logger.info(loggerPrefix + "batchid=" + batchid + " time7: " + new
// Date());
logger.info(loggerPrefix + "batchid=" + batchid + " valuationList size: " + valuationList.size());
logger.info(loggerPrefix + "batchid=" + batchid + " successList size: " + successList.size());
logger.info(loggerPrefix + "batchid=" + batchid + " valErrorList size: " + valErrorList.size());
List<String> errorIdList = valErrorList.stream().map(e -> e.getErrorId()).collect(Collectors.toList());
if (valuationList != null && valuationList.size() > 0) {
batchInsertValuation(valuationList, 2000);
batchDeleteError(successList, 2000);
}
if (valErrorList != null && valErrorList.size() > 0) {
batchUpdateError(errorIdList, 2000);
}
// logger.info(loggerPrefix + "batchid=" + batchid + " time8: " + new
// Date());
logger.info(loggerPrefix + "batchid=" + batchid + " end addValuationData... " + new Date());
return true;
}
//補算TOP10實時背離數據
private static void addDeviationData(String valuationTime){
logger.info(loggerPrefix + "start addDeviationData... ");
List<FundValDeviation> deviList = null;
List<FundValDeviation> validDeviList = new ArrayList<FundValDeviation>();
List<FundDeviError> errorList = new ArrayList<FundDeviError>();
List<String> successList = new ArrayList<String>();
logger.info(loggerPrefix + "before getDeviationListFromError... valuationTime:" + valuationTime);
deviList = fd.getDeviationListFromError(valuationTime, valuationTime.substring(0,8) , preTradeday, version );
logger.info(loggerPrefix + "after getDeviationListFromError... ");
for(FundValDeviation fvd: deviList){
String fundId = fvd.getFundId();
Double value1 = fvd.getValuation1();
Double value2 = fvd.getValuation2();
String valTime = fvd.getValuationTime();
fvd.setValuationDate(valTime.substring(0,8));
fvd.setIsSupplemented("1");
//Double deviPercent = fvd.getDeviPercent();
if(value1==null
|| value2==null
|| Double.doubleToLongBits(value1)==Double.doubleToLongBits(0)
|| Double.doubleToLongBits(value2)==Double.doubleToLongBits(0))
{
//logger.info(loggerPrefix + " lackage of value1 or value2...");
FundDeviError deviError = new FundDeviError();
deviError.setErrorId(fvd.getErrorId());
deviError.setFundId(fundId);
deviError.setValuationDate(valTime.substring(0,8));
deviError.setValuationTime(valTime);
errorList.add(deviError);
}else{
validDeviList.add(fvd);
successList.add(fvd.getErrorId());
}
}
logger.info(loggerPrefix + " valuationTime = " + valuationTime);
logger.info(loggerPrefix + " total deviation size = " + deviList.size());
logger.info(loggerPrefix + " valid deviation data size= " + validDeviList.size());
logger.info(loggerPrefix + " missing deviation data size= " + errorList.size());
List<String> errorIdList = errorList.stream().map(e -> e.getErrorId()).collect(Collectors.toList());
if(validDeviList!=null && validDeviList.size()>0){
fd.insertFundDeviMinTop10(validDeviList);
session.commit();
fd.deleteDeviErrorList(successList);
session.commit();
}
if(errorList!=null && errorList.size()>0){
fd.updateDeviErrorList(errorIdList);
session.commit();
}
logger.info(loggerPrefix + "end addDeviationData... ");
}
private static void batchInsertValuation(List<FundValuation> valuationList, int batchCount) {
int count = valuationList.size() / batchCount;
int mode = valuationList.size() % batchCount;
int i = 0;
for (; i < count; i++) {
fd.insertFundValuation(valuationList.subList(i * batchCount, (i + 1) * batchCount));
session.commit();
}
if (mode > 0) {
fd.insertFundValuation(valuationList.subList(i * batchCount, valuationList.size()));
session.commit();
}
}
private static void batchInsertError(List<FundValError> valErrorList, int batchCount) {
int count = valErrorList.size() / batchCount;
int mode = valErrorList.size() % batchCount;
int i = 0;
for (; i < count; i++) {
fd.insertFundValError(valErrorList.subList(i * batchCount, (i + 1) * batchCount));
session.commit();
}
if (mode > 0) {
fd.insertFundValError(valErrorList.subList(i * batchCount, valErrorList.size()));
session.commit();
}
}
private static void batchDeleteError(List<String> successList, int batchCount) {
int count = successList.size() / batchCount;
int mode = successList.size() % batchCount;
int i = 0;
for (; i < count; i++) {
fd.deleteErrorList(successList.subList(i * batchCount, (i + 1) * batchCount));
session.commit();
}
if (mode > 0) {
fd.deleteErrorList(successList.subList(i * batchCount, successList.size()));
session.commit();
}
}
private static void batchUpdateError(List<String> errorIdList, int batchCount) {
int count = errorIdList.size() / batchCount;
int mode = errorIdList.size() % batchCount;
int i = 0;
for (; i < count; i++) {
fd.updateErrorList(errorIdList.subList(i * batchCount, (i + 1) * batchCount));
session.commit();
}
if (mode > 0) {
fd.updateErrorList(errorIdList.subList(i * batchCount, errorIdList.size()));
session.commit();
}
}
private static void init() throws IOException {
Reader reader = Resources.getResourceAsReader(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
session = sqlSessionFactory.openSession();
fd = (fundDao) session.getMapper(fundDao.class);
currentDate = new SimpleDateFormat("yyyyMMdd").format(new Date());
}
private static void releaseResource() {
session.close();
}
private static void initFundDividendMap(String valuationTime){
List<FundDividend> fundDividendList = fd.getFundDividendList(valuationTime);
if(fundDividendList != null && fundDividendList.size() > 0){
fundDividendMap = fundDividendList.stream()
.collect(Collectors.toMap(FundDividend::getFundId, Function.identity()));
}else
fundDividendMap = new HashMap<String, FundDividend>();
}
}
fundvaluation2/src/com/pingan/rbpfunval/Process