package com.copy.trade.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.copy.trade.entity.dto.DogeAsset;
import com.copy.trade.entity.form.StatisticsDataForm;
import com.copy.trade.entity.form.TraderDataQueryForm;
import com.copy.trade.entity.po.Customer;
import com.copy.trade.entity.po.Position;
import com.copy.trade.entity.po.StatisticsData;
import com.copy.trade.constant.DogeApi;
import com.copy.trade.constant.RedisKey;
import com.copy.trade.consumer.KafkaConsumer;
import com.copy.trade.dao.PositionMapper;
import com.copy.trade.dao.StatisticsDataMapper;
import com.copy.trade.dao.TraderDataMapper;
import com.copy.trade.entity.po.TraderData;
import com.copy.trade.enums.EntrustStatusEnum;
import com.copy.trade.service.*;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.copy.trade.util.DogeContractUtils;
import com.copy.trade.util.LocalDateUtils;
import com.copy.trade.util.WebAssert;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 统计数据表 服务实现类
 * </p>
 *
 * @author wz
 * @since 2022-11-29
 */
@Service
public class StatisticsDataServiceImpl extends ServiceImpl<StatisticsDataMapper, StatisticsData> implements IStatisticsDataService {
	
    private final Logger log = LoggerFactory.getLogger(StatisticsDataServiceImpl.class);

    @Value("${doge.host_inner}")
    private String dogeHost;

    @Value("${doge.host}")
    private String host;

    @Autowired
    private ICustomerService customerServiceImpl;
    
    @Autowired
    private IPositionService positionServiceImpl;

    @Autowired
    private ITraderDataService traderDataServiceImpl;

    @Autowired
    private IFollowService followServiceImpl;
    
    @Override
    @Transactional
    public Boolean statisticsByDay() {
        //时间
        LocalDateTime now = LocalDateTime.now();
        //获取1天前的时间戳 昨天的16点时间和前天的16点时间
        LocalDateTime minus = LocalDateUtils.minus(now, 1, ChronoUnit.DAYS);
        long time = LocalDateUtils.get16HourOfDay(minus);
        long endTime = LocalDateUtils.get16HourOfDay(now);
        long dbTime = LocalDateUtils.getStartTimeOfDay(now);
        //获取交易员
        List<Customer> traderList = customerServiceImpl.traderList();
        traderList.forEach(trader -> {
        	TraderData traderData = traderDataServiceImpl.getByTraderId(trader.getId());
            if(traderData == null){
                traderData = new TraderData();
                traderData.setTraderId(trader.getId());
                traderDataServiceImpl.save(traderData);
            }
        	StatisticsData statisticsData = getStatisticsDataByDate(new Date(dbTime),trader.getId());
        	if(statisticsData == null) {
        		statisticsData = new StatisticsData();
        		statisticsData.setCustomerId(trader.getId());
        		//如果可以定制老师的数据,每日统计表为0,共计的表不更新.
        		if(trader.getEditDataSwitch() != null && trader.getEditDataSwitch()) {
        			statisticsData.setDayYield14(BigDecimal.ZERO);
        			statisticsData.setDateTime(new Date(dbTime));
        			StatisticsData recentStatisticsData = ((StatisticsDataMapper)baseMapper).recentStatisticsData(trader.getId());
        			if(recentStatisticsData != null && recentStatisticsData.getDayYield14() != null ) {
        				statisticsData.setDayYield14(recentStatisticsData.getDayYield14());//如果不修改,曲线图平移
        			}
        			save(statisticsData);
        			return ;
        		}
        	}
        	if(trader.getEditDataSwitch() != null && trader.getEditDataSwitch()) {
        		return ;
        	}
            //1.todo 获取资产余额,每日盈利算出最大回撤  14日最大回撤率：（14日内账户权益最大值-14日内账户权益最小值）/14日内账户权益最大值 * 100%，已通过净值计算方式剔除出入金影响，该数据每小时更新一次。
            BigDecimal balance = DogeContractUtils.asset(host + DogeApi.CONTRACT_ASSET_NEW,trader.getMemberId());
            statisticsData.setBalance(balance);
            trader.setBalance(balance);
            customerServiceImpl.updateById(trader);
            //2. todo 计算订单收益
            Map<String,BigDecimal> earningsToday = positionServiceImpl.earningsCalculationByDay(trader.getId(), time, endTime);
            statisticsData.setEarnings(earningsToday.get("earnings"));
            //3. todo 统计保证金
            statisticsData.setPrincipalAmount(earningsToday.get("principalAmount"));
            //4. todo 统计开仓笔数
            statisticsData.setOpenPosition(earningsToday.get("positionSize").longValue());
            statisticsData.setProfitOrderCount(earningsToday.get("profitOrderCount").longValue());
            statisticsData.setDateTime(new Date(dbTime));
            saveOrUpdate(statisticsData);
            //更新交易员统计数据
             /* 1、14日最大回撤率：（14日内账户权益最大值-14日内账户权益最小值）/14日内账户权益最大值 * 100%，已通过净值计算方式剔除出入金影响，该数据每小时更新一次。

            	2、14日订单平均收益率：14日内订单盈亏之和/ 14日保证金之和 * 100%。(平仓后才计算盈亏)

            	3、14日胜率：14日内盈利订单数量/ 14日订单总数量 * 100%

            	4、资金实力（USDT）：当前在账户中存放资金量。

            	5、累计跟单盈利额（USDT）：账户历史累计盈利金额- 账户历史累计亏损金额。

            	6、累计跟随资金（USDT）：账户历史累计学生跟单金额。

            	7、累计跟单人数：历史累计学生跟单人数。

            	8、14日成交订单：最近14日内交易员交易次数，每完成一次开平仓算一笔成交。

            	9、累计交易天数：账户历史累计交易天数(以持仓笔数为准，一天多笔只算一笔。)。

            	10、累计盈利天数：账户历史累计盈利天数(以平仓数据为准，平仓时为盈利，则此笔订单为盈利，一天多笔只算一笔)。

            	11、30日订单平均收益率：30日内订单盈亏之和/ 30日保证金之和 * 100%*/
            
            //14日收益率
            StatisticsData statisticsData14 = count(trader.getId(), 14);
            BigDecimal earnings14 = statisticsData14.getEarnings();
            BigDecimal principalAmount14 = statisticsData14.getPrincipalAmount();
            BigDecimal percentage = new BigDecimal("100");
            BigDecimal dayYield14 = BigDecimal.ZERO;
            if(earnings14.compareTo(BigDecimal.ZERO) != 0){
                 dayYield14 = earnings14.multiply(percentage).divide(principalAmount14,8,BigDecimal.ROUND_HALF_UP);
            }
            traderData.setDayYield14(dayYield14);
            StatisticsData sd = new StatisticsData();
            sd.setId(statisticsData.getId());
            sd.setDayYield14(dayYield14);
            //更新14日收益率
            updateById(sd);
            //30日收益率
            StatisticsData statisticsData30 = count(trader.getId(), 30);
            BigDecimal earnings30 = statisticsData30.getEarnings();
            BigDecimal principalAmount30 = statisticsData30.getPrincipalAmount();
            BigDecimal dayYield30 = BigDecimal.ZERO;

            if(earnings30.compareTo(BigDecimal.ZERO) != 0){
                dayYield30 = earnings30.multiply(percentage).divide(principalAmount30,8,BigDecimal.ROUND_HALF_UP);
            }
            traderData.setDayYield30(dayYield30);
            //14日胜率
            BigDecimal winRate14 = BigDecimal.ZERO;
            if(statisticsData14.getProfitOrderCount() > 0){
                winRate14 = new BigDecimal(statisticsData14.getProfitOrderCount())
                        .multiply(percentage)
                        .divide(new BigDecimal(statisticsData14.getOpenPosition()),8,BigDecimal.ROUND_HALF_UP);
            }
            traderData.setWinRate14(winRate14);
            //累积盈利额
            BigDecimal earningsCount = earningsCount(trader.getId());
            traderData.setProfitAmount(earningsCount);
            //累积跟随人数
            Integer followTotal = followServiceImpl.countByTrader(trader.getId(),null);
            traderData.setFollowCustomer(Long.valueOf(followTotal));
            //14日成交单量
            traderData.setOrderDeal14(statisticsData14.getOpenPosition());
            
            //14日最大回撤率
            //查询出最近14日所有的statisticsData数据.算出每日的盈亏率.最后算出最大的回撤率
            //BigDecimal retractionRate14 = retractionRate14(trader.getId(), 14);
            //BigDecimal minBalance = balanceSort(trader.getId(),14, "min");
            //BigDecimal maxBalance = balanceSort(trader.getId(),14, "max");
            //BigDecimal retractionRate14 = minBalance.multiply(percentage).divide(maxBalance, 8, BigDecimal.ROUND_HALF_UP);
            //traderData.setRetractionRate14(retractionRate14);
            //累积交易天数
            Integer tradingDays = tradingDays(trader.getId());
            traderData.setTradingDays(Long.valueOf(tradingDays));
            //累积盈利天数
            Integer profitDays = profitDays(trader.getId());
            traderData.setProfitDays(Long.valueOf(profitDays));
            //本月跟随人数
            //String firstDayOfMonthStr = LocalDateUtils.getBeforeLastMonthdate();
            //Integer currentMonthFollow = followServiceImpl.countByTrader(trader.getId(), firstDayOfMonthStr);
            //traderData.setCurrentMonthFollow(Long.valueOf(currentMonthFollow));
            //保存或更新
            traderDataServiceImpl.saveOrUpdate(traderData);

        });

        return true;
    }
    @Override
    @Transactional
    public Boolean statisticsByDayNew() {
    	LocalDateTime now = LocalDateTime.now();
		log.info("开始统计老师数据:----------START-------------时间{}",now);
    	LocalDateTime minus = LocalDateUtils.minus(now, 1, ChronoUnit.DAYS);
    	LocalDateTime minus15 = LocalDateUtils.minus(now, 14, ChronoUnit.DAYS);
    	LocalDateTime minus31 = LocalDateUtils.minus(now, 30, ChronoUnit.DAYS);
    	//long time = LocalDateUtils.get16HourOfDay(minus);
    	//long endTime = LocalDateUtils.get16HourOfDay(now);
    	long time = LocalDateUtils.getStartTimeOfDay(minus);
    	long endTime = LocalDateUtils.getStartTimeOfDay(now);
    	long dbTime = LocalDateUtils.getStartTimeOfDay(now);
    	long dbTime15 = LocalDateUtils.getStartTimeOfDay(minus15);
    	long dbTime31 = LocalDateUtils.getStartTimeOfDay(minus31);
    	//获取交易员
    	List<Customer> traderList = customerServiceImpl.traderList();
    	log.info("统计老师数据:老师集合{}",traderList.toString());
    	traderList.forEach(trader -> {
    		log.info("统计老师数据:老师会员id:{},个人信息{}",trader.getMemberId(),trader.toString());
    		TraderData traderData = traderDataServiceImpl.getByTraderId(trader.getId());
    		if(traderData == null){
    			traderData = new TraderData();
    			traderData.setTraderId(trader.getId());
    		}
    		log.info("统计老师数据:老师昨天的统计数据{}",traderData.toString());
    		StatisticsData statisticsData = getStatisticsDataByDate(new Date(dbTime),trader.getId());
    		StatisticsData statisticsData15 = getStatisticsDataByDate(new Date(dbTime15),trader.getId());
    		StatisticsData statisticsData31 = getStatisticsDataByDate(new Date(dbTime31),trader.getId());
    		BigDecimal balance = DogeContractUtils.asset(dogeHost + DogeApi.CONTRACT_ASSET_NEW_STUDENT,trader.getMemberId());
    		if(statisticsData == null) {
    			statisticsData = new StatisticsData();
    			statisticsData.setCustomerId(trader.getId());
    			statisticsData.setBalance(balance);
    		}
    		
    		trader.setBalance(balance);
    		customerServiceImpl.updateById(trader);
    		
    		//-----------------开始统计在statistics表中的数据------------------------------------
    		statisticsData.setBalance(balance);
    		Map<String,BigDecimal> earningsToday = positionServiceImpl.earningsCalculationByDay(trader.getId(), time, endTime);
    		statisticsData.setEarnings(earningsToday.get("earnings"));
    		statisticsData.setPrincipalAmount(earningsToday.get("principalAmount"));
    		statisticsData.setOpenPosition(earningsToday.get("positionSize").longValue());
    		statisticsData.setProfitOrderCount(earningsToday.get("profitOrderCount").longValue());
    		statisticsData.setDateTime(new Date(dbTime));
    		log.info("统计老师数据:老师今日的每日统计数据{}",statisticsData.toString());
    		saveOrUpdate(statisticsData);
    		
    		//------------------开始统计trader_data表中的汇总数据-------------------------------------------------
    		//获取 当天15天,31天时 的收益率
    		BigDecimal dayYieldToday = getDayYieldByDays(statisticsData);
    		BigDecimal dayYield15 = getDayYieldByDays(statisticsData15);
    		BigDecimal dayYield31 = getDayYieldByDays(statisticsData31);
    		log.info("统计老师数据:老师今日收益率{},15天前那天的收益率{},31天前那天的收益率{}",dayYieldToday,dayYield15,dayYield31);
    		//这个收益率为后台设定的初值,加上今天的收益率减去前15天那天的收益率.同理30天的收益率
    		//traderData.setDayYield14(((traderData.getDayYield14() == null ?BigDecimal.ZERO : traderData.getDayYield14())
    		//		.add(dayYieldToday)).subtract(dayYield15));
    		traderData.setDayYield14(transDayYield(traderData.getDayYield14(),dayYield15,dayYieldToday,14));    		
    		//----------------更新每日统计的表----------------
    		StatisticsData sd = new StatisticsData();
            sd.setId(statisticsData.getId());
            //两张表的dayYield14保持一致
            sd.setDayYield14(traderData.getDayYield14() == null ?BigDecimal.ZERO : traderData.getDayYield14());
            updateById(sd);
    		
    		//30日收益率,同14日收益率一致,只是改了统计范围
    		traderData.setDayYield30(transDayYield(traderData.getDayYield30(),dayYield31,dayYieldToday,30));
    		
    		//14日成交单量  : 初始值+今天的-15天前那一天的  
    		traderData.setOrderDeal14((traderData.getOrderDeal14() == null ? 0 : traderData.getOrderDeal14())
    				+ (statisticsData.getOpenPosition() == null ? 0L : statisticsData.getOpenPosition())
    				- ((statisticsData15 == null || statisticsData15.getOpenPosition()== null) ? 0L : statisticsData15.getOpenPosition()));
    		if(traderData.getOrderDeal14() < 0) {
    			traderData.setOrderDeal14(0L);
    		}
    		//14日胜率
    		StatisticsData statisticsData14 = count(trader.getId(), 14);//statisticsData14只用来统计了 14日胜率
    		log.info("统计老师数据:14日胜率汇总数据{}",statisticsData14);
    		BigDecimal winRate14 = BigDecimal.ZERO;
    		BigDecimal percentage = new BigDecimal("100");
    		if(statisticsData14.getProfitOrderCount() > 0){
    			winRate14 = new BigDecimal(statisticsData14.getProfitOrderCount())
    					.multiply(percentage)
    					.divide(new BigDecimal(statisticsData14.getOpenPosition()),8,BigDecimal.ROUND_HALF_UP);
    		}
    		BigDecimal winRate14Init = traderData.getWinRate14() == null ? BigDecimal.ZERO : traderData.getWinRate14();
    		traderData.setWinRate14(winRate14);
    		
    		//14日最大回撤率 
    		//查询出最近14日所有的statisticsData数据.算出每日的盈亏率.最后算出最大的回撤率
    		BigDecimal retractionRate14 = retractionRate14New(trader.getId(), 14);
    		log.info("统计老师数据:14日最大回撤值(统计值){}",retractionRate14);
    		//BigDecimal retractionRate14Init = traderData.getRetractionRate14() == null ? BigDecimal.ZERO : traderData.getRetractionRate14();
    		traderData.setRetractionRate14(retractionRate14 == null ? BigDecimal.ZERO : retractionRate14.multiply(percentage));
    		
    		//如果是特定的用户 胜率和回撤做特别处理 :胜率和回撤都是去大值
    		if(trader.getEditDataSwitch() != null && trader.getEditDataSwitch()) {
//    			if(retractionRate14Init.compareTo(retractionRate14) > 0) {
//    				traderData.setRetractionRate14(retractionRate14Init);
//    			}
    			if(winRate14Init.compareTo(winRate14) > 0) {
    				traderData.setWinRate14(winRate14Init);
    			}
    			//非指定用户才更新累计盈利额和累计跟单额
    		} else {
    			//累积盈利额  
    			traderData.setProfitAmount((traderData.getProfitAmount() == null ? BigDecimal.ZERO : traderData.getProfitAmount())
    					.add(statisticsData.getEarnings() == null ? BigDecimal.ZERO : statisticsData.getEarnings()));
        		}
    		
    		
    		//累积跟随人数
    		Integer followTotalToday = followServiceImpl.countByTraderToday(trader.getId(),new Date(time));
    		traderData.setFollowCustomer((traderData.getFollowCustomer() == null ? 0L :traderData.getFollowCustomer()) 
    				+ Long.valueOf(followTotalToday == null ? 0L : followTotalToday));
    		
    		//累积交易天数和累计盈利天数 +1 或者+0
    		Long openPositionDaysToday = (statisticsData.getOpenPosition() == null || statisticsData.getOpenPosition() == 0 ) ? 0L : 1L;
    		List<Position> historyPositionList = positionServiceImpl.updatePositionList(trader.getId(), new Date(time), new Date(endTime));
    		if(historyPositionList != null && !historyPositionList.isEmpty()) {
    			openPositionDaysToday = 1L;
    		}
    		traderData.setTradingDays((traderData.getTradingDays() == null ? 0L : traderData.getTradingDays()) + openPositionDaysToday);
    		
    		//累积盈利天数
    		Long openPositionProfitDaysToday = (statisticsData.getEarnings() != null && statisticsData.getEarnings().compareTo(BigDecimal.ZERO) > 0 ) ? 1L : 0L;
    		traderData.setProfitDays((traderData.getProfitDays() == null ? 0L : traderData.getProfitDays()) + openPositionProfitDaysToday);
    		
    		//近14日团队盈利（滑动窗口：+今日收益 -15天前那天收益，与 dayYield14 逻辑一致）
    		BigDecimal teamProfit14Today = statisticsData.getEarnings() == null ? BigDecimal.ZERO : statisticsData.getEarnings();
    		BigDecimal teamProfit14Minus15 = (statisticsData15 == null || statisticsData15.getEarnings() == null) ? BigDecimal.ZERO : statisticsData15.getEarnings();
    		traderData.setTeamProfit14(
    				(traderData.getTeamProfit14() == null ? BigDecimal.ZERO : traderData.getTeamProfit14())
    				.add(teamProfit14Today)
    				.subtract(teamProfit14Minus15)
    		);

    		//本月跟随人数 + 今天的跟随人数  :如果是1号,直接是0 + 今天的
    		if(LocalDateUtils.isFirstDay()) {
    			traderData.setCurrentMonthFollow(0L);
    		}
    		traderData.setCurrentMonthFollow((traderData.getCurrentMonthFollow() == null ? 0L :traderData.getCurrentMonthFollow()) 
    				+ Long.valueOf(followTotalToday == null ? 0L : followTotalToday));
    		//保存或更新
    		traderDataServiceImpl.saveOrUpdate(traderData);
    		log.info("统计老师数据:更新后的老师统计数据{}",traderData.toString());
    	});
    	log.info("结束统计老师数据:----------END-------------");
    	return true;
    }
    
	@Override
	public List<StatisticsData> traderDataList(Long traderId) {
		List<StatisticsData> list = ((StatisticsDataMapper)baseMapper).traderDataList(traderId);
		//在查询的时候给之前没有交易数据的地方添加初值0
        int size = 0;
        if(list != null && list.size() > 0) {
        	size = list.size();
        }
        LocalDateTime now = LocalDateTime.now();
        
		for(int i = 14; i > size;i--) {
        	Date endTime = null;
        	Calendar calendar=Calendar.getInstance();
        	int hour = calendar.get(Calendar.HOUR_OF_DAY);
        	if(hour >= 16) {
        		endTime = new Date(LocalDateUtils.getStartTimeOfDay(LocalDateUtils.minus(now, i-1, ChronoUnit.DAYS)));
        	} else {
        		endTime = new Date(LocalDateUtils.getStartTimeOfDay(LocalDateUtils.minus(now, i, ChronoUnit.DAYS)));
        	}
			//给他添加初始数据id customerId ,datetime day14=0  
			StatisticsData statisticsData = new StatisticsData();
			statisticsData.setCustomerId(traderId);
			statisticsData.setDayYield14(BigDecimal.ZERO);
			statisticsData.setDateTime(endTime);
			save(statisticsData);
		}
		
		List<StatisticsData> listEnd = ((StatisticsDataMapper)baseMapper).traderDataList(traderId);
		
		return listEnd;
	}
	
	public BigDecimal getDayYieldByDays(StatisticsData statisticsData) {
		BigDecimal dayYield = BigDecimal.ZERO;
		if(statisticsData != null ) {
			BigDecimal earnings = statisticsData.getEarnings() == null ? BigDecimal.ZERO : statisticsData.getEarnings();
			BigDecimal principalAmount = statisticsData.getPrincipalAmount() == null ? BigDecimal.ZERO : statisticsData.getPrincipalAmount();
			if(earnings.compareTo(BigDecimal.ZERO) != 0 && principalAmount.compareTo(BigDecimal.ZERO) != 0) {
				dayYield = earnings.multiply(new BigDecimal("100")).divide(principalAmount,8,BigDecimal.ROUND_HALF_UP);
			}
		}
		return dayYield;
	}
	
	public BigDecimal transDayYield(BigDecimal initDayYield,BigDecimal lastDayYield,BigDecimal dayYieldToday,Integer day) {
		BigDecimal totalDayYield = (initDayYield == null ? BigDecimal.ZERO : initDayYield).multiply(new BigDecimal(day))
				.add(dayYieldToday == null ? BigDecimal.ZERO : dayYieldToday).subtract(lastDayYield == null ? BigDecimal.ZERO : lastDayYield);
		BigDecimal dayYield14 = (totalDayYield == null ? BigDecimal.ZERO : totalDayYield)
				.divide(new BigDecimal(day),8,BigDecimal.ROUND_HALF_UP);
		return dayYield14;
	}


    public StatisticsData count(Long traderId,Integer day){
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime minus = LocalDateUtils.minus(now, day, ChronoUnit.DAYS);
        String startTime = LocalDateUtils.format(minus, LocalDateUtils.DATE_PATTERN);
        StatisticsData statisticsData = ((StatisticsDataMapper)baseMapper).dataCount(traderId,startTime);
        return  statisticsData;
    }
    
//    public BigDecimal retractionRate14(Long traderId,Integer day){
//    	// 查询出最近14日所有的statisticsData数据.算出每日的盈亏率.最后算出最大的回撤率
//    	BigDecimal retractionRate14 = new BigDecimal("0");
//    	List<BigDecimal> profitList = new ArrayList<BigDecimal>();
//    	LocalDateTime now = LocalDateTime.now();
//    	LocalDateTime minus = LocalDateUtils.minus(now, day, ChronoUnit.DAYS);
//    	String startTime = LocalDateUtils.format(minus, LocalDateUtils.DATE_PATTERN);
//    	List<BigDecimal> profit14List = ((StatisticsDataMapper)baseMapper).selectStatisticsDataForRetractionRate14(traderId,startTime);
//    	
//    	//算出14日最大回撤率
//    	if(profit14List != null && !profit14List.isEmpty()) {
//    		if(profit14List.size() == 1) {
//    			profitList.add(profit14List.get(1) == null ? BigDecimal.ZERO : profit14List.get(1));
//    		} else {
//    			//根据13天的数据算出每天的收益率
//    			for (int i = 0; i < profit14List.size() - 1; i++) {
//    				profitList.add((profit14List.get(i + 1) == null ? BigDecimal.ZERO : profit14List.get(i + 1))
//    						.subtract(profit14List.get(i) == null ? BigDecimal.ZERO : profit14List.get(i)));
//    			}
//    		}
//    	}
//    	
//    	//开始遍历profitList找出最大回撤值.
//    	BigDecimal maxProfittemp = new BigDecimal("0");
//    	Boolean flag = false;//当天收益为正时是否需要计算
//    	Boolean flag2 = false;//是否回撤后又开始赚钱.
//    	BigDecimal temp = new BigDecimal("0");
//    	if(profitList != null && profitList.size() > 0) {
//    		for(int i = 0;i< profitList.size();i++) {
//    			if((profitList.get(i).compareTo(new BigDecimal("0")) > 0 && !flag) || profitList.get(i).compareTo(new BigDecimal("0")) == 0)  {
//    				continue;
//    			}
//    			if(profitList.get(i).compareTo(new BigDecimal("0")) < 0) {
//    				if(flag2) {
//    					temp =temp.add(profitList.get(i));
//    					if(temp.compareTo(maxProfittemp) < 0) {
//    						maxProfittemp = temp;
//    						continue;
//    					}
//    					
//    				} else {
//    					maxProfittemp = maxProfittemp.add(profitList.get(i));
//    					temp = maxProfittemp;
//    					flag = true;
//    					continue;
//    				}
//    			}else {
//    				temp =temp.add(profitList.get(i));
//    				
//    				if(temp.compareTo(new BigDecimal("0")) > 0) {
//    					flag = false;
//    					temp = new BigDecimal("0");
//    					if(retractionRate14.compareTo(maxProfittemp) > 0) {
//    						retractionRate14 = maxProfittemp;
//    					}
//    					maxProfittemp = new BigDecimal("0");
//    					flag2 = false;
//    					continue;
//    				}
//    				flag2 = true;
//    			}
//    		}
//    		if(retractionRate14.compareTo(maxProfittemp) > 0) {
//    			retractionRate14 = maxProfittemp;
//    		}
//    	}
//    	return  retractionRate14;
//    }
    
    public BigDecimal retractionRate14New(Long traderId,Integer day){
    	// 查询出最近14日所有的statisticsData数据.算出每日的盈亏率.最后算出最大的回撤率
    	LocalDateTime now = LocalDateTime.now();
    	LocalDateTime minus = LocalDateUtils.minus(now, day, ChronoUnit.DAYS);
    	String startTime = LocalDateUtils.format(minus, LocalDateUtils.DATE_PATTERN);
    	//相对资金的收益率集合
    	List<BigDecimal> balanceProfitList = new ArrayList<BigDecimal>();
    	//查询最近15天的数据
    	List<StatisticsData> statisticsDataList = ((StatisticsDataMapper)baseMapper).selectStatisticsDataForRetractionRate14(traderId,startTime);
		log.info("统计老师数据:近15天的每日统计数据{}",statisticsDataList.toString());
    	if(statisticsDataList != null && statisticsDataList.size() > 1) {
    		for (int i = 0; i < statisticsDataList.size() - 1; i++) {
    			BigDecimal earningsToday = statisticsDataList.get(i + 1).getEarnings();
    			BigDecimal balanceYesterday = statisticsDataList.get(i).getBalance();
    			
    			BigDecimal profit = BigDecimal.ZERO;
    			if(balanceYesterday != null && balanceYesterday.compareTo(BigDecimal.ZERO) != 0) {
    				profit = (earningsToday == null ? BigDecimal.ZERO : earningsToday).divide(balanceYesterday,BigDecimal.ROUND_CEILING);
    			}
    			balanceProfitList.add(profit);
    		}
    	}
    	log.info("统计老师数据:近14天的相对与资产的每日收益率集合{}",balanceProfitList.toString());
    	BigDecimal maxRetraction = getMaxRetraction(balanceProfitList);
    	return  maxRetraction;
    }
    
    public BigDecimal getMaxRetraction(List<BigDecimal> profit14List) {
    	List<BigDecimal> profitList = new ArrayList<BigDecimal>();
    	if(profit14List != null && !profit14List.isEmpty()) {
   			for (int i = 0; i < profit14List.size() - 1; i++) {
   				if(i == 0) {
   					profitList.add(new BigDecimal(1).multiply(new BigDecimal(1).add(profit14List.get(0) == null ? BigDecimal.ZERO : profit14List.get(0))));
   				}
   				BigDecimal transProfit = (profitList.get(i) == null ? BigDecimal.ZERO : profitList.get(i))
   				.multiply(new BigDecimal(1).add(profit14List.get(i + 1) == null ? BigDecimal.ZERO : profit14List.get(i + 1)));
   				profitList.add(transProfit == null ? BigDecimal.ZERO : transProfit);
   			}
    	}
    	log.info("统计老师数据:近14天的相对与资产的每日收益率集合(在昨日基础上算后){}",profitList.toString());
    	
    	//BigDecimal min = Collections.min(profitList) ;
    	BigDecimal min = (profitList == null || profitList.isEmpty()) ? new BigDecimal("1") : Collections.min(profitList) ;
    	log.info("统计老师数据:近14日最大回撤那天的收益率{}",min);
    	BigDecimal retractionRate14 = new BigDecimal(1).subtract(min == null ? new BigDecimal(1) : min);
    	
    	if(retractionRate14.compareTo(BigDecimal.ZERO) < 0) {
    		retractionRate14 = BigDecimal.ZERO;
    	} else if(retractionRate14.compareTo(new BigDecimal(1)) > 0) {
    		retractionRate14 = new BigDecimal(1);
    	}
    	return retractionRate14;
    	
    }

    public BigDecimal earningsCount(Long traderId){
        BigDecimal earningsTotal = ((StatisticsDataMapper)baseMapper).earningsCount(traderId);
        return earningsTotal;
    }
    
    public BigDecimal earningsCountToday(Long traderId,Long startTime){
    	BigDecimal earningsTotal = ((StatisticsDataMapper)baseMapper).earningsCountToday(traderId,startTime);
    	return earningsTotal;
    }

    public BigDecimal balanceSort(Long traderId,Integer day, String sort){
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime minus = LocalDateUtils.minus(now, day, ChronoUnit.DAYS);
        String startTime = LocalDateUtils.format(minus, LocalDateUtils.DATE_PATTERN);
        return ((StatisticsDataMapper)baseMapper).balanceSort(traderId,startTime, sort);
    }

    public Integer tradingDays(Long traderId){
        QueryWrapper<StatisticsData> statisticsDataQueryWrapper = new QueryWrapper<>();
        statisticsDataQueryWrapper.eq("customer_id",traderId)
                .gt("open_position",0);
        return count(statisticsDataQueryWrapper);
    }

    public Integer profitDays(Long traderId){
        QueryWrapper<StatisticsData> statisticsDataQueryWrapper = new QueryWrapper<>();
        statisticsDataQueryWrapper.eq("customer_id",traderId)
                .gt("earnings",0);
        return count(statisticsDataQueryWrapper);
    }
    
    public StatisticsData getStatisticsDataByDate(Date dateTime,Long traderId){
    	QueryWrapper<StatisticsData> statisticsDataQueryWrapper = new QueryWrapper<>();
    	statisticsDataQueryWrapper.eq("date_time",dateTime)
    	.eq("customer_id", traderId);
        return getOne(statisticsDataQueryWrapper);
    }
    
    @Override
    public Boolean edit(List<StatisticsDataForm> statisticsDataForms) {
    	WebAssert.isTrue(statisticsDataForms != null && statisticsDataForms.size() > 0, "chk.trader.datatotal.not.null");
    	Long idMax = 0L;
    	Long traderId = 0L;
    	BigDecimal dayYield14 = BigDecimal.ZERO;
    	for (StatisticsDataForm statisticsDataForm : statisticsDataForms) {
    		StatisticsData statisticsDataDB = getById(statisticsDataForm.getId());
    		statisticsDataDB.setDayYield14(statisticsDataForm.getDayYield14());
    		if(statisticsDataForm.getId() > idMax) {
    			idMax = statisticsDataForm.getId();
    			traderId = statisticsDataDB.getCustomerId();
    			dayYield14 = statisticsDataDB.getDayYield14();
    		}
    		updateById(statisticsDataDB);
		}
    	
    	//根据traderId更新
    	TraderData traderData = traderDataServiceImpl.getByTraderId(traderId);
    	traderData.setDayYield14(dayYield14);
    	traderDataServiceImpl.updateById(traderData);

    	return true;
    }
    
    
	@Override
	public void updateMaxDateDate(Long traderId, BigDecimal yield14) {
		((StatisticsDataMapper)baseMapper).updateMaxDateDate(traderId,yield14);
	}
	
	
	public static void main(String[] args) {
		List<BigDecimal> profitList2 =  new ArrayList<BigDecimal>();
		BigDecimal min = (profitList2 == null || profitList2.isEmpty()) ? new BigDecimal("1") : Collections.min(profitList2) ;
		profitList2.add(new BigDecimal("0.10"));
		profitList2.add(new BigDecimal("0"));
		profitList2.add(new BigDecimal("0"));
		profitList2.add(new BigDecimal("0"));
		profitList2.add(new BigDecimal("0"));
		profitList2.add(new BigDecimal("0"));
		profitList2.add(new BigDecimal("0"));
		profitList2.add(new BigDecimal("0.10"));
		profitList2.add(new BigDecimal("0.05"));
		profitList2.add(new BigDecimal("0.04"));
		profitList2.add(new BigDecimal("0.02"));
		profitList2.add(new BigDecimal("-0.02"));
		profitList2.add(new BigDecimal("0.99"));
		profitList2.add(new BigDecimal("0.99"));
		//BigDecimal maxRetraction = getMaxRetraction(profitList2);
		//System.out.println(maxRetraction);
		
//		BigDecimal transDayYield = transDayYield(new BigDecimal(60),new BigDecimal(30),new BigDecimal(10),14);
//		System.out.println(transDayYield);
		//Long a = Long.valueOf(null);
		boolean firstDay = LocalDateUtils.isFirstDay();
		System.out.println(firstDay);
		Date firstDayOfMonthStr = LocalDateUtils.getBeforeLastMonthdate();
		System.out.println(firstDayOfMonthStr);
		
    	BigDecimal retractionRate14 = new BigDecimal("0");
		List<BigDecimal> profitList =  new ArrayList<BigDecimal>();
		profitList.add(new BigDecimal("0"));
		profitList.add(new BigDecimal("0"));
		profitList.add(new BigDecimal("0"));
		profitList.add(new BigDecimal("0"));
		profitList.add(new BigDecimal("0"));
		profitList.add(new BigDecimal("0"));
		profitList.add(new BigDecimal("0"));
		profitList.add(new BigDecimal("0"));
		profitList.add(new BigDecimal("-137.37645413"));
		profitList.add(new BigDecimal("1"));
		profitList.add(new BigDecimal("44.70524077"));
		profitList.add(new BigDecimal("113.62963279"));
		profitList.add(new BigDecimal("8.25955995"));
		profitList.add(new BigDecimal("-200"));
		
		BigDecimal maxProfittemp = new BigDecimal("0");
    	Boolean flag = false;//当天收益为正时是否需要计算
    	Boolean flag2 = false;//是否回撤后又开始赚钱.
    	BigDecimal temp = new BigDecimal("0");
    	if(profitList != null && profitList.size() > 0) {
    		for(int i = 0;i< profitList.size();i++) {
    			if((profitList.get(i).compareTo(new BigDecimal("0")) > 0 && !flag) || profitList.get(i).compareTo(new BigDecimal("0")) == 0)  {
    			//	if((profitList.get(i).compareTo(new BigDecimal("0")) > 0 && !flag))  {
    				continue;
    			}
    			if(profitList.get(i).compareTo(new BigDecimal("0")) < 0) {
    				if(flag2) {
    					temp =temp.add(profitList.get(i));
    					if(temp.compareTo(maxProfittemp) < 0) {
    						maxProfittemp = temp;
    						continue;
    					}
    					
    				} else {
    					maxProfittemp = maxProfittemp.add(profitList.get(i));
    					temp = maxProfittemp;
    					flag = true;
    					continue;
    				}
    			}else {
    				temp =temp.add(profitList.get(i));
    				
    				if(temp.compareTo(new BigDecimal("0")) > 0) {
    					flag = false;
    					temp = new BigDecimal("0");
    					if(retractionRate14.compareTo(maxProfittemp) > 0) {
    						retractionRate14 = maxProfittemp;
    					}
    					maxProfittemp = new BigDecimal("0");
    					flag2 = false;
    					continue;
    				}
    				flag2 = true;
    			}
    		}
    		if(retractionRate14.compareTo(maxProfittemp) > 0) {
    			retractionRate14 = maxProfittemp;
    		}
    	}
		
    	System.out.println(retractionRate14);
    	System.out.println(retractionRate14);
    	System.out.println(retractionRate14);
    	
	}
}
