olá eu estava com o mesmo problema pra encontra algo confiavel e então fiz esta gambiarrinha ,
apenas na primeira criada do objeto da class o progama dar uma erroscadinha porque ele precisa da variavel global no terminal para funcionar bem, depois nas novas inicializações ele fica lizo
para garantir uma prescisão vou ajustando a hora de tempo em tempo, no meu caso foi de segundo em segundo, porem esse tempo tem que ser maior em progamas mais complexos, porque talvez o processador não processe tudo do OnTime() em menos de 1 segundo
espero que ajude quem ainda esta com esse tipo de problema e espero que o autor desse post tenha encontrado uma solução melhor para nos compartilhar, abrçs
enum ENUM_MARKET_STATES{ FECHADO = -1, SEM_CONEXAO = 0, ABERTO = 1 }; class MarketStates{ public: // construtor // desconstrutor MarketStates(){ criarVariavelGlobal(); } ~MarketStates(){} private: void criarVariavelGlobal(){ // se minha variavel global já foi configurada só vou confirmar ela no proximo tick if(GlobalVariableCheck("Difereça entre minha hora e da Corretora")) return; // looping até criar uma variavel global que garda a diferença entre minha hora e corretora while(IsStopped()){ // verificando se esta sincronizado com o servirdo if( SeriesInfoInteger(_Symbol,_Period,SERIES_SYNCHRONIZED) ){ ResetLastError(); // criando a minha variavel global no terminal para mim saber as difereças de horas TimeLocal() e TimeCorrent() if(0 != GlobalVariableSet("Difereça entre minha hora e da Corretora", TimeCurrent() - TimeLocal() )) Print("a Variavel Global \"Difereça entre minha hora e da Corretora\" foi criada"); else Print("ERRO : " + IntegerToString(GetLastError())); // pulando fora do loop break; } // esperar mais 1 segundo para tentar de novo Sleep(1000); } Print("HORA SEVIDOR (ultimo tick) : " + TimeToString((TimeCurrent())) ); Print("HORA LOCAL : " + TimeToString(TimeLocal()) ); Print("DIFERENÇA " + TimeToString((datetime)MathAbs(GlobalVariableGet("Difereça entre minha hora e da Corretora")), TIME_SECONDS) ); Sleep(2000); // esperar 2s para que // a primeira chamada da fução segundosrestantes() // não retornar um numero positivo // caso o mercado esteja fechado // uma vez a variavel global criada no terminal // essa demora não existira mais nas proximas iniciações do progama mql } public: // aqui vou usar a barra M1 por ser a unica que não falta pedaço quando o mercado fecha e abre só no outro dia datetime timeBarra(ENUM_TIMEFRAMES tempoGrafico = PERIOD_M1, int index = 0){ datetime time[1]; CopyTime(_Symbol,tempoGrafico,index,1,time); return time[0]; } int segundosRestantesDaBarra(ENUM_TIMEFRAMES tempoGrafico){ // ajustarDiferecaEntreMinhaHoraEServidor(); return int( timeBarra(tempoGrafico) + PeriodSeconds(tempoGrafico) - meuTime() ); } // aqui esta configurado para ser chamada de segundo em segundo no OnTime() porem nada impede de usar otura configuração void ajustarDiferencaEntreHoraLocalECorretora(){ static int timeCurrentMaisUm = int(TimeCurrent()) + 1; static int segundosConsecultivos = 0; static int novaDiferenca; static int ajustarAgora = 2; static bool suporteTime = false; int variou = segundosRestantesDaBarra(PERIOD_M1) - 59; if( variou > 0) GlobalVariableSet("Difereça entre minha hora e da Corretora", GlobalVariableGet("Difereça entre minha hora e da Corretora") + variou); if(timeCurrentMaisUm == TimeCurrent()){ segundosConsecultivos++; if( segundosConsecultivos == 2) novaDiferenca = timeCurrentMaisUm - int(TimeLocal()); if( segundosConsecultivos == ajustarAgora){ GlobalVariableSet("Difereça entre minha hora e da Corretora", timeCurrentMaisUm - TimeLocal()); segundosConsecultivos = 0; ajustarAgora++; } timeCurrentMaisUm++; } else if( TimeCurrent() > timeCurrentMaisUm ){ timeCurrentMaisUm = int(TimeCurrent()) + 1; segundosConsecultivos = 0; } } static datetime meuTime(){ if( !GlobalVariableCheck("Difereça entre minha hora e da Corretora") ){ Print("Criando outra variavel global \"Difereça entre minha hora e da Corretora\" porque a anterior foi apagada "); GlobalVariableSet("Difereça entre minha hora e da Corretora", TimeCurrent() - TimeLocal() ); } return TimeLocal() + (datetime) GlobalVariableGet("Difereça entre minha hora e da Corretora"); } // função para saber se o mercado esta aberto, fechado ou sem conexão ENUM_MARKET_STATES mercadoStatus(){ // verifica conecção if(SymbolIsSynchronized(_Symbol)) // se segundos restantes for menor que zero é ou porque não esta sicronizado ou o mercado ta fechado if(segundosRestantesDaBarra(PERIOD_M1) < 0) return FECHADO; else return ABERTO; return SEM_CONEXAO; } };
Olá Francisco,
Ainda não encontrei uma solução confiável, vou analisar seu código pra ver se ele encaixa na no meu EA.
O mais decepcionante é que na boleta do MT é verificado se o mercado está aberto, mas esse código não está disponível para desenvolvedores.
Eu uso essa função no bovespa,
porém eu comentei algumas partes porque no bovespa a corretora permite serie histórica a operação de EAs
mas não permite trade manual nessas series continuas.. aqui é tudo invertido... rs
//+------------------------------------------------------------------+ //| Gets the information about permission to trade | //+------------------------------------------------------------------+ bool IsTradeAllowed() { if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) { ShowComment("Verifique se a negociação automática é permitida nas configurações do terminal!"); return(false); } if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) { ShowComment("Verifique se a negociação automática é permitida nas configurações do terminal!"); return(false); } //else // { // if(!MQLInfoInteger(MQL_TRADE_ALLOWED)) // { // ShowComment("A negociação automatizada está proibida nas configurações do programa para "+__FILE__); // return(false); // } // } if(!AccountInfoInteger(ACCOUNT_TRADE_EXPERT)) { ShowComment("A negociação automatizada é proibida para a conta "+AccountInfoInteger(ACCOUNT_LOGIN)+ " no lado do servidor de comércio"); return(false); } //if(!AccountInfoInteger(ACCOUNT_TRADE_ALLOWED)) // { // ShowComment("A negociação está proibida para a conta "+AccountInfoInteger(ACCOUNT_LOGIN)+ // ".\n Talvez uma senha de investidor tenha sido usada para se conectar à conta de negociação."+ // "\n Verifique o diário do terminal para a seguinte entrada:"+ // "\n\'"+AccountInfoInteger(ACCOUNT_LOGIN)+"\': A negociação foi desativada - modo investidor."); // return(false); // } //--- return(true); }
Francisco do céu, ainda bem que você escreveu que é uma gambiarrinha. rs
Que código imenso cheio de loops! Ha partes opnde uma coisa cancela a outra logo em seguinda (Ex: você soma o timelocal(), e na função que faz a chamada você subtrai o mesmo valor de timelocal() que foi somado, logo, uma coisa anula a outra e é apenas gasto de processamento fazer tanto vai e vem..
Seria uma critica, mas não é, pois você avisou que o código é uma gambiarra.
Pela sua sinceridade, analisei seu código, peguei o seu código acima, removi todas as partes as quais uma cancela a outra, removi loops desnecessários, e seu código ficou assim:
É exatamente o que tudo aquilo lá está fazendo:
enum ENUM_MARKET_STATES { FECHADO = -1, SEM_CONEXAO = 0, ABERTO = 1 }; ENUM_MARKET_STATES mercadoStatus() { if(TerminalInfoInteger(TERMINAL_CONNECTED)) { ENUM_TIMEFRAMES tempoGrafico = PERIOD_M1; datetime time[]; CopyTime(_Symbol,tempoGrafico,0,1,time); int segundosRestantesDaBarra = ( (int)time[0] - (int)TimeCurrent() + PeriodSeconds(tempoGrafico) ); if(segundosRestantesDaBarra < 0) { return FECHADO; } else { return ABERTO; } } return SEM_CONEXAO; }
Tomei a liberdade de mudar apenas a função SymbolIsSynchronized(_Symbol) que você utiliza para detectar se está conectado, pela função correta pra essa finalidade if(TerminalInfoInteger(TERMINAL_CONNECTED)) .
Essa lógica toda é funcional em grande parte do tempo, eu a estou utilizando (obrigado!), mas ela pode falhar em ativos ou moedas onde o volume de ticks é baixo.
Francisco do céu, ainda bem que você escreveu que é uma gambiarrinha. rs
Que código imenso cheio de loops! Ha partes opnde uma coisa cancela a outra logo em seguinda (Ex: você soma o timelocal(), e na função que faz a chamada você subtrai o mesmo valor de timelocal() que foi somado, logo, uma coisa anula a outra e é apenas gasto de processamento fazer tanto vai e vem..
Seria uma critica, mas não é, pois você avisou que o código é uma gambiarra.
Pela sua sinceridade, analisei seu código, peguei o seu código acima, removi todas as partes as quais uma cancela a outra, removi loops desnecessários, e seu código ficou assim:
É exatamente o que tudo aquilo lá está fazendo:
Tomei a liberdade de mudar apenas a função SymbolIsSynchronized(_Symbol) que você utiliza para detectar se está conectado, pela função correta pra essa finalidade if(TerminalInfoInteger(TERMINAL_CONNECTED)) .
Essa lógica toda é funcional em grande parte do tempo, eu a estou utilizando (obrigado!), mas ela pode falhar em ativos ou moedas onde o volume de ticks é baixo.
Belissimo refactoring!!!
Para evitar o problema com ativos pouco liquidos, e já que o objetivo é só entender se esta fechado ou não, não seria melhor usar como Simbolo o IBOV ao invés da constante _Symbol?
Belissimo refactoring!!!
Para evitar o problema com ativos pouco liquidos, e já que o objetivo é só entender se esta fechado ou não, não seria melhor usar como Simbolo o IBOV ao invés da constante _Symbol?
olá, depende de que mercado, a vista ou futuro.
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso
Boa dia pessoal,
Alguém sabe como verificar, via código, se neste momento o mercado está aberto?
A pergunta é extremamente simples, mas ainda não encontrei uma solução confiável que se aplique à Bovespa. Tudo o que encontrei, aparentemente, funciona para bolsas fora do Brasil, mas não aqui.
Estou trabalhando com o evento OnTimer e não OnTick, assim, antes de tentar enviar uma ordem ou tomar alguma outra decisão preciso verificar se o mercado está aberto.
Já tentei comparar TimeCurrent() com TimeLocal() e TimeTradeServer(). Seria simples, TimeCurrent fica parado se não houverem ticks, mas TimeLocal (horário do computador) não é confiável e TimeTradeServer aparentemente retorna o mesmo que TimeLocal, logo, também não é confiável. E além disso, o ativo pode ficar algum tempo sem receber ticks mesmo com o mercado aberto e não retornaria uma resposta precisa.
Já tentei também algumas funções de Market Information e OrderCheck, como SymbolInfoSessionQuote() e SymbolInfoSessionTrade() mas a tabela de sessão não ajuda em nada, pois o horário não está correto:
Neste momento, este é o código que elaborei pra teste:
Alguma outra ideia?