//+------------------------------------------------------------------+ //| S1_Ignicao_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 #include #include "MarketBook.mqh" #include "S0_Admissao_v4_4.mqh" #include "S2_Motor_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" //+------------------------------------------------------------------+ //| 0.2 - ENTRADAS DE USUARIO | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 0.2.1 - INPUTS DE GERENCIAMENTO DE RISCOS | //+------------------------------------------------------------------+ input group "Gerenciamento de Capital------------------|---------------------------------------------------------------" input double saldoInicial = 4000; //X(0) R$: Saldo inicial do dia; CHescalona = F input double alvoPercentual = 0.30; //sup[X(t)] %: alvo 0.05 = 5%; CHescalona = T; inf < dX < 0.30 input double stopPercentual = 0.10; //inf[X(t)] %: stop 0.05 = 5%; CHescalona = T; -0.1 < dX < sup //+------------------------------------------------------------------+ //| 0.2.2 - INPUTS DE GERENCIAMENTO DE INVENTARIO | //+------------------------------------------------------------------+ input group "Gerenciamento de Inventário---------------|---------------------------------------------------------------" input int niveis = 4; //η: Níveis máximos η, CHescalona = F; -ηr < q < ηr input int rajada = 1; //r: Quantidade por ordem r, se Cescalona = F; -ηr < q < ηr //+------------------------------------------------------------------+ //| 0.2.3 - INPUTS DE GERENCIAMENTO DE TEMPO | //+------------------------------------------------------------------+ input group "Gerenciamento de Tempo--------------------|---------------------------------------------------------------" input ushort horarioShort_inicial = 545; //inf[t] min: Horário inicial 09:05 = 545; 545 < t < sup[t] input ushort horarioShort_final = 1040; //sup[t] min: Horário final 16:20 = 980; inf[t] < t < 980 input ushort horarioShort_fechamento = 1043; //ta min: Horário limite de after 16:23 = 983; sup[t] < ta < 983 //+------------------------------------------------------------------+ //| 0.2.4 - INPUTS DE GERENCIAMENTO DE RISCOS | //+------------------------------------------------------------------+ input group "Gerenciamento de Riscos-------------------|---------------------------------------------------------------" input double fi = 0.5; //φ: Running Penalty (aversao a risco) input double gama = 1.0; //γ: Fator multiplicativo gama, influencia no q * desvio double fatorStop = 2.5; //fSL: Fator multiplicativo do stoploss da ordem double offsetStartTrailingC = 60.0; //δATSstartC pontos: Start= #pts para iniciar o trailing double offsetStartTrailingV = 60.0; //δATSstartV pontos: Start= #pts para iniciar o trailing double offsetStopTrailingC = 20.0; //inf[δA]TSstopC: pontos entre o precoMax e o sl; inf[δCA]<δCA double offsetStopTrailingV = 20.0; //inf[δA]TSstopV: pontos entre o precoMax e o sl; inf[δVA]<δVA //+------------------------------------------------------------------+ //| 0.2.5 - INPUTS DE GERENCIAMENTO DE ESTRATEGIA | //+------------------------------------------------------------------+ input group "Gerenciamento de Estratégia---------------|---------------------------------------------------------------" input double custoOperacao = 0.47; //ζ R$: Custo por operacao ζ {1.20} [0.0, 2.0[ input int fatorLambdaBacktest = 1; //fλ: Fator de multiplicacao Lambda input double fatorAlfa = 1; //fA: Fator de multiplicacao de Alfa input double fatorUpsilon = 1; //fU: Fator de multiplicacao de Upsilon input double expAlpha = 1.0; //exp Alpha input double expUpsilon = 1.0; //exp Upsilon input int periodoMedia = 2; //periodo media int spreadCusto = 15; //δCusto pontos: Spread Offset do Custo de Envio input int refreshOrdem = 5; //τOr seg: Tempo em seg da duracao de uma ordem pendente input int refreshPosicao = 5; //τPr seg: Tempo em seg do refresh de uma posicao input int expiraOrdem = 5; //TOe seg: Tempo em seg de expiracao de uma ordem pendente int expiraPosicao = 500; //TPe seg: Tempo em seg de expiracao de uma posicao input int intervaloTicks = 2000; //i: Intervalo de ticks i do ArrayTick int periodoSTDDEVLongo = 100; //nσ: Periodo do Desvio Padrao Longo {100} int periodoSTDDEVCurto = 10; //nσ: Periodo do Desvio Padrao Curto {100} int profundidadeBook = 5; //β: Profundidade do book a calcular o k {5}[1, +inf[ int n = 5; //n: Índice da potencia do spread int fatorHedge = 10; //fH: Fator de spread alvo do hedge input double fatorTempo = 12; //fator de tempo do expira posicao input double fatorVol = 1.0; //fator que multiplica a volatilidade do spread double corteImbalance = 0.40; //fZ: Offset do corte do regime Z do imbalance p double limiteSupDesvioCurto = 100; //sup[σ] pontos: Supremo de VolC;CHRiscoTend = T inf[σ] < σ < 290 //+------------------------------------------------------------------+ //| 0.2.6 - INPUTS DE GERENCIAMENTO DE OPERACOES | //+------------------------------------------------------------------+ input group "Gerenciamento de Operações----------------|---------------------------------------------------------------" input bool chaveSaldoChumbado = false; //Chave do saldo chumbado input bool chaveEscalonador = true; //Chave do escalonador dos lotes input bool chaveRiscoSaldo = true; //Chave do risco saldo input bool chaveTrailing = true; //Chave do trailing stop input bool chaveTheta = true; //Chave do theta, expira variavel input bool chaveLambda = false; //Chave do lambda input bool chaveLambdaBacktest = true; //Chave do lambda backtest input bool chaveBook = false; //Chave do book input bool chaveBookBacktest = false; //Chave do book backtest input bool chaveDeltaH = true; //Chave do uso do deltaH (funcao de valor) input bool chaveDesvio = true; //Chave do desvio * niveis input bool chaveGama = true; //Chave do gama (faz nao acumular inventário) input bool chaveFi = true; //Chave do fi (faz o inventário voltar a 0) input bool chaveUpsilon = true; //Chave do upsilon (faz acompanhar a tendencia longa) input bool chaveAlpha = true; //Chave do alpha (faz acompanhar a tendencia curta) input bool chaveAssimetria = true; //Chave da assimetria input bool chaveCurtose = true; //Chave da curtose, espalhamento dos lotes input bool chaveDeinitOrdens = false; //Chave do cancelamento de ordens no Deinit input bool chaveDeinitPosicoes = false; //Chave do fechamento de posicoes no Deinit bool chaveRiscoVolCurto = false; //Chave do risco de volatilidade curta //+------------------------------------------------------------------+ //| 0.3 - VARIAVEIS GLOBAIS | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 0.3.1 - OBJETOS OPERACIONAIS | //+------------------------------------------------------------------+ gerenciador Gerenciador; operacao Operacao; fluido Fluidos; slot SlotsC[]; slot SlotsV[]; MqlTick ArrayTick[]; MqlBookInfo ArrayBook[]; CMarketBook Book(_Symbol); //+===================================================================================================================================================================================+ //| 1 - SESSAO DE DAR A PARTIDA E CONTROLA EVENTOS / IGNICAO //+===================================================================================================================================================================================+ //+------------------------------------------------------------------+ //| 1.1 - FUNCAO DE INICIALIZACAO | //+------------------------------------------------------------------+ int OnInit() { Print("DESENVOLVIMENTO v4.4"); //Inicializao basica Fluidos.q = 0; Fluidos.t = 0; Fluidos.TOr = refreshOrdem; Fluidos.TPr = refreshPosicao; Fluidos.TOe = expiraOrdem; Fluidos.TPe = expiraPosicao; Fluidos.t0d = horarioShort_inicial; Fluidos.td = 0; Fluidos.Td = horarioShort_final; Fluidos.nBook = profundidadeBook; Fluidos.iBid0 = -1; Fluidos.iAsk0 = -1; Fluidos.iSlot = 0; Fluidos.niveis = niveis; Fluidos.rajada = rajada; Fluidos.handlerMA = -1; Fluidos.handlerSTDDEVLongo = -1; Fluidos.handlerSTDDEVCurto = -1; Fluidos.handlerVolumeReal = -1; Fluidos.handlerVolumeNegocios = -1; Fluidos.periodoMA = periodoMedia; Fluidos.periodoSTDDEVLongo = periodoSTDDEVLongo; Fluidos.periodoSTDDEVCurto = periodoSTDDEVCurto; Fluidos.periodoVolume = 10; Fluidos.intervaloTicks = intervaloTicks; Fluidos.media = -1; Fluidos.midPrice = -1; Fluidos.drift = 0; Fluidos.upsilon = 0.0; Fluidos.alpha = 0.0; Fluidos.alpha0 = 0.0; Fluidos.alpha1 = 0.0; Fluidos.fA = fatorAlfa; Fluidos.fU = fatorUpsilon; Fluidos.expA = expAlpha; Fluidos.expU = expUpsilon; Fluidos.sigmaHFT = -1; Fluidos.sigmaLFT = -1; Fluidos.assimetria = 0.0; Fluidos.curtose = 0.0; Fluidos.KC = 100; Fluidos.KV = 100; Fluidos.lambdaC = 10; Fluidos.lambdaV = 10; Fluidos.lobC = 0.0; Fluidos.lobV = 0.0; Fluidos.fi = fi; Fluidos.gama = 0; Fluidos.c = custoOperacao; Fluidos.tickMin = 5; Fluidos.precoAbertura = -1; Fluidos.precoOpen = -1; Fluidos.precoClose = -1; Fluidos.limiteInfTend = -1; Fluidos.limiteSupTend = -1; Fluidos.limiteInfDesvio = -1; Fluidos.limiteSupDesvioCurto = limiteSupDesvioCurto; Fluidos.imbalance = 0.0; Fluidos.corteImbalance = corteImbalance; Fluidos.LC = true; Fluidos.LV = true; Fluidos.fatorHedge = fatorHedge; Fluidos.tendencia = ""; Fluidos.spreadCusto = spreadCusto; if(chaveEscalonador == true) Fluidos.rajada = floor(AccountInfoDouble(ACCOUNT_BALANCE)/10000) + 1; if(chaveEscalonador == true) Fluidos.niveis = floor(AccountInfoDouble(ACCOUNT_BALANCE)/(Fluidos.rajada*1000)); if(chaveGama == true) Fluidos.gama = gama; Fluidos.Q = Fluidos.rajada * Fluidos.niveis; Fluidos.n = n; Fluidos.eC = 0.0; Fluidos.eV = 0.0; Fluidos.fatorLambdaBacktest = fatorLambdaBacktest; Fluidos.fatorStop = fatorStop; Fluidos.ft = fatorTempo; Fluidos.fatorVol = fatorVol; Operacao.chaveSaldoChumbado = chaveSaldoChumbado; Operacao.chaveEscalonador = chaveEscalonador; Operacao.chaveRiscoSaldo = chaveRiscoSaldo; Operacao.chaveRiscoVolCurto = chaveRiscoVolCurto; Operacao.chaveTrailing = chaveTrailing; Operacao.chaveLambda = chaveLambda; Operacao.chaveLambdaBacktest = chaveLambdaBacktest; Operacao.chaveBook = chaveBook; Operacao.chaveBookBacktest = chaveBookBacktest; Operacao.chaveDeltaH = chaveDeltaH; Operacao.chaveTheta = chaveTheta; Operacao.chaveUpsilon = chaveUpsilon; Operacao.chaveAlpha = chaveAlpha; Operacao.chaveDesvio = chaveDesvio; Operacao.chaveGama = chaveGama; Operacao.chaveFi = chaveFi; Operacao.chaveCurtose = chaveCurtose; Operacao.chaveAssimetria = chaveAssimetria; Operacao.magic = 11111; Operacao.diaAtual = 0; Operacao.diaAnt = 0; Operacao.posicoes_total_prev = 0; Operacao.posicoes_total = 0; Operacao.normalizeDoubleSize = 0; Operacao.horarioShort_atual =0; Operacao.horarioShort_inicial = horarioShort_inicial; Operacao.horarioShort_final = horarioShort_final; Operacao.horarioShort_fechamento = horarioShort_fechamento; Operacao.countSaldo = 0; Operacao.countFechaDia = 0; Operacao.handlerNormalizeDoubleSize = ""; Operacao.expiraPosicao = expiraPosicao; Operacao.numeroContratos = 0; Operacao.numeroContratosAcumulado = 0; Operacao.offsetStartTrailingC = offsetStartTrailingC; Operacao.offsetStopTrailingC = offsetStopTrailingC; Operacao.offsetStartTrailingV = offsetStartTrailingC; Operacao.offsetStopTrailingV = offsetStopTrailingC; Gerenciador.capitalTotal = AccountInfoDouble(ACCOUNT_BALANCE); if(Operacao.chaveSaldoChumbado == true) Gerenciador.capitalInvestido = saldoInicial; else Gerenciador.capitalInvestido = Gerenciador.capitalTotal; Gerenciador.capitalInicialDia = saldoInicial; if(Operacao.chaveSaldoChumbado == true) Gerenciador.capitalFechado = saldoInicial; else Gerenciador.capitalFechado = Gerenciador.capitalTotal; Gerenciador.capitalAberto = 0.0; Gerenciador.lucroBrutoComposto = 0.0; Gerenciador.lucroBrutoFechado = 0.0; Gerenciador.lucroBrutoAberto = 0.0; Gerenciador.lucroLiquido = 0.0; Gerenciador.lucroLiquidoAcumulado = 0.0; Gerenciador.alvoPercentual = alvoPercentual; if(stopPercentual > 0) Gerenciador.stopPercentual = stopPercentual * -1; else Gerenciador.stopPercentual = stopPercentual; //Inicializa a contagem de dias TimeToStruct(TimeCurrent(), Operacao.horarioMQL_atual); Operacao.diaAtual = Operacao.horarioMQL_atual.day; //Inicializa o MarketBook if(Operacao.chaveBook == true) if(!MarketBookAdd(_Symbol)) Print("Falha para inicializar o book"); ArrayResize(ArrayTick, Fluidos.intervaloTicks, 0); //Inicializa o ArrayTick if(CopyTicks(_Symbol, ArrayTick, COPY_TICKS_ALL, 0, Fluidos.intervaloTicks) != -1) { ArraySetAsSeries(ArrayTick, true); } else Print("Falha para inicializar o ArrayTicks: ", GetLastError()); //NormalizeDouble Operacao.handlerNormalizeDoubleSize = DoubleToString(Fluidos.tickMin); Operacao.handlerNormalizeDoubleSize = StringReplace(Operacao.handlerNormalizeDoubleSize,".",""); Operacao.normalizeDoubleSize = (StringLen(Operacao.handlerNormalizeDoubleSize))-1; //Ajusta o tamanho dos arrays de slots de compra e venda ArrayResize(SlotsC, Fluidos.niveis); ArrayResize(SlotsV, Fluidos.niveis); //Inicializa os slots de compra e venda for(int i=0; i Gerenciador.lucroBrutoFechado) { //loss PlaySound("loss.wav"); } Gerenciador.capitalFechado = AccountInfoDouble(ACCOUNT_BALANCE) - (Gerenciador.capitalTotal-Gerenciador.capitalInvestido); Gerenciador.capitalAberto = Gerenciador.capitalFechado + Gerenciador.lucroBrutoAberto; } if(Operacao.chaveEscalonador == true) { //Atualiza as rajadas e niveis de acordo com o novo saldo Fluidos.rajada = floor(AccountInfoDouble(ACCOUNT_BALANCE)/10000) + 1; Fluidos.niveis = floor(AccountInfoDouble(ACCOUNT_BALANCE)/(Fluidos.rajada*1000)); Fluidos.Q = Fluidos.rajada * Fluidos.niveis; ArrayResize(SlotsC, Fluidos.niveis); ArrayResize(SlotsV, Fluidos.niveis); } Fluidos.precoAbertura = iOpen(_Symbol, PERIOD_D1, 0); Fluidos.precoOpen = iOpen(_Symbol, PERIOD_M1, 0); Fluidos.precoClose = iClose(_Symbol, PERIOD_M1, 0); //Atualiza o horario TimeToStruct(TimeCurrent(), Operacao.horarioMQL_atual); //Atualiza o book if(!Operacao.simbolo.RefreshRates()) return; if(Operacao.chaveBook == true) { if(MarketBookGet(_Symbol, ArrayBook)) { //Atualiza os indices do topo do book Fluidos.iBid0 = Book.InfoGetInteger(MBOOK_BEST_BID_INDEX); Fluidos.iAsk0 = Book.InfoGetInteger(MBOOK_BEST_ASK_INDEX); } else { Print("Falha ao atualizar o Book"); } } ArrayResize(ArrayTick, Fluidos.intervaloTicks, 0); //Atualiza os ticks if(CopyTicks(Symbol(), ArrayTick,COPY_TICKS_ALL, 0, Fluidos.intervaloTicks) != -1) ArraySetAsSeries(ArrayTick, true); else Print("Falha para inicializar o ArrayTicks: ", GetLastError()); //Atualiza os buffers de media e desvio padrao CopyBuffer(Fluidos.handlerMA, 0 ,1, 2, Fluidos.MA); CopyBuffer(Fluidos.handlerSTDDEVLongo, 0, 1, 2, Fluidos.STDDEVLONGO); CopyBuffer(Fluidos.handlerSTDDEVCurto, 0, 1, 2, Fluidos.STDDEVCURTO); CopyBuffer(Fluidos.handlerVolumeReal, 0, 1, 2, Fluidos.VOLUMEREAL); CopyBuffer(Fluidos.handlerVolumeNegocios, 0, 1, 2, Fluidos.VOLUMENEGOCIOS); Fluidos.midPrice = (Operacao.simbolo.Ask() + Operacao.simbolo.Bid())/2; Fluidos.media = Fluidos.MA[0]; Fluidos.sigmaHFT = MathAbs(Fluidos.STDDEVCURTO[0]); Fluidos.sigmaLFT = MathAbs(Fluidos.STDDEVLONGO[0]); Fluidos.volumeReal = Fluidos.VOLUMEREAL[0]; Fluidos.volumeNegocios = Fluidos.VOLUMENEGOCIOS[0]; Fluidos.upsilon = Fluidos.MA[0] - Fluidos.MA[1]; Fluidos.q = AtualizaQuantidade(Operacao, Fluidos); Fluidos.td = Operacao.horarioMQL_atual.hour*60 + Operacao.horarioMQL_atual.min; double precos0[]; double precos1[]; ArrayResize(precos0, Fluidos.intervaloTicks/2, 0); ArrayResize(precos1, Fluidos.intervaloTicks/2, 0); for(int i=0;i