247 lines
No EOL
22 KiB
MQL5
247 lines
No EOL
22 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| S4_Cambio4x4_v0.mq5 |
|
|
//| DESENVOLVIMENTO |
|
|
//| 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 "DEV_v0"
|
|
#property description "HFT MARKET MAKING BASED ON OXFORD'S STUDIES. MINI INDICE."
|
|
//INDICE
|
|
|
|
//+===================================================================================================================================================================================+
|
|
//| 1 - SESSAO DE CABECALHO / ADMISSAO
|
|
//+===================================================================================================================================================================================+
|
|
//+------------------------------------------------------------------+
|
|
//| 1.1 - IMPORTACOES |
|
|
//+------------------------------------------------------------------+
|
|
#include <Trade/SymbolInfo.mqh>
|
|
#include "MarketBook.mqh"
|
|
#include "S1_Admissao1_v0.mqh"
|
|
#include "S5_Direcao1_v0.mqh"
|
|
|
|
//status 0 (backlog) -> status 1 (pendente)
|
|
|
|
//status 1 (pendente & sem alteração) -> status 1 (pendente & sem alteração)
|
|
//status 1 (pendente & sem alteração) -> status 2 (pendente & precisa de alteração)
|
|
//status 1 (pendente & sem alteração) -> status 3 (filled & sem alteração)
|
|
//********status 1 (pendente) -> status 5 (cancelada/reset)********
|
|
|
|
//status 2 (pendente & precisa de alteração) -> status 1 (pendente & sem alteração)
|
|
//status 2 (pendente & precisa de alteração) -> status 3 (filled & sem alteração)
|
|
|
|
//status 3 (filled) -> status 3 (atualiza valores de stop e alvo novos)
|
|
|
|
//status 4 (filled & não precisa de alteração) -> status 4 (filled & não precisa de alteração)
|
|
//status 4 (filled & não precisa de alteração) -> status 5 (filled & precisa de alteração)
|
|
//status 4 (filled & não precisa de alteração) -> status 6 (vencido)
|
|
|
|
//status 5 (filled & precisa de alteração) -> status 5 (filled & precisa de alteração)
|
|
|
|
//status 6 (vencido) -> status 0 (backlog)
|
|
|
|
|
|
|
|
//+===================================================================================================================================================================================+
|
|
//| 4 - SESSAO DE QUANTIDADES / CAMBIO
|
|
//+===================================================================================================================================================================================+
|
|
//+------------------------------------------------------------------+
|
|
//| 4.1 - FUNCAO QUE GERENCIA OS STATUS DOS SLOTS |
|
|
//+------------------------------------------------------------------+
|
|
void GerenciaSlots(MqlBookInfo &ArrayBook[], fluido &Fluidos, slot &SlotsC[], slot &SlotsV[], MqlDateTime &horarioMQL_atual)
|
|
{
|
|
//Varre os slots
|
|
for(int i=0; i<ArraySize(SlotsC); i++)
|
|
{
|
|
Fluidos.iSlot = i;
|
|
//Troca status dos slots de compra
|
|
TrocaStatus(ArrayBook, Fluidos, SlotsC, horarioMQL_atual);
|
|
//Troca status dos slots de venda
|
|
TrocaStatus(ArrayBook, Fluidos, SlotsV, horarioMQL_atual);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 4.2 - FUNCAO QUE CALCULA A QUANTIDADE A SER ENVIADA |
|
|
//+------------------------------------------------------------------+
|
|
int VerificaQuantidade(fluido &Fluidos, slot &Slots[])
|
|
{
|
|
int retorno = 0;
|
|
|
|
CalculaQuantidade(Fluidos, Slots);
|
|
|
|
return retorno;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 4.3 - FUNCAO QUE CALCULA A QUANTIDADE MAXIMA NAQUELE PRECO |
|
|
//+------------------------------------------------------------------+
|
|
int CalculaQuantidade(fluido &Fluidos, slot &Slots[])
|
|
{
|
|
int config = 1;
|
|
|
|
config = 1;
|
|
|
|
if(config == 1)
|
|
{
|
|
Slots[Fluidos.iSlot].qtd = Fluidos.rajada;
|
|
}
|
|
|
|
return config;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 4.4 - FUNCAO QUE TROCA STATUS DOS SLOTS |
|
|
//+------------------------------------------------------------------+
|
|
void TrocaStatus(MqlBookInfo &ArrayBook[], fluido &Fluidos, slot &Slots[], MqlDateTime &horarioMQL_atual)
|
|
{
|
|
|
|
switch(Slots[Fluidos.iSlot].status)
|
|
{
|
|
//Preencha os precos e qtd para enviar uma ordem (Backlog) - Vermelho
|
|
case 0 :
|
|
CalculaPreco(ArrayBook, Fluidos, Slots);
|
|
VerificaQuantidade(Fluidos, Slots);
|
|
Slots[Fluidos.iSlot].status = 1;
|
|
// Print("Transicao 0->1. Slot: ", Fluidos.iSlot, "Ponta: ", Slots[Fluidos.iSlot].ponta);
|
|
break;
|
|
|
|
//Slot enviado e nao precisa de alteracao (Estável) - Amarelo
|
|
case 1 :
|
|
//Seleciona uma ordem
|
|
OrderSelect(Slots[Fluidos.iSlot].idOrdem);
|
|
|
|
//Verifica se e uma ordem do robo e se esta pendente
|
|
if(OrderGetInteger(ORDER_STATE) == ORDER_STATE_PLACED)
|
|
{
|
|
//Armazena o estado da ordem no slot correspondente
|
|
Slots[Fluidos.iSlot].state = OrderGetInteger(ORDER_STATE);
|
|
// Print("entrou no case 1 placed");
|
|
//Verifica se houve alteracao estatistica (media, desvio) e manda para o status 2
|
|
if((Fluidos.driftLFTTend > 2000) || (Fluidos.driftLFTTend < -2000) || (Fluidos.driftLFTVol > 2000) || (Fluidos.driftLFTVol < -2000))
|
|
{
|
|
CalculaPreco(ArrayBook, Fluidos, Slots);
|
|
VerificaQuantidade(Fluidos, Slots);
|
|
Slots[Fluidos.iSlot].status = 2;
|
|
// Print("Transicao 1->2. Slot: ", Fluidos.iSlot, "Ponta: ", Slots[Fluidos.iSlot].ponta);
|
|
}//verifica se a ordem deveria expirar
|
|
else if(CalculaExpiraOrdem(horarioMQL_atual, Slots, Fluidos) == true)
|
|
{
|
|
//Expira ordem e libera o slot
|
|
Slots[Fluidos.iSlot].status = 4;
|
|
}
|
|
else //senao mantem no status atual
|
|
{
|
|
Slots[Fluidos.iSlot].status = 1;
|
|
}
|
|
}
|
|
//Verifica se e uma ordem do robo e se esta executada
|
|
else
|
|
{
|
|
OrderSelect(Slots[Fluidos.iSlot].idOrdem);
|
|
Slots[Fluidos.iSlot].state = OrderGetInteger(ORDER_STATE);
|
|
//Se acabou de ser executada, mande para o status 3
|
|
if(Slots[Fluidos.iSlot].state != ORDER_STATE_FILLED)
|
|
{
|
|
Slots[Fluidos.iSlot].state = ORDER_STATE_FILLED;
|
|
Slots[Fluidos.iSlot].idPosicao = OrderGetInteger(ORDER_POSITION_ID);
|
|
Slots[Fluidos.iSlot].status = 3;
|
|
// Print("Transicao 1->3. Slot: ", Fluidos.iSlot, "Ponta: ", Slots[Fluidos.iSlot].ponta);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
//Slot enviado e precisa de alteracao (Pendente alterar) - Amarelo
|
|
case 2 :
|
|
//Seleciona uma ordem
|
|
OrderSelect(Slots[Fluidos.iSlot].idOrdem);
|
|
|
|
//Verifica se e uma ordem do robo e se esta executada
|
|
if(OrderGetInteger(ORDER_STATE) == ORDER_STATE_PLACED)
|
|
{
|
|
//Armazena o estado da ordem no slot correspondente
|
|
Slots[Fluidos.iSlot].state = OrderGetInteger(ORDER_STATE);
|
|
|
|
//Verifica se ainda precisa de alteracao
|
|
if((Fluidos.driftLFTTend > 2000) || (Fluidos.driftLFTTend < -2000) || (Fluidos.driftLFTVol > 2000) || (Fluidos.driftLFTVol < -2000))
|
|
{
|
|
CalculaPreco(ArrayBook, Fluidos, Slots);
|
|
VerificaQuantidade(Fluidos, Slots);
|
|
Slots[Fluidos.iSlot].status = 2;
|
|
// Print("Transicao 2->2. Slot: ", Fluidos.iSlot, "Ponta: ", Slots[Fluidos.iSlot].ponta);
|
|
}
|
|
else if(CalculaExpiraOrdem(horarioMQL_atual, Slots, Fluidos) == true)
|
|
{
|
|
//Expira ordem e libera o slot
|
|
Slots[Fluidos.iSlot].status = 4;
|
|
}
|
|
else //senao mantem no status atual
|
|
{
|
|
Slots[Fluidos.iSlot].status = 1;
|
|
// Print("Transicao 2->1. Slot: ", Fluidos.iSlot, "Ponta: ", Slots[Fluidos.iSlot].ponta);
|
|
}
|
|
}
|
|
//Verifica se e uma ordem do robo e se esta executada
|
|
else if((HistoryOrderGetInteger(Slots[Fluidos.iSlot].idOrdem, ORDER_MAGIC) == Fluidos.magic) && (HistoryOrderSelect(Slots[Fluidos.iSlot].idOrdem) == true))
|
|
{
|
|
//Se acabou de ser executada, mande para o status 3
|
|
if(Slots[Fluidos.iSlot].state != ORDER_STATE_FILLED)
|
|
{
|
|
Slots[Fluidos.iSlot].state = ORDER_STATE_FILLED;
|
|
Slots[Fluidos.iSlot].idPosicao = OrderGetInteger(ORDER_POSITION_ID);
|
|
Slots[Fluidos.iSlot].status = 3;
|
|
// Print("Transicao 2->3. Slot: ", Fluidos.iSlot, "Ponta: ", Slots[Fluidos.iSlot].ponta);
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
//Slot executado - Verde
|
|
case 3 :
|
|
Slots[Fluidos.iSlot].status = 0;
|
|
// Print("Transicao 3->0. Slot: ", Fluidos.iSlot, "Ponta: ", Slots[Fluidos.iSlot].ponta);
|
|
|
|
break;
|
|
|
|
//Slot pendente a muito tempo - Laranja
|
|
case 4 :
|
|
Slots[Fluidos.iSlot].status = 0;
|
|
break;
|
|
} //Termino do switch
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 4.5 - FUNCAO QUE CALCULA TEMPO DE EXPIRACAO DE SLOTS |
|
|
//+------------------------------------------------------------------+
|
|
bool CalculaExpiraOrdem(MqlDateTime &horarioMQL_atual, slot &Slots[], fluido &Fluidos)
|
|
{
|
|
//Captura o horario atual e coloca em Struct MqlDateTime
|
|
TimeToStruct(TimeCurrent(), horarioMQL_atual);
|
|
|
|
ushort horarioOrdem = 0;
|
|
horarioOrdem = Slots[Fluidos.iSlot].cronometro.hour*60 + Slots[Fluidos.iSlot].cronometro.min;
|
|
|
|
ushort horarioShortAtual = 0;
|
|
horarioShortAtual = horarioMQL_atual.hour*60 + horarioMQL_atual.min;
|
|
|
|
//Verifica se esta dentro da sessao de trade do dia
|
|
if((horarioShortAtual - horarioOrdem) > Fluidos.lifetime)
|
|
{
|
|
return true;
|
|
}
|
|
else return false;
|
|
}
|
|
|
|
|
|
//+===================================================================================================================================================================================+
|
|
//| FIM DO PROGRAMA
|
|
//+===================================================================================================================================================================================+ |