SuperCharlie_Oxford/Producao_v4_1/S5_Direcao1_v4_1.mqh
super.admin 513958a1f2 convert
2025-05-30 16:27:23 +02:00

373 lines
No EOL
35 KiB
MQL5

//+------------------------------------------------------------------+
//| S5_Direcao1_v4_1.mq5 |
//| PRODUCAO |
//| 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 "PROD_v1"
#property description "HFT MARKET MAKING BASED ON OXFORD'S STUDIES. MINI INDICE."
//INDICE
//+===================================================================================================================================================================================+
//| 0 - SESSAO DE CABECALHO / ADMISSAO
//+===================================================================================================================================================================================+
//+------------------------------------------------------------------+
//| 0.1 - IMPORTACOES |
//+------------------------------------------------------------------+
#include "MarketBook.mqh"
#include "S0_Admissao1_v4_1.mqh"
//SLOTS_i,q = -Φ*k*q^2 , i=q
//SLOTS_i,q = λc/e , i=q-1
//SLOTS_i,q = λv/e , i=q+1
//SLOTS_i,q = 0 , default
//+===================================================================================================================================================================================+
//| 5 - SESSAO DE PRECOS / DIRECAO
//+===================================================================================================================================================================================+
//+------------------------------------------------------------------+
//| 5.1 - FUNCAO QUE VERIFICA O PRECO NAQUELE INSTANTE |
//+------------------------------------------------------------------+
int CalculaPrecoOrdem(operacao &Operacao, fluido &Fluidos, slot &Slots[], MqlTick &ArrayTick[], MqlBookInfo &ArrayBook[])
{
//Calcula os spreads
if(Slots[0].ponta == 0)
{
Fluidos.precoMedioC = CalculaSpreadOrdemC(Operacao, Fluidos, Slots, ArrayTick, ArrayBook);
}
else Fluidos.precoMedioV = CalculaSpreadOrdemV(Operacao, Fluidos, Slots, ArrayTick, ArrayBook);
return 0;
}
//+------------------------------------------------------------------+
//| 5.1 - FUNCAO QUE VERIFICA O PRECO NAQUELE INSTANTE |
//+------------------------------------------------------------------+
int CalculaPrecoPosicao(operacao &Operacao, fluido &Fluidos, slot &Slots[], MqlTick &ArrayTick[], MqlBookInfo &ArrayBook[])
{
//Calcula os spreads
if(Slots[0].ponta == 0)
{
Fluidos.precoMedioC = CalculaSpreadPosicaoC(Operacao, Fluidos, Slots, ArrayTick, ArrayBook);
}
else Fluidos.precoMedioV = CalculaSpreadPosicaoV(Operacao, Fluidos, Slots, ArrayTick, ArrayBook);
return 0;
}
//+------------------------------------------------------------------+
//| 5.2 - FUNCAO QUE CALCULA SPREAD BUY |
//+------------------------------------------------------------------+
double CalculaSpreadOrdemC(operacao &Operacao, fluido &Fluidos, slot &SlotsC[], MqlTick &ArrayTick[], MqlBookInfo &ArrayBook[])
{
double spreadB = 0.0;
if(Operacao.chaveBook == true) Fluidos.KC = CalculaKC(Fluidos, ArrayBook);
if(Operacao.chaveLambda == true) Fluidos.lambdaC = CalculaLambdaCompra(ArrayTick, Fluidos.T);
TimeToStruct(TimeCurrent(), Operacao.horarioMQL_atual);
//Converte o horario atual Struct em ushort
int atual = Operacao.horarioMQL_atual.hour * 60 + Operacao.horarioMQL_atual.min;
double HC_q = CalculaHC(Fluidos, Fluidos.q);
double HC_qmais1 = CalculaHC(Fluidos, Fluidos.q+1);
double diferenca = HC_q - HC_qmais1;
if(diferenca < 0) diferenca = 0.0;
double spreadCompra = MathRound(100*Fluidos.tickMin*((Fluidos.lambdaV/Fluidos.KC) + diferenca) / Fluidos.tickMin) * Fluidos.tickMin;
double spreadStop = MathRound(Fluidos.sigmaHFT / Fluidos.tickMin) * Fluidos.tickMin * 5;
double desvio = MathRound(Fluidos.sigmaHFT / Fluidos.tickMin) * Fluidos.tickMin;
double nivel = MathRound(log(Fluidos.iSlot+1) * 100 / Fluidos.tickMin) / 100 * Fluidos.tickMin;
double spreadTotal = Fluidos.tickMin/2 + MathRound((spreadCompra + desvio * nivel)/Fluidos.tickMin)*Fluidos.tickMin;
SlotsC[Fluidos.iSlot].precoEnvio = Fluidos.midPrice - spreadTotal;
if(MathMod(SlotsC[Fluidos.iSlot].precoEnvio, Fluidos.tickMin) != 0)
{
SlotsC[Fluidos.iSlot].precoEnvio = SlotsC[Fluidos.iSlot].precoEnvio - MathMod(SlotsC[Fluidos.iSlot].precoEnvio, Fluidos.tickMin);
}
SlotsC[Fluidos.iSlot].precoAlvo = SlotsC[Fluidos.iSlot].precoEnvio + Fluidos.tickMin*2 + spreadCompra;
if(MathMod(SlotsC[Fluidos.iSlot].precoAlvo, Fluidos.tickMin) != 0)
{
SlotsC[Fluidos.iSlot].precoAlvo = SlotsC[Fluidos.iSlot].precoAlvo - MathMod(SlotsC[Fluidos.iSlot].precoAlvo, Fluidos.tickMin);
}
SlotsC[Fluidos.iSlot].precoStop = SlotsC[Fluidos.iSlot].precoEnvio - spreadStop;
if(MathMod(SlotsC[Fluidos.iSlot].precoStop, Fluidos.tickMin) != 0)
{
SlotsC[Fluidos.iSlot].precoStop = SlotsC[Fluidos.iSlot].precoStop - MathMod(SlotsC[Fluidos.iSlot].precoStop, Fluidos.tickMin);
}
// Print("HC_q: ", HC_q, " HC_qmais1: ", HC_qmais1, " diferenca: ", diferenca);
// Print("PrecoEnvio: ", SlotsC[Fluidos.iSlot].precoEnvio, " PrecoAlvo: ", SlotsC[Fluidos.iSlot].precoAlvo, " PrecoStop: ", SlotsC[Fluidos.iSlot].precoStop);
return spreadB;
}
//+------------------------------------------------------------------+
//| 5.3 - FUNCAO QUE CALCULA SPREAD SELL |
//+------------------------------------------------------------------+
double CalculaSpreadOrdemV(operacao &Operacao, fluido &Fluidos, slot &SlotsV[], MqlTick &ArrayTick[], MqlBookInfo &ArrayBook[])
{
double spread = 0.0;
if(Operacao.chaveBook == true) Fluidos.KV = CalculaKV(Fluidos, ArrayBook);
if(Operacao.chaveLambda == true) Fluidos.lambdaV = CalculaLambdaVenda(ArrayTick, Fluidos.T);
TimeToStruct(TimeCurrent(), Operacao.horarioMQL_atual);
//Converte o horario atual Struct em ushort
int atual = Operacao.horarioMQL_atual.hour * 60 + Operacao.horarioMQL_atual.min;
double HV_q = CalculaHV(Fluidos, Fluidos.q);
double HV_qmenos1 = CalculaHV(Fluidos, Fluidos.q-1);
double diferenca = HV_q - HV_qmenos1;
if(diferenca < 0) diferenca = 0.0;
double spreadVenda = MathRound(100*Fluidos.tickMin*((Fluidos.lambdaC/Fluidos.KV) + diferenca) / Fluidos.tickMin) * Fluidos.tickMin;
double spreadStop = MathRound(Fluidos.sigmaHFT / Fluidos.tickMin) * Fluidos.tickMin * 5;
double desvio = MathRound(Fluidos.sigmaHFT / Fluidos.tickMin) * Fluidos.tickMin;
double nivel = MathRound(log(Fluidos.iSlot+1) * 100 / Fluidos.tickMin) / 100 * Fluidos.tickMin;
double spreadTotal = Fluidos.tickMin/2 + MathRound((spreadVenda + desvio * nivel) / Fluidos.tickMin) * Fluidos.tickMin;
SlotsV[Fluidos.iSlot].precoEnvio = Fluidos.midPrice + spreadTotal;
if(MathMod(SlotsV[Fluidos.iSlot].precoEnvio, Fluidos.tickMin) != 0)
{
SlotsV[Fluidos.iSlot].precoEnvio = SlotsV[Fluidos.iSlot].precoEnvio + (Fluidos.tickMin-MathMod(SlotsV[Fluidos.iSlot].precoEnvio, Fluidos.tickMin));
}
SlotsV[Fluidos.iSlot].precoAlvo = SlotsV[Fluidos.iSlot].precoEnvio - Fluidos.tickMin*2 - spreadVenda;
if(MathMod(SlotsV[Fluidos.iSlot].precoAlvo, Fluidos.tickMin) != 0)
{
SlotsV[Fluidos.iSlot].precoAlvo = SlotsV[Fluidos.iSlot].precoAlvo + (Fluidos.tickMin-MathMod(SlotsV[Fluidos.iSlot].precoAlvo, Fluidos.tickMin));
}
SlotsV[Fluidos.iSlot].precoStop = SlotsV[Fluidos.iSlot].precoEnvio + spreadStop;
if(MathMod(SlotsV[Fluidos.iSlot].precoStop, Fluidos.tickMin) != 0)
{
SlotsV[Fluidos.iSlot].precoStop = SlotsV[Fluidos.iSlot].precoStop + (Fluidos.tickMin-MathMod(SlotsV[Fluidos.iSlot].precoStop, Fluidos.tickMin));
}
// Print("HV_q: ", HV_q, " HV_qmenos1: ", HV_qmenos1, " diferenca: ", diferenca);
// Print("PrecoEnvio: ", SlotsV[Fluidos.iSlot].precoEnvio, " PrecoAlvo: ", SlotsV[Fluidos.iSlot].precoAlvo, " PrecoStop: ", SlotsV[Fluidos.iSlot].precoStop);
return spread;
}
//+------------------------------------------------------------------+
//| 5.2 - FUNCAO QUE CALCULA SPREAD BUY |
//+------------------------------------------------------------------+
double CalculaSpreadPosicaoC(operacao &Operacao, fluido &Fluidos, slot &SlotsC[], MqlTick &ArrayTick[], MqlBookInfo &ArrayBook[])
{
double spreadB = 0.0;
if(Operacao.chaveBook == true) Fluidos.KC = CalculaKC(Fluidos, ArrayBook);
if(Operacao.chaveLambda == true) Fluidos.lambdaC = CalculaLambdaCompra(ArrayTick, Fluidos.T);
//Fluidos.lambdaV = 1;
//Falta Calcular Fluidos.lambdaV
double spreadCompra = MathRound(100*Fluidos.tickMin*((Fluidos.lambdaV/Fluidos.KC) + CalculaHC(Fluidos, Fluidos.q) - CalculaHC(Fluidos, Fluidos.q+1)) / Fluidos.tickMin) * Fluidos.tickMin;
double spreadStop = MathRound(Fluidos.sigmaHFT / Fluidos.tickMin) * Fluidos.tickMin * 5;
double desvio = MathRound(Fluidos.sigmaHFT / Fluidos.tickMin) * Fluidos.tickMin;
double nivel = MathRound(log(Fluidos.iSlot+1) * 100 / Fluidos.tickMin) / 100 * Fluidos.tickMin;
// Print("Passo: ", passo);
SlotsC[Fluidos.iSlot].precoAlvo = Fluidos.midPrice + Fluidos.tickMin/2 + spreadCompra;
SlotsC[Fluidos.iSlot].precoStop = SlotsC[Fluidos.iSlot].precoEnvio - spreadStop;
return spreadB;
}
//+------------------------------------------------------------------+
//| 5.3 - FUNCAO QUE CALCULA SPREAD SELL |
//+------------------------------------------------------------------+
double CalculaSpreadPosicaoV(operacao &Operacao, fluido &Fluidos, slot &SlotsV[], MqlTick &ArrayTick[], MqlBookInfo &ArrayBook[])
{
double spread = 0.0;
if(Operacao.chaveBook == true) Fluidos.KV = CalculaKV(Fluidos, ArrayBook);
if(Operacao.chaveLambda == true) Fluidos.lambdaV = CalculaLambdaVenda(ArrayTick, Fluidos.T);
//Fluidos.lambdaC = 1;
//Falta Calcular Fluidos.lambdaC
double spreadVenda = MathRound(100*Fluidos.tickMin*((Fluidos.lambdaC/Fluidos.KV) + CalculaHV(Fluidos, Fluidos.q) - CalculaHV(Fluidos, Fluidos.q-1)) / Fluidos.tickMin) * Fluidos.tickMin;
double spreadStop = MathRound(Fluidos.sigmaHFT / Fluidos.tickMin) * Fluidos.tickMin * 5;
double passo = MathRound(Fluidos.sigmaHFT / Fluidos.tickMin) * Fluidos.tickMin;
double nivel = MathRound(log(Fluidos.iSlot+1) * 100 / Fluidos.tickMin) / 100 * Fluidos.tickMin;
SlotsV[Fluidos.iSlot].precoAlvo = Fluidos.midPrice - Fluidos.tickMin/2 - spreadVenda;
SlotsV[Fluidos.iSlot].precoStop = SlotsV[Fluidos.iSlot].precoEnvio + spreadStop;
return spread;
}
//+------------------------------------------------------------------+
//| 5.5 - FUNCAO QUE CALCULA A MEDIA DE PRECOS |
//+------------------------------------------------------------------+
void GetPrecosPassados(MqlTick &ArrayTick[], double &precos[], int T)
{
if(CopyTicks(Symbol(),ArrayTick,COPY_TICKS_TRADE,0,T) != -1)
{
ArraySetAsSeries(ArrayTick,true);
for(int i=0;i<ArraySize(ArrayTick);i++)
{
precos[i] = ArrayTick[i].last;
}
}
else
{
Print("Falha ao obter o ArrayTick, falha para GetPrecosPassados");
}
return;
}
//+------------------------------------------------------------------+
//| 5.7 - FUNCAO QUE CALCULA O LAMBDA COMPRA |
//+------------------------------------------------------------------+
int CalculaLambdaCompra(MqlTick &ArrayTick[], int T)
{
int lambda = 0;
double t = 0;
int segundosIntInicial = 0;
int segundosIntAtual = 0;
MqlDateTime horaMqlTickInicial;
MqlDateTime horaMqlTickAtual;
T = T * 5;
for(int i=0;i<ArraySize(ArrayTick);i++)
{
if(t<T)
{
TimeToStruct(ArrayTick[0].time, horaMqlTickInicial);
TimeToStruct(ArrayTick[i].time, horaMqlTickAtual);
segundosIntInicial = horaMqlTickInicial.hour*60*60 + horaMqlTickInicial.min*60 + horaMqlTickInicial.sec;
segundosIntAtual = horaMqlTickAtual.hour*60*60 + horaMqlTickAtual.min*60 + horaMqlTickAtual.sec;
t = segundosIntInicial - segundosIntAtual;
if(ArrayTick[i].flags == 56)
lambda += ArrayTick[i].volume;
}
}
lambda = lambda / T;
return lambda;
}
//+------------------------------------------------------------------+
//| 5.8 - FUNCAO QUE CALCULA O LAMBDA VENDA |
//+------------------------------------------------------------------+
int CalculaLambdaVenda(MqlTick &ArrayTick[], int T)
{
int lambda = 0;
double t = 0;
int segundosIntInicial = 0;
int segundosIntAtual = 0;
MqlDateTime horaMqlTickInicial;
MqlDateTime horaMqlTickAtual;
T = T * 5;
for(int i=0;i<ArraySize(ArrayTick);i++)
{
if(t<T)
{
TimeToStruct(ArrayTick[0].time, horaMqlTickInicial);
TimeToStruct(ArrayTick[i].time, horaMqlTickAtual);
segundosIntInicial = horaMqlTickInicial.hour*60*60 + horaMqlTickInicial.min*60 + horaMqlTickInicial.sec;
segundosIntAtual = horaMqlTickAtual.hour*60*60 + horaMqlTickAtual.min*60 + horaMqlTickAtual.sec;
t = segundosIntInicial - segundosIntAtual;
if(ArrayTick[i].flags == 88)
lambda += ArrayTick[i].volume;
}
}
lambda = lambda / T;
return lambda;
}
//+------------------------------------------------------------------+
//| 5.9 - FUNCAO QUE CALCULA O LOB COMPRA |
//+------------------------------------------------------------------+
int CalculaLobCompra(fluido &Fluidos, MqlBookInfo &ArrayBook[])
{
int lobC = 0;
for(int i=0; i<Fluidos.nBook;i++)
{
lobC = ArrayBook[Fluidos.iBid0 + i].volume;
}
return lobC;
}
//+------------------------------------------------------------------+
//| 5.10 - FUNCAO QUE CALCULA O LOB VENDA |
//+------------------------------------------------------------------+
int CalculaLobVenda(fluido &Fluidos, MqlBookInfo &ArrayBook[])
{
int lobV = 0;
for(int i=0; i<Fluidos.nBook;i++)
{
lobV = ArrayBook[Fluidos.iAsk0 - i].volume;
}
return lobV;
}
//+------------------------------------------------------------------+
//| 5.11 - FUNCAO QUE CALCULA O KC |
//+------------------------------------------------------------------+
int CalculaKC(fluido &Fluidos, MqlBookInfo &ArrayBook[])
{
int KC = 0;
KC = CalculaLobCompra(Fluidos, ArrayBook) / Fluidos.nBook;
return KC;
}
//+------------------------------------------------------------------+
//| 5.12 - FUNCAO QUE CALCULA O KV |
//+------------------------------------------------------------------+
int CalculaKV(fluido &Fluidos, MqlBookInfo &ArrayBook[])
{
int KV = 0;
KV = CalculaLobVenda(Fluidos, ArrayBook) / Fluidos.nBook;
return KV;
}
//+------------------------------------------------------------------+
//| 5.13 - FUNCAO QUE CALCULA O h(t,q) do SpreadBuy |
//+------------------------------------------------------------------+
double CalculaHC(fluido &Fluidos, int q)
{
double h = 0.0;
h = (Fluidos.lambdaV / Fluidos.KC) * log10(exp( -Fluidos.fi*Fluidos.KC*pow(q,2) * pow(((Fluidos.Td-Fluidos.td)/(Fluidos.Td-Fluidos.t0d)),0.125) ) * exp( -Fluidos.alpha*Fluidos.KC*pow(q,2) ) );
//pow(((Fluidos.Td-Fluidos.td)/(Fluidos.Td-Fluidos.t0d)),0.125)
return h;
}
//+------------------------------------------------------------------+
//| 5.14 - FUNCAO QUE CALCULA O h(t,q) do SpreadSell |
//+------------------------------------------------------------------+
double CalculaHV(fluido &Fluidos, int q)
{
double h = 0.0;
h = (Fluidos.lambdaC / Fluidos.KV) * log10(exp( -Fluidos.fi*Fluidos.KV*pow(q,2) * pow(((Fluidos.Td-Fluidos.td)/(Fluidos.Td-Fluidos.t0d)),0.125) ) * exp( -Fluidos.alpha*Fluidos.KV*pow(q,2) ) ) ;
//pow(((Fluidos.Td-Fluidos.td)/(Fluidos.Td-Fluidos.t0d)),0.125)
return h;
}
//+===================================================================================================================================================================================+
//| FIM DO PROGRAMA
//+===================================================================================================================================================================================+