Subversion Repositories Integrator Subversion

Rev

Blame | Last modification | View Log | Download | RSS feed

package br.com.kronus.ibkr.futures;

import java.math.BigDecimal;
import java.time.Duration;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

import com.ib.client.Contract;
import com.ib.client.Decimal;
import com.ib.client.Order;

import br.com.kronus.core.StatusOrdemFuturos;
import br.com.kronus.core.trade.ServicoOrdensFuturos;
import br.com.kronus.ibkr.api.IbkrClient;
import br.com.kronus.ibkr.api.IbkrMapper;

/**
 * Implementação de ordens usando IBKR, mantendo a assinatura da Binance.
 */

public class ServicoOrdensFuturosIbkr implements ServicoOrdensFuturos {

    private final IbkrClient ibkr;
    private final Map<String, Integer> mapaClientOrder = new ConcurrentHashMap<>();

    public ServicoOrdensFuturosIbkr(IbkrClient ibkr) {
        super();
        this.ibkr = ibkr;
    }

    @Override
    public StatusOrdemFuturos novaOrdemLimit(
            String symbol,
            String side,
            BigDecimal quantity,
            BigDecimal price,
            String clientOrderId
    ) throws Exception {

        int orderId = ibkr.getNextOrderIdBlocking(Duration.ofSeconds(5));

        Contract contract = IbkrMapper.contratoFuturoIndice(symbol);

        Order order = new Order();
        order.action(side);
        order.orderType("LMT");
        order.totalQuantity(Decimal.get(quantity));
        order.lmtPrice(price.doubleValue());
        order.tif("GTC");
        order.orderRef(clientOrderId);

        mapaClientOrder.put(clientOrderId, orderId);

        CompletableFuture<StatusOrdemFuturos> future = ibkr.registrarFutureOrdem(orderId);
       
        System.out.println("[IBKR-ORDEM] Enviando ordem: id=" + orderId +
                ", symbol=" + contract.symbol() +
                ", localSymbol=" + contract.localSymbol() +
                ", secType=" + contract.getSecType() +
                ", exchange=" + contract.exchange() +
                ", primaryExch=" + contract.primaryExch() +
                ", currency=" + contract.currency());


        ibkr.getClient().placeOrder(orderId, contract, order);

        StatusOrdemFuturos status = future.get(10, TimeUnit.SECONDS);
        status.setClientOrderId(clientOrderId);
        status.setSymbol(symbol);
        return status;
    }

    @Override
    public StatusOrdemFuturos consultarStatusOrdem(String symbol, String origClientOrderId) throws Exception {
        Integer orderId = mapaClientOrder.get(origClientOrderId);
        if (orderId == null) {
            throw new IllegalArgumentException("Não há orderId mapeado para clientOrderId=" + origClientOrderId);
        }

        CompletableFuture<StatusOrdemFuturos> future = ibkr.registrarFutureOrdem(orderId);

        ibkr.getClient().reqOpenOrders();

        StatusOrdemFuturos status = future.get(5, TimeUnit.SECONDS);
        status.setClientOrderId(origClientOrderId);
        status.setSymbol(symbol);
        return status;
    }
}