Chassis/S2_MotorLFT_v0.mq5
super.admin 808b3a6b3c convert
2025-05-30 14:46:03 +02:00

462 lines
No EOL
43 KiB
MQL5

//+------------------------------------------------------------------+
//| SuperCharlie_Aldridge_Dev_v0.mq5|
//| HEDGING HORN CAPITAL |
//| https://www.hhcapital.com.br |
//+------------------------------------------------------------------+
#property copyright "HEDGING HORN CAPITAL"
#property link "https://www.hhcapítal.com.br"
#property version "DEV_v0"
#property description "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_Cambio1_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 = 5; //Inventario máximo Q {1}[1, +inf[
input int rajada = 1; //Quantidade por ordem η {1}[1, +inf[
input double fiPenalty = 0.00002; //Fi: Running Penalty (injeção eletrônica)
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[
//+------------------------------------------------------------------+
//| 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
//+------------------------------------------------------------------+
//| 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 midPrice = 0.0;
double buyPrice = 0.0;
double sellPrice = 0.0;
double stopBuyPrice = 0.0;
double stopSellPrice = 0.0;
double spreadBuy = 0.0;
double spreadSell = 0.0;
double stopBuySpread = 0.0;
double stopSellSpread = 0.0;
double qtdBuy = 0.0;
double qtdSell = 0.0;
double qtdCompraEnviada = 0.0;
double qtdVendaEnviada = 0.0;
double qtdCompraFilada = 0.0;
double qtdVendaFilada = 0.0;
double saldoInicialDia = 0.0;
double saldoFinalDia = 0.0;
double diferencaSaldo = 0.0;
int spreadTotal = 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;
CExpert extExpert;
CMarketBook Book(_Symbol);
CTrade negocio;
MqlBookInfo ArrayBook[];
MqlTick ArrayTick[];
int iBid[];
int iAsk[];
double MA[];
double STDDEV[];
int handlerMA;
int handlerSTDDEV;
int periodoMA = 88;
int periodoSTDDEV = 88;
int tempo = 1000;
MqlTradeRequest request;
MqlTradeResult result;
MqlTradeTransaction transaction;
MqlTradeCheckResult check_result;
string handlerNormalizeDoubleSize;
int normalizeDoubleSize;
int intervaloTicks = 500;
double limiteInfDesvio = 0;
double limiteSupDesvio = 500;
fluido Fluidos;
slot SlotsC[];
slot SlotsV[];
slot SlotsTPC[];
slot SlotsTPV[];
posicao SlotPos;
ulong t = 0;
//+------------------------------------------------------------------+
//| 1.3.5 - VARIAVEIS DE LOG E FEEDBACK |
//+------------------------------------------------------------------+
int arqResultados = 0;
int idResultados = 0;
string headerRes = "ID_RESULTADO,TIMESTAMP,BID,PRECO_COMPRA,MIDPRICE,PRECO_VENDA,ASK,DESVIO,SOMA,ALPHA,EPSILON,RES_BRUTO,RES_LIQ,K_C,K_V,LAMBDA_C,LAMBDA_V,FILL_C,FILL_V,TRADES,ACERTOS,ERROS";
//+===================================================================================================================================================================================+
//| 2 - SESSAO DE LOGICA CENTRAL / MOTOR
//+===================================================================================================================================================================================+
//+------------------------------------------------------------------+
//| 2.1 - FUNCAO DE INICIALIZACAO |
//+------------------------------------------------------------------+
int OnInit()
{
//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(!MarketBookAdd(_Symbol)) Print("Falha para inicializar o book");
//Inicializa o ArrayTick
if(CopyTicks(Symbol(),ArrayTick,COPY_TICKS_TRADE,0,intervaloTicks) != -1) ArraySetAsSeries(ArrayTick,true);
else Print("Falha para inicializar o ArrayTicks");
//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);
ArrayResize(SlotsTPC, inventario);
ArrayResize(SlotsTPV, inventario);
//inicializa os slots de compra e venda
for(int i=0; i<inventario ;i++)
{
SlotsC[i].status = 0;
SlotsV[i].status = 0;
SlotsTPC[i].status = 0;
SlotsTPV[i].status = 0;
}
//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.sigmaLFT = STDDEV[0];
Fluidos.driftLFTTend = MA[0] - MA[1];
Fluidos.driftLFTVol = STDDEV[0] - STDDEV[1];
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 2.2 - FUNCAO EVENTO TICK / CORACAO |
//+------------------------------------------------------------------+
void OnTick()
{
//Atualiza os ticks e variaveis
AtualizaVariaveis();
//Chamar o motor
if(VerificaHorarioOrdens(horarioMQL_atual, horarioShort_inicial, horarioShort_final)) FazTrades();
else if(VerificaHorarioFechamento(horarioMQL_atual, horarioShort_fechamento))
{
FechaPosicao(negocio);
CancelaOrdensAbertas(negocio);
ArrayFree(SlotsC);
ArrayFree(SlotsV);
ArrayFree(SlotsTPC);
ArrayFree(SlotsTPV);
ArrayResize(SlotsC, inventario);
ArrayResize(SlotsV, inventario);
ArrayResize(SlotsTPC, inventario);
ArrayResize(SlotsTPV, inventario);
for(int i=0;i<ArraySize(SlotsC);i++)
{
SlotsC[i].status = 0;
SlotsV[i].status = 0;
SlotsTPC[i].status = 0;
SlotsTPV[i].status = 0;
}
}
else return;
return;
}
//+------------------------------------------------------------------+
//| 2.3 - FUNCAO EVENTO BOOK |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
{
/* //Atualiza os melhores indices de bid e ask do book
if(MarketBookGet(_Symbol, ArrayBook))
{
iBid[0] = Book.InfoGetInteger(MBOOK_BEST_BID_INDEX);
iAsk[0] = Book.InfoGetInteger(MBOOK_BEST_ASK_INDEX);
iBid[1] = iBid[0] + 1;
iAsk[1] = iAsk[0] - 1;
iBid[2] = iBid[0] + 2;
iAsk[2] = iAsk[0] - 2;
Fluidos.iBid0 = iBid[0];
Fluidos.iBid1 = iBid[1];
Fluidos.iBid2 = iBid[2];
Fluidos.iAsk0 = iAsk[0];
Fluidos.iAsk1 = iAsk[1];
Fluidos.iAsk2 = iAsk[2];
}
else
{
Print("Falha ao obter o Book");
} */
return;
}
//+------------------------------------------------------------------+
//| 2.4 - FUNCAO EVENTO TRADE |
//+------------------------------------------------------------------+
void OnTrade()
{
static int previous_open_positions = 0;
int current_open_positions = PositionsTotal();
double last_trade_profit = 0.0;
if(current_open_positions < previous_open_positions) // a position just got closed:
{
previous_open_positions = current_open_positions;
HistorySelect(TimeCurrent()-300, TimeCurrent()); // 5 minutes ago
int All_Deals = HistoryDealsTotal();
if(All_Deals < 1) Print("Some nasty shit error has occurred :s");
// last deal (should be an DEAL_ENTRY_OUT type):
ulong temp_Ticket = HistoryDealGetTicket(All_Deals-1);
// here check some validity factors of the position-closing deal
// (symbol, position ID, even MagicNumber if you care...)
last_trade_profit = HistoryDealGetDouble(temp_Ticket , DEAL_PROFIT);
// if(last_trade_profit < 0) Sleep(sleepTime);
// Print("Last Trade Profit : ", DoubleToString(last_trade_profit));
}
else if(current_open_positions > previous_open_positions) // a position just got opened:
previous_open_positions = current_open_positions;
}
//+------------------------------------------------------------------+
//| 2.5 - FUNCAO DE DESLIGAMENTO |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//Fecha os arquivos de log
// FileClose(arqResultados);
// Print("Fechou arquivos de log.");
//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 e ticks
if(!simbolo.RefreshRates()) return;
/*
if(MarketBookGet(_Symbol, ArrayBook))
{
//Atualiza os indices do topo do book
iBid[0] = Book.InfoGetInteger(MBOOK_BEST_BID_INDEX);
iAsk[0] = Book.InfoGetInteger(MBOOK_BEST_ASK_INDEX);
iBid[1] = iBid[0] + 1;
iAsk[1] = iAsk[0] - 1;
iBid[2] = iBid[0] + 2;
iAsk[2] = iAsk[0] - 2;
}
else
{
Print("Falha ao atualizar o Book");
} */
//Atualiza os buffers de media e desvio padrao
CopyBuffer(handlerMA,0,1,2,MA);
CopyBuffer(handlerSTDDEV,0,1,2,STDDEV);
Fluidos.media = MA[0];
Fluidos.sigmaLFT = STDDEV[0];
Fluidos.driftLFTTend = MA[0] - MA[1];
Fluidos.driftLFTVol = STDDEV[0] - STDDEV[1];
return;
}
//+------------------------------------------------------------------+
//| 2.7 - FUNCAO QUE FAZ NEGOCIACOES |
//+------------------------------------------------------------------+
void FazTrades()
{
//Verifica se atingiu os riscos de VaR (3a camada de riscos} ou volatilidade (2a camada de riscos)
if(VerificaRiscos(alvoFinanceiro, stopFinanceiro, intervaloTicks, MA, diaAtual, horarioMQL_atual, diferencaSaldo, saldoInicialDia, saldoFinalDia, limiteSupDesvio, ArrayTick, Fluidos.sigmaLFT, SlotsC, SlotsV, inventario) == false)
{
//Avanca os status dos slots
GerenciaSlots(magic, tickMin, rajada, Fluidos, SlotsC, SlotsV, SlotPos, simbolo, request, result, check_result);
//Verifica os slots de compra e venda, se estiverem vazios, mande ordens
for(int i=0; i<ArraySize(SlotsC); i++)
{
//Para cada possibilidade de status
switch(SlotsC[i].status)
{
//Preenche ordens de slots ready
case 0 :
//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, simbolo, request, result, check_result);
if(result.retcode == 10009)
{
//Avanca o status do slot para enviado
SlotsC[i].idOrdem = result.order;
SlotsC[i].status = 1;
}
else Print("Erro no envio Compra, RETCODE: ",result.retcode);
}
break;
//Altera ordem enviada com precoEnvio, precoStop ou precoAlvo novos (atualiza o box de ordem)
case 2 :
ModificaOrdemEnviada(SlotsC[i].idOrdem, SlotsC[i].precoEnvio, SlotsC[i].precoAlvo, SlotsC[i].precoStop, magic, negocio, simbolo, request, result, check_result);
// SlotsC[i].status = 1;
break;
//Manda uma saida para a posicao fazendo uma venda limite contraria a posicao de compra (manda a saida do box de position)
case 3:
VendaLimite(SlotPos.precoMedio + 0.2*Fluidos.sigmaLFT*SlotPos.qtd, 0, SlotPos.qtd, magic, simbolo, request, result, check_result);
SlotsTPC[i].idOrdem = result.order;
SlotsTPC[i].precoEnvio = SlotPos.precoMedio + 0.2*Fluidos.sigmaLFT*SlotPos.qtd;
SlotsTPC[i].qtd = SlotPos.qtd;
SlotsTPC[i].status = 1;
SlotsC[i].status = 4;
// Print("Compra virou status 3->4");
break;
//Altera ordem enviada para saida (atualiza a saida do box de position)
case 4 :
ModificaOrdemEnviada(SlotPos.idPosicao, SlotPos.precoMedio + 0.2*Fluidos.sigmaLFT*SlotPos.qtd, 0, 0, magic, negocio, simbolo, request, result, check_result);
SlotsTPC[i].status = 1;
break;
case 5:
//Altera o precoStop de position (atualiza o box de position)
SlotsC[i].status = 4;
// Print("Compra virou status 5->4");
break;
//Default
default :
break;
}
}
//Verifica os slots de venda, se estiverem vazios, mande ordens
for(int i=0; i<ArraySize(SlotsV); i++)
{
//Para cada possibilidade de status
switch(SlotsV[i].status)
{
//Preenche ordens de slots ready
case 0 :
//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, simbolo, request, result, check_result);
if(result.retcode == 10009)
{
//Avanca o status do slot para enviado
SlotsV[i].idOrdem = result.order;
SlotsV[i].status = 1;
}
else Print("Erro no envio Venda, RETCODE: ",result.retcode);
}
break;
//Altera ordem enviada com precoEnvio, precoStop ou precoAlvo novos (atualiza o box de ordem)
case 2 :
ModificaOrdemEnviada(SlotsV[i].idOrdem, SlotsV[i].precoEnvio, SlotsV[i].precoAlvo, SlotsV[i].precoStop, magic, negocio, simbolo, request, result, check_result);
break;
//Manda uma saida para a posicao fazendo uma venda limite contraria a posicao de compra (manda a saida do box de position)
case 3:
CompraLimite(SlotPos.precoMedio - 0.2*Fluidos.sigmaLFT*SlotPos.qtd, 0, SlotPos.qtd, magic, simbolo, request, result, check_result);
SlotsTPV[i].idOrdem = result.order;
SlotsTPV[i].precoEnvio = SlotPos.precoMedio - 0.2*Fluidos.sigmaLFT*SlotPos.qtd;
SlotsTPV[i].qtd = SlotPos.qtd;
SlotsTPV[i].status = 1;
SlotsC[i].status = 4;
// Print("Venda modificada 3->4");
break;
//Altera ordem enviada para saida (atualiza a saida do box de position)
case 4 :
ModificaOrdemEnviada(SlotPos.idPosicao, SlotPos.precoMedio - 0.2*Fluidos.sigmaLFT*SlotPos.qtd, 0, 0, magic, negocio, simbolo, request, result, check_result);
SlotsTPV[i].status = 1;
break;
case 5:
//modifica position
SlotsV[i].status = 4;
// Print("Venda modificada 5->4");
break;
//Default
default :
break;
}
}
}
return;
}
//+===================================================================================================================================================================================+
//| FIM DO PROGRAMA
//+===================================================================================================================================================================================+