Discussão do artigo "Desenvolvendo um sistema de Replay - Simulação de mercado (Parte 10): Usando apenas dados reais na replay"

 

Novo artigo Desenvolvendo um sistema de Replay - Simulação de mercado (Parte 10): Usando apenas dados reais na replay foi publicado:

Aqui vamos ver como você pode utilizar dados mais fieis ( tickets negociados ) no sistema de replay, sem necessariamente ter que se preocupar se eles estão ou não ajustados.

No vídeo abaixo, você pode ver o resultado do trabalho feito neste artigo. Se bem, que algumas coisas, não serão de fato vistas. Já que são informações não visuais. Mas ao ver o vídeo, você já terá uma boa ideia do progresso do sistema de replay/simulador, durante cada um destes artigos. É só olhar os vídeos, e comparar as mudanças desde o inicio, até aqui.


No próximo artigo, iremos continuar o desenvolvimento deste sistema. Já que o mesmo ainda não está fazendo algumas coisas, que precisamos de fato.


Autor: Daniel Jose

 

Ei Daniel, boa noite !

Daniel, estou com a seguinte situação, eu consigo rodar e debugar o serviço. Mas não consigo debugar o indicador, pois quando rodo o serviço já carrega o executavel do indicador.

Não sei o que estou fazendo de errado, mas pelo que entendi, não dá para rodar o código do indicador para debugar. Seria isto mesmo ? Poderia me dar uma dica ? 

 
fernandomsoares #:

Ei Daniel, boa noite !

Daniel, estou com a seguinte situação, eu consigo rodar e debugar o serviço. Mas não consigo debugar o indicador, pois quando rodo o serviço já carrega o executavel do indicador.

Não sei o que estou fazendo de errado, mas pelo que entendi, não dá para rodar o código do indicador para debugar. Seria isto mesmo ? Poderia me dar uma dica ? 

Você NÃO está fazendo absolutamente nada de errado.😁👍

De fato o serviço inicializa o indicador de controle, assim que tudo está devidamente preparado para que o usuário venha a dar play no serviço.

Não entendendo bem, o motivo pelo qual você deseja debugar o indicador. Já que nele não é executado praticamente nada. Ele apenas serve como uma forma de interação entre o usuário e o serviço. Já que sem ele seria algo bastante complicado controlar quando queremos dar play ou pausar a execução do serviço. De qualquer maneira você não está fazendo nada de errado, em tentar estudar como o sistema funciona. Mas como dica, lhe aconselho a ler com calma os artigos. Pois neles explico em detalhes como o sistema funciona, o que irá lhe poupar muito esforço tentando entender a forma como as interações acontece. 😁👍

 

Ei Daniel, bom dia ! 

Daniel, fiz alguns estudos do seu codigo e do desenvolvimento na plataforma Metatrader 5, a fim de conseguir colocar um robo rodando no replay / simulador proposto nos seus artigos.

O Robo se baseia nos fluxo dos dados que estão chegando, isto é, vai contabilizando os ticks que chegam e fazendo calculos, para indicar se executa as operações.

Eu já interagi com este mesmo problema em outros posts, inclusive de antemão, peço desculpas pela insistencia, fato é que estudei mais um pouco e fiz as implementações que julguei necessárias para que o robo (EA) pudesse receber os ticks do serviço de Replay.

Mas estou com o seguinte problema: O robo recebe certinho os primeiros ticks, um a um, mas depois dos primeiros 47 ticks recebidos (coloquei um contador), passa a receber de forma muito espaçada os ticks, e não consegui compreender o porque.

Gostaria de te mostrar as implementações e te pedir uma ajuda para resolver o problema, se possível.

Segue as alterações que fiz:

- Na classe C_Replay (linhas em amarelo):

  - No metodo Event_OnTime:

     - Criei uma variavel do tipo MqlTick para receber o tick que será enviado para o grafico;

     - Após ser enviado a atualização da barra (CustomRatesUpdate), coloquei um codigo para enviar o tick para o grafico e ficar esperando se o mesmo foi processado atraves da variavel global "def_GlobalVariableTick";

inline int Event_OnTime(void)
                        {
                                bool    bNew;
                                int     mili, iPos;
                                u_Interprocess Info;
                                MqlTick TickToAdd[1];
                                static MqlRates Rate[1];
                                static datetime _dt = 0;
                                
                                if (m_ReplayCount >= m_Ticks.nTicks) return -1;
                                if (bNew = (_dt != m_Ticks.Info[m_ReplayCount].time))
                                {
                                        _dt = m_Ticks.Info[m_ReplayCount].time;
                                        Rate[0].real_volume = 0;
                                        Rate[0].tick_volume = 0;
                                }
                                mili = (int) m_Ticks.Info[m_ReplayCount].time_msc;
                                do
                                {
                                        while (mili == m_Ticks.Info[m_ReplayCount].time_msc)
                                        {
                                                Rate[0].close = m_Ticks.Info[m_ReplayCount].last;
                                                Rate[0].open = (bNew ? Rate[0].close : Rate[0].open);
                                                Rate[0].high = (bNew || (Rate[0].close > Rate[0].high) ? Rate[0].close : Rate[0].high);
                                                Rate[0].low = (bNew || (Rate[0].close < Rate[0].low) ? Rate[0].close : Rate[0].low);
                                                Rate[0].real_volume += (long) m_Ticks.Info[m_ReplayCount].volume_real;
                                                bNew = false;
                                                m_ReplayCount++;
                                        }
                                        mili++;
                                }while (mili == m_Ticks.Info[m_ReplayCount].time_msc);
                                Rate[0].time = m_Ticks.Info[m_ReplayCount].time;
                                CustomRatesUpdate(def_SymbolReplay, Rate, 1);
                                iPos = (int)((m_ReplayCount * def_MaxPosSlider) / m_Ticks.nTicks);
                                GlobalVariableGet(def_GlobalVariableReplay, Info.u_Value.df_Value);
                                if (Info.s_Infos.iPosShift != iPos)
                                {
                                        Info.s_Infos.iPosShift = (ushort) iPos;
                                        GlobalVariableSet(def_GlobalVariableReplay, Info.u_Value.df_Value);
                                }
				// Apenas plotará o tick no grafico se o robo tiver criado a variavel "def_GlobalVariableTick"
                                if (GlobalVariableCheck(def_GlobalVariableTick))
                                {
                                	TickToAdd[0]=m_Ticks.Info[m_ReplayCount];
             				Print("Tick enviado: Time: ", TickToAdd[0].time, " Time_msc: ", TickToAdd[0].time_msc, " Bid: ", TickToAdd[0].bid, " Ask: ", TickToAdd[0].ask, " Last: ", TickToAdd[0].last, " Volume: ", TickToAdd[0].volume_real);
                                	GlobalVariableSet(def_GlobalVariableTick, 1); // Quando o EA receber o tick (OnTick) irá alterar para ZERO
             		  		CustomTicksAdd(def_SymbolReplay, TickToAdd);
                                        short ctd=0;
                                	while (GlobalVariableGet(def_GlobalVariableTick) > 0 && (!_StopFlag) && ctd <= 50) { ctd++; Sleep(50) };
                                }
                                return (int)(m_Ticks.Info[m_ReplayCount].time_msc < mili ? m_Ticks.Info[m_ReplayCount].time_msc + (1000 - mili) : m_Ticks.Info[m_ReplayCount].time_msc - mili);
                        }


  - Codigo do robo (EA) que recebe o tick para processar:

#define def_GlobalVariableTick       "ReplayTick"
//+------------------------------------------------------------------+
int OnInit()
{
        GlobalVariableTemp(def_GlobalVariableTick);
        Print("Variavel Criada: ", def_GlobalVariableTick);
                
        return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason) 
{
   GlobalVariableDel(def_GlobalVariableTick);
}
//+------------------------------------------------------------------+
void OnTick() 
{
   MqlTick mTick;
   static int ctd=0;
   SymbolInfoTick(Symbol(),mTick);
   ctd++;
   Print(Symbol(), "   Tick Recebido ", ctd, ": Time: ", mTick.time, " Time_msc: ", mTick.time_msc, " Bid: ", mTick.bid, " Ask: ", mTick.ask, " Last: ", mTick.last, " Volume: ", mTick.volume);
   // .
   // .
   // Codigo de processamento do tick
   // .
   // .
   // Altera o valor da variavel global para zero, para receber o proximo tick
   GlobalVariableSet(def_GlobalVariableTick, 0);
}
 

continuando ....

Desta forma quando precisasse parar o robo para debugar, o replay estaria esperando até que passasse pela linha que seta a variavel global  "def_GlobalVariableTick" para ZERO;

Entendeu ?

 
fernandomsoares #:

continuando ....

Desta forma quando precisasse parar o robo para debugar, o replay estaria esperando até que passasse pela linha que seta a variavel global  "def_GlobalVariableTick" para ZERO;

Entendeu ?

O detalhe é que este mecanismo, passou por mudanças. Veja os artigos mais novos, pois neles mostro como os ticks serão lançados de forma correta. Inclusive sendo possível acompanhar os mesmo na janela de observação de mercado, o tal DOM. No momento já estamos com o artigo da parte 28 já publicado em português. Então este código que você está tentando ajustar e manipular já está completamente obsoleto. Você precisa acompanhar os artigos para conseguir acompanhar o desenvolvimento do sistema. Não se apegue a nenhum dos código em nenhum dos artigos, até que a serie esteja completamente publicada. Já que eles irão sofrer diversas mudanças ao logo do tempo, para ser possível cumprir o que é prometido: DESENVOLVER UM REPLAY / SIMULADOR e este deverá possibilitar usar qualquer coisa que você já tenha, ou esteja desenvolvendo para usar em conta DEMO ou conta REAL. Seja no mercado de BOLSA ou FOREX.

NÃO TENTE combinar seu Expert Advisor, indicador ou script ao REPLAY / SIMULADOR, pelo menos por enquanto. Pois ele vai sofrer grandes mudanças ainda no código ... Apenas crie o seu código sem se preocupar com o REPLAY / SIMULADOR ... vai chegar um momento, em que darei uma breve parada no desenvolvimento dele para mostrar como criar alguns modulos de suporte. Quando isto acontecer, ai você poderá começar a integrar seus códigos a ele. E mesmo assim bem devagar, pois quando os modulos que eu mostrar como desenvolver estiverem em um dado nível de funcionalidade, eles serão integrados ao REPLAY / SIMULADOR ... é nesta hora que você deverá de fato entender como todo o sistema estará funcionando. Caso contrário, não conseguirá integrar os seus código ao SERVIÇO DE REPLAY / SIMULADOR.

Então tenha CALMA e estude os artigos, sempre acompanhando o que está sendo desenvolvido... 😁👍