Subversion Repositories Integrator Subversion

Rev

Rev 791 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

package br.com.sl.core;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.List;

import br.com.sl.domain.dto.OrdemBinanceDTO;
import br.com.sl.domain.dto.robo.SinalTradeGatilho3;
import br.com.sl.domain.model.Candle;
import br.com.sl.domain.model.tipos.TipoSinal;

public class ExportadorSinalBinance {

    // Ajuste a pasta como preferir
    private static final String PASTA_SINAIS = "D:/Dropbox/BLP/INVESTIMENTOS/DAYTRADE/sinais";

    // Se quiser usar em algum momento para quantidade padrão
    private static final BigDecimal QTDE_PADRAO = BigDecimal.ONE;

    /**
     * Exporta todos os sinais para arquivos CSV,
     * 1 arquivo por sinal, pronto para ser lido por outro serviço.
     */

    public static void exportarSinaisParaPasta(List<SinalTradeGatilho3> sinais) {
        if (sinais == null || sinais.isEmpty()) {
            System.out.println("[BinanceSignalExporter] Nenhum sinal para exportar.");
            return;
        }

        File pasta = new File(PASTA_SINAIS);
        if (!pasta.exists()) {
            boolean ok = pasta.mkdirs();
            if (!ok) {
                System.err.println("[BinanceSignalExporter] Não foi possível criar a pasta: " + PASTA_SINAIS);
                return;
            }
        }

        for (SinalTradeGatilho3 sinal : sinais) {
            try {
                OrdemBinanceDTO payload = converterParaPayloadBinance(sinal);
                String csv = converterParaCsv(payload);
                String nomeArquivo = montarNomeArquivoCsv(pasta, payload, sinal);
                gravarArquivo(nomeArquivo, csv);
            } catch (Exception e) {
                System.err.println("[BinanceSignalExporter] Erro ao exportar sinal: " + e.getMessage());
                e.printStackTrace();
            }
        }
    }

    /**
     * Converte um SinalTradeGatilho3 para o payload de ordem "modelo Binance".
     */

    private static OrdemBinanceDTO converterParaPayloadBinance(SinalTradeGatilho3 sinal) {
        OrdemBinanceDTO p = new OrdemBinanceDTO();

        // 1) Symbol da Binance
        String symbol = mapearParaSymbolBinance(sinal);

        // 2) Side -> BUY ou SELL
        String side = sinal.getTipoOperacao() == TipoSinal.COMPRA_C ? "BUY" : "SELL";

        // 3) Tipo de ordem – exemplo LIMIT padrão
        String type = "LIMIT";
        String timeInForce = "GTC";

        // 4) Quantidade – usa contratosTotais, mas pode ajustar
        BigDecimal quantity = BigDecimal.valueOf(sinal.getContratosTotais());

        // 5) Preço de entrada – Entrada 1 como principal
        BigDecimal price = sinal.getPrecoEntrada1();

        // 6) Stops e Targets
        BigDecimal stopLoss = sinal.getStopMenos100();
        BigDecimal tp1 = sinal.getAlvo1();
        BigDecimal tp2 = sinal.getAlvo2();

        // 7) ClientOrderId – algo identificável
        Candle g3 = sinal.getGatilho3();
        String dataHora = "";
        if (g3 != null && g3.getDataHora() != null) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
            dataHora = sdf.format(g3.getDataHora());   // aqui getDataHora() é Date
        }
        String clientOrderId = "G3_" + symbol + "_" + dataHora + "_c" + sinal.getGatilho3().getContadorCandle();

        p.setSymbol(symbol);
        p.setSide(side);
        p.setType(type);
        p.setTimeInForce(timeInForce);
        p.setQuantity(quantity);
        p.setPrice(price);
        p.setStopLoss(stopLoss);
        p.setTakeProfit1(tp1);
        p.setTakeProfit2(tp2);
        p.setClientOrderId(clientOrderId);

        return p;
    }

    /**
     * Mapeia o ativo interno para o símbolo da Binance.
     */

    private static String mapearParaSymbolBinance(SinalTradeGatilho3 sinal) {
        String nomeAtivo = null;

        if (sinal.getReferencia() != null && sinal.getReferencia().getAtivo() != null) {
            nomeAtivo = sinal.getReferencia().getAtivo().getNome();
        } else if (sinal.getReferencia() != null) {
            nomeAtivo = sinal.getReferencia().getNomeAtivo();
        }

        if (nomeAtivo == null) {
            return "BTCUSDT";
        }

        if (nomeAtivo.equalsIgnoreCase("BTC") || nomeAtivo.equalsIgnoreCase("BTCUSDT")) {
            return "BTCUSDT";
        }
        if (nomeAtivo.equalsIgnoreCase("ETH") || nomeAtivo.equalsIgnoreCase("ETHUSDT")) {
            return "ETHUSDT";
        }

        return nomeAtivo.toUpperCase() + "USDT";
    }

    /**
     * Gera o conteúdo CSV (cabeçalho + linha única).
     * Novo campo: status = "P" (pendente)
     */

    private static String converterParaCsv(OrdemBinanceDTO p) {
        StringBuilder sb = new StringBuilder();

        // Cabeçalho
        sb.append("symbol,side,type,timeInForce,quantity,price,stopLoss,takeProfit1,takeProfit2,clientOrderId,status\n");

        // Linha de dados
        sb.append(escapeCsv(p.getSymbol())).append(",");
        sb.append(escapeCsv(p.getSide())).append(",");
        sb.append(escapeCsv(p.getType())).append(",");
        sb.append(escapeCsv(p.getTimeInForce())).append(",");
        sb.append(p.getQuantity()).append(",");
        sb.append(p.getPrice()).append(",");
        sb.append(p.getStopLoss()).append(",");
        sb.append(p.getTakeProfit1()).append(",");
        sb.append(p.getTakeProfit2()).append(",");
        sb.append(escapeCsv(p.getClientOrderId())).append(",");
       
        sb.append("P"); // status pendente

        sb.append("\n");

        return sb.toString();
    }


    /**
     * Escapa campos texto para CSV básico.
     */

    private static String escapeCsv(String s) {
        if (s == null) return "";
        // Se tiver vírgula, aspas ou quebra de linha, envolve em aspas e escapa aspas
        boolean precisaAspas = s.contains(",") || s.contains("\"") || s.contains("\n") || s.contains("\r");
        String valor = s.replace("\"", "\"\"");
        return precisaAspas ? "\"" + valor + "\"" : valor;
    }

    /**
     * Monta nome de arquivo: BINANCE_SIGNAL_<symbol>_<clientOrderId>.csv
     */

    private static String montarNomeArquivoCsv(File pasta, OrdemBinanceDTO payload, SinalTradeGatilho3 sinal) {
        String symbol = payload.getSymbol();
        String clientId = payload.getClientOrderId();
        String nome = "BINANCE_SIGNAL_" + symbol + "_" + clientId + ".csv";
        return new File(pasta, nome).getAbsolutePath();
    }

    private static void gravarArquivo(String caminho, String conteudo) throws IOException {
        try (FileWriter fw = new FileWriter(caminho, false)) {
            fw.write(conteudo);
        }
        System.out.println("[BinanceSignalExporter] Arquivo CSV criado: " + caminho);
    }
}