package br.com.kronus.strategy;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import br.com.kronus.core.PadraoGatilho;
import br.com.sl.domain.dto.robo.SinalTradeGatilho3;
import br.com.sl.domain.model.Candle;
import br.com.sl.domain.model.tipos.TipoSinal;
import br.com.sl.domain.util.BigDecimalUtils;
public class EstrategiaGatilhoTipo3Sinais
{
private static final int CONTRATOS_TOTAIS =
6;
private static final int CONTRATOS_ENTRADA1 =
4; // 2/3
private static final int CONTRATOS_ENTRADA2 =
2; // 1/3
/**
* Gera sinais de trade (sem executar backtest) para todos os padrões
* que tenham gatilho 3 identificado.
*
* @param padroes lista de padrões (GR, G1, G2, G3, G4)
* @return lista de sinais de trade conforme a estratégia do Gatilho 3
*/
public List<SinalTradeGatilho3
> gerarSinais
(List<PadraoGatilho
> padroes
) {
List<SinalTradeGatilho3
> sinais =
new ArrayList<>();
if (padroes ==
null || padroes.
isEmpty()) {
return sinais
;
}
for (PadraoGatilho p : padroes
) {
if (p ==
null) continue;
// só interessa padrão completo até G3
if (p.
getTipoPadrao() != PadraoGatilho.
TipoPadrao.
COMPLETO_G3) {
continue;
}
Candle ref = p.
getReferencia();
Candle g1 = p.
getGatilho1();
Candle g2 = p.
getGatilho2();
Candle g3 = p.
getGatilho3();
// só interessa padrão completo até G3
if (ref ==
null || g2 ==
null || g3 ==
null) {
continue;
}
if (g3.
isCandleVendedor()) {
// G3 vendedor -> operação VENDIDA
SinalTradeGatilho3 sinal = montarSinalVenda
(ref, g1, g2, g3, p
);
if (sinal
!=
null) {
sinais.
add(sinal
);
}
} else if (g3.
isCandleComprador()) {
// G3 comprador -> operação COMPRADA
SinalTradeGatilho3 sinal = montarSinalCompra
(ref, g1, g2, g3, p
);
if (sinal
!=
null) {
sinais.
add(sinal
);
}
}
}
return sinais
;
}
/**
* Monta sinal de VENDA (referência comprador):
* - Fibo preço com base nos candles G2 e G3.
* - 0% no topo de G2
* - 100% no fundo de G3
*/
private SinalTradeGatilho3 montarSinalVenda
(Candle ref, Candle g1, Candle g2, Candle g3, PadraoGatilho padrao
) {
BigDecimal topoG2 = g2.
getMaxima();
BigDecimal fundoG3 = g3.
getMinima();
// Garantia mínima de geometria: topo > fundo
if (BigDecimalUtils.
ehMenorOuIgualQue(topoG2, fundoG3
)) {
return null;
}
// Orientação: 0% = topo (G3), 100% = fundo (G2)
BigDecimal base0 = topoG2
;
BigDecimal base100 = fundoG3
;
BigDecimal entrada1 = nivelFibo
(base0, base100,
50.0); // 50%
BigDecimal entrada2 = nivelFibo
(base0, base100,
25.0); // 25%
BigDecimal alvo1 = nivelFibo
(base0, base100,
100.0); // 100%
BigDecimal alvo2 = nivelFibo
(base0, base100,
123.6); // 123,6%
BigDecimal stopFib = nivelFibo
(base0, base100, -
100.0); // -100%
// Stop alternativo: 25% acima do último fundo relevante (aqui uso fundo de G2)
BigDecimal stopAlt = fundoG3.
add(
topoG2.
subtract(fundoG3
).
multiply(BigDecimal.
valueOf(0.25))
);
SinalTradeGatilho3 s =
new SinalTradeGatilho3
();
s.
setIdAtivo(padrao.
getIdAtivo());
s.
setPadrao(padrao
);
s.
setReferencia(ref
);
s.
setGatilho1(g1
);
s.
setGatilho2(g2
);
s.
setGatilho3(g3
);
s.
setTipoOperacao(TipoSinal.
VENDA_V);
s.
setContratosTotais(CONTRATOS_TOTAIS
);
s.
setContratosEntrada1(CONTRATOS_ENTRADA1
);
s.
setContratosEntrada2(CONTRATOS_ENTRADA2
);
s.
setPrecoEntrada1(entrada1.
setScale(2,
RoundingMode.
HALF_UP));
s.
setPrecoEntrada2(entrada2.
setScale(2,
RoundingMode.
HALF_UP));
s.
setAlvo1(alvo1.
setScale(2,
RoundingMode.
HALF_UP));
s.
setAlvo2(alvo2.
setScale(2,
RoundingMode.
HALF_UP));
s.
setStopMenos100(stopFib.
setScale(2,
RoundingMode.
HALF_UP));
s.
setStopAlternativo(stopAlt.
setScale(2,
RoundingMode.
HALF_UP));
return s
;
}
/**
* Monta sinal de COMPRA (referência vendedor):
* - Fibo preço com base nos candles G2 e G3.
* - 0% no fundo de G2
* - 100% no topo de G3
*/
private SinalTradeGatilho3 montarSinalCompra
(Candle ref, Candle g1, Candle g2, Candle g3, PadraoGatilho padrao
) {
BigDecimal topoG3 = g3.
getMaxima();
BigDecimal fundoG2 = g2.
getMinima();
if (BigDecimalUtils.
ehMenorOuIgualQue(topoG3, fundoG2
)) {
return null;
}
// Orientação: 0% = fundo (G3), 100% = topo (G2)
BigDecimal base0 = fundoG2
;
BigDecimal base100 = topoG3
;
BigDecimal entrada1 = nivelFibo
(base0, base100,
50.0); // 50%
BigDecimal entrada2 = nivelFibo
(base0, base100,
25.0); // 25%
BigDecimal alvo1 = nivelFibo
(base0, base100,
100.0); // 100%
BigDecimal alvo2 = nivelFibo
(base0, base100,
123.6); // 123,6%
BigDecimal stopFib = nivelFibo
(base0, base100, -
100.0); // -100%
// Stop alternativo: 25% abaixo do último topo relevante (aqui uso topo de G2)
BigDecimal stopAlt = topoG3.
subtract(
topoG3.
subtract(fundoG2
).
multiply(BigDecimal.
valueOf(0.25))
);
SinalTradeGatilho3 s =
new SinalTradeGatilho3
();
s.
setIdAtivo(padrao.
getIdAtivo());
s.
setPadrao(padrao
);
s.
setReferencia(ref
);
s.
setGatilho1(g1
);
s.
setGatilho2(g2
);
s.
setGatilho3(g3
);
s.
setTipoOperacao(TipoSinal.
COMPRA_C);
s.
setContratosTotais(CONTRATOS_TOTAIS
);
s.
setContratosEntrada1(CONTRATOS_ENTRADA1
);
s.
setContratosEntrada2(CONTRATOS_ENTRADA2
);
s.
setPrecoEntrada1(entrada1.
setScale(2,
RoundingMode.
HALF_UP));
s.
setPrecoEntrada2(entrada2.
setScale(2,
RoundingMode.
HALF_UP));
s.
setAlvo1(alvo1.
setScale(2,
RoundingMode.
HALF_UP));
s.
setAlvo2(alvo2.
setScale(2,
RoundingMode.
HALF_UP));
s.
setStopMenos100(stopFib.
setScale(2,
RoundingMode.
HALF_UP));
s.
setStopAlternativo(stopAlt.
setScale(2,
RoundingMode.
HALF_UP));
return s
;
}
/**
* Cálculo genérico do nível de Fibonacci:
* base0 = 0% , base100 = 100%
*/
private BigDecimal nivelFibo
(BigDecimal base0,
BigDecimal base100,
double percentual
) {
BigDecimal range = base100.
subtract(base0
);
BigDecimal fator =
BigDecimal.
valueOf(percentual
).
movePointLeft(2); // /100
return base0.
add(range.
multiply(fator
));
}
}