880 lines
54 KiB
MQL5
880 lines
54 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| Tiktok.mq5 |
|
|
//| Copyright 2021, TraderDroid |
|
|
//| https://www.traderdroid.com.br |
|
|
//+------------------------------------------------------------------+
|
|
//+------------------------------------------------------------------+
|
|
//| DEFINIÇÔES |
|
|
//+------------------------------------------------------------------+
|
|
#define VERSAO "1.0";
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| PROPRIEDADES |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "@TraderDroid"
|
|
#property link "www.traderdroid.com.br"
|
|
#property version VERSAO
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| INCLUSÔES |
|
|
//+------------------------------------------------------------------+
|
|
#include <Trade\Trade.mqh>
|
|
#include <JAson.mqh>
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| CONSTANTES |
|
|
//+------------------------------------------------------------------+
|
|
const int ROBO_ID = 2; //Identificação do Robô na API
|
|
const int SEGUNDOS_TIMER = 40;
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| ENUM |
|
|
//+------------------------------------------------------------------+
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| INPUTS |
|
|
//+------------------------------------------------------------------+
|
|
input int inputIdCliente = 0; //ID do Cliente
|
|
input double inputQtdContratos = 0; // Valor do Caixa
|
|
input group "As Ordens Limitada/Saída serão deletadas"
|
|
input group "e recalculadas na abertura do dia seguinte."
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| VARIAVEIS GLOBAIS |
|
|
//+------------------------------------------------------------------+
|
|
CTrade trade;
|
|
|
|
CJAVal json;
|
|
|
|
MqlTick tick;
|
|
|
|
bool compradoMercado = false, vendidoMercado = false, compradoPendente = false, vendidoPendente = false;
|
|
|
|
ulong ticketCompradoMercado = 0, ticketVendidoMercado = 0, ticketCompradoPendente = 0, ticketVendidoPendente = 0;
|
|
|
|
// USADO PARA BUSCAR A QUANTIDADE DE LOTES NA POSIÇÃO DE COMPRA E USÁ-LA NA VENDA PARA ZERAR A POSIÇÃO
|
|
double quantLotesVenda = 0;
|
|
|
|
// USADA PARA SABER QUANTAS POSIÇÕES ABERTAS EM TODOS OS ATIVOS
|
|
uint quantPosicoesExecutadasGlobal = 0;
|
|
|
|
// SÍMBOLO QUE INICIA O ROBO, NECESSÁRIO PARA EVITAR DE TROCAR O ATIVO NA MESMA JANELA
|
|
static string simboloInicial = "";
|
|
|
|
ENUM_ACCOUNT_TRADE_MODE tipoConta = AccountInfoInteger(ACCOUNT_TRADE_MODE);
|
|
//+------------------------------------------------------------------+
|
|
//| INDICADORES |
|
|
//+------------------------------------------------------------------+
|
|
|
|
//---MA130
|
|
int maHandler = INVALID_HANDLE;
|
|
|
|
double maBuffer[];
|
|
|
|
//---MA200
|
|
int maHandler200 = INVALID_HANDLE;
|
|
|
|
double maBuffer200[];
|
|
|
|
//---ATR
|
|
int atrHandler = INVALID_HANDLE;
|
|
|
|
double atrBuffer[];
|
|
|
|
|
|
int OnInit() {
|
|
//if (!VerificarInputs()) return (INIT_PARAMETERS_INCORRECT);
|
|
|
|
//if (!VerificarParametrosApi()) return (INIT_FAILED);
|
|
|
|
// EVITAR DE TROCAR O ATIVO NA MESMA JANELA
|
|
if(simboloInicial == "") simboloInicial = _Symbol;
|
|
|
|
if (simboloInicial != _Symbol) {
|
|
Alert("Tentativa de alteração de ativo não permitida com o robo em execução!");
|
|
|
|
RemoverIndicadores();
|
|
|
|
ChartSetSymbolPeriod(0, simboloInicial, _Period);
|
|
}
|
|
|
|
InicializarIndicadores();
|
|
|
|
EventSetTimer(SEGUNDOS_TIMER);
|
|
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
|
|
void OnDeinit(const int reason) {
|
|
RemoverIndicadores();
|
|
|
|
EventKillTimer();
|
|
}
|
|
|
|
void OnTick() {
|
|
//+------------------------------------------------------------------+
|
|
//| USADO PARA FORÇAR A ATUALIZAÇÃO DOS INDICADORES |
|
|
//+------------------------------------------------------------------+
|
|
if (VerificarOrdensPosicoes()) LogicaOperacional();
|
|
|
|
// if (NovoBarraUmMin()) {
|
|
|
|
|
|
|
|
|
|
// }
|
|
|
|
if (NovoBarraUmMin()) {
|
|
|
|
FecharOrdemPendente();
|
|
|
|
FecharOrdemPendenteCompra();
|
|
|
|
if (VerificarOrdensPosicoes()) {
|
|
|
|
VendaLimitada();
|
|
|
|
CompraLimitada();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//+-------------------------------------------------------------------+
|
|
//| VERIFICAÇÃO DE QUANDO O ROBO FICAR RODANDO DE UM DIA PARA O OUTRO |
|
|
//+-------------------------------------------------------------------+
|
|
|
|
|
|
}
|
|
|
|
|
|
void OnTimer(void) {
|
|
//+---------------------------------------------------------------------------------------+
|
|
//| SE CHEGOU O HORARIO DE FECHAMENTO, APAGA AS ORDENS PENDENTES DE VENDA |
|
|
//+---------------------------------------------------------------------------------------+
|
|
if (HorarioFechamento()) {
|
|
|
|
FecharOrdemPendente();
|
|
|
|
FecharOrdemPendenteCompra();
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| FUNÇÕES AUXILIARES |
|
|
//+------------------------------------------------------------------+
|
|
//---
|
|
bool NovoBarraUmMin() {
|
|
static datetime ultimaHora = 0;
|
|
|
|
datetime ultimaHoraBarra = (datetime) SeriesInfoInteger(_Symbol, PERIOD_M1, 0);
|
|
|
|
if(ultimaHora == 0) {
|
|
ultimaHora = ultimaHoraBarra;
|
|
|
|
return false;
|
|
}
|
|
|
|
if(ultimaHora != ultimaHoraBarra) {
|
|
|
|
ultimaHora = ultimaHoraBarra;
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
//---
|
|
bool NovaBarra() {
|
|
static datetime ultimaHora = 0;
|
|
|
|
datetime ultimaHoraBarra = (datetime) SeriesInfoInteger(_Symbol, _Period, SERIES_LASTBAR_DATE);
|
|
|
|
if(ultimaHora == 0) {
|
|
ultimaHora = ultimaHoraBarra;
|
|
|
|
return false;
|
|
}
|
|
|
|
if(ultimaHora != ultimaHoraBarra) {
|
|
|
|
ultimaHora = ultimaHoraBarra;
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
bool VerificarInputs() {
|
|
if (!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) {
|
|
Print("ERRO: Verifique se a negociação automatizada é permitida nas configurações do terminal!");
|
|
|
|
return false;
|
|
}
|
|
|
|
if(!MQLInfoInteger(MQL_TRADE_ALLOWED)) {
|
|
Print("ERRO: A negociação automatizada é proibida nas configurações do Robô!");
|
|
|
|
return false;
|
|
}
|
|
|
|
//
|
|
ENUM_ACCOUNT_MARGIN_MODE tipoConta = (ENUM_ACCOUNT_MARGIN_MODE) AccountInfoInteger(ACCOUNT_MARGIN_MODE);
|
|
if (tipoConta != ACCOUNT_MARGIN_MODE_RETAIL_NETTING) {
|
|
Print("ERRO: Este robô só poderá ser executado em conta NETTING!");
|
|
|
|
return false;
|
|
}
|
|
|
|
if (inputIdCliente <= 0) {
|
|
Print("ERRO: É obrigatótio informar o ID!");
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
if (inputQtdContratos == 0) {
|
|
Print("ERRO: É obrigatótio informar o Valor do Caixa!");
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//---
|
|
bool IndicadorATR() {
|
|
ArraySetAsSeries(atrBuffer, true);
|
|
|
|
atrHandler = iATR(_Symbol, _Period, 1080);
|
|
|
|
if (atrHandler == INVALID_HANDLE) {
|
|
Print("ERRO: Falha na inicialização do Indicador ATR!");
|
|
|
|
return(false);
|
|
} else {
|
|
int dadosCopiar = 10;
|
|
|
|
CopyBuffer(atrHandler, 0, 0, dadosCopiar, atrBuffer);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//---
|
|
bool IndicadorMediaMovel() {
|
|
ArraySetAsSeries(maBuffer, true);
|
|
|
|
maHandler = iMA(_Symbol, _Period, 60, 0, MODE_EMA, PRICE_CLOSE);
|
|
|
|
if (maHandler == INVALID_HANDLE) {
|
|
Print("ERRO: Falha na inicialização do Indicador Media Móvel!");
|
|
|
|
return(false);
|
|
} else {
|
|
int dadosCopiar = 10;
|
|
|
|
CopyBuffer(maHandler, 0, 0, dadosCopiar, maBuffer);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//---
|
|
bool IndicadorMediaMovel200() {
|
|
ArraySetAsSeries(maBuffer200, true);
|
|
|
|
maHandler200 = iMA(_Symbol, _Period, 200, 0, MODE_SMA, PRICE_CLOSE);
|
|
|
|
if (maHandler200 == INVALID_HANDLE) {
|
|
Print("ERRO: Falha na inicialização do Indicador Media Móvel!");
|
|
|
|
return(false);
|
|
} else {
|
|
int dadosCopiar = 10;
|
|
|
|
CopyBuffer(maHandler200, 0, 0, dadosCopiar, maBuffer200);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
//---
|
|
bool InicializarIndicadores() {
|
|
RemoverIndicadores();
|
|
|
|
IndicadorMediaMovel();
|
|
|
|
IndicadorMediaMovel200();
|
|
|
|
IndicadorATR();
|
|
|
|
// COLOCAR OS INDICADORES NO GRáFICO
|
|
if(!ChartIndicatorAdd(0, 0, maHandler)) {
|
|
Print("ERRO: Erro ao colocar indicador Média Móvel no gráfico!");
|
|
|
|
return(false);
|
|
}
|
|
|
|
if(!ChartIndicatorAdd(0, 0, maHandler200)) {
|
|
Print("ERRO: Erro ao colocar indicador Média Móvel no gráfico!");
|
|
|
|
return(false);
|
|
}
|
|
|
|
if(!ChartIndicatorAdd(0, 0, atrHandler)) {
|
|
Print("ERRO: Erro ao colocar indicador ATR no gráfico!");
|
|
|
|
return(false);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//---
|
|
bool RemoverIndicadores() {
|
|
int subWindows = (int) ChartGetInteger(0, CHART_WINDOWS_TOTAL);
|
|
|
|
for(int i = subWindows-1; i>=0; i--) {
|
|
int inds = ChartIndicatorsTotal(0,i);
|
|
|
|
if(inds >= 1) {
|
|
for(int j = inds; j >= 0; j--) {
|
|
string indName = ChartIndicatorName(0, i, j);
|
|
|
|
ChartIndicatorDelete(0, i, indName);
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//---
|
|
bool VerificarOrdensPosicoes() {
|
|
compradoMercado = false;
|
|
vendidoMercado = false;
|
|
compradoPendente = false;
|
|
vendidoPendente = false;
|
|
|
|
|
|
ticketCompradoMercado = 0;
|
|
ticketVendidoMercado = 0;
|
|
ticketCompradoPendente = 0;
|
|
ticketVendidoPendente = 0;
|
|
|
|
quantLotesVenda = 0;
|
|
quantPosicoesExecutadasGlobal = 0;
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| LOOP NAS ORDENS - COMPRA/VENDA PENDENTE AINDA NÃO EXECUTADAS |
|
|
//+------------------------------------------------------------------+
|
|
int ordersTotal = OrdersTotal();
|
|
|
|
for (int i=0; i < ordersTotal && !IsStopped(); i++) {
|
|
ulong orderTicket = OrderGetTicket(i);
|
|
|
|
if(OrderSelect(orderTicket)) {
|
|
ulong orderMagic = OrderGetInteger(ORDER_MAGIC);
|
|
|
|
string orderSymbol = OrderGetString(ORDER_SYMBOL);
|
|
|
|
ENUM_ORDER_TYPE orderType = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
|
|
|
|
if (orderSymbol == _Symbol) {
|
|
if (orderType == ORDER_TYPE_BUY_LIMIT) {
|
|
compradoPendente = true;
|
|
|
|
ticketCompradoPendente = orderTicket;
|
|
}
|
|
|
|
if (orderType == ORDER_TYPE_SELL_LIMIT) {
|
|
vendidoPendente = true;
|
|
|
|
ticketVendidoPendente = orderTicket;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------+
|
|
//| LOOP NAS POSIÇÕES - COMPRA/VENDA A MERCADO OU ORDENS QUE FORAM EXECUTADAS |
|
|
//+---------------------------------------------------------------------------+
|
|
int positionsTotal = PositionsTotal();
|
|
|
|
for (int i=0; i < positionsTotal && !IsStopped(); i++) {
|
|
ulong posTicket = PositionGetTicket(i);
|
|
|
|
if(PositionSelectByTicket(posTicket)) {
|
|
ulong posMagic = PositionGetInteger(POSITION_MAGIC);
|
|
|
|
string posSymbol = PositionGetString(POSITION_SYMBOL);
|
|
|
|
ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
|
|
|
|
if (posType == POSITION_TYPE_BUY) quantPosicoesExecutadasGlobal++;
|
|
|
|
if(posSymbol == _Symbol) {
|
|
if (posType == POSITION_TYPE_BUY) {
|
|
compradoMercado = true;
|
|
|
|
quantLotesVenda = NormalizeDouble(PositionGetDouble(POSITION_VOLUME), _Digits);
|
|
|
|
ticketCompradoMercado = posTicket;
|
|
}
|
|
|
|
if (posType == POSITION_TYPE_SELL) {
|
|
vendidoMercado = true;
|
|
|
|
ticketVendidoMercado = posTicket;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//---
|
|
bool LogicaOperacional() {
|
|
if( !SymbolInfoTick(_Symbol, tick) ) {
|
|
Print("ERRO: Dados de ticks não foram copiados corretamente");
|
|
|
|
return(false);
|
|
}
|
|
|
|
|
|
bool podeComprar = false;
|
|
bool podeVender = false;
|
|
|
|
|
|
|
|
double ma200Valor = NormalizeDouble(maBuffer200[0], _Digits);
|
|
double atrValor = NormalizeDouble(atrBuffer[0], _Digits);
|
|
double atrValorMulti = NormalizeDouble(atrValor*3.5, _Digits);
|
|
double precoAtual = NormalizeDouble(tick.last, _Digits);
|
|
double maior = NormalizeDouble(iHighest(_Symbol, _Period, MODE_HIGH, 8, 0), _Digits);
|
|
double menor = NormalizeDouble(iLowest(_Symbol, _Period, MODE_LOW, 8, 0), _Digits);
|
|
double precoMaximo = NormalizeDouble(iHigh(_Symbol, _Period, maior), _Digits);
|
|
double precoMinimo = NormalizeDouble(iLow(_Symbol, _Period, menor), _Digits);
|
|
double precoRange = NormalizeDouble(precoMaximo-precoMinimo, _Digits);
|
|
double aberturaBarraAtual = NormalizeDouble(iOpen(_Symbol, _Period, 0), _Digits);
|
|
double precoHighBarraAnterior = NormalizeDouble(iHigh(_Symbol, _Period, 1), _Digits);
|
|
double precoLowBarraAnterior = NormalizeDouble(iLow(_Symbol, _Period, 1), _Digits);
|
|
double quantidadeContratos = NormalizeDouble(inputQtdContratos, _Digits);
|
|
double IBarra = NormalizeDouble(iBars(_Symbol, _Period), _Digits);
|
|
double maValor = NormalizeDouble(maBuffer[0], _Digits);
|
|
|
|
|
|
Print("IBarra = ", IBarra);
|
|
Print("atrValorMulti ", atrValorMulti);
|
|
Print("precoRange ", precoRange);
|
|
Print("atrValor ", atrValor);
|
|
Print("HorarioPermitido() ", HorarioPermitido());
|
|
Print("CompraLimitada() ", CompraLimitada());
|
|
Print("VendaLimitada() ", VendaLimitada());
|
|
|
|
|
|
|
|
podeComprar = aberturaBarraAtual > ma200Valor &&
|
|
aberturaBarraAtual > maValor &&
|
|
precoRange < atrValorMulti
|
|
|
|
;
|
|
|
|
podeVender = aberturaBarraAtual < ma200Valor &&
|
|
aberturaBarraAtual < maValor &&
|
|
precoRange < atrValorMulti
|
|
|
|
;
|
|
|
|
|
|
if (HorarioPermitido()) {
|
|
if (podeComprar && !compradoPendente && !vendidoPendente && !compradoMercado && !vendidoMercado) {
|
|
bool ok = trade.BuyLimit(quantidadeContratos, precoLowBarraAnterior, _Symbol, 0, 0, ORDER_TIME_DAY, 0, "Compra a Mercado!");
|
|
|
|
if (ok) {
|
|
if (trade.ResultRetcode() == 10008 || trade.ResultRetcode() == 10009) {
|
|
Print("Ordem de COMPRA PENDENTE enviada com sucesso!");
|
|
} else {
|
|
Print("ERRO: Retorno inesperado do servidor");
|
|
|
|
return(false);
|
|
}
|
|
} else {
|
|
Print("ERRO: Erro ao enviar trade.BuyLimit");
|
|
|
|
return(false);
|
|
}
|
|
} else if (podeVender && !compradoPendente && !vendidoPendente && !compradoMercado && !vendidoMercado && HorarioPermitido()) {
|
|
bool ok = trade.SellLimit(quantidadeContratos, precoHighBarraAnterior, _Symbol, 0, 0, ORDER_TIME_DAY, 0, "Venda a Mercado!");
|
|
|
|
if (ok) {
|
|
if (trade.ResultRetcode() == 10008 || trade.ResultRetcode() == 10009) {
|
|
Print("Ordem de VENDA PENDENTE enviada com sucesso!");
|
|
} else {
|
|
Print("ERRO: Retorno inesperado do servidor");
|
|
|
|
return(false);
|
|
}
|
|
} else {
|
|
Print("ERRO: Erro ao enviar trade.SellLimit");
|
|
return(false);
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------------+
|
|
//| SE TIVER COMPRADO A MERCADO, ABRE UMA ORDEM DE VENDA PENDENTE PARA TENTAR ZERAR |
|
|
//+---------------------------------------------------------------------------------+
|
|
//---
|
|
bool VendaLimitada() {
|
|
|
|
if (compradoMercado && !vendidoPendente) {
|
|
//bool ok = trade.Sell(quantidadeContratos, _Symbol, 0, 0, 0, "Zeragem da Compra!");
|
|
double precoHighBarraAnterior = NormalizeDouble(iHigh(_Symbol, _Period, 1), _Digits);
|
|
bool ok = trade.SellLimit(1.0, precoHighBarraAnterior, _Symbol, 0, 0, ORDER_TIME_DAY, 0, "Venda Para Zerar Posição");
|
|
|
|
if (ok) {
|
|
if (trade.ResultRetcode() == 10008 || trade.ResultRetcode() == 10009) {
|
|
Print("Ordem de Zeragem da Compra enviada com sucesso!");
|
|
} else {
|
|
Print("ERRO: Retorno inesperado do servidor");
|
|
|
|
return(false);
|
|
}
|
|
} else {
|
|
Print("ERRO: Erro ao enviar trade.SellLimit");
|
|
|
|
return(false);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------------+
|
|
//| SE TIVER VENDIDO A MERCADO, ABRE UMA ORDEM DE COMPRA PENDENTE PARA TENTAR ZERAR |
|
|
//+---------------------------------------------------------------------------------+
|
|
|
|
//---
|
|
bool CompraLimitada() {
|
|
if (vendidoMercado && !compradoPendente) {
|
|
//bool ok = trade.Buy(quantidadeContratos, _Symbol, 0, 0, 0, "Zeragem da Venda!");
|
|
double precoLowBarraAnterior = NormalizeDouble(iLow(_Symbol, _Period, 1), _Digits);
|
|
bool ok = trade.BuyLimit(1.0, precoLowBarraAnterior, _Symbol, 0, 0, ORDER_TIME_DAY, 0, "Compra Para Zerar Posição");
|
|
if (ok) {
|
|
if (trade.ResultRetcode() == 10008 || trade.ResultRetcode() == 10009) {
|
|
Print("Ordem de Zeragem da Venda enviada com sucesso!");
|
|
} else {
|
|
Print("ERRO: Retorno inesperado do servidor");
|
|
|
|
return(false);
|
|
}
|
|
} else {
|
|
Print("ERRO: Erro ao enviar trade.BuyLimit");
|
|
|
|
return(false);
|
|
}
|
|
}
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
//---
|
|
datetime DataExpiracao() {
|
|
MqlRates barraAtual[];
|
|
|
|
CopyRates(_Symbol, PERIOD_D1, 0, 1, barraAtual);
|
|
|
|
return barraAtual[0].time + 86399; //'23:59:59'
|
|
}
|
|
|
|
bool NovoDia() {
|
|
static datetime today;
|
|
|
|
if (today != iTime(_Symbol, PERIOD_D1, 0)) {
|
|
today = iTime(_Symbol, PERIOD_D1, 0);
|
|
|
|
//Print("É um novo dia: ", TimeToString(today));
|
|
|
|
return true;
|
|
} else //Print("Não é um novo dia!");
|
|
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
bool FecharPosicao(ulong ticket, bool compra) {
|
|
string sinal = compra ? "COMPRA" : "VENDA";
|
|
|
|
string msgOK = "Ordem de " + sinal + " fechada com sucesso!";
|
|
|
|
string msgErro = "ERRO: Erro ao enviar trade.PositionClose (" + sinal + ")";
|
|
|
|
bool ok = trade.PositionClose(ticket);
|
|
|
|
if (ok) {
|
|
if (trade.ResultRetcode() == 10008 || trade.ResultRetcode() == 10009) {
|
|
Print(msgOK);
|
|
} else {
|
|
Print("ERRO: Retorno inesperado do servidor");
|
|
|
|
return(false);
|
|
}
|
|
} else {
|
|
Print(msgErro);
|
|
|
|
return(false);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
//---
|
|
bool HorarioPermitido() {
|
|
string horaInicialAbrirPosicao = "09:30"; //Aqui Seta o Horário que o robô vai começar a operar
|
|
string horaLimiteComprar = "17:42"; //Aqui Seta o Horário que o robô vai parar de fazer entradas/operar
|
|
|
|
MqlDateTime horaAtual, horarioLimiteAbrirPosicao, horarioInicialAbrirPosicao;
|
|
|
|
TimeToStruct(TimeCurrent(), horaAtual);
|
|
TimeToStruct(StringToTime(horaLimiteComprar), horarioLimiteAbrirPosicao);
|
|
TimeToStruct(StringToTime(horaInicialAbrirPosicao), horarioInicialAbrirPosicao);
|
|
|
|
|
|
if ((horaAtual.hour == horarioInicialAbrirPosicao.hour) && (horaAtual.min >= horarioInicialAbrirPosicao.min))return true;
|
|
|
|
if ((horaAtual.hour > horarioInicialAbrirPosicao.hour) && (horaAtual.hour < horarioLimiteAbrirPosicao.hour)) return true;
|
|
|
|
if ((horaAtual.hour == horarioLimiteAbrirPosicao.hour) && (horaAtual.min < horarioLimiteAbrirPosicao.min)) return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
bool HorarioPermitidoDois() {
|
|
string horaInicialAbrirPosicao = "11:40"; //Aqui Seta o Horário que o robô vai começar a operar
|
|
string horaLimiteComprar = "11:50"; //Aqui Seta o Horário que o robô vai parar de fazer entradas/operar
|
|
|
|
MqlDateTime horaAtual, horarioLimiteAbrirPosicao, horarioInicialAbrirPosicao;
|
|
|
|
TimeToStruct(TimeCurrent(), horaAtual);
|
|
TimeToStruct(StringToTime(horaLimiteComprar), horarioLimiteAbrirPosicao);
|
|
TimeToStruct(StringToTime(horaInicialAbrirPosicao), horarioInicialAbrirPosicao);
|
|
|
|
|
|
if ((horaAtual.hour == horarioInicialAbrirPosicao.hour) && (horaAtual.min >= horarioInicialAbrirPosicao.min))return true;
|
|
|
|
if ((horaAtual.hour > horarioInicialAbrirPosicao.hour) && (horaAtual.hour < horarioLimiteAbrirPosicao.hour)) return true;
|
|
|
|
if ((horaAtual.hour == horarioLimiteAbrirPosicao.hour) && (horaAtual.min < horarioLimiteAbrirPosicao.min)) return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
bool HorarioPermitidoTres() {
|
|
string horaInicialAbrirPosicao = "12:30"; //Aqui Seta o Horário que o robô vai começar a operar
|
|
string horaLimiteComprar = "13:15"; //Aqui Seta o Horário que o robô vai parar de fazer entradas/operar
|
|
|
|
MqlDateTime horaAtual, horarioLimiteAbrirPosicao, horarioInicialAbrirPosicao;
|
|
|
|
TimeToStruct(TimeCurrent(), horaAtual);
|
|
TimeToStruct(StringToTime(horaLimiteComprar), horarioLimiteAbrirPosicao);
|
|
TimeToStruct(StringToTime(horaInicialAbrirPosicao), horarioInicialAbrirPosicao);
|
|
|
|
|
|
if ((horaAtual.hour == horarioInicialAbrirPosicao.hour) && (horaAtual.min >= horarioInicialAbrirPosicao.min))return true;
|
|
|
|
if ((horaAtual.hour > horarioInicialAbrirPosicao.hour) && (horaAtual.hour < horarioLimiteAbrirPosicao.hour)) return true;
|
|
|
|
if ((horaAtual.hour == horarioLimiteAbrirPosicao.hour) && (horaAtual.min < horarioLimiteAbrirPosicao.min)) return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
bool HorarioPermitidoQuatro() {
|
|
string horaInicialAbrirPosicao = "16:00"; //Aqui Seta o Horário que o robô vai começar a operar
|
|
string horaLimiteComprar = "16:30"; //Aqui Seta o Horário que o robô vai parar de fazer entradas/operar
|
|
|
|
MqlDateTime horaAtual, horarioLimiteAbrirPosicao, horarioInicialAbrirPosicao;
|
|
|
|
TimeToStruct(TimeCurrent(), horaAtual);
|
|
TimeToStruct(StringToTime(horaLimiteComprar), horarioLimiteAbrirPosicao);
|
|
TimeToStruct(StringToTime(horaInicialAbrirPosicao), horarioInicialAbrirPosicao);
|
|
|
|
|
|
if ((horaAtual.hour == horarioInicialAbrirPosicao.hour) && (horaAtual.min >= horarioInicialAbrirPosicao.min))return true;
|
|
|
|
if ((horaAtual.hour > horarioInicialAbrirPosicao.hour) && (horaAtual.hour < horarioLimiteAbrirPosicao.hour)) return true;
|
|
|
|
if ((horaAtual.hour == horarioLimiteAbrirPosicao.hour) && (horaAtual.min < horarioLimiteAbrirPosicao.min)) return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
bool HorarioPermitidoCinco() {
|
|
string horaInicialAbrirPosicao = "16:55"; //Aqui Seta o Horário que o robô vai começar a operar
|
|
string horaLimiteComprar = "17:34"; //Aqui Seta o Horário que o robô vai parar de fazer entradas/operar
|
|
|
|
MqlDateTime horaAtual, horarioLimiteAbrirPosicao, horarioInicialAbrirPosicao;
|
|
|
|
TimeToStruct(TimeCurrent(), horaAtual);
|
|
TimeToStruct(StringToTime(horaLimiteComprar), horarioLimiteAbrirPosicao);
|
|
TimeToStruct(StringToTime(horaInicialAbrirPosicao), horarioInicialAbrirPosicao);
|
|
|
|
|
|
if ((horaAtual.hour == horarioInicialAbrirPosicao.hour) && (horaAtual.min >= horarioInicialAbrirPosicao.min))return true;
|
|
|
|
if ((horaAtual.hour > horarioInicialAbrirPosicao.hour) && (horaAtual.hour < horarioLimiteAbrirPosicao.hour)) return true;
|
|
|
|
if ((horaAtual.hour == horarioLimiteAbrirPosicao.hour) && (horaAtual.min < horarioLimiteAbrirPosicao.min)) return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
bool HorarioFechamento() {
|
|
string horaLimiteFicarPosicionado = "17:35"; //Aqui Seta o Horário que, se houver posição ou ordens pendentes(limitadas), Tudo será fechado!
|
|
|
|
MqlDateTime horaAtual, horarioLimiteFecharOrdem;
|
|
|
|
TimeToStruct(TimeCurrent(), horaAtual);
|
|
|
|
TimeToStruct(StringToTime(horaLimiteFicarPosicionado), horarioLimiteFecharOrdem);
|
|
|
|
//if ((horaAtual.hour == horaFechamento.hour) && (horaAtual.min >= horaFechamento.min)) return true;
|
|
|
|
//if (horaAtual.hour > horaFechamento.hour) return true;
|
|
|
|
if (horaAtual.hour > horarioLimiteFecharOrdem.hour) return true;
|
|
|
|
if ((horaAtual.hour == horarioLimiteFecharOrdem.hour) && (horaAtual.min >= horarioLimiteFecharOrdem.min)) return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
//---
|
|
bool FecharOrdemPendente() {
|
|
int ordersTotal = OrdersTotal();
|
|
|
|
for (int i=0; i < ordersTotal && !IsStopped(); i++) {
|
|
ulong orderTicket = OrderGetTicket(i);
|
|
|
|
if(OrderSelect(orderTicket)) {
|
|
ulong orderMagic = OrderGetInteger(ORDER_MAGIC);
|
|
|
|
string orderSymbol = OrderGetString(ORDER_SYMBOL);
|
|
|
|
ENUM_ORDER_TYPE orderType = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
|
|
|
|
if (orderSymbol == _Symbol) {
|
|
if (orderType == ORDER_TYPE_SELL_LIMIT) {
|
|
bool ok = trade.OrderDelete(orderTicket);
|
|
|
|
if (ok) {
|
|
if (trade.ResultRetcode() == 10008 || trade.ResultRetcode() == 10009) {
|
|
Print("Ordem de VENDA PENDENTE excluida com sucesso!");
|
|
} else {
|
|
Print("ERRO: Retorno inesperado do servidor");
|
|
|
|
return(false);
|
|
}
|
|
} else {
|
|
Print("ERRO: Erro ao enviar trade.OrderDelete (VENDA PENDENTE)");
|
|
|
|
return(false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//---
|
|
bool FecharOrdemPendenteCompra() {
|
|
int ordersTotal = OrdersTotal();
|
|
|
|
for (int i=0; i < ordersTotal && !IsStopped(); i++) {
|
|
ulong orderTicket = OrderGetTicket(i);
|
|
|
|
if(OrderSelect(orderTicket)) {
|
|
ulong orderMagic = OrderGetInteger(ORDER_MAGIC);
|
|
|
|
string orderSymbol = OrderGetString(ORDER_SYMBOL);
|
|
|
|
ENUM_ORDER_TYPE orderType = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
|
|
|
|
if (orderSymbol == _Symbol) {
|
|
if (orderType == ORDER_TYPE_BUY_LIMIT) {
|
|
bool ok = trade.OrderDelete(orderTicket);
|
|
|
|
if (ok) {
|
|
if (trade.ResultRetcode() == 10008 || trade.ResultRetcode() == 10009) {
|
|
Print("Ordem de COMPRA PENDENTE excluida com sucesso!");
|
|
} else {
|
|
Print("ERRO: Retorno inesperado do servidor");
|
|
|
|
return(false);
|
|
}
|
|
} else {
|
|
Print("ERRO: Erro ao enviar trade.OrderDelete (COMPRA PENDENTE)");
|
|
|
|
return(false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
//---
|
|
bool FecharPosicaoAbertas() {
|
|
int positionsTotal = PositionsTotal();
|
|
|
|
for (int i = 0; i < positionsTotal && !IsStopped(); i++) {
|
|
ulong posTicket = PositionGetTicket(i);
|
|
|
|
if (PositionSelectByTicket(posTicket)) {
|
|
ulong posMagic = PositionGetInteger(POSITION_MAGIC);
|
|
|
|
string posSymbol = PositionGetString(POSITION_SYMBOL);
|
|
|
|
ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
|
|
|
|
// já tenho posição com meu magic number
|
|
//if(posSymbol == _Symbol && posMagic == VALOR_NUMERO_MAGICO) {
|
|
if(posSymbol == _Symbol) {
|
|
if (posType == POSITION_TYPE_BUY || posType == POSITION_TYPE_SELL) {
|
|
FecharPosicao(posTicket, posType == POSITION_TYPE_BUY ? true : false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|