438 lines
No EOL
42 KiB
MQL5
438 lines
No EOL
42 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| S1_Ignicao_v1_0.mq5 |
|
|
//| DELTA |
|
|
//| HEDGING HORN CAPITAL |
|
|
//| https://www.hhcapital.com.br |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2023, HEDGING HORN CAPITAL"
|
|
#property link "https://www.hhcapital.com.br"
|
|
#property version "DELTA PRODUCAO v1_0"
|
|
#property description "HFT MARKET MAKING. MINI INDICE."
|
|
|
|
//+===================================================================================================================================================================================+
|
|
//| 0 - SESSAO DE CABECALHO / ADMISSAO
|
|
//+===================================================================================================================================================================================+
|
|
//+------------------------------------------------------------------+
|
|
//| 0.1 - IMPORTACOES |
|
|
//+------------------------------------------------------------------+
|
|
#include <Expert/Expert.mqh>
|
|
#include <Trade/Trade.mqh>
|
|
#include <Trade/SymbolInfo.mqh>
|
|
#include "MarketBook.mqh"
|
|
#include "S0_Admissao_v1_0.mqh"
|
|
#include "S2_Motor_v1_0.mqh"
|
|
#include "S3_Freios_v1_0.mqh"
|
|
#include "S4_Cambio_v1_0.mqh"
|
|
#include "S5_Direcao_v1_0.mqh"
|
|
#include "S6_Transmissao_v1_0.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 slices = 20; //η: 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 = 1059; //sup[t] min: Horário final 16:20 = 980; inf[t] < t < 980
|
|
input ushort horarioShort_fechamento = 1060; //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 int pontosAlvo = 55; //Alvo em pontos
|
|
input double stopPercent = 0.035; //Risco nivel 1: hard stop
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 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 ENUM_TIMEFRAMES timeframe = PERIOD_M15; //Timeframe dos candles
|
|
input int periodoMA = 36; //Periodo da media movel
|
|
input int refreshOrdem = 32000; //τOr seg: Tempo em seg da duracao de uma ordem pendente
|
|
input int expiraOrdem = 32000; //TOe seg: Tempo em seg de expiracao de uma ordem pendente
|
|
input double desvioPercent = 0.002; //Afastamento entre slices percentual da media
|
|
input double spreadOffsetPercent = 0.0; //Offset de afastamento da regiao de apregoacao para a media
|
|
int intervaloTicks = 10; //i: Intervalo de ticks i do ArrayTick
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 0.2.6 - INPUTS DE GERENCIAMENTO DE OPERACOES |
|
|
//+------------------------------------------------------------------+
|
|
input group "Gerenciamento de Operações----------------|---------------------------------------------------------------"
|
|
input bool chaveSaldoChumbado = true; //Chave do saldo chumbado
|
|
input bool chaveEscalonador = false; //Chave do escalonador dos lotes
|
|
input bool chaveRiscoSaldo = false; //Chave do risco saldo
|
|
input bool chaveDeinitOrdens = true; //Chave do cancelamento de ordens no Deinit
|
|
input bool chaveDeinitPosicoes = true; //Chave do fechamento de posicoes no Deinit
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 0.3 - VARIAVEIS GLOBAIS |
|
|
//+------------------------------------------------------------------+
|
|
//+------------------------------------------------------------------+
|
|
//| 0.3.1 - OBJETOS OPERACIONAIS |
|
|
//+------------------------------------------------------------------+
|
|
gerenciador Gerenciador;
|
|
operacao Operacao;
|
|
fluido Fluidos;
|
|
slot SlotsC[];
|
|
slot SlotsV[];
|
|
MqlTick ArrayTick[];
|
|
|
|
//+===================================================================================================================================================================================+
|
|
//| 1 - SESSAO DE DAR A PARTIDA E CONTROLA EVENTOS / IGNICAO
|
|
//+===================================================================================================================================================================================+
|
|
//+------------------------------------------------------------------+
|
|
//| 1.1 - FUNCAO DE INICIALIZACAO |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
Print("DELTA PRODUCAO v1_0: HFT MARKET MAKING. MINI INDICE.");
|
|
|
|
//Inicializa as structs basicas
|
|
InicializaGerenciador();
|
|
InicializaOperacao();
|
|
InicializaFluidos();
|
|
InicializaBuffers();
|
|
|
|
//Inicializa a contagem de dias
|
|
TimeToStruct(TimeCurrent(), Operacao.horarioMQL_atual);
|
|
Operacao.diaAtual = Operacao.horarioMQL_atual.day;
|
|
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 1.2 - FUNCAO EVENTO TICK / CORACAO |
|
|
//+------------------------------------------------------------------+
|
|
void OnTick()
|
|
{
|
|
//Atualiza os ticks e variaveis
|
|
AtualizaVariaveis();
|
|
|
|
//Chama o motor
|
|
if(VerificaHorarioOrdens(Operacao)) FazTrades(Gerenciador, Operacao, Fluidos, SlotsC, SlotsV);
|
|
else if(VerificaHorarioFechamento(Operacao))
|
|
{
|
|
if(Operacao.countFechaDia == 0)
|
|
{
|
|
FechaPosicoes(Operacao);
|
|
Print("Mandou fechar todas as posicoes por fechamento de dia.");
|
|
CancelaOrdensAbertas(Operacao);
|
|
Print("Mandou cancelar todas as ordens abertas por fechamento de dia.");
|
|
ArrayFree(SlotsC);
|
|
ArrayFree(SlotsV);
|
|
ArrayResize(SlotsC, Fluidos.niveis);
|
|
ArrayResize(SlotsV, Fluidos.niveis);
|
|
|
|
for(int i=0;i<ArraySize(SlotsC);i++)
|
|
{
|
|
SlotsC[i].statusCambio = 0;
|
|
SlotsC[i].statusMotor = 0;
|
|
SlotsV[i].statusCambio = 0;
|
|
SlotsV[i].statusMotor = 0;
|
|
}
|
|
|
|
if((PositionsTotal() + OrdersTotal()) == 0) Operacao.countFechaDia = 1;
|
|
}
|
|
}
|
|
else return;
|
|
|
|
return;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 1.3 - FUNCAO EVENTO BOOK |
|
|
//+------------------------------------------------------------------+
|
|
void OnBookEvent(const string &symbol)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 1.4 - FUNCAO EVENTO TRADE |
|
|
//+------------------------------------------------------------------+
|
|
void OnTrade()
|
|
{
|
|
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 1.5 - FUNCAO DE DESLIGAMENTO |
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason)
|
|
{
|
|
//Da release nos indicadores
|
|
AtualizaVariaveis();
|
|
IndicatorRelease(Fluidos.handlerMA);
|
|
if(chaveDeinitOrdens == true)
|
|
{
|
|
CancelaOrdensAbertas(Operacao);
|
|
}
|
|
if(chaveDeinitPosicoes == true)
|
|
{
|
|
FechaPosicoes(Operacao);
|
|
}
|
|
Print("Numero de contratos operados: ", Operacao.numeroContratosAcumulado+Operacao.numeroContratos);
|
|
Print("Lucro liquido: ", Gerenciador.lucroLiquidoAcumulado+Gerenciador.lucroLiquido);
|
|
Print("Payoff medio: ", ((Gerenciador.lucroLiquidoAcumulado+Gerenciador.lucroLiquido)/(Operacao.numeroContratosAcumulado+Operacao.numeroContratos)));
|
|
Print("OUTPUT PATH=",TerminalInfoString(TERMINAL_DATA_PATH));
|
|
|
|
//Falha na desinicializacao
|
|
printf("Deinit reason: %d", reason);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 1.6 - FUNCAO DE CASO EM BACKTEST |
|
|
//+------------------------------------------------------------------+
|
|
double OnTester()
|
|
{
|
|
double lucroLiquido;
|
|
double numeroDeContratos;
|
|
double payoffMedio;
|
|
|
|
lucroLiquido = Gerenciador.lucroLiquidoAcumulado+Gerenciador.lucroLiquido;
|
|
numeroDeContratos = Operacao.numeroContratosAcumulado+Operacao.numeroContratos;
|
|
payoffMedio = ((Gerenciador.lucroLiquidoAcumulado+Gerenciador.lucroLiquido)/(Operacao.numeroContratosAcumulado+Operacao.numeroContratos));
|
|
|
|
return (payoffMedio);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 1.7 - FUNCAO QUE INICIALIZA A STRUCT GERENCIADOR |
|
|
//+------------------------------------------------------------------+
|
|
void InicializaGerenciador()
|
|
{
|
|
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;
|
|
|
|
return;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 1.8 - FUNCAO QUE INICIALIZA A STRUCT OPERACAO |
|
|
//+------------------------------------------------------------------+
|
|
void InicializaOperacao()
|
|
{
|
|
Operacao.chaveSaldoChumbado = chaveSaldoChumbado;
|
|
Operacao.chaveEscalonador = chaveEscalonador;
|
|
Operacao.chaveRiscoSaldo = chaveRiscoSaldo;
|
|
Operacao.magic = 44444;
|
|
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.numeroContratos = 0;
|
|
Operacao.numeroContratosAcumulado = 0;
|
|
|
|
return;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 1.9 - FUNCAO QUE INICIALIZA A STRUCT FLUIDOS |
|
|
//+------------------------------------------------------------------+
|
|
void InicializaFluidos()
|
|
{
|
|
Fluidos.q = 0;
|
|
Fluidos.t = 0;
|
|
Fluidos.TOr = refreshOrdem;
|
|
Fluidos.TOe = expiraOrdem;
|
|
Fluidos.t0d = horarioShort_inicial;
|
|
Fluidos.td = 0;
|
|
Fluidos.Td = horarioShort_final;
|
|
Fluidos.iSlot = 0;
|
|
Fluidos.niveis = slices;
|
|
Fluidos.rajada = rajada;
|
|
Fluidos.handlerMA = -1;
|
|
Fluidos.periodoMA = periodoMA;
|
|
Fluidos.timeframe = timeframe;
|
|
Fluidos.media = -1;
|
|
Fluidos.c = custoOperacao;
|
|
Fluidos.precoMedioC = 0.0;
|
|
Fluidos.precoMedioV = 0.0;
|
|
Fluidos.tickMin = 5;
|
|
Fluidos.intervaloTicks = intervaloTicks;
|
|
if(chaveEscalonador == true) Fluidos.rajada = floor(AccountInfoDouble(ACCOUNT_BALANCE)/10000) + 1;
|
|
if(chaveEscalonador == true) Fluidos.niveis = floor(AccountInfoDouble(ACCOUNT_BALANCE)/(Fluidos.rajada*200));
|
|
Fluidos.Q = Fluidos.rajada * Fluidos.niveis;
|
|
Fluidos.pontosAlvo = pontosAlvo;
|
|
Fluidos.stopPercent = stopPercent;
|
|
Fluidos.desvioPercent = desvioPercent;
|
|
Fluidos.spreadOffsetPercent = spreadOffsetPercent;
|
|
|
|
return;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 1.10 - FUNCAO QUE INICIALIZA OS BUFFERS |
|
|
//+------------------------------------------------------------------+
|
|
void InicializaBuffers()
|
|
{
|
|
//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<Fluidos.niveis ;i++)
|
|
{
|
|
SlotsC[i].statusCambio = 0;
|
|
SlotsC[i].statusMotor = 0;
|
|
SlotsV[i].statusCambio = 0;
|
|
SlotsV[i].statusMotor = 0;
|
|
SlotsC[i].ponta = 0;
|
|
SlotsV[i].ponta = 2;
|
|
}
|
|
|
|
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());
|
|
|
|
//Cria os buffers dos indicadores de media e desvio padrao
|
|
Fluidos.handlerMA = iMA(_Symbol, Fluidos.timeframe, Fluidos.periodoMA, 0, MODE_SMA, PRICE_CLOSE);
|
|
ArraySetAsSeries(Fluidos.MA, true);
|
|
CopyBuffer(Fluidos.handlerMA, 0, 1, 1, Fluidos.MA);
|
|
Fluidos.media = Fluidos.MA[0];
|
|
|
|
return;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 1.11 - FUNCAO QUE ATUALIZA AS VARIAVEIS E E STRUCTS |
|
|
//+------------------------------------------------------------------+
|
|
void AtualizaVariaveis()
|
|
{
|
|
Operacao.diaAtual = Operacao.horarioMQL_atual.day;
|
|
//PRIMEIRO TICK DO DIA
|
|
if(Operacao.diaAtual != Operacao.diaAnt)
|
|
{
|
|
Operacao.countSaldo = 0;
|
|
Operacao.diaAnt = Operacao.diaAtual;
|
|
Gerenciador.capitalTotal = AccountInfoDouble(ACCOUNT_BALANCE);
|
|
Gerenciador.capitalInvestido = Gerenciador.capitalFechado;
|
|
|
|
if(Operacao.chaveSaldoChumbado == false)
|
|
{
|
|
Gerenciador.capitalFechado = AccountInfoDouble(ACCOUNT_BALANCE);
|
|
}
|
|
else
|
|
{
|
|
Gerenciador.capitalFechado = Gerenciador.capitalInicialDia + Gerenciador.lucroBrutoFechado;
|
|
}
|
|
|
|
Gerenciador.capitalInicialDia = Gerenciador.capitalFechado;
|
|
Gerenciador.capitalAberto = 0.0;
|
|
Gerenciador.lucroBrutoAberto = 0.0;
|
|
Gerenciador.lucroBrutoFechado = 0.0;
|
|
Gerenciador.lucroBrutoComposto = 0.0;
|
|
Gerenciador.lucroLiquidoAcumulado = Gerenciador.lucroLiquidoAcumulado + Gerenciador.lucroLiquido;
|
|
Gerenciador.lucroLiquido = 0.0;
|
|
Gerenciador.alvoFinanceiro = Gerenciador.capitalInicialDia * Gerenciador.alvoPercentual;
|
|
Gerenciador.stopFinanceiro = Gerenciador.capitalInicialDia * Gerenciador.stopPercentual;
|
|
Operacao.countSaldo = 1;
|
|
Operacao.countFechaDia = 0;
|
|
Operacao.numeroContratosAcumulado = Operacao.numeroContratosAcumulado + (Operacao.numeroContratos - (2*Fluidos.niveis*Fluidos.rajada));
|
|
Operacao.numeroContratos = 0;
|
|
|
|
//ZERA OS SLOTS DE COMPRA E VENDA
|
|
for(int i=0;i<Fluidos.niveis;i++)
|
|
{
|
|
SlotsC[i].statusCambio = 0;
|
|
SlotsC[i].statusMotor = 0;
|
|
SlotsV[i].statusCambio = 0;
|
|
SlotsV[i].statusMotor = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Gerenciador.lucroBrutoAberto = AccountInfoDouble(ACCOUNT_EQUITY) - AccountInfoDouble(ACCOUNT_BALANCE);
|
|
Gerenciador.lucroBrutoFechado = AccountInfoDouble(ACCOUNT_BALANCE) - Gerenciador.capitalInicialDia - (Gerenciador.capitalTotal - Gerenciador.capitalInvestido);
|
|
Gerenciador.lucroBrutoComposto = Gerenciador.lucroBrutoAberto + Gerenciador.lucroBrutoFechado;
|
|
Gerenciador.lucroLiquido = Gerenciador.lucroBrutoComposto - ((Operacao.numeroContratos - (2*Fluidos.rajada*Fluidos.niveis)) * (Fluidos.c *2));
|
|
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*200));
|
|
Fluidos.Q = Fluidos.rajada * Fluidos.niveis;
|
|
ArrayResize(SlotsC, Fluidos.niveis);
|
|
ArrayResize(SlotsV, Fluidos.niveis);
|
|
}
|
|
|
|
//Atualiza o horario
|
|
TimeToStruct(TimeCurrent(), Operacao.horarioMQL_atual);
|
|
|
|
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, 1, Fluidos.MA);
|
|
Fluidos.media = Fluidos.MA[0];
|
|
Fluidos.q = AtualizaQuantidade(Operacao, Fluidos);
|
|
Fluidos.td = Operacao.horarioMQL_atual.hour*60 + Operacao.horarioMQL_atual.min;
|
|
|
|
for(int i=0; i<Fluidos.niveis ;i++)
|
|
{
|
|
SlotsC[i].ponta = 0;
|
|
SlotsV[i].ponta = 2;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
//+===================================================================================================================================================================================+
|
|
//| FIM DO PROGRAMA
|
|
//+===================================================================================================================================================================================+ |