576 lines
No EOL
50 KiB
MQL5
576 lines
No EOL
50 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| S5_Direcao1_v4_1.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 "DESENV_v1"
|
|
#property description "HFT MARKET MAKING BASED ON OXFORD'S STUDIES. MINI INDICE."
|
|
|
|
//+===================================================================================================================================================================================+
|
|
//| 0 - SESSAO DE CABECALHO / ADMISSAO
|
|
//+===================================================================================================================================================================================+
|
|
//+------------------------------------------------------------------+
|
|
//| 0.1 - IMPORTACOES |
|
|
//+------------------------------------------------------------------+
|
|
#include "MarketBook.mqh"
|
|
#include "S0_Admissao1_v4_1.mqh"
|
|
|
|
//+===================================================================================================================================================================================+
|
|
//| 5 - SESSAO DE PRECOS / DIRECAO
|
|
//+===================================================================================================================================================================================+
|
|
//+------------------------------------------------------------------+
|
|
//| 5.1 - FUNCAO QUE DA GET NOS SPREADS E SET NOS PRECOS DA ORDEM |
|
|
//+------------------------------------------------------------------+
|
|
void CalculaPrecoOrdem(operacao &Operacao, fluido &Fluidos, slot &Slots[], MqlTick &ArrayTick[], MqlBookInfo &ArrayBook[])
|
|
{
|
|
//Calcula os spreads
|
|
if(Slots[0].ponta == 0)
|
|
{
|
|
CalculaSpreadOrdemC(Operacao, Fluidos, Slots, ArrayTick, ArrayBook);
|
|
SetPrecosOrdemCompra(Fluidos, Slots);
|
|
}
|
|
else
|
|
{
|
|
CalculaSpreadOrdemV(Operacao, Fluidos, Slots, ArrayTick, ArrayBook);
|
|
SetPrecosOrdemVenda(Fluidos, Slots);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 5.2 - FUNCAO QUE DA GET NOS SPREADS E SET NOS PRECOS DA POSICAO |
|
|
//+------------------------------------------------------------------+
|
|
void CalculaPrecoPosicao(operacao &Operacao, fluido &Fluidos, slot &Slots[], MqlTick &ArrayTick[], MqlBookInfo &ArrayBook[])
|
|
{
|
|
if(Operacao.tipoPosicao == POSITION_TYPE_BUY)
|
|
{
|
|
Operacao.precoAlvo = Fluidos.midPrice + CalculaSpreadPosicaoAlvoC(Fluidos);
|
|
Operacao.precoAlvo = Operacao.precoAlvo + MathMod(Operacao.precoAlvo, Fluidos.tickMin);
|
|
}
|
|
else
|
|
{
|
|
Operacao.precoAlvo = Fluidos.midPrice - CalculaSpreadPosicaoAlvoV(Fluidos);
|
|
Operacao.precoAlvo = Operacao.precoAlvo + MathMod(Operacao.precoAlvo, Fluidos.tickMin);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 5.3 - FUNCAO QUE CALCULA OS SPREADS DA ORDEM DE COMPRA |
|
|
//+------------------------------------------------------------------+
|
|
void CalculaSpreadOrdemC(operacao &Operacao, fluido &Fluidos, slot &SlotsC[], MqlTick &ArrayTick[], MqlBookInfo &ArrayBook[])
|
|
{
|
|
|
|
Fluidos.tendencia = GetTendencia(Fluidos, ArrayTick, ArrayBook);
|
|
TimeToStruct(TimeCurrent(), Operacao.horarioMQL_atual);
|
|
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 desvio = MathRound(Fluidos.sigmaHFT / Fluidos.tickMin) * Fluidos.tickMin;
|
|
double nivel = MathRound(log(Fluidos.iSlot+1) * 100 / Fluidos.tickMin) / 100 * Fluidos.tickMin;
|
|
|
|
if(Fluidos.tendencia == "BAIXA FORTE")
|
|
{
|
|
Fluidos.LC = false;
|
|
return;
|
|
}
|
|
else Fluidos.LC = true;
|
|
|
|
if(Fluidos.tendencia == "ALTA FORTE")
|
|
{
|
|
double spreadTend = MathRound((Fluidos.imbalance * Fluidos.tickMin * 10 * Fluidos.fatorHedge) / Fluidos.tickMin) * Fluidos.tickMin;
|
|
if(spreadTend < -20) spreadTend = 0;
|
|
|
|
SlotsC[Fluidos.iSlot].spreadEnvio = 3 * Fluidos.tickMin/2;
|
|
SlotsC[Fluidos.iSlot].spreadAlvo = spreadTend;
|
|
SlotsC[Fluidos.iSlot].spreadStop = MathRound(Fluidos.sigmaHFT / Fluidos.tickMin) * Fluidos.tickMin * 5;
|
|
|
|
}
|
|
else if(Fluidos.tendencia == "ALTA LEVE")
|
|
{
|
|
SlotsC[Fluidos.iSlot].spreadEnvio = Fluidos.tickMin/2 + Fluidos.spreadOffsetEnvioLeve + MathRound((spreadCompra + desvio * nivel)/Fluidos.tickMin)*Fluidos.tickMin;
|
|
SlotsC[Fluidos.iSlot].spreadAlvo = Fluidos.tickMin*2 + Fluidos.spreadOffsetAlvoLeve + spreadCompra;
|
|
SlotsC[Fluidos.iSlot].spreadStop = MathRound(Fluidos.sigmaHFT / Fluidos.tickMin) * Fluidos.tickMin * 5;
|
|
}
|
|
else if(Fluidos.tendencia == "LADO")
|
|
{
|
|
SlotsC[Fluidos.iSlot].spreadEnvio = Fluidos.tickMin/2 + Fluidos.spreadOffsetEnvioLado + MathRound((spreadCompra + desvio * nivel)/Fluidos.tickMin)*Fluidos.tickMin;
|
|
SlotsC[Fluidos.iSlot].spreadAlvo = Fluidos.tickMin*2 + Fluidos.spreadOffsetAlvoLado + spreadCompra;
|
|
SlotsC[Fluidos.iSlot].spreadStop = MathRound(Fluidos.sigmaHFT / Fluidos.tickMin) * Fluidos.tickMin * 5;
|
|
}
|
|
else if(Fluidos.tendencia == "BAIXA LEVE")
|
|
{
|
|
SlotsC[Fluidos.iSlot].spreadEnvio = Fluidos.tickMin/2 + Fluidos.spreadOffsetEnvioLeve + MathRound((spreadCompra + desvio * nivel)/Fluidos.tickMin)*Fluidos.tickMin;
|
|
SlotsC[Fluidos.iSlot].spreadAlvo = Fluidos.tickMin*2 + Fluidos.spreadOffsetAlvoLeve + spreadCompra;
|
|
SlotsC[Fluidos.iSlot].spreadStop = MathRound(Fluidos.sigmaHFT / Fluidos.tickMin) * Fluidos.tickMin * 5;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 5.4 - FUNCAO QUE CALCULA OS SPREADS DA ORDEM DE VENDA |
|
|
//+------------------------------------------------------------------+
|
|
void CalculaSpreadOrdemV(operacao &Operacao, fluido &Fluidos, slot &SlotsV[], MqlTick &ArrayTick[], MqlBookInfo &ArrayBook[])
|
|
{
|
|
Fluidos.tendencia = GetTendencia(Fluidos, ArrayTick, ArrayBook);
|
|
TimeToStruct(TimeCurrent(), Operacao.horarioMQL_atual);
|
|
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 desvio = MathRound(Fluidos.sigmaHFT / Fluidos.tickMin) * Fluidos.tickMin;
|
|
double nivel = MathRound(log(Fluidos.iSlot+1) * 100 / Fluidos.tickMin) / 100 * Fluidos.tickMin;
|
|
|
|
if(Fluidos.tendencia == "ALTA FORTE")
|
|
{
|
|
Fluidos.LV = false;
|
|
return;
|
|
}
|
|
else Fluidos.LV = true;
|
|
|
|
if(Fluidos.tendencia == "ALTA LEVE")
|
|
{
|
|
SlotsV[Fluidos.iSlot].spreadEnvio = Fluidos.tickMin/2 + Fluidos.spreadOffsetEnvioLeve + MathRound((spreadVenda + desvio * nivel) / Fluidos.tickMin) * Fluidos.tickMin;
|
|
SlotsV[Fluidos.iSlot].spreadAlvo = Fluidos.tickMin*2 + Fluidos.spreadOffsetAlvoLeve + spreadVenda;
|
|
SlotsV[Fluidos.iSlot].spreadStop = MathRound(Fluidos.sigmaHFT / Fluidos.tickMin) * Fluidos.tickMin * 5;
|
|
}
|
|
else if(Fluidos.tendencia == "LADO")
|
|
{
|
|
SlotsV[Fluidos.iSlot].spreadEnvio = Fluidos.tickMin/2 + Fluidos.spreadOffsetEnvioLado + MathRound((spreadVenda + desvio * nivel) / Fluidos.tickMin) * Fluidos.tickMin;
|
|
SlotsV[Fluidos.iSlot].spreadAlvo = Fluidos.tickMin*2 + Fluidos.spreadOffsetAlvoLado + spreadVenda;
|
|
SlotsV[Fluidos.iSlot].spreadStop = MathRound(Fluidos.sigmaHFT / Fluidos.tickMin) * Fluidos.tickMin * 5;
|
|
}
|
|
else if(Fluidos.tendencia == "BAIXA LEVE")
|
|
{
|
|
SlotsV[Fluidos.iSlot].spreadEnvio = Fluidos.tickMin/2 + Fluidos.spreadOffsetEnvioLeve + MathRound((spreadVenda + desvio * nivel) / Fluidos.tickMin) * Fluidos.tickMin;
|
|
SlotsV[Fluidos.iSlot].spreadAlvo = Fluidos.tickMin*2 + Fluidos.spreadOffsetAlvoLeve + spreadVenda;
|
|
SlotsV[Fluidos.iSlot].spreadStop = MathRound(Fluidos.sigmaHFT / Fluidos.tickMin) * Fluidos.tickMin * 5;
|
|
}
|
|
else if(Fluidos.tendencia == "BAIXA FORTE")
|
|
{
|
|
double spreadTend = MathRound((Fluidos.imbalance * Fluidos.tickMin * 10 * Fluidos.fatorHedge) / Fluidos.tickMin) * Fluidos.tickMin;
|
|
if(spreadTend > 20) spreadTend = 0;
|
|
|
|
SlotsV[Fluidos.iSlot].spreadEnvio = 3 * Fluidos.tickMin/2;
|
|
SlotsV[Fluidos.iSlot].spreadAlvo = spreadTend;
|
|
SlotsV[Fluidos.iSlot].spreadStop = MathRound(Fluidos.sigmaHFT / Fluidos.tickMin) * Fluidos.tickMin * 5;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 5.5 - FUNCAO QUE CALCULA O SPREAD DE ALVO DA POSICAO DE COMPRA |
|
|
//+------------------------------------------------------------------+
|
|
double CalculaSpreadPosicaoAlvoC(fluido &Fluidos)
|
|
{
|
|
double spreadAlvo = 0.0;
|
|
|
|
if(Fluidos.tendencia == "ALTA FORTE")
|
|
{
|
|
double spreadTend = MathRound((Fluidos.imbalance * Fluidos.tickMin * 10 * Fluidos.fatorHedge) / Fluidos.tickMin) * Fluidos.tickMin;
|
|
|
|
if(spreadTend < -20) spreadTend = 0;
|
|
|
|
spreadAlvo = Fluidos.tickMin/2 + spreadTend;
|
|
}
|
|
else if(Fluidos.tendencia == "ALTA LEVE")
|
|
{
|
|
spreadAlvo = Fluidos.tickMin/2 + Fluidos.spreadOffsetAlvoLeve + MathRound(100*Fluidos.tickMin*((Fluidos.lambdaC/Fluidos.KV) + CalculaHC(Fluidos, Fluidos.q) - CalculaHC(Fluidos, Fluidos.q+1)) / Fluidos.tickMin) * Fluidos.tickMin;
|
|
}
|
|
else if(Fluidos.tendencia == "LADO")
|
|
{
|
|
spreadAlvo = Fluidos.tickMin/2 + Fluidos.spreadOffsetAlvoLado + MathRound(100*Fluidos.tickMin*((Fluidos.lambdaC/Fluidos.KV) + CalculaHC(Fluidos, Fluidos.q) - CalculaHC(Fluidos, Fluidos.q+1)) / Fluidos.tickMin) * Fluidos.tickMin;
|
|
}
|
|
else if(Fluidos.tendencia == "BAIXA LEVE")
|
|
{
|
|
spreadAlvo = Fluidos.tickMin/2 + Fluidos.spreadOffsetAlvoLeve + MathRound(100*Fluidos.tickMin*((Fluidos.lambdaC/Fluidos.KV) + CalculaHC(Fluidos, Fluidos.q) - CalculaHC(Fluidos, Fluidos.q+1)) / Fluidos.tickMin) * Fluidos.tickMin;
|
|
|
|
}
|
|
else if(Fluidos.tendencia == "BAIXA FORTE")
|
|
{
|
|
//FAZ NADA
|
|
}
|
|
|
|
return spreadAlvo;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 5.6 - FUNCAO QUE CALCULA O SPREAD DE ALVO DA POSICAO DE VENDA |
|
|
//+------------------------------------------------------------------+
|
|
double CalculaSpreadPosicaoAlvoV(fluido &Fluidos)
|
|
{
|
|
double spreadAlvo = 0.0;
|
|
|
|
if(Fluidos.tendencia == "ALTA FORTE")
|
|
{
|
|
//FAZ NADA
|
|
}
|
|
else if(Fluidos.tendencia == "ALTA LEVE")
|
|
{
|
|
spreadAlvo = Fluidos.tickMin/2 + Fluidos.spreadOffsetAlvoLeve + MathRound(100*Fluidos.tickMin*((Fluidos.lambdaV/Fluidos.KC) + CalculaHV(Fluidos, Fluidos.q) - CalculaHV(Fluidos, Fluidos.q-1)) / Fluidos.tickMin) * Fluidos.tickMin;
|
|
}
|
|
else if(Fluidos.tendencia == "LADO")
|
|
{
|
|
spreadAlvo = Fluidos.tickMin/2 + Fluidos.spreadOffsetAlvoLado + MathRound(100*Fluidos.tickMin*((Fluidos.lambdaV/Fluidos.KC) + CalculaHV(Fluidos, Fluidos.q) - CalculaHV(Fluidos, Fluidos.q+1)) / Fluidos.tickMin) * Fluidos.tickMin;
|
|
}
|
|
else if(Fluidos.tendencia == "BAIXA LEVE")
|
|
{
|
|
spreadAlvo = Fluidos.tickMin/2 + Fluidos.spreadOffsetAlvoLeve + MathRound(100*Fluidos.tickMin*((Fluidos.lambdaV/Fluidos.KC) + CalculaHV(Fluidos, Fluidos.q) - CalculaHV(Fluidos, Fluidos.q-1)) / Fluidos.tickMin) * Fluidos.tickMin;
|
|
|
|
}
|
|
else if(Fluidos.tendencia == "BAIXA FORTE")
|
|
{
|
|
double spreadTend = MathRound((Fluidos.imbalance * Fluidos.tickMin * 10 * Fluidos.fatorHedge) / Fluidos.tickMin) * Fluidos.tickMin;
|
|
|
|
if(spreadTend > 20) spreadTend = 0;
|
|
|
|
spreadAlvo = Fluidos.tickMin/2 - spreadTend;
|
|
}
|
|
|
|
return spreadAlvo;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 5.7 - FUNCAO QUE DA SET NOS PRECOS DA ORDEM DE COMPRA |
|
|
//+------------------------------------------------------------------+
|
|
void SetPrecosOrdemCompra(fluido &Fluidos, slot &SlotsC[])
|
|
{
|
|
//SET PRECO ENVIO
|
|
SlotsC[Fluidos.iSlot].precoEnvio = Fluidos.midPrice - SlotsC[Fluidos.iSlot].spreadEnvio;
|
|
|
|
if(MathMod(SlotsC[Fluidos.iSlot].precoEnvio, Fluidos.tickMin) != 0)
|
|
{
|
|
SlotsC[Fluidos.iSlot].precoEnvio = SlotsC[Fluidos.iSlot].precoEnvio - MathMod(SlotsC[Fluidos.iSlot].precoEnvio, Fluidos.tickMin);
|
|
}
|
|
|
|
//SET PRECO ALVO
|
|
SlotsC[Fluidos.iSlot].precoAlvo = SlotsC[Fluidos.iSlot].precoEnvio + SlotsC[Fluidos.iSlot].spreadAlvo;
|
|
|
|
if(MathMod(SlotsC[Fluidos.iSlot].precoAlvo, Fluidos.tickMin) != 0)
|
|
{
|
|
SlotsC[Fluidos.iSlot].precoAlvo = SlotsC[Fluidos.iSlot].precoAlvo - MathMod(SlotsC[Fluidos.iSlot].precoAlvo, Fluidos.tickMin);
|
|
}
|
|
|
|
//SET PRECO STOP
|
|
SlotsC[Fluidos.iSlot].precoStop = SlotsC[Fluidos.iSlot].precoEnvio - SlotsC[Fluidos.iSlot].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);
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 5.8 - FUNCAO QUE DA SET NOS PRECOS DA ORDEM DE VENDA |
|
|
//+------------------------------------------------------------------+
|
|
void SetPrecosOrdemVenda(fluido &Fluidos, slot &SlotsV[])
|
|
{
|
|
//SET PRECO ENVIO
|
|
SlotsV[Fluidos.iSlot].precoEnvio = Fluidos.midPrice + SlotsV[Fluidos.iSlot].spreadEnvio;
|
|
|
|
if(MathMod(SlotsV[Fluidos.iSlot].precoEnvio, Fluidos.tickMin) != 0)
|
|
{
|
|
SlotsV[Fluidos.iSlot].precoEnvio = SlotsV[Fluidos.iSlot].precoEnvio + MathMod(SlotsV[Fluidos.iSlot].precoEnvio, Fluidos.tickMin);
|
|
}
|
|
|
|
//SET PRECO ALVO
|
|
SlotsV[Fluidos.iSlot].precoAlvo = SlotsV[Fluidos.iSlot].precoEnvio - SlotsV[Fluidos.iSlot].spreadAlvo;
|
|
|
|
if(MathMod(SlotsV[Fluidos.iSlot].precoAlvo, Fluidos.tickMin) != 0)
|
|
{
|
|
SlotsV[Fluidos.iSlot].precoAlvo = SlotsV[Fluidos.iSlot].precoAlvo + MathMod(SlotsV[Fluidos.iSlot].precoAlvo, Fluidos.tickMin);
|
|
}
|
|
|
|
//SET PRECO STOP
|
|
SlotsV[Fluidos.iSlot].precoStop = SlotsV[Fluidos.iSlot].precoEnvio + SlotsV[Fluidos.iSlot].spreadStop;
|
|
|
|
if(MathMod(SlotsV[Fluidos.iSlot].precoStop, Fluidos.tickMin) != 0)
|
|
{
|
|
SlotsV[Fluidos.iSlot].precoStop = SlotsV[Fluidos.iSlot].precoStop + MathMod(SlotsV[Fluidos.iSlot].precoStop, Fluidos.tickMin);
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 5.9 - FUNCAO QUE VERIFICA QUAL E A TENDENCIA PELO IMBALANCE |
|
|
//+------------------------------------------------------------------+
|
|
string GetTendencia(fluido &Fluidos, MqlTick &ArrayTick[], MqlBookInfo &ArrayBook[])
|
|
{
|
|
if(Operacao.chaveLambda == true)
|
|
{
|
|
Fluidos.lambdaC = CalculaLambdaCompra(ArrayTick, Fluidos.T);
|
|
Fluidos.lambdaV = CalculaLambdaVenda(ArrayTick, Fluidos.T);
|
|
}
|
|
else
|
|
{
|
|
if(Operacao.chaveLambdaBacktest == true)
|
|
{
|
|
Fluidos.lambdaC = CalculaLambdaCompraBacktest(Fluidos);
|
|
Fluidos.lambdaV = CalculaLambdaVendaBacktest(Fluidos);
|
|
}
|
|
}
|
|
|
|
if(Operacao.chaveBook == true)
|
|
{
|
|
Fluidos.KC = CalculaKC(Fluidos, ArrayBook);
|
|
Fluidos.KV = CalculaKV(Fluidos, ArrayBook);
|
|
}
|
|
else
|
|
{
|
|
if(Operacao.chaveBookBacktest == true)
|
|
{
|
|
Fluidos.KC = CalculaKCBacktest(Fluidos);
|
|
Fluidos.KV = CalculaKVBacktest(Fluidos);
|
|
}
|
|
}
|
|
|
|
if((Fluidos.KC != 0) && (Fluidos.KV != 0)) Fluidos.imbalance = (Fluidos.lambdaC / Fluidos.KV) - (Fluidos.lambdaV / Fluidos.KC);
|
|
else Fluidos.imbalance = 0.0;
|
|
|
|
if(Fluidos.imbalance > 8*Fluidos.corteImbalance) return "ALTA FORTE";
|
|
else if((Fluidos.imbalance > 4*Fluidos.corteImbalance) && (Fluidos.imbalance < 8*Fluidos.corteImbalance)) return "ALTA LEVE";
|
|
else if((Fluidos.imbalance < -4*Fluidos.corteImbalance) && (Fluidos.imbalance > -8*Fluidos.corteImbalance)) return "BAIXA LEVE";
|
|
else if(Fluidos.imbalance < -8*Fluidos.corteImbalance) return "BAIXA FORTE";
|
|
else return "LADO";
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 5.10 - 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.11 - 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.12 - 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.13 - 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.14 - FUNCAO QUE CALCULA O KC |
|
|
//+------------------------------------------------------------------+
|
|
int CalculaKC(fluido &Fluidos, MqlBookInfo &ArrayBook[])
|
|
{
|
|
int KC = 0;
|
|
|
|
KC = CalculaLobCompra(Fluidos, ArrayBook) / Fluidos.nBook;
|
|
|
|
return KC;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 5.15 - FUNCAO QUE CALCULA O KV |
|
|
//+------------------------------------------------------------------+
|
|
int CalculaKV(fluido &Fluidos, MqlBookInfo &ArrayBook[])
|
|
{
|
|
int KV = 0;
|
|
|
|
KV = CalculaLobVenda(Fluidos, ArrayBook) / Fluidos.nBook;
|
|
|
|
return KV;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 5.16 - 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.17 - 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;
|
|
}
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 5.18 - FUNCAO QUE CALCULA O LAMBDA COMPRA BACKTEST |
|
|
//+------------------------------------------------------------------+
|
|
int CalculaLambdaCompraBacktest(fluido &Fluidos)
|
|
{
|
|
int lambda = 0;
|
|
int lambdaC = 0;
|
|
double rate = 0.0;
|
|
|
|
if(Fluidos.volumeNegocios != 0) lambda = 5*Fluidos.volumeReal / Fluidos.volumeNegocios;
|
|
else lambda = 1;
|
|
|
|
rate = (Fluidos.precoClose - Fluidos.precoOpen)/Fluidos.sigmaHFT;
|
|
if(rate < -1) lambdaC = 1;
|
|
else lambdaC = lambda * (1+rate);
|
|
|
|
return lambdaC;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 5.19 - FUNCAO QUE CALCULA O LAMBDA VENDA BACKTEST |
|
|
//+------------------------------------------------------------------+
|
|
int CalculaLambdaVendaBacktest(fluido &Fluidos)
|
|
{
|
|
int lambda = 0;
|
|
int lambdaV = 0;
|
|
double rate = 0.0;
|
|
|
|
if(Fluidos.volumeNegocios != 0) lambda = 5*Fluidos.volumeReal / Fluidos.volumeNegocios;
|
|
else lambda = 1;
|
|
|
|
rate = (Fluidos.precoClose - Fluidos.precoOpen)/Fluidos.sigmaHFT;
|
|
if(rate > 1) lambdaV = 1;
|
|
else lambdaV = lambda * (1-rate);
|
|
|
|
return lambdaV;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 5.20 - FUNCAO QUE CALCULA O BOOK COMPRA BACKTEST |
|
|
//+------------------------------------------------------------------+
|
|
int CalculaKCBacktest(fluido &Fluidos)
|
|
{
|
|
int book = 0;
|
|
|
|
return book;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 5.21 - FUNCAO QUE CALCULA O BOOK VENDA BACKTEST |
|
|
//+------------------------------------------------------------------+
|
|
int CalculaKVBacktest(fluido &Fluidos)
|
|
{
|
|
int book = 0;
|
|
|
|
return book;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 5.22 - 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;
|
|
}
|
|
|
|
//+===================================================================================================================================================================================+
|
|
//| FIM DO PROGRAMA
|
|
//+===================================================================================================================================================================================+ |