Subversion Repositories Integrator Subversion

Rev

Rev 761 | Rev 767 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 761 Rev 764
Line 5... Line 5...
5
import java.math.BigDecimal;
5
import java.math.BigDecimal;
6
import java.nio.file.Path;
6
import java.nio.file.Path;
7
import java.time.LocalDate;
7
import java.time.LocalDate;
8
import java.time.LocalDateTime;
8
import java.time.LocalDateTime;
9
import java.time.LocalTime;
9
import java.time.LocalTime;
-
 
10
import java.time.ZoneId;
10
import java.time.format.DateTimeFormatter;
11
import java.time.format.DateTimeFormatter;
-
 
12
import java.util.ArrayList;
-
 
13
import java.util.Collections;
-
 
14
import java.util.Date;
11
import java.util.HashMap;
15
import java.util.HashMap;
12
import java.util.List;
16
import java.util.List;
-
 
17
import java.util.Locale;
13
import java.util.Map;
18
import java.util.Map;
14
19
-
 
20
import org.apache.poi.EncryptedDocumentException;
15
import org.apache.poi.ss.usermodel.Cell;
21
import org.apache.poi.ss.usermodel.Cell;
16
import org.apache.poi.ss.usermodel.CellType;
22
import org.apache.poi.ss.usermodel.CellType;
17
import org.apache.poi.ss.usermodel.DateUtil;
23
import org.apache.poi.ss.usermodel.DateUtil;
18
import org.apache.poi.ss.usermodel.Row;
24
import org.apache.poi.ss.usermodel.Row;
19
import org.apache.poi.ss.usermodel.Sheet;
25
import org.apache.poi.ss.usermodel.Sheet;
20
import org.apache.poi.ss.usermodel.Workbook;
26
import org.apache.poi.ss.usermodel.Workbook;
21
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
27
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
22
28
-
 
29
import br.com.kronus.core.Timeframe;
23
import br.com.sl.domain.dto.robo.ProfitTick;
30
import br.com.sl.domain.dto.robo.ProfitTick;
24
import br.com.sl.domain.model.Candle;
31
import br.com.sl.domain.model.Candle;
-
 
32
import br.com.sl.domain.model.tipos.TipoPeriodoCandle;
25
33
26
public class ExcelProfitDataProvider implements ProfitDataProvider {
34
public class ExcelProfitDataProvider implements ProfitDataProvider {
27
35
28
    private final Path excelFile;
-
 
-
 
36
        private final Path excelFile;
29
    private final String sheetName;
37
    private final String sheetName;
30
38
31
    // índices de coluna (0 = A, 1 = B, etc.)
39
    // índices de coluna (0 = A, 1 = B, etc.)
32
    private final int colAsset = 0;
40
    private final int colAsset = 0;
33
    private final int colDate  = 1;
41
    private final int colDate  = 1;
Line 35... Line 43...
35
    private final int colLast  = 3;
43
    private final int colLast  = 3;
36
44
37
    // formatos da data e hora, conforme Excel
45
    // formatos da data e hora, conforme Excel
38
    private final DateTimeFormatter fmtData = DateTimeFormatter.ofPattern("dd/MM/yyyy");
46
    private final DateTimeFormatter fmtData = DateTimeFormatter.ofPattern("dd/MM/yyyy");
39
    private final DateTimeFormatter fmtHora = DateTimeFormatter.ofPattern("HH:mm:ss");
47
    private final DateTimeFormatter fmtHora = DateTimeFormatter.ofPattern("HH:mm:ss");
-
 
48
   
-
 
49
    private static final DateTimeFormatter STRING_DATA_FORMATTER = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
-
 
50
    private static final DateTimeFormatter STRING_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
40
51
41
    public ExcelProfitDataProvider(Path excelFile, String sheetName) {
52
    public ExcelProfitDataProvider(Path excelFile, String sheetName) {
42
        this.excelFile = excelFile;
53
        this.excelFile = excelFile;
43
        this.sheetName = sheetName;
54
        this.sheetName = sheetName;
44
    }
55
    }
45
-
 
-
 
56
   
46
    @Override
57
    @Override
47
    public Map<String, ProfitTick> readCurrentTicks() {
58
    public Map<String, ProfitTick> readCurrentTicks() {
48
        Map<String, ProfitTick> ticks = new HashMap<>();
-
 
-
 
59
        // TODO Auto-generated method stub
-
 
60
        return null;
-
 
61
    }
-
 
62
   
-
 
63
    /**
-
 
64
     * Lê o arquivo Excel dentro do resources.
-
 
65
     * Exemplo de uso:
-
 
66
     *    lerCandles("/dados/Dados Trade 20251117.xlsx");
-
 
67
     * @throws IOException
-
 
68
     */
-
 
69
    public List<Candle> lerCandles() throws IOException {
-
 
70
        List<Candle> candles = new ArrayList<>();
49
71
50
        try (FileInputStream fis = new FileInputStream(excelFile.toFile()); Workbook workbook = new XSSFWorkbook(fis)) {
72
        try (FileInputStream fis = new FileInputStream(excelFile.toFile()); Workbook workbook = new XSSFWorkbook(fis)) {
51
            Sheet sheet = (sheetName != null)
-
 
52
                    ? workbook.getSheet(sheetName)
-
 
53
                    : workbook.getSheetAt(0);
-
 
-
 
73
            int numberOfSheets = workbook.getNumberOfSheets();
54
74
55
            if (sheet == null) {
-
 
56
                System.err.println("[ExcelProfitDataProvider] Aba não encontrada: " + sheetName);
-
 
57
                return ticks;
-
 
58
            }
-
 
59
           
-
 
60
            int firstRow = sheet.getFirstRowNum() + 1; // pula cabeçalho
-
 
61
            int lastRow = sheet.getLastRowNum();
-
 
62
-
 
63
            for (int i = firstRow; i <= lastRow; i++) {
-
 
64
                Row row = sheet.getRow(i);
-
 
65
                if (row == null) continue;
-
 
66
-
 
67
                Cell cellAsset = row.getCell(colAsset);
-
 
68
                if (cellAsset == null) continue;
-
 
69
-
 
70
                String asset = cellAsset.toString().trim();
-
 
71
                if (asset.isEmpty()) continue;
-
 
72
-
 
73
                LocalDate date = lerData(row.getCell(colDate));
-
 
74
                LocalTime time = lerHora(row.getCell(colTime));
-
 
75
                BigDecimal price = lerPreco(row.getCell(colLast));
-
 
76
-
 
77
                if (date == null || time == null || price == null) {
-
 
78
                    continue;
-
 
79
                }
-
 
80
-
 
81
                LocalDateTime dateTime = LocalDateTime.of(date, time);
-
 
82
                ProfitTick tick = new ProfitTick(asset, dateTime, price);
-
 
83
-
 
84
                // Se tiver mais de uma linha por ativo, você pode decidir
-
 
85
                // se guarda o último (maior horário) ou o primeiro; aqui guardo o último
-
 
86
                ProfitTick tickExistente = ticks.get(asset);
-
 
87
                if (tickExistente == null || tick.getDateTime().isAfter(tickExistente.getDateTime())) {
-
 
88
                    ticks.put(asset, tick);
-
 
-
 
75
            for (int i = 0; i < numberOfSheets; i++) {
-
 
76
                Sheet sheet = workbook.getSheetAt(i);
-
 
77
                if (sheet.getSheetName().equals(sheetName)) {
-
 
78
                        boolean firstRow = true;
-
 
79
       
-
 
80
                        for (Row row : sheet) {
-
 
81
                            if (firstRow) {
-
 
82
                                firstRow = false; // pula o cabeçalho
-
 
83
                                continue;
-
 
84
                            }
-
 
85
                           
-
 
86
                            // 0 = Contador
-
 
87
                            // 0 = Ativo
-
 
88
                            // 1 = Dia
-
 
89
                            // 2 = Hora
-
 
90
                            // 3 = Abertura
-
 
91
                            // 4 = Máxima
-
 
92
                            // 5 = Mínima
-
 
93
                            // 6 = Fechamento
-
 
94
                            // 7 = Volume
-
 
95
                            // 8 = ...
-
 
96
       
-
 
97
                            Cell contadorCell   = row.getCell(0);
-
 
98
                            Cell ativoCell      = row.getCell(1);
-
 
99
                            Cell dataCell       = row.getCell(2);
-
 
100
                            Cell horaCell       = row.getCell(3);
-
 
101
                            Cell aberturaCell   = row.getCell(4);
-
 
102
                            Cell maximaCell     = row.getCell(5);
-
 
103
                            Cell minimaCell     = row.getCell(6);
-
 
104
                            Cell fechamentoCell = row.getCell(7);
-
 
105
                            Cell finalizadoCell = row.getCell(8);
-
 
106
       
-
 
107
                            if (!isNumeric(aberturaCell) || !isNumeric(maximaCell)
-
 
108
                                        || !isNumeric(minimaCell) || !isNumeric(fechamentoCell)) {
-
 
109
                                continue;
-
 
110
                            }
-
 
111
                           
-
 
112
                            Integer contador = BigDecimal.valueOf(contadorCell.getNumericCellValue()).intValue();
-
 
113
                            String ativoDescricao = ativoCell.getStringCellValue();
-
 
114
                           
-
 
115
        //                    String data = dataCell.getStringCellValue();
-
 
116
        //                    String hora = horaCell.getStringCellValue();
-
 
117
                           
-
 
118
                            LocalDate data = lerData(dataCell);
-
 
119
                            LocalTime hora = lerHora(horaCell);
-
 
120
                            LocalDateTime dataHora = LocalDateTime.of(data, hora);
-
 
121
       
-
 
122
        //                    Date data = diaCell.getDateCellValue();
-
 
123
        //                    String dia = new SimpleDateFormat("dd/MM/yyyy").format(data);
-
 
124
        //                    String hora = horaCell.getStringCellValue();
-
 
125
        //                    LocalDateTime time = getLocalDateTime(dia + " " + hora, STRING_DATA_FORMATTER);
-
 
126
                            BigDecimal abertura = BigDecimal.valueOf(aberturaCell.getNumericCellValue());
-
 
127
                            BigDecimal topo = BigDecimal.valueOf(maximaCell.getNumericCellValue());
-
 
128
                            BigDecimal fundo = BigDecimal.valueOf(minimaCell.getNumericCellValue());
-
 
129
                            BigDecimal fechamento = BigDecimal.valueOf(fechamentoCell.getNumericCellValue());
-
 
130
                           
-
 
131
                            String finalizado = finalizadoCell.getStringCellValue();
-
 
132
                            if (finalizado.equals("S")) {
-
 
133
                                Candle candle = new Candle(contador, ativoDescricao, dataHora, abertura, topo, fundo, fechamento, TipoPeriodoCandle.M1.getValor());
-
 
134
                                candles.add(candle);
-
 
135
                            }
-
 
136
                        }
89
                }
137
                }
90
            }
138
            }
-
 
139
        } catch (EncryptedDocumentException e) {
-
 
140
                        // TODO Auto-generated catch block
-
 
141
                        e.printStackTrace();
-
 
142
                }
-
 
143
//        return adicionarContadores(inverterLista(candles));
-
 
144
        return candles;
-
 
145
    }
-
 
146
   
-
 
147
    public static List<Candle> inverterLista(List<Candle> candles) {
-
 
148
        List<Candle> invertida = new ArrayList<>(candles);
-
 
149
        Collections.reverse(invertida);
-
 
150
        return invertida;
-
 
151
    }
91
152
92
        } catch (IOException e) {
-
 
93
            System.err.println("[ExcelProfitDataProvider] Erro ao ler Excel: " + e.getMessage());
-
 
-
 
153
    public static List<Candle> adicionarContadores(List<Candle> candles) {
-
 
154
        Integer contador = 1;
-
 
155
        List<Candle> comContadores = new ArrayList<>();
-
 
156
        for (Candle candle : candles) {
-
 
157
                candle.setContadorCandle(contador);
-
 
158
                comContadores.add(candle);
-
 
159
                contador++;
94
        }
160
        }
95
-
 
96
        return ticks;
-
 
-
 
161
        return comContadores;
97
    }
162
    }
98
-
 
-
 
163
   
99
    private LocalDate lerData(Cell cell) {
164
    private LocalDate lerData(Cell cell) {
100
        if (cell == null) return null;
165
        if (cell == null) return null;
101
166
102
        try {
167
        try {
103
            int t = cell.getCellType();
168
            int t = cell.getCellType();
Line 265... Line 330...
265
            System.out.println("[lerPreco] erro: " + e.getMessage());
330
            System.out.println("[lerPreco] erro: " + e.getMessage());
266
        }
331
        }
267
332
268
        return null;
333
        return null;
269
    }
334
    }
-
 
335
   
-
 
336
    /*
-
 
337
    public List<Candle> lerCandles(String resourcePath, Timeframe selecionarTipoTemporizador) throws IOException {
-
 
338
        List<Candle> candles = new ArrayList<>();
270
339

271
    @Override
-
 
272
    public List<Candle> lerCandles() throws IOException {
-
 
273
        // TODO Auto-generated method stub
-
 
274
        return null;
-
 
-
 
340
        // Arquivo dentro de src/main/resources
-
 
341
        InputStream is = getClass().getResourceAsStream(resourcePath);
-
 
342
        if (is == null) {
-
 
343
            throw new IOException("Arquivo não encontrado no resources: " + resourcePath);
-
 
344
        }
-
 
345

-
 
346
        try (Workbook workbook = WorkbookFactory.create(is)) {
-
 
347

-
 
348
            int numberOfSheets = workbook.getNumberOfSheets();
-
 
349

-
 
350
            for (int i = 0; i < numberOfSheets; i++) {
-
 
351

-
 
352
                Sheet sheet = workbook.getSheetAt(i);
-
 
353
                String sheetName = sheet.getSheetName();
-
 
354

-
 
355
                Timeframe tipoTemporizador = resolveTipoTemporizador(sheetName);
-
 
356
                if (tipoTemporizador == selecionarTipoTemporizador) {
-
 
357
                        boolean firstRow = true;
-
 
358
       
-
 
359
                        for (Row row : sheet) {
-
 
360
                            if (firstRow) {
-
 
361
                                firstRow = false; // pula o cabeçalho
-
 
362
                                continue;
-
 
363
                            }
-
 
364
       
-
 
365
                            // 0 = Data (data+hora)
-
 
366
                            // 1 = Abertura
-
 
367
                            // 2 = Máxima
-
 
368
                            // 3 = Mínima
-
 
369
                            // 4 = Fechamento
-
 
370
       
-
 
371
                            Cell dataCell       = row.getCell(0);
-
 
372
                            Cell aberturaCell   = row.getCell(1);
-
 
373
                            Cell maximaCell     = row.getCell(2);
-
 
374
                            Cell minimaCell     = row.getCell(3);
-
 
375
                            Cell fechamentoCell = row.getCell(4);
-
 
376
       
-
 
377
                            if (!isNumeric(aberturaCell) || !isNumeric(maximaCell)
-
 
378
                                    || !isNumeric(minimaCell) || !isNumeric(fechamentoCell)) {
-
 
379
                                // linha vazia ou inválida
-
 
380
                                continue;
-
 
381
                            }
-
 
382
       
-
 
383
                            LocalDateTime time = getLocalDateTime(dataCell, STRING_DATE_TIME_FORMATTER);
-
 
384
                            if (time == null) {
-
 
385
                                // se não conseguir converter a data/hora, pode pular ou manter null
-
 
386
                                // aqui vou pular para evitar candle "incompleto"
-
 
387
                                continue;
-
 
388
                            }
-
 
389
       
-
 
390
                            BigDecimal abertura = BigDecimal.valueOf(aberturaCell.getNumericCellValue());
-
 
391
                            BigDecimal topo = BigDecimal.valueOf(maximaCell.getNumericCellValue());
-
 
392
                            BigDecimal fundo = BigDecimal.valueOf(minimaCell.getNumericCellValue());
-
 
393
                            BigDecimal fechamento = BigDecimal.valueOf(fechamentoCell.getNumericCellValue());
-
 
394

-
 
395
                            Candle candle = new Candle(time, abertura, topo, fundo, fechamento, TipoPeriodoCandle.M1.getValor());
-
 
396
                            candles.add(candle);
-
 
397
                        }
-
 
398
                }
-
 
399
            }
-
 
400
        } catch (EncryptedDocumentException e) {
-
 
401
                        // TODO Auto-generated catch block
-
 
402
                        e.printStackTrace();
-
 
403
                } catch (InvalidFormatException e) {
-
 
404
                        // TODO Auto-generated catch block
-
 
405
                        e.printStackTrace();
-
 
406
                }
-
 
407

-
 
408
        return candles;
275
    }
409
    }
-
 
410
    */
276
411
-
 
412
    /**
-
 
413
     * 1 minuto = 1, 5 minutos = 2, 15 minutos = 3, 1 dia = 4
-
 
414
     */
-
 
415
    private Timeframe resolveTipoTemporizador(String sheetName) {
-
 
416
        if (sheetName == null) return null;
-
 
417
-
 
418
        String name = sheetName.toUpperCase(Locale.ROOT);
-
 
419
-
 
420
        if (name.startsWith("1 MIN"))  return Timeframe.M1;
-
 
421
        if (name.startsWith("5 MIN"))  return Timeframe.M5;
-
 
422
        if (name.startsWith("15 MIN")) return Timeframe.M15;
-
 
423
        if (name.startsWith("1 DIA"))  return Timeframe.D1;
-
 
424
-
 
425
        return null;
-
 
426
    }
-
 
427
-
 
428
    private boolean isNumeric(Cell cell) {
-
 
429
        if (cell == null) return false;
-
 
430
-
 
431
        if (cell.getCellType() == CellType.NUMERIC.getCode()) {
-
 
432
            return true;
-
 
433
        }
-
 
434
-
 
435
        if (cell.getCellType() == CellType.STRING.getCode()) {
-
 
436
            try {
-
 
437
                Double.parseDouble(cell.getStringCellValue().replace(",", "."));
-
 
438
                return true;
-
 
439
            } catch (NumberFormatException e) {
-
 
440
                return false;
-
 
441
            }
-
 
442
        }
-
 
443
-
 
444
        return false;
-
 
445
    }
-
 
446
-
 
447
    /**
-
 
448
     * Converte a célula de data/hora do Excel para LocalDateTime.
-
 
449
     */
-
 
450
    private LocalDateTime getLocalDateTime(Cell cell, DateTimeFormatter formatacaoDataTime) {
-
 
451
        if (cell == null) {
-
 
452
            return null;
-
 
453
        }
-
 
454
-
 
455
        // Caso seja data/hora numérica do Excel
-
 
456
        if (cell.getCellType() == CellType.NUMERIC.getCode() && DateUtil.isCellDateFormatted(cell)) {
-
 
457
            Date date = cell.getDateCellValue(); // disponível em todas as versões
-
 
458
            if (date == null) {
-
 
459
                return null;
-
 
460
            }
-
 
461
            return date.toInstant()
-
 
462
                       .atZone(ZoneId.systemDefault())
-
 
463
                       .toLocalDateTime();
-
 
464
        }
-
 
465
-
 
466
        // Caso venha como TEXT (por exemplo num CSV importado)
-
 
467
        if (cell.getCellType() == CellType.STRING.getCode()) {
-
 
468
            String text = cell.getStringCellValue();
-
 
469
            if (text == null || text.trim().isEmpty()) {
-
 
470
                return null;
-
 
471
            }
-
 
472
            text = text.trim();
-
 
473
            try {
-
 
474
                // Ajuste o pattern se seu Excel estiver em outro formato
-
 
475
                return LocalDateTime.parse(text, formatacaoDataTime);
-
 
476
            } catch (Exception e) {
-
 
477
                return null;
-
 
478
            }
-
 
479
        }
-
 
480
        return null;
-
 
481
    }
-
 
482
   
-
 
483
    /**
-
 
484
     * Converte a célula de data/hora do Excel para LocalDateTime.
-
 
485
     */
-
 
486
    private LocalDateTime getLocalDateTime(String cell, DateTimeFormatter formatacaoDataTime) {
-
 
487
        if (cell == null || cell.trim().isEmpty()) {
-
 
488
            return null;
-
 
489
        }
-
 
490
        cell = cell.trim();
-
 
491
        try {
-
 
492
            return LocalDateTime.parse(cell, formatacaoDataTime);
-
 
493
        } catch (Exception e) {
-
 
494
            return null;
-
 
495
        }
-
 
496
    }
-
 
497
   
277
}
498
}