SuperCharlie_Oxford/Desenvolvimento_v0/S2_Motor1_v0.mq5
super.admin 513958a1f2 convert
2025-05-30 16:27:23 +02:00

446 lines
No EOL
39 KiB
MQL5

//+------------------------------------------------------------------+
//| S2_Motor1_v0.mq5 |
//| DESENVOLVIMENTO |
//| 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 "DEV_v0"
#property description "HFT MARKET MAKING BASED ON OXFORD'S STUDIES. MINI INDICE."
//INDICE
//+===================================================================================================================================================================================+
//| 1 - SESSAO DE CABECALHO / ADMISSAO
//+===================================================================================================================================================================================+
//+------------------------------------------------------------------+
//| 1.1 - IMPORTACOES |
//+------------------------------------------------------------------+
#include <Expert/Expert.mqh>
#include <Trade/Trade.mqh>
#include <Trade/SymbolInfo.mqh>
#include "MarketBook.mqh"
#include "S1_Admissao1_v0.mqh"
#include "S3_Freios1_v0.mqh"
#include "S4_Cambio4x4_v0.mqh"
#include "S5_Direcao1_v0.mqh"
#include "S6_Transmissao1_v0.mqh"
//+------------------------------------------------------------------+
//| 1.2 - ENTRADAS DE USUARIO |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| 1.2.1 - INPUTS DE GERENCIAMENTO DE INVENTARIO |
//+------------------------------------------------------------------+
input group "Gerenciamento de Inventário--------------------------------------------------------------------------------------------------"
input int inventario = 10; //Inventario máximo Q {1}[1, +inf[
input int rajada = 10; //Quantidade por ordem η {1}[1, +inf[
input double fi = 0.0002; //Fi: Running Penalty (injeção eletrônica)
input int lifetime = 10; //Tempo em minutos da duracao de uma ordem pendente
//+------------------------------------------------------------------+
//| 1.2.2 - INPUTS DE GERENCIAMENTO DE OPERACOES |
//+------------------------------------------------------------------+
input group "Gerenciamento de Operacões---------------------------------------------------------------------------------------------------"
input ushort horarioShort_inicial = 545; //Horário inicial 09:05 -> Τ0 em minutos {600}[600, 985]
input ushort horarioShort_final = 980; //Horário final 16:20 -> ΤF em minutos {700}[600, 985]
input ushort horarioShort_fechamento = 985; //Horário limite de after 16:25 -> ΤP em minutos {705}[600, 990]
input ulong T = 180; //Quantidade maxima de tempo para encerramento do trade
input int profundidadeBook = 10; //Profundidade do book a calcular o k {3}[1, +inf[
input double alpha = 0.0001; //Custo por zerar posição
input double premioOperacao = 10; //Premio por trade liquido ρ {0.64}[0.0, 1.0[
input double custoOperacao = 2.1; //Custo por operacao ζ {1.86}[0.0, 2.0[
input double tickMin = 5; //Tick minimo do ativo Δ {0.5}[0.01, +inf[
input bool chaveBook = false; //Chave que liga/desliga o book para usar na real ou backtest {false} [true=ligado,false=desligado]
input double desvioDiario = 8; //Desvios padroes limite para o preco do ativo no dia
input double lambdaC = 10; //Lambda de compra
input double lambdaV = 10; //Lambda de venda
input double KC = 100; //Fila media de compra
input double KV = 100; //Fila media de venda
//+------------------------------------------------------------------+
//| 1.2.3 - INPUTS DE GERENCIAMENTO DE RISCOS |
//+------------------------------------------------------------------+
input group "Gerenciamento de Riscos------------------------------------------------------------------------------------------------------"
input double alvoFinanceiro = 1000.0; //3º Order Risk M.: Alvo financeiro no dia sup(Χ)
input double stopFinanceiro = -1000.0; //3º Order Risk M.: Stop financeiro no dia inf(Χ)
//+------------------------------------------------------------------+
//| 1.3 - VARIAVEIS GLOBAIS |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| 1.3.1 - VARIAVEIS FINANCEIRAS |
//+------------------------------------------------------------------+
double saldoInicialDia = 0.0;
double saldoFinalDia = 0.0;
double diferencaSaldo = 0.0;
//+------------------------------------------------------------------+
//| 1.3.4 - VARIAVEIS OPERACIONAIS |
//+------------------------------------------------------------------+
int magic = 11111;
MqlDateTime horarioMQL_inicio,
horarioMQL_final,
horarioMQL_encerramento,
horarioMQL_atual,
horarioMQL_comprado,
horarioMQL_compra;
ushort horarioShort_atual;
datetime horarioDatetime_atual;
int diaAtual = 0;
CSymbolInfo simbolo;
CMarketBook Book(_Symbol);
CTrade negocio;
MqlTradeRequest request;
MqlTradeResult result;
MqlTradeTransaction transaction;
MqlTradeCheckResult check_result;
MqlBookInfo ArrayBook[];
MqlTick ArrayTick[];
double MA[];
double STDDEV[];
int handlerMA;
int handlerSTDDEV;
int periodoMA = 2;
int periodoSTDDEV = 2;
string handlerNormalizeDoubleSize;
int normalizeDoubleSize;
int intervaloTicks = 10;
double limiteInfDesvio = 0;
double limiteSupDesvio = 500;
fluido Fluidos;
slot SlotsC[];
slot SlotsV[];
bool chaveFechaPosicao = true;
//+===================================================================================================================================================================================+
//| 2 - SESSAO DE LOGICA CENTRAL / MOTOR
//+===================================================================================================================================================================================+
//+------------------------------------------------------------------+
//| 2.1 - FUNCAO DE INICIALIZACAO |
//+------------------------------------------------------------------+
int OnInit()
{
Print("DESENVOLVIMENTO V0");
//Inicializa o saldo da conta
saldoInicialDia = AccountInfoDouble(ACCOUNT_BALANCE);
//Inicializa a contagem de dias
TimeToStruct(TimeCurrent(), horarioMQL_atual);
diaAtual = horarioMQL_atual.day;
//Inicializa o MarketBook
if(chaveBook == true) if(!MarketBookAdd(_Symbol)) Print("Falha para inicializar o book");
ArrayResize(ArrayTick, intervaloTicks, intervaloTicks);
//Inicializa o ArrayTick
if(CopyTicks(_Symbol,ArrayTick,COPY_TICKS_ALL,0,intervaloTicks) != -1)
{
ArraySetAsSeries(ArrayTick,true);
}
else Print("Falha para inicializar o ArrayTicks: ", GetLastError());
//NormalizeDouble
handlerNormalizeDoubleSize = DoubleToString(tickMin);
handlerNormalizeDoubleSize = StringReplace(handlerNormalizeDoubleSize,".","");
normalizeDoubleSize = (StringLen(handlerNormalizeDoubleSize))-1;
//Ajusta o tamanho dos arrays de slots de compra e venda
ArrayResize(SlotsC, inventario);
ArrayResize(SlotsV, inventario);
//inicializa os slots de compra e venda
for(int i=0; i<inventario ;i++)
{
SlotsC[i].status = 0;
SlotsV[i].status = 0;
SlotsC[i].ponta = 0;
SlotsV[i].ponta = 2;
}
//Cria os buffers dos indicadores de media e desvio padrao
handlerMA = iMA(_Symbol, PERIOD_M5, periodoMA, 0, MODE_EMA, PRICE_MEDIAN);
handlerSTDDEV = iStdDev(_Symbol, PERIOD_M5, periodoSTDDEV, 0, MODE_EMA, PRICE_MEDIAN);
ArraySetAsSeries(MA, true);
ArraySetAsSeries(STDDEV, true);
CopyBuffer(handlerMA,0,1,2,MA);
CopyBuffer(handlerSTDDEV,0,1,2,STDDEV);
Fluidos.media = MA[0];
Fluidos.sigmaHFT = STDDEV[0];
Fluidos.driftLFTTend = MA[0] - MA[1];
Fluidos.driftLFTVol = STDDEV[0] - STDDEV[1];
Fluidos.fi = fi;
Fluidos.alpha = alpha;
Fluidos.q = 0;
Fluidos.Q = inventario;
Fluidos.rajada = rajada;
Fluidos.t = 0;
Fluidos.T = T;
Fluidos.nBook = profundidadeBook;
Fluidos.iSlot = 0;
Fluidos.magic = magic;
Fluidos.tickMin = tickMin;
Fluidos.chaveBook = chaveBook;
Fluidos.desvioDiario = desvioDiario;
Fluidos.lambdaC = lambdaC;
Fluidos.lambdaV = lambdaV;
Fluidos.KC = KC;
Fluidos.KV = KV;
Fluidos.lifetime = lifetime;
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 2.2 - FUNCAO EVENTO TICK / CORACAO |
//+------------------------------------------------------------------+
void OnTick()
{
//Atualiza os ticks e variaveis
AtualizaVariaveis();
Fluidos.precoAbertura = iOpen(_Symbol,PERIOD_D1,0);
//Chamar o motor
if(VerificaHorarioOrdens(horarioMQL_atual, horarioShort_inicial, horarioShort_final)) FazTrades();
else if(VerificaHorarioFechamento(horarioMQL_atual, horarioShort_fechamento))
{
if(chaveFechaPosicao == true) chaveFechaPosicao = FechaPosicao(negocio);
CancelaOrdensAbertas(negocio);
ArrayFree(SlotsC);
ArrayFree(SlotsV);
ArrayResize(SlotsC, inventario);
ArrayResize(SlotsV, inventario);
for(int i=0;i<ArraySize(SlotsC);i++)
{
SlotsC[i].status = 0;
SlotsV[i].status = 0;
}
}
else return;
return;
}
//+------------------------------------------------------------------+
//| 2.3 - FUNCAO EVENTO BOOK |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
{
if(Fluidos.chaveBook == true)
{
//Atualiza os melhores indices de bid e ask do book
if(MarketBookGet(_Symbol, ArrayBook))
{
Fluidos.iBid0 = Book.InfoGetInteger(MBOOK_BEST_BID_INDEX);
Fluidos.iAsk0 = Book.InfoGetInteger(MBOOK_BEST_ASK_INDEX);
}
else
{
Print("Falha ao obter o Book");
}
}
return;
}
//+------------------------------------------------------------------+
//| 2.4 - FUNCAO EVENTO TRADE |
//+------------------------------------------------------------------+
void OnTrade()
{
}
//+------------------------------------------------------------------+
//| 2.5 - FUNCAO DE DESLIGAMENTO |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//Da release nos indicadores
IndicatorRelease(handlerMA);
IndicatorRelease(handlerSTDDEV);
Print("OUTPUT PATH=",TerminalInfoString(TERMINAL_DATA_PATH));
//Falha na desinicializacao
printf("Deinit reason: %d", reason);
}
//+------------------------------------------------------------------+
//| 2.6 - FUNCAO QUE ATUALIZA AS VARIAVEIS IMPORTANTES |
//+------------------------------------------------------------------+
void AtualizaVariaveis()
{
//Atualiza o horario
TimeToStruct(TimeCurrent(), horarioMQL_atual);
//Atualiza o book
if(!simbolo.RefreshRates()) return;
if(Fluidos.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, intervaloTicks, 0);
//Atualiza os ticks
if(CopyTicks(Symbol(),ArrayTick,COPY_TICKS_ALL,0,intervaloTicks) != -1) ArraySetAsSeries(ArrayTick,true);
else Print("Falha para inicializar o ArrayTicks: ", GetLastError());
//Atualiza os buffers de media e desvio padrao
CopyBuffer(handlerMA,0,1,2,MA);
CopyBuffer(handlerSTDDEV,0,1,2,STDDEV);
Fluidos.media = (simbolo.Ask() + simbolo.Bid())/2;
Fluidos.sigmaHFT = STDDEV[0];
Fluidos.driftLFTTend = MA[0] - MA[1];
Fluidos.driftLFTVol = STDDEV[0] - STDDEV[1];
Fluidos.q = AtualizaQuantidade(Fluidos);
for(int i=0; i<inventario ;i++)
{
SlotsC[i].ponta = 0;
SlotsV[i].ponta = 2;
}
return;
}
//+------------------------------------------------------------------+
//| 2.7 - FUNCAO QUE FAZ NEGOCIACOES |
//+------------------------------------------------------------------+
void FazTrades()
{
chaveFechaPosicao = true;
//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(alvoFinanceiro, stopFinanceiro, diferencaSaldo, saldoInicialDia, saldoFinalDia, diaAtual, horarioMQL_atual, intervaloTicks, ArrayTick, Fluidos, simbolo) == false)
{
//Avanca os status dos slots
GerenciaSlots(ArrayBook, Fluidos, SlotsC, SlotsV, horarioMQL_atual);
//Verifica os Riscos de Nivel 2 para Compra
if(VerificaRiscosNivel2C(Fluidos) == false)
{
//Verifica os slots de compra, se estiverem disponiveis, mande ordens
DisparaSlotsCompra();
}
if(VerificaRiscosNivel2V(Fluidos) == false)
{
//Verifica os slots de venda, se estiverem disponiveis, mande ordens
DisparaSlotsVenda();
}
}
else
{
FechaPosicao(negocio);
CancelaOrdensAbertas(negocio);
}
return;
}
//+------------------------------------------------------------------+
//| 2.8 - FUNCAO QUE VARRE SLOTS DE COMPRA E ENVIA ORDENS |
//+------------------------------------------------------------------+
void DisparaSlotsCompra()
{
for(int i=0; i<ArraySize(SlotsC); i++)
{
//Para cada possibilidade de status
switch(SlotsC[i].status)
{
//Preenche ordens de slots ready
case 1 :
//Print("Preco envio: ",SlotsC[i].precoEnvio," Preco last: ", ArrayTick[0].last);
//Verifica se o preco de envio e menor que o preco atual (manda um novo box de ordem)
if(SlotsC[i].precoEnvio <= ArrayTick[0].last)
{
CompraLimite(SlotsC[i].precoEnvio, SlotsC[i].precoStop, SlotsC[i].qtd, magic, SlotsC, i, simbolo, request, result, check_result);
if(result.retcode == 10009)
{
//Avanca o status do slot para enviado
SlotsC[i].idOrdem = result.order;
OrderSelect(SlotsC[i].idOrdem);
TimeToStruct(OrderGetInteger(ORDER_TIME_SETUP),SlotsC[i].cronometro);
}
else
{
SlotsC[i].status = 0;
}
}
break;
//Altera ordem enviada com precoEnvio, precoStop ou precoAlvo novos (atualiza o box de ordem)
case 2 :
ModificaOrdemEnviada(SlotsC[i].idOrdem, SlotsC[i].precoEnvio, 0, SlotsC[i].precoStop, magic, negocio, simbolo, request, result, check_result);
break;
case 4 :
CancelaOrdemAberta(SlotsC[i].idOrdem, negocio);
break;
//Default
default :
break;
}
}
}
//+------------------------------------------------------------------+
//| 2.9 - FUNCAO QUE VARRE SLOTS DE VENDA E ENVIA ORDENS |
//+------------------------------------------------------------------+
void DisparaSlotsVenda()
{
for(int i=0; i<ArraySize(SlotsV); i++)
{
//Para cada possibilidade de status
switch(SlotsV[i].status)
{
//Preenche ordens de slots ready
case 1 :
//Verifica se o preco de envio e maior que o preco atual (manda um novo box de ordem)
if(SlotsV[i].precoEnvio >= ArrayTick[0].last)
{
VendaLimite(SlotsV[i].precoEnvio, SlotsV[i].precoStop, SlotsV[i].qtd, magic, SlotsV, i, simbolo, request, result, check_result);
if(result.retcode == 10009)
{
//Avanca o status do slot para enviado
SlotsV[i].idOrdem = result.order;
OrderSelect(SlotsV[i].idOrdem);
TimeToStruct(OrderGetInteger(ORDER_TIME_SETUP),SlotsV[i].cronometro);
}
else
{
SlotsV[i].status = 0;
}
}
break;
//Altera ordem enviada com precoEnvio, precoStop ou precoAlvo novos (atualiza o box de ordem)
case 2 :
ModificaOrdemEnviada(SlotsV[i].idOrdem, SlotsV[i].precoEnvio, 0, SlotsV[i].precoStop, magic, negocio, simbolo, request, result, check_result);
break;
case 4 :
CancelaOrdemAberta(SlotsV[i].idOrdem, negocio);
break;
//Default
default :
break;
}
}
}
//+===================================================================================================================================================================================+
//| FIM DO PROGRAMA
//+===================================================================================================================================================================================+