package link.at17.mid.tushare;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import link.at17.mid.tushare.dao.StockDailyDao;
import link.at17.mid.tushare.dao.StockMinuteDao;
import link.at17.mid.tushare.data.models.CostDistribution;
import link.at17.mid.tushare.data.models.StockInfo;
import link.at17.mid.tushare.data.models.StockValueEx;
import link.at17.mid.tushare.data.service.StockInfoService;
import link.at17.mid.tushare.data.util.Indicators;
import link.at17.mid.tushare.enums.ListStatus;
import link.at17.mid.tushare.enums.StockSpan;
import link.at17.mid.tushare.system.util.LocalDateTimeUtils;
import lombok.extern.slf4j.Slf4j;

/**
 * 竞价成交量增长测试 + 筹码分布
 * 其实可以看下换手率，因为换手率 = 成交量 / 流通股。
 * 如果随着股票增发导致换手率降低的，可能要多考虑一下
 * @author Barry
 *
 */
@SpringBootTest
@Slf4j
class MinuteCostDistribution {

    @Autowired
    StockDailyDao stockDailyDao;
    
    @Autowired
    StockMinuteDao stockMinuteDao;

    @Autowired
    StockInfoService stockInfoService;
    
    @Test
    void test() throws ParseException {
        List<StockInfo> stockInfos = stockInfoService.listByListStatus(ListStatus.LIST);
        // stockInfos = new ArrayList<>();
        // stockInfos.add(stockInfoDao.selectOne(new QueryWrapper<StockInfo>().eq("ts_code", "000812.SZ")));
        
        
        List<Double> profits = new ArrayList<>();
        int count = 10 * 241, window = 10 * 241;
        log.info("代码\t名称\t日期\t当日涨跌幅\t窗口期最大涨幅\t最大涨幅时间\t窗口期最大回撤\t最大回撤时间");
        stockInfos.parallelStream().forEach(stockInfo -> {
            try {
                String stockName = stockInfo.getName(), stockCode = stockInfo.getTsCode();
                if (stockName.contains("ST") || stockName.startsWith("N") || stockName.startsWith("C") || stockCode.endsWith("BJ")) {
                    return;
                }
                List<StockValueEx> minuteK = stockMinuteDao.getExQfqMinuteBefore(stockInfo.getTsCode(), StockSpan.Minute, null, 100L * 241);
                List<String> satisfiedDates = new ArrayList<>();
                for (int i = count; i < minuteK.size(); i++) {
                    StockValueEx current = minuteK.get(i);
                    StockValueEx previous = minuteK.get(i - 1);
                    minuteK.get(i - count).getClose();
                    minuteK.get(i - 1).getClose();
                    
                    // 看看前 count 个交易日内是否有获利比例小于 0.015% 的情况
                    List<CostDistribution> cds = Indicators.getCostDistributions(minuteK, i - count, i, 150, 120 * 241);
                    if (cds.stream().anyMatch(cd -> cd.getBenifitPart() <= 0.00015)) {
                        String date = current.getDateStr("yyyy-MM-dd");
                        if (satisfiedDates.contains(date)) {
                            continue;
                        }
                        satisfiedDates.add(date);
                        String dateTime = current.getDateStr("yyyy-MM-dd HH:mm:ss");
                        List<StockValueEx> future = minuteK.subList(i, Math.min(i + window, minuteK.size()));
                        StockValueEx max = future.stream().max((x, y) -> x.getClose().compareTo(y.getClose())).orElse(current);
                        StockValueEx min = future.stream().max((x, y) -> -x.getClose().compareTo(y.getClose())).orElse(current);
                        //if (date.equals("2021-10-18"))
                            // 代码 名称 日期 当日涨跌幅 窗口期最大涨幅 最大涨幅时间 窗口期最大回撤 最大回撤时间
                            log.info("{}\t{}\t{}\t{}%\t{}%\t{}\t{}%\t{}",
                                    stockInfo.getTsCode(), 
                                    stockInfo.getName(), 
                                    dateTime,
                                    (current.getClose() - previous.getClose()) / previous.getClose() * 100,
                                    (max.getClose() - current.getClose()) / current.getClose() * 100,
                                    LocalDateTimeUtils.format(max.getDate(), "yyyy-MM-dd HH:mm:ss"),
                                    (min.getClose() - current.getClose()) / current.getClose() * 100,
                                    LocalDateTimeUtils.format(min.getDate(), "yyyy-MM-dd HH:mm:ss")
                                    );
                    }
                }
            }
            catch (Exception e) {
                log.error(stockInfo.getStockCode() + "数据缺失", e);
            }
                
            
            /*
            bullishArrange.stream().forEach(index -> {
                log.info("{} {} - {} 出现多头排列",
                            stockInfo.getTsCode(), 
                            stockInfo.getName(), 
                            DateUtils.format(dailyK.get(index).getDate(), "yyyy-MM-dd"));
            });
            if (true) return;*/
        });
        System.out.println("总收益率 " + profits.stream().reduce(Double::sum).orElse(0d) / profits.size());
    }

}
