//+------------------------------------------------------------------+ //| S2_Motor_v4_4.mqh | //| OXFORD | //| HEDGING HORN CAPITAL | //| https://www.hhcapital.com.br | //+------------------------------------------------------------------+ #property copyright "Copyright 2022, HEDGING HORN CAPITAL" #property link "https://www.hhcapítal.com.br" #property version "DESENV_v4_4" #property description "HFT MARKET MAKING BASED ON OXFORD'S STUDIES. MINI INDICE." //+===================================================================================================================================================================================+ //| 0 - SESSAO DE CABECALHO / ADMISSAO //+===================================================================================================================================================================================+ //+------------------------------------------------------------------+ //| 0.1 - IMPORTACOES | //+------------------------------------------------------------------+ #include #include #include #include "MarketBook.mqh" #include "S0_Admissao_v4_4.mqh" #include "S3_Freios_v4_4.mqh" #include "S4_Cambio_v4_4.mqh" #include "S5_Direcao_v4_4.mqh" #include "S6_Transmissao_v4_4.mqh" //+===================================================================================================================================================================================+ //| 2 - SESSAO DE FAZER NEGOCIACOES / MOTOR //+===================================================================================================================================================================================+ //+------------------------------------------------------------------+ //| 2.1 - FUNCAO QUE FAZ NEGOCIACOES | //+------------------------------------------------------------------+ void FazTrades(gerenciador &Gerenciador, operacao &Operacao, fluido &Fluidos, slot &SlotsC[], slot &SlotsV[], MqlTick &ArrayTick[], MqlBookInfo &ArrayBook[]) { //Verifica os Riscos de Nivel 3 (Condicoes desfavoraveis para a estrategia no dia como: Stop Financeiro do dia ou limite de Tendencia do dia) if(VerificaRiscosNivel3(Gerenciador, Operacao, Fluidos) == false) { //AtualizaPosicoes(Operacao, Fluidos, ArrayTick, ArrayBook); //AtualizaOrdens(Operacao, Fluidos); //ExecutaSlotsDisponiveis(); //== atualiza triggers de entrada AtualizaTriggersEntrada (); ExecutaOrdens(); GerenciaPosicoes(); Operacao.countFechaDia == 0; } else { if(Operacao.countFechaDia == 0) { FechaPosicoes(Operacao); Print("Mandou fechar todas as posicoes pelo risco."); CancelaOrdensAbertas(Operacao); Print("Mandou cancelar todas as ordens abertas pelo risco."); if((PositionsTotal() + OrdersTotal()) == 0) Operacao.countFechaDia = 1; } } //ATUALIZA TELEMETRIA Comment( "===GERENCIAMENTO P&L===", "\n" + "CAPITAL BRUTO FECHADO: ", Gerenciador.capitalFechado, "\n" + "CAPITAL BRUTO ABERTO: ", Gerenciador.capitalAberto, "\n" + "LUCRO BRUTO FECHADO: ", Gerenciador.lucroBrutoFechado, "\n" + "LUCRO BRUTO ABERTO: ", Gerenciador.lucroBrutoAberto, "\n" + "LUCRO BRUTO COMPOSTO: ", Gerenciador.lucroBrutoComposto, "\n" + "LUCRO LIQUIDO: ", Gerenciador.lucroLiquido, "\n" + "NUMERO DE CONTRATOS (compra+venda): ", Operacao.numeroContratos - (2*(Fluidos.rajada*Fluidos.niveis)), "\n" + "CUSTO: ", (Operacao.numeroContratos - (2*Fluidos.rajada*Fluidos.niveis)) * (Fluidos.c*2), "\n" + "INVENTARIO: ", Fluidos.q, "\n" + "\n" + "===GERENCIAMENTO DA OPERACAO===", "\n" + "LC: ", NormalizeDouble(Fluidos.lambdaC,2), "\n" + "LV: ", NormalizeDouble(Fluidos.lambdaV,2), "\n" + "KC: ", Fluidos.KC, "\n" + "KV: ", Fluidos.KV, "\n" + "EC: ", NormalizeDouble(Fluidos.sigmaHFT/Fluidos.lambdaC, 2), "\n" + "EV: ", NormalizeDouble(Fluidos.sigmaHFT/Fluidos.lambdaC, 2), "\n" + "TC: ", NormalizeDouble((Fluidos.KV/Fluidos.lambdaC), 2), "\n" + "TV: ", NormalizeDouble((Fluidos.KC/Fluidos.lambdaV), 2), "\n" + "VOL: ", NormalizeDouble(Fluidos.sigmaLFT/600,2), "\n" + "A: ", NormalizeDouble(Fluidos.assimetria,2), "\n" + "C: ", NormalizeDouble(Fluidos.curtose,2), "\n" + "IMBALANCE: ", NormalizeDouble(Fluidos.imbalance,4), "\n" + "TENDENCIA: ", Fluidos.tendencia); // Print(Fluidos.midPrice,"/",NormalizeDouble(Fluidos.media,0),"/",SlotsC[0].spreadEnvio,"/",SlotsC[0].spreadAlvo,"/",SlotsV[0].spreadEnvio,"/",SlotsV[0].spreadAlvo,"/",NormalizeDouble(Fluidos.lambdaC,0),"/",NormalizeDouble(Fluidos.lambdaV,0),"/",Fluidos.KC,"/",Fluidos.KV,"/",NormalizeDouble(Fluidos.imbalance,2),"/",Fluidos.tendencia,"/",NormalizeDouble(Fluidos.sigmaHFT,0)); return; } //+------------------------------------------------------------------+ //| 2.2 - FUNCAO QUE ATUALIZA POSICOES | //+------------------------------------------------------------------+ void AtualizaTriggersEntrada(operacao &Operacao) TimeToStruct(TimeCurrent(), Operacao.horarioMQL_atual); ushort minutoAtual = (Operacao.horarioMQL_atual.hour * 60) + Operacao.horarioMQL_atual.min; if(minutoAtual == (horarioCorteFimAnalise){ { Operacao.horarioMQL_inicio.year = Operacao.horarioMQL_atual.year; Operacao.horarioMQL_inicio.month = Operacao.horarioMQL_atual.month; Operacao.horarioMQL_inicio.day = Operacao.horarioMQL_atual.day; Operacao.horarioMQL_inicio.hour = (horarioCorteInicioAnalise - MathMod(horarioCorteInicioAnalise,60))/60; Operacao.horarioMQL_inicio.min = MathMod(horarioCorteInicioAnalise,60); Operacao.horarioMQL_inicio.sec = Operacao.horarioMQL_atual.sec; Operacao.horarioMQL_inicio.day_of_week = Operacao.horarioMQL_atual.day_of_week; Operacao.horarioMQL_inicio.day_of_year = Operacao.horarioMQL_atual.day_of_year; Operacao.horarioMQL_final.year = Operacao.horarioMQL_atual.year; Operacao.horarioMQL_final.month = Operacao.horarioMQL_atual.month; Operacao.horarioMQL_final.day = Operacao.horarioMQL_atual.day; Operacao.horarioMQL_final.hour = (horarioCorteFimAnalise - MathMod(horarioCorteFimAnalise,60))/60; Operacao.horarioMQL_final.min = MathMod(horarioCorteFimAnalise,60); Operacao.horarioMQL_final.sec = Operacao.horarioMQL_atual.sec; Operacao.horarioMQL_final.day_of_week = Operacao.horarioMQL_atual.day_of_week; Operacao.horarioMQL_final.day_of_year = Operacao.horarioMQL_atual.day_of_year; int numeroBarras = Bars(_Symbol,PERIOD_M1, StructToTime(Operacao.horarioMQL_inicio) , StructToTime(Operacao.horarioMQL_final)); double faixaSuperior = 0.0; double faixaInferior = 0.0; for(int i = 0; i iLow(_Symbol, PERIOD_M1, i) faixaInferior = iLow(_Symbol, PERIOD_M1, i); } } else { //espera até as 10h } //+------------------------------------------------------------------+ //| 2.2 - FUNCAO QUE ATUALIZA POSICOES | //+------------------------------------------------------------------+ void AtualizaPosicoes(operacao &Operacao, fluido &Fluidos, MqlTick &ArrayTick[], MqlBookInfo &ArrayBook[]) { Fluidos.tendencia = GetTendencia(Fluidos, ArrayTick, ArrayBook); for(int i=0; i Operacao.expiraPosicao) { //cancela posicao FechaPosicao(Operacao, ticket); Print("Mandou fechar a posicao por expiracao de tempo."); } else { CalculaPrecoTrailing(Operacao, Fluidos); if(precoStopAnt != Operacao.precoStop) { if(Operacao.tipoPosicao == POSITION_TYPE_BUY) { if(precoStopAnt < Operacao.precoStop) ModificaStopPosicaoAberta(Operacao, ticket); } else { if(precoStopAnt > Operacao.precoStop) ModificaStopPosicaoAberta(Operacao, ticket); } } if( MathMod(refreshPosicao, Fluidos.TPr) >= (Fluidos.TPr -2) ) { //atualiza posicao CalculaPrecoPosicao(Operacao, Fluidos); if((Operacao.precoAlvo != precoAlvoAnt) || (Operacao.precoStop != precoStopAnt)) { if(Operacao.tipoPosicao == POSITION_TYPE_BUY) { if(Operacao.precoAlvo < Operacao.precoStop) Operacao.precoAlvo = precoAlvoAnt; ModificaPosicaoAberta(Operacao, ticket); } else if(Operacao.tipoPosicao == POSITION_TYPE_SELL) { if(Operacao.precoAlvo > Operacao.precoStop) Operacao.precoAlvo = precoAlvoAnt; ModificaPosicaoAberta(Operacao, ticket); } } } } } } } //+------------------------------------------------------------------+ //| 2.3 - FUNCAO QUE ATUALIZA ORDENS | //+------------------------------------------------------------------+ void AtualizaOrdens(operacao &Operacao, fluido &Fluidos) { ulong ticket = 0; MqlDateTime horarioMQL_ordem; string tendencia = ""; tendencia = GetTendencia(Fluidos, ArrayTick, ArrayBook); for(int i=OrdersTotal()-1;i>=0;i--) { ticket = OrderGetTicket(i); ushort horarioOrdem = 0; ushort horarioShortAtual = 0; OrderSelect(ticket); double tamanho = OrderGetDouble(ORDER_VOLUME_INITIAL); TimeToStruct(TimeCurrent(), Operacao.horarioMQL_atual); TimeToStruct(OrderGetInteger(ORDER_TIME_SETUP), horarioMQL_ordem); horarioOrdem = horarioMQL_ordem.hour*60*60 + horarioMQL_ordem.min*60 + horarioMQL_ordem.sec; horarioShortAtual = Operacao.horarioMQL_atual.hour*60*60 + Operacao.horarioMQL_atual.min*60 + Operacao.horarioMQL_atual.sec; // Print("horarioAtual: ", horarioShortAtual, " horarioOrdem: ", horarioOrdem, " Fluidos.lifetime: ", Fluidos.lifetimeOrdem); if((horarioShortAtual - horarioOrdem) > Fluidos.TOr) { bool retCancelou = Operacao.negocio.OrderDelete(ticket); if(retCancelou == true) Operacao.numeroContratos = Operacao.numeroContratos - tamanho; // Print("Cancelou ordem aberta por expiração."); } else { //SE FOR COMPRA if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_LIMIT) { //SE FOR BAIXA if(tendencia == "BAIXA FORTE") { bool retCancelou = Operacao.negocio.OrderDelete(ticket); if(retCancelou == true) Operacao.numeroContratos = Operacao.numeroContratos - tamanho; // Print("Cancelou ordem de compra aberta por tendência de baixa."); } } else { //SE FOR ALTA if(tendencia == "ALTA FORTE") { bool retCancelou = Operacao.negocio.OrderDelete(ticket); if(retCancelou == true) Operacao.numeroContratos = Operacao.numeroContratos - tamanho; // Print("Cancelou ordem de venda aberta por tendência de alta."); } } } } } //+------------------------------------------------------------------+ //| 2.4 - FUNCAO QUE ATUALIZA E EXECUTA OS SLOTS DISPONVEIS DE ORDENS| //+------------------------------------------------------------------+ void ExecutaSlotsDisponiveis() { //Avanca os status dos slots for(int i=0; i ArrayTick[0].last) { VendaLimite(Operacao, SlotsV, i); // Print("Mandou ordem de venda limite."); if(Operacao.result.retcode == 10009) { //Avanca o status do slot para enviado //SlotsV[i].idOrdem = Operacao.result.order; OrderSelect(SlotsV[i].idOrdem); TimeToStruct(TimeCurrent(), SlotsV[i].cronometro); } else { SlotsV[i].statusCambio = 0; SlotsV[i].statusMotor = 0; } } break; case 3 : CancelaOrdemAberta(Operacao, SlotsV[i].idOrdem); // Print("Cancelou ordem de compra limite."); break; default : break; } } //+------------------------------------------------------------------+ //| 2.7 - FUNCAO QUE CALCULA O TEMPO LIMITE DE EXPIRACAO DE POSICAO C| //+------------------------------------------------------------------+ int CalculaTempoExpiraPosicaoCompra(operacao &Operacao, fluido &Fluidos, int depth) { int tempo = 0; //int c = 1; tempo = Fluidos.ft * (depth * Fluidos.KV) / Fluidos.lambdaC; return tempo; } //+------------------------------------------------------------------+ //| 2.8 - FUNCAO QUE CALCULA O TEMPO LIMITE DE EXPIRACAO DE POSICAO V| //+------------------------------------------------------------------+ int CalculaTempoExpiraPosicaoVenda(operacao &Operacao, fluido &Fluidos, int depth) { int tempo = 0; //int c = 1; tempo = Fluidos.ft * (depth * Fluidos.KC) / Fluidos.lambdaV; return tempo; } //+------------------------------------------------------------------+ //| 2.9 - FUNCAO QUE CALCULA O TEMPO LIMITE DE EXPIRACAO DE ORDEM C | //+------------------------------------------------------------------+ int CalculaTempoExpiraOrdemCompra(operacao &Operacao, fluido &Fluidos, int depth) { int tempo = 0; int c = 1; //tempo = c * (depth * Fluidos.KC) / Fluidos.lambdaV; tempo = 60; return tempo; } //+------------------------------------------------------------------+ //| 2.10 - FUNCAO QUE CALCULA O TEMPO LIMITE DE EXPIRACAO DE ORDEM V | //+------------------------------------------------------------------+ int CalculaTempoExpiraOrdemVenda(operacao &Operacao, fluido &Fluidos, int depth) { int tempo = 0; int c = 1; tempo = c * (depth * Fluidos.KV) / Fluidos.lambdaC; tempo = 60; return tempo; } //+===================================================================================================================================================================================+ //| FIM DO PROGRAMA //+===================================================================================================================================================================================+