package br.com.kronus.ibkr.history;
import java.io.BufferedWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import com.ib.client.Bar;
import com.ib.client.Contract;
import com.ib.client.TagValue;
import br.com.kronus.ibkr.api.IbkrClient;
public class IbkrHistoricalDataService
{
private final IbkrClient ibkr
;
private static final DateTimeFormatter DATA = DateTimeFormatter.
ofPattern("yyyy-MM-dd");
private static final DateTimeFormatter HORA = DateTimeFormatter.
ofPattern("HH:mm:ss");
public IbkrHistoricalDataService
(IbkrClient ibkr
) {
this.
ibkr = ibkr
;
}
/**
* Solicita histórico para IBKR e grava tudo em CSV.
*
* @param contract contrato IBKR
* @param endDateTime "" para agora ou "yyyyMMdd HH:mm:ss"
* @param durationStr "2 D", "5 D", "1 W", "1 M", etc.
* @param barSizeSetting "1 min", "5 mins", "15 mins", "1 day", etc.
* @param whatToShow "TRADES", "MIDPOINT", etc.
*/
public void baixarHistoricoParaCsv
(
int reqId,
Contract contract,
String endDateTime,
String durationStr,
String barSizeSetting,
String whatToShow,
Path arquivoCsv
) throws Exception {
if (!Files.
exists(arquivoCsv.
getParent())) {
Files.
createDirectories(arquivoCsv.
getParent());
}
try (BufferedWriter writer = Files.
newBufferedWriter(arquivoCsv,
java.
nio.
file.
StandardOpenOption.
CREATE,
java.
nio.
file.
StandardOpenOption.
TRUNCATE_EXISTING)) {
writer.
write("data;hora;open;high;low;close;volume;wap;count");
writer.
newLine();
CompletableFuture
<List<Bar
>> fut = ibkr.
prepararFutureHistorico(reqId
);
ibkr.
getClient().
reqHistoricalData(
reqId,
contract,
endDateTime,
durationStr,
barSizeSetting,
whatToShow,
1,
2,
false,
(List<TagValue
>) null
);
/*
ibkr.getClient().reqHistoricalData(
reqId,
contract,
endDateTime,
durationStr,
barSizeSetting,
"MIDPOINT", // <-- para FX
1,
2,
false,
null
);
*/
List<Bar
> bars = fut.
get(60,
TimeUnit.
SECONDS);
ZoneId zoneId = ZoneId.
of("America/Maceio");
DateTimeFormatter FMT_DATA = DateTimeFormatter.
ofPattern("yyyy-MM-dd");
DateTimeFormatter FMT_HORA = DateTimeFormatter.
ofPattern("HH:mm:ss");
for (Bar b : bars
) {
long time =
new Long(b.
time()); // agora vem algo como 1764688966523
// Detecta se é segundos (10 dígitos) ou milissegundos (13 dígitos)
Instant inst
;
if (time
> 9999999999L
) {
inst = Instant.
ofEpochMilli(time
); // 13 dígitos = millis
} else {
inst = Instant.
ofEpochSecond(time
); // 10 dígitos = seconds
}
ZoneId zdt = ZoneId.
of("America/Maceio");
String dataStr = DATA.
format(inst.
atZone(zoneId
));
String horaStr = HORA.
format(inst.
atZone(zoneId
));
String linha =
String.
join(";",
dataStr,
horaStr,
String.
valueOf(b.
open()),
String.
valueOf(b.
high()),
String.
valueOf(b.
low()),
String.
valueOf(b.
close()),
String.
valueOf(b.
volume()),
String.
valueOf(b.
wap()),
String.
valueOf(b.
count())
);
writer.
write(linha
);
writer.
newLine();
}
writer.
flush();
}
}
}