//+------------------------------------------------------------------+ //| S3_Freios_v4_4.mq5 | //| OXFORD | //| HEDGING HORN CAPITAL | //| https://www.hhcapital.com.br | //+------------------------------------------------------------------+ #property copyright "Copyright 2022, HEDGING HORN CAPITAL" #property link "https://www.hhcapital.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 "S0_Admissao_v4_4.mqh"; //+===================================================================================================================================================================================+ //| 3.1 - SESSAO DE HORARIOS / CRONOMETRO //+===================================================================================================================================================================================+ //+------------------------------------------------------------------+ //| 3.1.1 - FUNCAO DE ATUALIZAR HORARIO DE PREGAO | //+------------------------------------------------------------------+ bool VerificaHorarioOrdens(operacao &Operacao) { //Captura o horario atual e coloca em Struct MqlDateTime TimeToStruct(TimeCurrent(), Operacao.horarioMQL_atual); ushort horarioShort_atual = 0; //Converte o horario atual Struct em ushort horarioShort_atual = Operacao.horarioMQL_atual.hour * 60 + Operacao.horarioMQL_atual.min; //Verifica se esta dentro da sessao de trade do dia if((horarioShort_atual > Operacao.horarioShort_inicial) && (horarioShort_atual < Operacao.horarioShort_final)) { return true; } else return false; } //+------------------------------------------------------------------+ //| 3.1.2 - FUNCAO DE ATUALIZAR HORARIO DE FECHAMENTO | //+------------------------------------------------------------------+ bool VerificaHorarioFechamento(operacao &Operacao) { //Captura o horario atual e coloca em Struct MqlDateTime TimeToStruct(TimeCurrent(), Operacao.horarioMQL_atual); ushort horarioShort_atual = 0; //Converte o horario atual Struct em ushort horarioShort_atual = Operacao.horarioMQL_atual.hour * 60 + Operacao.horarioMQL_atual.min; if(horarioShort_atual > Operacao.horarioShort_fechamento) { return true; } else return false; } //+===================================================================================================================================================================================+ //| 3.2 - SESSAO DE RISCOS DE MERCADO/PORTFOLIO / FREIO DE MAO //+===================================================================================================================================================================================+ //+------------------------------------------------------------------+ //| 3.2.1 - FUNCAO QUE VERIFICA OS RISCOS DE MERCADO NIVEL 3 | //+------------------------------------------------------------------+ bool VerificaRiscosNivel3(gerenciador &Gerenciador, operacao &Operacao, fluido &Fluidos) { if(VerificaRiscoSaldo(Gerenciador, Operacao, Fluidos) == false) { if(VerificaRiscoVol(Operacao, Fluidos) == false) { return false; } else return true; } else return true; } //+------------------------------------------------------------------+ //| 3.2.2 - FUNCAO QUE VERIFICA RISCO NIVEL 3 DE SALDO | //+------------------------------------------------------------------+ bool VerificaRiscoSaldo(gerenciador &Gerenciador, operacao &Operacao, fluido &Fluidos) { //PREPARACAO //Calcula a diferenca de saldo na conta //CONDICOES if(Operacao.chaveRiscoSaldo == true) { //Verifica se atingiu o drawdown maximo do dia (VAR) if( (Gerenciador.lucroBrutoComposto < Gerenciador.stopFinanceiro) || (Gerenciador.lucroBrutoComposto > Gerenciador.alvoFinanceiro) ) { return true; } else return false; } else return false; } //+------------------------------------------------------------------+ //| 3.2.2 - FUNCAO QUE VERIFICA OS RISCOS DE MERCADO NIVEL 3 | //+------------------------------------------------------------------+ bool VerificaRiscoVol(operacao &Operacao, fluido &Fluidos) { if(Operacao.chaveRiscoVolCurto == true) { if(Fluidos.sigmaHFT > Fluidos.limiteSupDesvioCurto) { return true; } else return false; } else return false; } //+------------------------------------------------------------------+ //| 3.2.4 - FUNCAO QUE CALCULA A MEDIA DE PRECOS | //+------------------------------------------------------------------+ void GetPrecosPassados(fluido &Fluidos, MqlTick &ArrayTick[], double &Precos[]) { if(CopyTicks(Symbol(), ArrayTick, COPY_TICKS_TRADE, 0, Fluidos.intervaloTicks) != -1) { ArraySetAsSeries(ArrayTick,true); for(int i=0;i 0) return true; else return false; } //+------------------------------------------------------------------+ //| 3.3.4 - FUNCAO QUE VERIFICA LIMITE DE ORDENS VENDA | //+------------------------------------------------------------------+ bool VerificaLimiteVenda(operacao &Operacao, fluido &Fluidos) { double limite_Venda = Fluidos.Q; double qtdVendaEnviada = 0.0; double qtdVendaExecutada = 0.0; limite_Venda = limite_Venda - Fluidos.rajada*OrdensVendaLimitadasAbertas(Operacao, Fluidos, qtdVendaEnviada, qtdVendaExecutada) - Fluidos.rajada*PosicoesVendaAbertas(Operacao, Fluidos); if(limite_Venda > 0) return true; else return false; } //+------------------------------------------------------------------+ //| 3.3.5 - FUNCAO QUE VERIFICA LIMITE EM VOLUME DE ORDENS DE COMPRA | //+------------------------------------------------------------------+ int VerificaLimiteVolumeCompra(const int loteEnvio, double qtdCompraEnviada) { double limite = loteEnvio; int returnCode = 1; if(qtdCompraEnviada == 0.0) return 0; if(qtdCompraEnviada == limite) return 1; return returnCode; } //+------------------------------------------------------------------+ //| 3.3.6 - FUNCAO QUE VERIFICA LIMITE EM VOLUME DE ORDENS VENDA | //+------------------------------------------------------------------+ int VerificaLimiteVolumeVenda(const int loteEnvio, double qtdVendaEnviada) { double limite = loteEnvio; int returnCode = 1; if(qtdVendaEnviada == 0.0) return 0; if(qtdVendaEnviada == limite) return 1; return returnCode; } //+--------------------------------------------------------------------------+ //| 3.3.7 - FUNCAO DE CALCULO DO NUMERO DE ORDENS COMPRA LIMITADAS ABERTAS | //+--------------------------------------------------------------------------+ int OrdensCompraLimitadasAbertas(operacao &Operacao, fluido &Fluidos, double &qtdCompraEnviada, double &qtdCompraExecutada) { int ordens = 0; //Percorre todas as ordens for(int i=OrdersTotal()-1; i>=0; i--) { ulong ticket = OrderGetTicket(i); string symbol = OrderGetString(ORDER_SYMBOL); ulong magicEA = OrderGetInteger(ORDER_MAGIC); //Verifica para cada ordem, se eh do simbolo corrente e do mesmo robo if((symbol == _Symbol) && (magicEA == Operacao.magic)) { //Verifica se a ordem eh do tipo buy limit if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_LIMIT) { ordens = ordens + 1; qtdCompraEnviada = OrderGetDouble(ORDER_VOLUME_INITIAL); qtdCompraExecutada = qtdCompraEnviada - OrderGetDouble(ORDER_VOLUME_CURRENT); } } } return ordens; } //+--------------------------------------------------------------------------+ //| 3.3.8 - FUNCAO DE CALCULO DO NUMERO DE ORDENS VENDA LIMITADAS ABERTAS | //+--------------------------------------------------------------------------+ int OrdensVendaLimitadasAbertas(operacao &Operacao, fluido &Fluidos, double &qtdVendaEnviada, double &qtdVendaExecutada) { int ordens = 0; //Percorre todas as ordens for(int i=OrdersTotal()-1; i>=0; i--) { ulong ticket = OrderGetTicket(i); string symbol = OrderGetString(ORDER_SYMBOL); ulong magicEA = OrderGetInteger(ORDER_MAGIC); //Verifica para cada ordem, se eh do simbolo corrente e do mesmo robo if((symbol == _Symbol) && (magicEA == Operacao.magic)) { //Verifica se a ordem eh do tipo sell limit if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_LIMIT) { ordens = ordens + 1; qtdVendaEnviada = OrderGetDouble(ORDER_VOLUME_INITIAL); qtdVendaExecutada = qtdVendaEnviada - OrderGetDouble(ORDER_VOLUME_CURRENT); } } } return ordens; } //+------------------------------------------------------------------+ //| 3.3.9 - FUNCAO DE CALCULO DO q | //+------------------------------------------------------------------+ int AtualizaQuantidade(operacao &Operacao, fluido &Fluidos) { int q = 0; q = Fluidos.rajada*PosicoesCompraAbertas(Operacao, Fluidos) - Fluidos.rajada*PosicoesVendaAbertas(Operacao, Fluidos); return q; } //+------------------------------------------------------------------+ //| 3.3.10 - FUNCAO DE VERIFICACAO DE POSICAO DE COMPRA | //+------------------------------------------------------------------+ int PosicoesCompraAbertas(operacao &Operacao, fluido &Fluidos) { int positions = 0; //Percorre todas as posicoes for(int i=PositionsTotal()-1; i>=0; i--) { ulong ticket = PositionGetTicket(i); string symbol = PositionGetString(POSITION_SYMBOL); ulong magicEA = PositionGetInteger(POSITION_MAGIC); //Verifica para cada posicao, se eh do simbolo corrente e do mesmo robo if((symbol == _Symbol) && (magicEA == Operacao.magic)) { //Verifica se a posicao eh do tipo buy if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { positions = positions + 1; } } } return positions; } //+------------------------------------------------------------------+ //| 3.3.11 - FUNCAO DE VERIFICACAO DE POSICAO DE VENDAS | //+------------------------------------------------------------------+ int PosicoesVendaAbertas(operacao &Operacao, fluido &Fluidos) { int positions = 0; //Percorre todas as posicoes for(int i = PositionsTotal()-1; i>=0; i--) { ulong ticket = PositionGetTicket(i); string symbol = PositionGetString(POSITION_SYMBOL); ulong magicEA = PositionGetInteger(POSITION_MAGIC); //Verifica para cada posicao, se eh do simbolo corrente e do mesmo robo if((symbol == _Symbol) && (magicEA == Operacao.magic)) { //Verifica se a posicao eh do tipo sell if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) { positions = positions + 1; } } } return positions; } //+===================================================================================================================================================================================+ //| FIM DO PROGRAMA //+===================================================================================================================================================================================+