Subversion Repositories Integrator Subversion

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
791 blopes 1
package br.com.sl.core;
2
 
3
import java.io.File;
4
import java.io.FileWriter;
5
import java.io.IOException;
6
import java.math.BigDecimal;
7
import java.text.SimpleDateFormat;
8
import java.time.format.DateTimeFormatter;
9
import java.util.List;
10
 
11
import br.com.sl.domain.dto.OrdemBinanceDTO;
12
import br.com.sl.domain.dto.robo.SinalTradeGatilho3;
13
import br.com.sl.domain.model.Candle;
14
import br.com.sl.domain.model.tipos.TipoSinal;
15
 
16
public class ExportadorSinalBinance {
17
 
18
    // Ajuste a pasta como preferir
19
    private static final String PASTA_SINAIS = "D:/Dropbox/BLP/INVESTIMENTOS/DAYTRADE/sinais";
20
 
21
    // Se quiser usar em algum momento para quantidade padrão
22
    private static final BigDecimal QTDE_PADRAO = BigDecimal.ONE;
23
 
24
    /**
25
     * Exporta todos os sinais para arquivos CSV,
26
     * 1 arquivo por sinal, pronto para ser lido por outro serviço.
27
     */
28
    public static void exportarSinaisParaPasta(List<SinalTradeGatilho3> sinais) {
29
        if (sinais == null || sinais.isEmpty()) {
30
            System.out.println("[BinanceSignalExporter] Nenhum sinal para exportar.");
31
            return;
32
        }
33
 
34
        File pasta = new File(PASTA_SINAIS);
35
        if (!pasta.exists()) {
36
            boolean ok = pasta.mkdirs();
37
            if (!ok) {
38
                System.err.println("[BinanceSignalExporter] Não foi possível criar a pasta: " + PASTA_SINAIS);
39
                return;
40
            }
41
        }
42
 
43
        for (SinalTradeGatilho3 sinal : sinais) {
44
            try {
45
                OrdemBinanceDTO payload = converterParaPayloadBinance(sinal);
46
                String csv = converterParaCsv(payload);
47
                String nomeArquivo = montarNomeArquivoCsv(pasta, payload, sinal);
48
                gravarArquivo(nomeArquivo, csv);
49
            } catch (Exception e) {
50
                System.err.println("[BinanceSignalExporter] Erro ao exportar sinal: " + e.getMessage());
51
                e.printStackTrace();
52
            }
53
        }
54
    }
55
 
56
    /**
57
     * Converte um SinalTradeGatilho3 para o payload de ordem "modelo Binance".
58
     */
59
    private static OrdemBinanceDTO converterParaPayloadBinance(SinalTradeGatilho3 sinal) {
60
        OrdemBinanceDTO p = new OrdemBinanceDTO();
61
 
62
        // 1) Symbol da Binance
63
        String symbol = mapearParaSymbolBinance(sinal);
64
 
65
        // 2) Side -> BUY ou SELL
66
        String side = sinal.getTipoOperacao() == TipoSinal.COMPRA_C ? "BUY" : "SELL";
67
 
68
        // 3) Tipo de ordem – exemplo LIMIT padrão
69
        String type = "LIMIT";
70
        String timeInForce = "GTC";
71
 
72
        // 4) Quantidade – usa contratosTotais, mas pode ajustar
73
        BigDecimal quantity = BigDecimal.valueOf(sinal.getContratosTotais());
74
 
75
        // 5) Preço de entrada – Entrada 1 como principal
76
        BigDecimal price = sinal.getPrecoEntrada1();
77
 
78
        // 6) Stops e Targets
79
        BigDecimal stopLoss = sinal.getStopMenos100();
80
        BigDecimal tp1 = sinal.getAlvo1();
81
        BigDecimal tp2 = sinal.getAlvo2();
82
 
83
        // 7) ClientOrderId – algo identificável
84
        Candle g3 = sinal.getGatilho3();
85
        String dataHora = "";
86
        if (g3 != null && g3.getDataHora() != null) {
87
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
88
            dataHora = sdf.format(g3.getDataHora());   // aqui getDataHora() é Date
89
        }
90
        String clientOrderId = "G3_" + symbol + "_" + dataHora + "_c" + sinal.getGatilho3().getContadorCandle();
91
 
92
        p.setSymbol(symbol);
93
        p.setSide(side);
94
        p.setType(type);
95
        p.setTimeInForce(timeInForce);
96
        p.setQuantity(quantity);
97
        p.setPrice(price);
98
        p.setStopLoss(stopLoss);
99
        p.setTakeProfit1(tp1);
100
        p.setTakeProfit2(tp2);
101
        p.setClientOrderId(clientOrderId);
102
 
103
        return p;
104
    }
105
 
106
    /**
107
     * Mapeia o ativo interno para o símbolo da Binance.
108
     */
109
    private static String mapearParaSymbolBinance(SinalTradeGatilho3 sinal) {
110
        String nomeAtivo = null;
111
 
112
        if (sinal.getReferencia() != null && sinal.getReferencia().getAtivo() != null) {
113
            nomeAtivo = sinal.getReferencia().getAtivo().getNome();
114
        } else if (sinal.getReferencia() != null) {
115
            nomeAtivo = sinal.getReferencia().getNomeAtivo();
116
        }
117
 
118
        if (nomeAtivo == null) {
119
            return "BTCUSDT";
120
        }
121
 
122
        if (nomeAtivo.equalsIgnoreCase("BTC") || nomeAtivo.equalsIgnoreCase("BTCUSDT")) {
123
            return "BTCUSDT";
124
        }
125
        if (nomeAtivo.equalsIgnoreCase("ETH") || nomeAtivo.equalsIgnoreCase("ETHUSDT")) {
126
            return "ETHUSDT";
127
        }
128
 
129
        return nomeAtivo.toUpperCase() + "USDT";
130
    }
131
 
132
    /**
133
     * Gera o conteúdo CSV (cabeçalho + linha única).
134
     * Novo campo: status = "P" (pendente)
135
     */
136
    private static String converterParaCsv(OrdemBinanceDTO p) {
137
        StringBuilder sb = new StringBuilder();
138
 
139
        // Cabeçalho
140
        sb.append("symbol,side,type,timeInForce,quantity,price,stopLoss,takeProfit1,takeProfit2,clientOrderId,status\n");
141
 
142
        // Linha de dados
143
        sb.append(escapeCsv(p.getSymbol())).append(",");
144
        sb.append(escapeCsv(p.getSide())).append(",");
145
        sb.append(escapeCsv(p.getType())).append(",");
146
        sb.append(escapeCsv(p.getTimeInForce())).append(",");
147
        sb.append(p.getQuantity()).append(",");
148
        sb.append(p.getPrice()).append(",");
149
        sb.append(p.getStopLoss()).append(",");
150
        sb.append(p.getTakeProfit1()).append(",");
151
        sb.append(p.getTakeProfit2()).append(",");
152
        sb.append(escapeCsv(p.getClientOrderId())).append(",");
153
 
154
        sb.append("P"); // status pendente
155
 
156
        sb.append("\n");
157
 
158
        return sb.toString();
159
    }
160
 
161
 
162
    /**
163
     * Escapa campos texto para CSV básico.
164
     */
165
    private static String escapeCsv(String s) {
166
        if (s == null) return "";
167
        // Se tiver vírgula, aspas ou quebra de linha, envolve em aspas e escapa aspas
168
        boolean precisaAspas = s.contains(",") || s.contains("\"") || s.contains("\n") || s.contains("\r");
169
        String valor = s.replace("\"", "\"\"");
170
        return precisaAspas ? "\"" + valor + "\"" : valor;
171
    }
172
 
173
    /**
174
     * Monta nome de arquivo: BINANCE_SIGNAL_<symbol>_<clientOrderId>.csv
175
     */
176
    private static String montarNomeArquivoCsv(File pasta, OrdemBinanceDTO payload, SinalTradeGatilho3 sinal) {
177
        String symbol = payload.getSymbol();
178
        String clientId = payload.getClientOrderId();
179
        String nome = "BINANCE_SIGNAL_" + symbol + "_" + clientId + ".csv";
180
        return new File(pasta, nome).getAbsolutePath();
181
    }
182
 
183
    private static void gravarArquivo(String caminho, String conteudo) throws IOException {
184
        try (FileWriter fw = new FileWriter(caminho, false)) {
185
            fw.write(conteudo);
186
        }
187
        System.out.println("[BinanceSignalExporter] Arquivo CSV criado: " + caminho);
188
    }
189
}