457 lines
No EOL
42 KiB
MQL5
457 lines
No EOL
42 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 = 2; //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 = 22222;
|
|
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 = 2;
|
|
int periodoSTDDEV = 2;
|
|
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, 0, 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;
|
|
//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, 0, 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
|
|
//+===================================================================================================================================================================================+ |