package com.jxy.marketall.task;

import com.jxy.common.core.text.Convert;
import com.jxy.common.core.utils.DateUtils;
import com.jxy.common.core.utils.StringUtils;
import com.jxy.common.core.web.Result.AjaxResult;
import com.jxy.common.redis.service.RedisService;
import com.jxy.marketall.dto.*;
import com.jxy.marketall.enums.BTCRedisName;
import com.jxy.marketall.mapper.BTC2Mapper;
import com.jxy.marketall.mapper.BTCMapper;
import com.jxy.marketall.vo.QueryVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Description TODO
 * @Date 2022/7/7 18:03
 * @Author 杜懿
 */
@Configuration
@EnableScheduling
public class BTCTask {

    /** 132服务器上btcdb库 */

    /** 112服务器上btcdb4库 */

    /** 112服务器上btcdb库 */
    @Autowired
    private BTC2Mapper btc2Mapper;

    @Autowired
    private BTCMapper btcMapper;

    @Autowired
    private RedisService redisService;

    /** btc每日交易量的数据 */
    //@Scheduled(cron = "0 0,5,15 0,2 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    //public void BTCVolumeToRedis(){
    //
    //    /** 获取最新一条数据 */
    //    BTCVolumeDto btcVolumeDto = btc4Mapper.selectLastBTCVolume();
    //
    //    Calendar startCalendar = new GregorianCalendar();
    //    startCalendar.setTime(btcVolumeDto.getDate());
    //    startCalendar.add(startCalendar.MONTH,-1);
    //    String start = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startCalendar.getTime());
    //
    //    QueryVo vo = new QueryVo();
    //
    //    vo.setStart(start);
    //
    //    List<BTCVolumeDto> list = btc4Mapper.getBTCVolumeList(vo);
    //
    //    if(list.size() > 0){
    //        //存入redis 先删除原有数据再重新插入数据
    //        redisService.deleteObject("BTCVolume");
    //        redisService.setCacheList("BTCVolume",list);
    //    }
    //}



    /***********************************************112服务器 btcdb（4418端口）数据库相关接口***********************************************/

    /** btc cdd历史数据 */
    @Scheduled(cron = "0 0 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void CDDToRedis(){

        QueryVo vo = new QueryVo();
        /** 获取最新一条数据 */
        List<CoinDayDesDto> list = btc2Mapper.getCDDList(vo);


        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject("CoinDayDes");
            redisService.setCacheList("CoinDayDes",list);
        }
    }

    /** btc cdd历史数据 */
    //@Scheduled(cron = "0 0 0/1 * * ?")
    @Scheduled(cron = "0 0/5 * * * ?")
    public void VDDToRedis(){

        QueryVo vo = new QueryVo();
        /** 获取最新一条数据 */
        List<DateBigDecimalDto> list = btc2Mapper.getVDDList(vo);


        if(list.size() > 365){
            List<DateBigDecimalDto> sma30 = getSMA(list, 30);

            List<DateBigDecimalDto> sma365= getSMA(list, 365);

            //int diff = 335;
            //if(DateUtils.isSameDay(sma30.get(diff).getDate(),sma365.get(0).getDate())){
            //    sma30.subList(diff,sma30.size());
            //}
            List<DateBigDecimalDto> returnList = sma365.stream().map(e1 -> {
                sma30.stream().filter(e2 -> DateUtils.isSameDay(e1.getDate(), e2.getDate())).forEach(e2 -> {
                    if (e1.getValue().compareTo(BigDecimal.ZERO) > 0) {
                        e1.setValue(e2.getValue().divide(e1.getValue(), 2, BigDecimal.ROUND_HALF_UP));
                    }
                });
                return e1;
            }).collect(Collectors.toList());

            if(returnList.size() > 0){
                //存入redis 先删除原有数据再重新插入数据
                redisService.deleteObject(BTCRedisName.BTC_VDD.getKey());
                redisService.setCacheList(BTCRedisName.BTC_VDD.getKey(),returnList);
            }
        }


    }

    /** btc 已实现盈利交易占比profitRate历史数据 */
    @Scheduled(cron = "0 0 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void ProfitRateToRedis(){

        QueryVo vo = new QueryVo();
        vo.setStart("2010-08-19");
        List<DateBigDecimalDto> list = btc2Mapper.getProfitRateList(vo);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(BTCRedisName.BTC_PROFITRATE.getKey());
            redisService.setCacheList(BTCRedisName.BTC_PROFITRATE.getKey(),list);
        }
    }

    /** btc 交易费fees历史数据 */
    @Scheduled(cron = "0 0 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void FeesToRedis(){

        QueryVo vo = new QueryVo();
        /** 获取最新一条数据 */
        List<DateBigDecimalDto> list = btc2Mapper.getFeesList(vo);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(BTCRedisName.BTC_FEES.getKey());
            redisService.setCacheList(BTCRedisName.BTC_FEES.getKey(),list);
        }

    }

    /** btc 地址相关信息newAddress历史数据 */
    //@Scheduled(cron = "0 2 0/1 * * ?")
    @Scheduled(cron = "0 0/2 * * * ?")
    public void AddressToRedis(){

        QueryVo vo = new QueryVo();
        /** 获取最新一条数据 */
        List<AddressDto> list = btc2Mapper.getAddressList(vo);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(BTCRedisName.BTC_ADDRESS.getKey());
            redisService.setCacheList(BTCRedisName.BTC_ADDRESS.getKey(),list);
        }
    }

    /** btc 交易量volume历史数据 */
    @Scheduled(cron = "0 2 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void VolumeToRedis(){

        QueryVo vo = new QueryVo();
        /** 获取最新一条数据 */
        List<DateBigDecimalDto> list = btc2Mapper.getVolumeList(vo);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(BTCRedisName.BTC_VOLUME.getKey());
            redisService.setCacheList(BTCRedisName.BTC_VOLUME.getKey(),list);
        }
    }

    /** btc 交易量(找零消除)eaVolume历史数据 */
    @Scheduled(cron = "0 4 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void eaVolumeToRedis(){

        QueryVo vo = new QueryVo();
        /** 获取最新一条数据 */
        List<DateBigDecimalDto> list = btc2Mapper.geteaVolumeList(vo);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(BTCRedisName.BTC_EAVOLUME.getKey());
            redisService.setCacheList(BTCRedisName.BTC_EAVOLUME.getKey(),list);
        }
    }

    /** btc 已花费输出盈利比历史数据 */
    @Scheduled(cron = "0 4 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void SoprToRedis(){

        QueryVo vo = new QueryVo();
        vo.setStart("2010-08-19");
        List<SoprDto> list = btc2Mapper.getSoprList(vo);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(BTCRedisName.BTC_SOPR.getKey());
            redisService.setCacheList(BTCRedisName.BTC_SOPR.getKey(),list);
        }
    }

    /** btc 已花费输出平均寿命历史数据 */
    @Scheduled(cron = "0 4 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void AsolToRedis(){

        QueryVo vo = new QueryVo();
        vo.setStart("2010-08-19");
        List<ASOLDto> list = btc2Mapper.getAsolList(vo);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject("asolList");
            redisService.setCacheList("asolList",list);
        }
    }

    /** btc 已花费输出休眠平均天数历史数据 */
    @Scheduled(cron = "0 6 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void DormancyToRedis(){

        QueryVo vo = new QueryVo();
        List<DormancyDto> list = btc2Mapper.getDormancyList(vo);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject("dormancyList");
            redisService.setCacheList("dormancyList",list);
        }
    }

    /** btc 币天销毁量年龄分布历史数据 */
    @Scheduled(cron = "0 6 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void SoagToRedis(){

        QueryVo vo = new QueryVo();
        List<SOAGDto> list = btc2Mapper.getSoagList(vo);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject("soagList");
            redisService.setCacheList("soagList",list);
        }
    }

    /** btc 流通供应量历史数据 */
    @Scheduled(cron = "0 6 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void CirculatingSupplyToRedis(){

        QueryVo vo = new QueryVo();
        List<DateBigDecimalDto> list = btc2Mapper.getCsupplyList(vo);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject("circulatingSupplyList");
            redisService.setCacheList("circulatingSupplyList",list);
        }
    }

    /** btc 累计币天销毁量(流通供应量)历史数据 */
    @Scheduled(cron = "0 8 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void SumCSupplyToRedis(){

        QueryVo vo = new QueryVo();
        List<DateBigDecimalDto> list = btc2Mapper.getSumCsupplyList(vo);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject("sumCirculatingSupplyList");
            redisService.setCacheList("sumCirculatingSupplyList",list);
        }
    }

    /** btc 累计币天销毁量历史数据 */
    @Scheduled(cron = "0 8 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void SumCddToRedis(){

        QueryVo vo = new QueryVo();
        List<DateBigDecimalDto> list = btc2Mapper.getSumCddList(vo);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject("sumCddList");
            redisService.setCacheList("sumCddList",list);

        }
    }

    /** btc 累计币天销毁量(找零消除)历史数据 */
    @Scheduled(cron = "0 8 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void SumEaCddToRedis(){

        QueryVo vo = new QueryVo();
        List<DateBigDecimalDto> list = btc2Mapper.getSumEaCddList(vo);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject("sumEaCddList");
            redisService.setCacheList("sumEaCddList",list);

        }
    }

    /** btc 活跃度历史数据 */
    @Scheduled(cron = "0 8 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void LiveLinessToRedis(){

        QueryVo vo = new QueryVo();
        List<LiveLinessDto> list = btc2Mapper.getLiveLinessList(vo);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject("liveLinessList");
            redisService.setCacheList("liveLinessList",list);

        }
    }

    /** btc 已实现盈利量rprofit历史数据 */
    @Scheduled(cron = "0 10 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void RealizedProfitToRedis(){

        QueryVo vo = new QueryVo();
        vo.setStart("2010-08-19");
        List<DateBigDecimalDto> list = btc2Mapper.getRealizedProfitList(vo);
        if(list.size()>2){
            for(int i=list.size()-1;i > 1;i--){
                DateBigDecimalDto dto1 = list.get(i);
                DateBigDecimalDto dto2 = list.get(i-1);
                list.get(i).setValue(dto1.getValue().subtract(dto2.getValue()));
            }
        }
        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(BTCRedisName.BTC_REALIZED_PROFIT.getKey());
            redisService.setCacheList(BTCRedisName.BTC_REALIZED_PROFIT.getKey(),list);
        }
    }

    /** btc 已实现亏损量rloss历史数据 */
    @Scheduled(cron = "0 10 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void RealizedLossToRedis(){

        QueryVo vo = new QueryVo();
        vo.setStart("2010-08-19");
        List<DateBigDecimalDto> list = btc2Mapper.getRealizedLossList(vo);

        if(list.size()>2){
            for(int i=list.size()-1;i > 1;i--){
                DateBigDecimalDto dto1 = list.get(i);
                DateBigDecimalDto dto2 = list.get(i-1);
                list.get(i).setValue(dto1.getValue().subtract(dto2.getValue()));
            }
        }

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            System.out.println("已实现损失量数据更新条数："+list.size());
            redisService.deleteObject("realizedLossList");
            redisService.setCacheList("realizedLossList",list);
        }
    }

    /** btc 已实现净收益损失比rplrate历史数据 */
    @Scheduled(cron = "0 10 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void RplRateToRedis(){

        QueryVo vo = new QueryVo();
        vo.setStart("2010-08-19");
        List<DateBigDecimalsDto> tList = btc2Mapper.getRealizedProfitAndLossList();
        List<DateBigDecimalDto> list = new ArrayList<>();
        if(tList.size()>2){
            for(int i=tList.size()-1;i > 1;i--){
                DateBigDecimalsDto dto1 = tList.get(i);
                DateBigDecimalsDto dto2 = tList.get(i-1);
                DateBigDecimalDto dto = new DateBigDecimalDto();
                dto.setDate(dto1.getDate());
                BigDecimal rprofit = dto1.getValue1().subtract(dto2.getValue1());
                BigDecimal rloss = dto1.getValue2().subtract(dto2.getValue2());
                if(rloss.compareTo(BigDecimal.ZERO) == 0){
                    dto.setValue(BigDecimal.valueOf(0));
                }else {
                    dto.setValue(rprofit.divide(rloss,8,BigDecimal.ROUND_HALF_UP).stripTrailingZeros());
                }
                list.add(dto);
            }
        }
        Collections.reverse(list);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            System.out.println("已实现净收益损失比数据更新条数："+list.size());
            redisService.deleteObject("rplRateList");
            redisService.setCacheList("rplRateList",list);
        }
    }

    /** btc 流通市值marketcap历史数据 */
    @Scheduled(cron = "0 12 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void MarketCapToRedis(){

        QueryVo vo = new QueryVo();
        vo.setStart("2010-08-19");
        List<DateBigDecimalDto> list = btc2Mapper.getMarketCapList(vo);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(BTCRedisName.BTC_MARKETCAP.getKey());
            redisService.setCacheList(BTCRedisName.BTC_MARKETCAP.getKey(),list);
        }
    }

    /** btc 已实现流通市值RealizedCap历史数据 */
    //@Scheduled(cron = "0 12 0/1 * * ?")
    @Scheduled(cron = "0 0/1 * * * ?")
    public void RealizedCapToRedis(){

        List<DateBigDecimalDto> list = btc2Mapper.getListByTableAndField(BTCRedisName.BTC_REALIZED_CAP.getTable(), BTCRedisName.BTC_REALIZED_CAP.getFiled());

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(BTCRedisName.BTC_REALIZED_CAP.getKey());
            redisService.setCacheList(BTCRedisName.BTC_REALIZED_CAP.getKey(),list);
        }
    }

    /** btc 已实现流通市值RealizedCap历史数据 */
    //@Scheduled(cron = "0 12 0/1 * * ?")
    @Scheduled(cron = "0 0/1 * * * ?")
    public void eaRealizedCapToRedis(){

        List<DateBigDecimalDto> list = btc2Mapper.getListByTableAndField(BTCRedisName.BTC_ENTIT_ADJUSTED_REALIZED_CAP.getTable(), BTCRedisName.BTC_ENTIT_ADJUSTED_REALIZED_CAP.getFiled());

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(BTCRedisName.BTC_ENTIT_ADJUSTED_REALIZED_CAP.getKey());
            redisService.setCacheList(BTCRedisName.BTC_ENTIT_ADJUSTED_REALIZED_CAP.getKey(),list);
        }
    }


    /** btc 流通市值-已实现流通市值比mvrv历史数据 */
    @Scheduled(cron = "0 12 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void MVRVToRedis(){

        QueryVo vo = new QueryVo();
        vo.setStart("2012-01-01");
        List<DataDto> list = btc2Mapper.getMVRVList(vo);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject("mvrvList");
            redisService.setCacheList("mvrvList",list);
        }
    }

    /** btc mvrvz历史数据 */
    //@Scheduled(cron = "0 12 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    //public void MVRVZScoreToRedis(){
    //
    //    QueryVo vo = new QueryVo();
    //    List<DataDto> list = btc2Mapper.getMVRVList(vo);
    //
    //    if(list.size() > 0){
    //        //存入redis 先删除原有数据再重新插入数据
    //        redisService.deleteObject(BTCRedisName.BTC_MVRVZ.getKey());
    //        redisService.setCacheList(BTCRedisName.BTC_MVRVZ.getKey(),list);
    //    }
    //}

    //@Scheduled(cron = "0 12 0/1 * * ?")
    @Scheduled(cron = "0 0/1 * * * ?")
    public void McapAndRcapToRedis(){

        QueryVo vo = new QueryVo();
        vo.setStart("2010-08-19");
        List<RCapAndMCapDto> list = btc2Mapper.getRealizedCapAndMarketCapList(vo);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(BTCRedisName.BTC_MVRVZ.getKey());
            redisService.setCacheList(BTCRedisName.BTC_MVRVZ.getKey(),list);
        }
    }



    /** btc 长持者流通市值-已实现流通市值比lthmvrv历史数据 */
    //@Scheduled(cron = "0 14 0/1 * * ?")
    @Scheduled(cron = "0 0/2 * * * ?")
    public void LthMVRVToRedis(){

        QueryVo vo = new QueryVo();
        vo.setStart("2022-06-01");
        List<TermHoldermvrvDto> list = btc2Mapper.getLthMVRVList(vo);

        TermHoldermvrvDto dto1 = new TermHoldermvrvDto();
        BeanUtils.copyProperties(list.stream().filter(e -> DateUtils.isSameDay(e.getDate(),DateUtils.parseDate("2023-02-04"))).findFirst().get(),dto1);
        dto1.setDate(DateUtils.parseDate("2023-02-05 00:00:00"));

        TermHoldermvrvDto dto2 = new TermHoldermvrvDto();
        BeanUtils.copyProperties(list.stream().filter(e -> DateUtils.isSameDay(e.getDate(),DateUtils.parseDate("2023-05-09"))).findFirst().get(),dto2);
        dto2.setDate(DateUtils.parseDate("2023-05-10 00:00:00"));

        TermHoldermvrvDto dto3 = new TermHoldermvrvDto();
        BeanUtils.copyProperties(list.stream().filter(e -> DateUtils.isSameDay(e.getDate(),DateUtils.parseDate("2023-05-09"))).findFirst().get(),dto3);
        dto3.setDate(DateUtils.parseDate("2023-05-11 00:00:00"));

        list.add(dto1);
        list.add(dto2);
        list.add(dto3);

        //根据时间去重排序
        list = list.stream()
                .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(TermHoldermvrvDto::getDate))),ArrayList::new));


        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(BTCRedisName.BTC_LTH_MVRV.getKey());
            redisService.setCacheList(BTCRedisName.BTC_LTH_MVRV.getKey(),list);
        }
    }

    /** btc 短持者流通市值-已实现流通市值比sthmvrv历史数据 */
    //@Scheduled(cron = "0 14 0/1 * * ?")
    @Scheduled(cron = "0 0/2 * * * ?")
    public void SthMVRVToRedis(){

        QueryVo vo = new QueryVo();
        vo.setStart("2022-06-01");
        List<TermHoldermvrvDto> list = btc2Mapper.getSthMVRVList(vo);

        TermHoldermvrvDto dto1 = new TermHoldermvrvDto();
        BeanUtils.copyProperties(list.stream().filter(e -> DateUtils.isSameDay(e.getDate(),DateUtils.parseDate("2023-02-04"))).findFirst().get(),dto1);
        dto1.setDate(DateUtils.parseDate("2023-02-05 00:00:00"));

        TermHoldermvrvDto dto2 = new TermHoldermvrvDto();
        BeanUtils.copyProperties(list.stream().filter(e -> DateUtils.isSameDay(e.getDate(),DateUtils.parseDate("2023-05-09"))).findFirst().get(),dto2);
        dto2.setDate(DateUtils.parseDate("2023-05-10 00:00:00"));

        TermHoldermvrvDto dto3 = new TermHoldermvrvDto();
        BeanUtils.copyProperties(list.stream().filter(e -> DateUtils.isSameDay(e.getDate(),DateUtils.parseDate("2023-05-09"))).findFirst().get(),dto3);
        dto3.setDate(DateUtils.parseDate("2023-05-11 00:00:00"));

        list.add(dto1);
        list.add(dto2);
        list.add(dto3);

        //根据时间去重排序
        list = list.stream()
                .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(TermHoldermvrvDto::getDate))),ArrayList::new));

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(BTCRedisName.BTC_STH_MVRV.getKey());
            redisService.setCacheList(BTCRedisName.BTC_STH_MVRV.getKey(),list);
        }
    }

    /** btc 未实现的净收益损失比Nupl历史数据 */
    @Scheduled(cron = "0 14 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void NuplToRedis(){

        QueryVo vo = new QueryVo();
        vo.setStart("2010-08-19");
        List<DateBigDecimalDto> list = btc2Mapper.getNuplList(vo);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(BTCRedisName.BTC_NUPL.getKey());
            redisService.setCacheList(BTCRedisName.BTC_NUPL.getKey(),list);
        }
    }

    /** btc 未实现的净收益量uprofit历史数据 */
    //@Scheduled(cron = "0 16 0/1 * * ?")
    @Scheduled(cron = "0 0/1 * * * ?")
    public void uProfitToRedis(){
        //uprofit/marketcap

        QueryVo vo = new QueryVo();
        vo.setStart("2018-10-01");
        List<DateBigDecimalDto> uList = btc2Mapper.getUnrealizedProfitList(vo);
        List<DateBigDecimalDto> mList = btc2Mapper.getMarketCapList(vo);

        List<DateBigDecimalDto> list = uList.stream().map(u -> {
            DateBigDecimalDto dto = new DateBigDecimalDto();
            mList.stream().filter(m -> Objects.equals(u.getDate(),m.getDate())).forEach(m -> {
                dto.setDate(m.getDate());
                if(StringUtils.isNotNull(m.getValue())){
                    if(m.getValue().compareTo(BigDecimal.ZERO) > 0){
                        //分母不能为null且不能为0
                        dto.setValue(u.getValue().divide(m.getValue(),8,BigDecimal.ROUND_HALF_UP));
                    }
                }
            });
            return dto;
        }).collect(Collectors.toList());

        list = tempAddUtxosData(list);

        list = list.stream().filter(e -> StringUtils.isNotNull(e.getValue())).collect(Collectors.toList());

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            System.out.println("uprofit第一条数据"+list.get(0));
            redisService.deleteObject(BTCRedisName.BTC_UNREALIZED_PROFIT.getKey());
            redisService.setCacheList(BTCRedisName.BTC_UNREALIZED_PROFIT.getKey(),list);
        }
    }

    /** btc 未实现的净亏损量uloss历史数据 */
    //@Scheduled(cron = "0 16 0/1 * * ?")
    @Scheduled(cron = "0 0/2 * * * ?")
    public void uLossToRedis(){

        QueryVo vo = new QueryVo();
        vo.setStart("2018-10-01");
        List<DateBigDecimalDto> uList = btc2Mapper.getUnrealizedLossList(vo);

        List<DateBigDecimalDto> mList = btc2Mapper.getMarketCapList(vo);

        List<DateBigDecimalDto> list = uList.stream().map(u -> {
            DateBigDecimalDto dto = new DateBigDecimalDto();
            mList.stream().filter(m -> Objects.equals(u.getDate(),m.getDate())).forEach(m -> {
                dto.setDate(m.getDate());
                if(StringUtils.isNotNull(m.getValue())){
                    if(m.getValue().compareTo(BigDecimal.ZERO) > 0){
                        //分母不能为null且不能为0
                        dto.setValue(u.getValue().divide(m.getValue(),8,BigDecimal.ROUND_HALF_UP));
                    }
                }
            });
            return dto;
        }).collect(Collectors.toList());

        list = tempAddUtxosData(list);

        list = list.stream().filter(e -> StringUtils.isNotNull(e.getValue())).collect(Collectors.toList());


        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            System.out.println("uloss第一条数据"+list.get(0));
            redisService.deleteObject(BTCRedisName.BTC_UNREALIZED_LOSS.getKey());
            redisService.setCacheList(BTCRedisName.BTC_UNREALIZED_LOSS.getKey(),list);
        }
    }

    /** btc 长持者未实现的净收益损失比lthnupl */
    //@Scheduled(cron = "0 16 0/1 * * ?")
    @Scheduled(cron = "0 0/2 * * * ?")
    public void LthNuplToRedis(){

        QueryVo vo = new QueryVo();
        vo.setStart("2018-10-01");
        List<DateBigDecimalsDto> tempList = btc2Mapper.getLthNuplList(vo);

        List<DateBigDecimalDto> list = tempList.stream().map(e -> {
            DateBigDecimalDto dto = new DateBigDecimalDto();
            dto.setDate(e.getDate());
            BigDecimal marketcap = e.getValue2().add(e.getValue3());
            if (marketcap.compareTo(BigDecimal.ZERO) == 0){
                dto.setValue(BigDecimal.ZERO);
            }else {
                dto.setValue(e.getValue1().divide(marketcap,8,BigDecimal.ROUND_HALF_UP));
            }
            return dto;
        }).collect(Collectors.toList());

        list = tempAddUtxosData(list);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(BTCRedisName.BTC_LTH_NUPL.getKey());
            redisService.setCacheList(BTCRedisName.BTC_LTH_NUPL.getKey(),list);
        }
    }

    /** btc 短持者未实现的净收益损失比sthnupl */
    //@Scheduled(cron = "0 16 0/1 * * ?")
    @Scheduled(cron = "0 0/2 * * * ?")
    public void SthNuplToRedis(){

        QueryVo vo = new QueryVo();
        vo.setStart("2018-10-01");
        List<DateBigDecimalsDto> tempList = btc2Mapper.getSthNuplList(vo);

        List<DateBigDecimalDto> list = tempList.stream().map(e -> {
            DateBigDecimalDto dto = new DateBigDecimalDto();
            dto.setDate(e.getDate());
            BigDecimal marketcap = e.getValue2().add(e.getValue3());
            if (marketcap.compareTo(BigDecimal.ZERO) == 0){
                dto.setValue(BigDecimal.ZERO);
            }else {
                dto.setValue(e.getValue1().divide(marketcap,8,BigDecimal.ROUND_HALF_UP));
            }
            return dto;
        }).collect(Collectors.toList());

        list = tempAddUtxosData(list);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(BTCRedisName.BTC_STH_NUPL.getKey());
            redisService.setCacheList(BTCRedisName.BTC_STH_NUPL.getKey(),list);
        }
    }

    /** btc 发行价值（USD）mintusd */
    //@Scheduled(cron = "0 18 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void MintusdToRedis(){

        //获取每年的平均值
        Map<Integer, YearMaDto> map = btc2Mapper.getMintusdYearAvg();

        QueryVo vo = new QueryVo();
        List<DateBigDecimalDto> list = btc2Mapper.getMintusdList(vo);

        for(int i=0; i < list.size();i++){
            DateBigDecimalDto entry = list.get(i);
            int year = Convert.toInt(DateUtils.parseDateToStr(DateUtils.YYYY,entry.getDate()));
            YearMaDto dto = map.get(year);
            BigDecimal ma = dto.getValue();

            if(StringUtils.isNull(ma)){
                //ma为null 说明当前年份没有平均值
            }else {
                if(BigDecimal.ZERO.compareTo(ma) == 0){
                    //ma为0 说明当前年份平均值为0.0
                }else {
                    entry.setValue(entry.getValue().divide(ma, 8,BigDecimal.ROUND_HALF_UP).stripTrailingZeros());
                }
            }
        }
        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(BTCRedisName.BTC_MINTUSD.getKey());
            redisService.setCacheList(BTCRedisName.BTC_MINTUSD.getKey(),list);
        }
    }

    /** btc PuellMultiple */
    @Scheduled(cron = "0 18 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void PuellMultipleToRedis(){

        QueryVo vo = new QueryVo();
        //vo.setStart("2010-08-19");
        List<DateBigDecimalDto> list = btc2Mapper.getMintusdList(vo);

        int day = 365;

        BigDecimal total = BigDecimal.ZERO;
        BigDecimal divideNumber = new BigDecimal(day);
        for(int i = 0 ; i < day ;i++){
            total =  list.get(i).getValue().add(total);
        }
        BigDecimal startY = total.divide(divideNumber, 8, BigDecimal.ROUND_HALF_UP);
        DateBigDecimalDto startDto = new DateBigDecimalDto();
        startDto.setDate(list.get(day-1).getDate());
        if(startY.compareTo(BigDecimal.ZERO) >0){
            //mintusd/sma365(mintusd)
            startDto.setValue(list.get(day).getValue().divide(startY,8,BigDecimal.ROUND_HALF_UP).stripTrailingZeros());
        }else {
            startDto.setValue(startY.stripTrailingZeros());
        }
        System.out.println("数据初始条数："+list.size());
        System.out.println("puell第一条数据："+startDto);

        List<DateBigDecimalDto> smaList = new ArrayList<>();
        smaList.add(startDto);
        for (int i = day; i < list.size(); i++) {

            total = total.add(list.get(i).getValue()).subtract(list.get(i-day).getValue());

            startY = total.divide(divideNumber,8, BigDecimal.ROUND_HALF_UP);

            DateBigDecimalDto dto = new DateBigDecimalDto();
            dto.setDate(list.get(i).getDate());
            //分母大于0 才做计算 否则直接强
            if(startY.compareTo(BigDecimal.ZERO) >0){
                //mintusd/sma365(mintusd)
                dto.setValue(list.get(i).getValue().divide(startY,8,BigDecimal.ROUND_HALF_UP).stripTrailingZeros());
            }else {
                dto.setValue(startY.stripTrailingZeros());
            }

            smaList.add(dto);
        }

        //过滤掉2011之前过大的数据
        Date start = DateUtils.parseDate("2011-01-01");
        smaList = smaList.stream().filter(dto -> (dto.getDate().after(start) || dto.getDate().equals(start))).collect(Collectors.toList());


        if(smaList.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject("mintusdList");
            redisService.setCacheList("mintusdList",smaList);
        }


    }

    /** btc 币价Price */
    @Scheduled(cron = "8 18 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void BtcPriceToRedis(){

        QueryVo vo = new QueryVo();
        //vo.setStart("2010-08-19");
        //List<DataDto> list = btc2Mapper.getPriceList(vo);
        List<PriceDataDto> list = btc2Mapper.getPriceList(vo);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject("btcPriceList");
            redisService.setCacheList("btcPriceList",list);
        }
    }

    /** btc 币价Price BigDecimal */
    @Scheduled(cron = "0 18 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void BtcPriceBigDecimalToRedis(){
        QueryVo vo = new QueryVo();
        //vo.setStart("2010-08-19");
        //List<PriceSMADto> list = btc2Mapper.getPriceBigDecimalList(vo);
        List<PriceSMADto> list = btc2Mapper.getPriceBigDecimalList(vo);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject("btcPriceBigDecimalList");
            redisService.setCacheList("btcPriceBigDecimalList",list);
        }
    }

    /** btc 矿工地址数 */
    //@Scheduled(cron = "0 20 0/1 * * ?")
    @Scheduled(cron = "0 0/2 * * * ?")
    public void MinerAddressToRedis(){

        QueryVo vo = new QueryVo();
        vo.setStart("2018-10-01");
        List<DateBigDecimalDto> list = btc2Mapper.getMinerAddressList(vo);

        list = tempAddUtxosData(list);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(BTCRedisName.BTC_MINER_ADDRESS.getKey());
            redisService.setCacheList(BTCRedisName.BTC_MINER_ADDRESS.getKey(),list);
        }
    }

    /** btc 矿工地址余额 */
    //@Scheduled(cron = "0 20 0/1 * * ?")
    @Scheduled(cron = "0 0/2 * * * ?")
    public void MinerBalanceToRedis(){

        QueryVo vo = new QueryVo();
        vo.setStart("2018-10-01");
        List<DateBigDecimalDto> list = btc2Mapper.getMinerBalanceList(vo);

        list = tempAddUtxosData(list);
        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(BTCRedisName.BTC_MINER_BALANCE.getKey());
            redisService.setCacheList(BTCRedisName.BTC_MINER_BALANCE.getKey(),list);
        }
    }


    /** btc 币价 */
    @Scheduled(cron = "0 20 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void BTCPriceToRedis(){

        QueryVo vo = new QueryVo();
        List<PriceDataDto> list  = btcMapper.getPriceList(vo);

        list.stream().forEach(e -> e.setTime(DateUtils.dateTime(DateUtils.YYYY_MM_DD,DateUtils.dateTime(e.getTime()))));

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(BTCRedisName.BTC_PRICE.getKey());
            redisService.setCacheList(BTCRedisName.BTC_PRICE.getKey(),list);
        }
    }

    public List<DateBigDecimalDto> tempAddUtxosData(List<DateBigDecimalDto> list){


        //临时处理 补充缺失数据 同时去重 防止数据补充后产生重复数据
        //补充操作 拿前一天数据
        DateBigDecimalDto dto1 = new DateBigDecimalDto();
        BeanUtils.copyProperties(list.stream().filter(e -> DateUtils.isSameDay(e.getDate(),DateUtils.parseDate("2018-10-21"))).findFirst().get(),dto1);
        dto1.setDate(DateUtils.parseDate("2018-10-22 00:00:00"));

        DateBigDecimalDto dto2 = new DateBigDecimalDto();
        BeanUtils.copyProperties(list.stream().filter(e -> DateUtils.isSameDay(e.getDate(),DateUtils.parseDate("2018-12-23"))).findFirst().get(),dto2);
        dto2.setDate(DateUtils.parseDate("2018-12-24 00:00:00"));

        DateBigDecimalDto dto3 = new DateBigDecimalDto();
        BeanUtils.copyProperties(list.stream().filter(e -> DateUtils.isSameDay(e.getDate(),DateUtils.parseDate("2018-12-30"))).findFirst().get(),dto3);
        dto3.setDate(DateUtils.parseDate("2018-12-31 00:00:00"));

        DateBigDecimalDto dto4 = new DateBigDecimalDto();
        BeanUtils.copyProperties(list.stream().filter(e -> DateUtils.isSameDay(e.getDate(),DateUtils.parseDate("2020-02-02"))).findFirst().get(),dto4);
        dto4.setDate(DateUtils.parseDate("2020-02-03 00:00:00"));

        DateBigDecimalDto dto5 = new DateBigDecimalDto();
        BeanUtils.copyProperties(list.stream().filter(e -> DateUtils.isSameDay(e.getDate(),DateUtils.parseDate("2021-10-25"))).findFirst().get(),dto5);
        dto5.setDate(DateUtils.parseDate("2021-10-26 00:00:00"));

        DateBigDecimalDto dto6 = new DateBigDecimalDto();
        BeanUtils.copyProperties(list.stream().filter(e -> DateUtils.isSameDay(e.getDate(),DateUtils.parseDate("2022-04-24"))).findFirst().get(),dto6);
        dto6.setDate(DateUtils.parseDate("2022-04-25 00:00:00"));

        DateBigDecimalDto dto7 = new DateBigDecimalDto();
        BeanUtils.copyProperties(list.stream().filter(e -> DateUtils.isSameDay(e.getDate(),DateUtils.parseDate("2023-02-04"))).findFirst().get(),dto7);
        dto7.setDate(DateUtils.parseDate("2023-02-05 00:00:00"));

        DateBigDecimalDto dto8 = new DateBigDecimalDto();
        BeanUtils.copyProperties(list.stream().filter(e -> DateUtils.isSameDay(e.getDate(),DateUtils.parseDate("2023-05-09"))).findFirst().get(),dto8);
        dto8.setDate(DateUtils.parseDate("2023-05-10 00:00:00"));

        DateBigDecimalDto dto9 = new DateBigDecimalDto();
        BeanUtils.copyProperties(list.stream().filter(e -> DateUtils.isSameDay(e.getDate(),DateUtils.parseDate("2023-05-09"))).findFirst().get(),dto9);
        dto9.setDate(DateUtils.parseDate("2023-05-11 00:00:00"));

        list.add(dto1);
        list.add(dto2);
        list.add(dto3);
        list.add(dto4);
        list.add(dto5);
        list.add(dto6);
        list.add(dto7);
        list.add(dto8);
        list.add(dto9);

        //根据时间去重排序
        list = list.stream()
                .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(DateBigDecimalDto::getDate))),ArrayList::new));

        return list;
    }


    /**
     * sma处理
     * @param list
     * @return
     */
    public List<DateBigDecimalDto> getSMA(List<DateBigDecimalDto> list,int day) {

        if (list.size()< day){
            return new ArrayList<>();
        }
        if(list.size() < 1){
            return list;
        }

        BigDecimal total = BigDecimal.ZERO;
        BigDecimal divideNumber = new BigDecimal(day);
        for(int i = 0 ; i < day ;i++){
            total =  list.get(i).getValue().add(total);
        }
        BigDecimal startY = total.divide(divideNumber, 8, BigDecimal.ROUND_HALF_UP);
        DateBigDecimalDto startDto = new DateBigDecimalDto();
        startDto.setDate(list.get(day-1).getDate());
        startDto.setValue(startY.stripTrailingZeros());

        List<DateBigDecimalDto> returnList = new ArrayList<>();
        returnList.add(startDto);
        for (int i = day; i < list.size(); i++) {

            total = total.add(list.get(i).getValue()).subtract(list.get(i-day).getValue());

            startY = total.divide(divideNumber,8,BigDecimal.ROUND_HALF_UP);

            DateBigDecimalDto dto = new DateBigDecimalDto();
            dto.setDate(list.get(i).getDate());
            dto.setValue(startY.stripTrailingZeros());

            returnList.add(dto);
        }
        return returnList;
    }


}
