Subversion Repositories Integrator Subversion

Rev

Rev 796 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
795 blopes 1
package br.com.kronus.ibkr.history;
2
 
3
import java.io.BufferedWriter;
4
import java.nio.file.Files;
5
import java.nio.file.Path;
796 blopes 6
import java.time.Instant;
7
import java.time.ZoneId;
8
import java.time.ZonedDateTime;
9
import java.time.format.DateTimeFormatter;
795 blopes 10
import java.util.List;
11
import java.util.concurrent.CompletableFuture;
12
import java.util.concurrent.TimeUnit;
13
 
14
import com.ib.client.Bar;
15
import com.ib.client.Contract;
16
import com.ib.client.TagValue;
17
 
18
import br.com.kronus.ibkr.api.IbkrClient;
19
 
20
public class IbkrHistoricalDataService {
21
 
22
    private final IbkrClient ibkr;
796 blopes 23
 
24
    private static final DateTimeFormatter DATA = DateTimeFormatter.ofPattern("yyyy-MM-dd");
25
    private static final DateTimeFormatter HORA = DateTimeFormatter.ofPattern("HH:mm:ss");
795 blopes 26
 
27
    public IbkrHistoricalDataService(IbkrClient ibkr) {
28
        this.ibkr = ibkr;
29
    }
30
 
31
    /**
32
     * Solicita histórico para IBKR e grava tudo em CSV.
33
     *
34
     * @param contract        contrato IBKR
35
     * @param endDateTime     "" para agora ou "yyyyMMdd HH:mm:ss"
36
     * @param durationStr     "2 D", "5 D", "1 W", "1 M", etc.
37
     * @param barSizeSetting  "1 min", "5 mins", "15 mins", "1 day", etc.
38
     * @param whatToShow      "TRADES", "MIDPOINT", etc.
39
     */
40
    public void baixarHistoricoParaCsv(
41
            int reqId,
42
            Contract contract,
43
            String endDateTime,
44
            String durationStr,
45
            String barSizeSetting,
46
            String whatToShow,
47
            Path arquivoCsv
48
    ) throws Exception {
49
 
50
        if (!Files.exists(arquivoCsv.getParent())) {
51
            Files.createDirectories(arquivoCsv.getParent());
52
        }
53
 
54
        try (BufferedWriter writer = Files.newBufferedWriter(arquivoCsv,
55
                java.nio.file.StandardOpenOption.CREATE,
56
                java.nio.file.StandardOpenOption.TRUNCATE_EXISTING)) {
57
 
58
            writer.write("data;hora;open;high;low;close;volume;wap;count");
59
            writer.newLine();
60
 
61
            CompletableFuture<List<Bar>> fut = ibkr.prepararFutureHistorico(reqId);
797 blopes 62
/*
795 blopes 63
            ibkr.getClient().reqHistoricalData(
64
                    reqId,
65
                    contract,
66
                    endDateTime,
67
                    durationStr,
68
                    barSizeSetting,
69
                    whatToShow,
70
                    1,
71
                    2,
72
                    false,
73
                    (List<TagValue>) null
74
            );
797 blopes 75
            */
76
 
77
            ibkr.getClient().reqHistoricalData(
78
                    reqId,
79
                    contract,
80
                    endDateTime,
81
                    durationStr,
82
                    barSizeSetting,
83
                    "MIDPOINT",  // <-- para FX
84
                    1,
85
                    2,
86
                    false,
87
                    null
88
                );
795 blopes 89
 
797 blopes 90
 
91
 
795 blopes 92
            List<Bar> bars = fut.get(60, TimeUnit.SECONDS);
93
 
796 blopes 94
            ZoneId zoneId = ZoneId.of("America/Maceio");
95
            DateTimeFormatter FMT_DATA = DateTimeFormatter.ofPattern("yyyy-MM-dd");
96
            DateTimeFormatter FMT_HORA = DateTimeFormatter.ofPattern("HH:mm:ss");
97
 
795 blopes 98
            for (Bar b : bars) {
796 blopes 99
 
100
                long time = new Long(b.time()); // agora vem algo como 1764688966523
795 blopes 101
 
796 blopes 102
                // Detecta se é segundos (10 dígitos) ou milissegundos (13 dígitos)
103
                Instant inst;
104
                if (time > 9999999999L) {
105
                    inst = Instant.ofEpochMilli(time);   // 13 dígitos = millis
106
                } else {
107
                    inst = Instant.ofEpochSecond(time);   // 10 dígitos = seconds
108
                }
795 blopes 109
 
796 blopes 110
                ZoneId zdt = ZoneId.of("America/Maceio");
111
                String dataStr = DATA.format(inst.atZone(zoneId));
112
                String horaStr = HORA.format(inst.atZone(zoneId));
113
 
795 blopes 114
                String linha = String.join(";",
796 blopes 115
                                dataStr,
795 blopes 116
                        horaStr,
117
                        String.valueOf(b.open()),
118
                        String.valueOf(b.high()),
119
                        String.valueOf(b.low()),
120
                        String.valueOf(b.close()),
121
                        String.valueOf(b.volume()),
122
                        String.valueOf(b.wap()),
123
                        String.valueOf(b.count())
124
                );
796 blopes 125
 
795 blopes 126
                writer.write(linha);
127
                writer.newLine();
128
            }
796 blopes 129
 
795 blopes 130
            writer.flush();
131
        }
132
    }
796 blopes 133
 
795 blopes 134
}