English Русский 中文 Español Deutsch 日本語
preview
Desenvolvendo um sistema de Replay - Simulação de mercado (Parte 14): Nascimento do SIMULADOR (IV)

Desenvolvendo um sistema de Replay - Simulação de mercado (Parte 14): Nascimento do SIMULADOR (IV)

MetaTrader 5Testador | 6 junho 2023, 15:58
477 0
Daniel Jose
Daniel Jose

Introdução

No artigo anterior, Desenvolvendo um sistema de Replay - Simulação de mercado (Parte 13): Nascimento do SIMULADOR (III), mostrei as mudanças feitas, no arquivo de serviço, de forma a promover uma movimentação, e apresentação mais adequada do tickets. Apesar de tudo, o foco principal do artigo anterior, foi mostrar como você faz, e onde precisa mexer e adicionar código, a fim de conseguir tirar dos dados de dentro do serviço. Isto para que você viesse a conseguir, transportar eles para um outro local, que no caso é um arquivo. Tendo este arquivo em mãos, você poderia usar um programa, que no caso mostrei como sendo o EXCEL, e conseguir analisar os dados que o simulador estará gerando.

Tal tipo de coisa, apesar de ser aparentemente banal, é de suma importância para o que iremos fazer neste artigo daqui. Pois sem saber como analisar os dados que o simulador estará gerando, você não conseguirá entender o que será preciso implementar. Mas principalmente não irá entender, por que está sendo implementado daquela forma, que estarei mostrando. Mas além deste fato que foi o tema principal no artigo anterior. Tivemos também, a explicação de alguns pontos a serem modificados no código a fim de conseguir fazer com que a barra seja criada em um tempo próximo de 1 minuto. E isto com uma boa precisão, fazendo com que as coisas ficassem bem perto da realidade. No entanto, apesar de tudo, para entender o que vamos fazer aqui neste artigo, é necessário entender uma coisa. E como o artigo anterior, já estava com bastante informação. Decidi explicar aqui, um último detalhe, que pode ser visto no código presente lá no anexo.


Tentando o Random Walk livre

A versão mais básica da rotina, que irá tentar criar o random walk livre, pode ser vista logo abaixo.

inline void Simulation(const MqlRates &rate, MqlTick &tick[])
                        {
#define macroRandomLimits(A, B) (int)(MathMin(A, B) + (((rand() & 32767) / 32767.0) * MathAbs(B - A)))

                                long il0, max;
                                double v0, v1;
                                int p0;
                                
                                ArrayResize(m_Ticks.Rate, (m_Ticks.nRate > 0 ? m_Ticks.nRate + 3 : def_BarsDiary), def_BarsDiary);
                                m_Ticks.Rate[++m_Ticks.nRate] = rate;                           
                                max = rate.tick_volume - 1;     
                                v0 = 4.0;
                                v1 = (60000 - v0) / (max + 1.0);
                                for (int c0 = 0; c0 <= max; c0++, v0 += v1)
                                {
                                        tick[c0].last = 0;
                                        tick[c0].flags = 0;
                                        il0 = (long)v0;
                                        tick[c0].time = rate.time + (datetime) (il0 / 1000);
                                        tick[c0].time_msc = il0 % 1000;
                                        tick[c0].volume_real = 1.0;
                                }
                                tick[0].last = rate.open;
                                tick[max].last = rate.close;
                                for (int c0 = (int)(rate.real_volume - rate.tick_volume); c0 > 0; c0--)
                                        tick[macroRandomLimits(0, max)].volume_real += 1.0;
                                for (int c0 = 1; c0 < max; c0++)
                                        tick[c0].last = macroRandomLimits(rate.low, rate.high);                                 
                                il0 = (long)(max * (0.3));
                                tick[macroRandomLimits(il0, il0 * 2)].last = rate.low;
                                tick[macroRandomLimits(max - il0, max)].last = rate.high;                                         
                                for (int c0 = 0; c0 <= max; c0++)
                                {
                                        ArrayResize(m_Ticks.Info, (m_Ticks.nTicks + 1), def_MaxSizeArray);
                                        m_Ticks.Info[m_Ticks.nTicks++] = tick[c0];
                                }
                        }
                        
#undef macroRandomLimits

É extremamente necessário entender este código acima, para entender o que iremos fazer de agora em diante. Então se você executar exatamente este código, irá obter um gráfico muito confuso. No entanto, é importante entender como esta rotina, mais básica funciona, para que você possa entender como as rotinas mais complicadas irão trabalhar. Então, vamos começar pela definição da macro. Pergunta: O que esta macro faz ?!?! Você pode estar olhando e pensando : Que maluquice é esta ?!?! Precisamos de algo assim tão doido ?!?! Bem. A resposta para isto é um SIM e um NÃO.

SIM, por que precisamos, que o valor aleatório, seja gerado dentro de um range bem especifico. Para isto precisamos firmar algum tipo de limite. E NÃO, por que para gerar o RANDOM WALK, não precisaremos deste calculo em si. Mas novamente, você precisa entender como este sistema mais simples funciona, para entender os outros que serão mais elaborados.

Pois bem, quando fazemos uma operação AND, iremos limitar o valor a um range. Este é o primeiro dos pontos. Se dividirmos este valor, pelo limite superior do range, teremos um valor que irá girar entre 0 e 1. Logo em seguida, iremos multiplicar este valor, que estará entre 0 e 1, pela diferença entre o limite superior e o inferior. Desta maneira, teremos um valor, que irá girar entre 0, e um valor máximo que será o nosso range. Agora se somarmos este range, com o valor mínimo, iremos obter o valor que realmente queremos e deveremos utilizar. Assim, não precisaremos nos preocupar, em fazer nenhum outro teste, a própria macro irá garantir que o valor esteja dentro dos limites. Conseguiu captar a ideia por de traz desta macro maluca ?? É pura e simples matemática, nada além disto.

Passemos então, para o primeiro dos quatro laços FOR, que temos dentro da rotina. Antes de entrarmos de fato no laço. Temos alguns cálculos simples, que irão nos ajudar no resto da rotina. A primeira coisa, é sabermos quantos tickets, iremos de fato simular. Logo depois, precisaremos saber, quanto tempo, cada um dos tickets irá ter. Ou melhor dizendo, em que momento, ele deverá aparecer. Para não complicar as coisas, iremos utilizar um tempo constante entre eles. Agora podemos entrar no laço, e distribuir os tickets, dentro do range da barra de 1 minuto. Em alguns casos, os tickets estarão mais afastados, e em outros casos, eles estarão mais próximos, uns dos outros. Isto de fato não importa, neste momento. O que precisamos e queremos é o que realmente importa. E isto será o fato de que cada um seja, e deva ser único. Isto é conseguido, colocando cada um, em um ponto diferente no tempo.

Você também pode notar, que estou definido, que cada ticket simulado, irá inicialmente conter um valor mínimo de volume. Isto também é importante, para o próximo passo. Então entramos no próximo laço. Aqui a coisa começa a ficar interessante, pois a primeira coisa que fazemos, é definir qual será o preço da abertura e de fechamento da barra de 1 minuto. No entanto, a questão realmente interessante, é o que esta acontecendo, dentro do laço. Notem que iremos subtrair o volume total, do numero de tickets que serão utilizados. Com isto, temos um valor, que é o volume que ainda não foi distribuído. Poderíamos colocar este valor diretamente no último ticket, ou em algum outro ticket. Entretanto, fazer isto, iria criar um movimento abruto no volume, e não é algo que muitas vezes, de fato acontece no mercado real. Assim precisamos de um outro método de distribuir os tickets restantes, de forma que o volume final, seja o que esta sendo expresso no valor da barra de 1 minuto. Para criar esta distribuição, de forma o mais suave, e ao mesmo tempo aleatória, iremos utilizar a nossa macro para isto. Vejam que a cada chamada, a macro irá gerar um valor, que estará entre os limites definidos. E exatamente, neste momento que o valor presente no volume, será adicionado em 1. Ou seja, o volume total será distribuído, de forma aleatória e sem sobressaltos, dando a impressão, que de fato, são dados similares aos de um mercado real.

Para finalizar, vamos ver os dois últimos laços. O primeiro laço, é que irá criar a aleatoriedade no nosso sistema de tickets. Vejam que não precisamos fazer esforço nenhum. Tudo que fazemos, é dizer ao sistema, qual é a mínima, e qual a máxima de preços a serem utilizados. Desta maneira, cada um dos tickets, terá um preço escolhido ao acaso. Notem que estamos utilizando a macro, para fazer este serviço de escolha para nos. Logo depois de isto ter sido feito, precisamos garantir, que tanto o ponto de máximo valor, quanto o ponto de menor valor, de fato estejam presentes. Isto por conta, que pode acontecer, de eles não serem de fato criados, durante a geração aleatória de valores. Mas a posição em que estes pontos estarão, também serão escolhidos de forma aleatória.

Já o último laço, irá apenas transferir os valores, para dentro do sistema de tickets. Isto que eles sejam utilizados, como se fossem tickets reais. O resultado pode ser visto e entendido, se você lançar os dados de saída em um arquivo e logo em seguida usar os dados obtidos como dados a serem manipulados em um gráfico. Normalmente fazemos isto em algum programa como Excel. Mas dá para fazer isto diretamente no MetaTrader 5. Usando algum tipo de ativo customizado. Mas não se preocupe com estes detalhes neste momento. O que importa é que você entenda que a simulação irá de fato acontecer como estará sendo esperado.

Com base na explicação anterior, que começamos a fazer no artigo anterior, você pode notar que comecei a dar prioridade, para uma randomização do movimento. Diferente do que pode ser visto nos outros artigos. Onde era feito o uso de um método, de forma a criar uma simulação muito parecida, com a encontrada no testador de estratégia. Usando o movimento de zig zag, muito próximo do que pode ser visto na figura abaixo:

Apesar de ser uma ótima ideia, para ser usada no testador de estratégia. Este tipo de abordagem, não é muito boa para um sistema de replay / simulação. Sendo necessária uma outra abordagem, um pouco mais criativa, e ao mesmo tempo mais complexa. Com isto nasceu o sistema, que acabei de explicar a pouco. Ali começamos a randomizar, de forma bastante simples, os movimentos dentro da barra de 1 minuto. Mas aquele tipo de abordagem, não é muito adequada quando a intenção, é ter um estilo de movimento, muito similar ao movimentação de um objeto suspenso em um liquido. Já que ali, havia pulos entre os pontos. Para ajudar a verificar como isto se dava, é importante você saber como transformar, uma serie de dados em algo visível em um gráfico. Isto de uma maneira simples, e o mais simples é utilizando o EXCEL para fazer a conversão. Novamente é importante você saber fazer isto.

No artigo anterior Desenvolvendo um sistema de Replay - Simulação de mercado (Parte 13): Nascimento do SIMULADOR (III) isto foi explicado em vídeo. É de suma importância, você saber como fazer isto. Caso queira realmente entender, o que irá acontecer neste artigo. Isto por que aqui criaremos, uma simulação de movimento, de maneira que o mesmo, irá se mostrar como sendo um RANDOM WALK. E ao ver os gráficos gerados pelo simulador, você irá logo de cara, ver o movimento, como sendo muito similar ao movimento visto, durante a fase de negociação de um ativo. Não irei neste artigo, mostrar formulas matemáticas, ou coisas do tipo. Não vejo nenhum tipo de beneficio, ao trazer este tipo de abordagem. O que de fato interessa a todos, é o código em sim, e o que ele produz. As formulas matemáticas envolvidas, para muitos, não agrega em absolutamente nada. E também não traz nenhum conhecimento, mesmo por que muitos, não irão entender as questões abstratas envolvidas. Então isto mais complicaria do que explicaria. Mas com toda a certeza, todos entenderão os resultados obtidos.

O que será visto neste artigo, será uma forma, que seja a mais simples, quanto for possível de ser feita, de transformar a Figura 01, na figura 02:                   

                       

Figura 01 - Movimento aleatório executado em pulos



Figura 02 : Movimento aleatório feito em passos


Mas usando, a mesma base de dados. Que no caso é esta vista logo a seguir:


Figura 03 : Base de dados usadas em ambos movimentos.


Mas, e novamente, irei repetir, e frisa a palavra, MAS. Existem questões, que diferente de um sistema totalmente aleatório, precisaremos corrigir. No entanto, ainda assim, não teremos logo de cara, um sistema de fato adequado, em mais de 99% das vezes, sendo que este 1% restante, se deve a alguma casualidade, que torna a modelagem perfeita. Isto será algo raro de acontecer. Então precisaremos de algumas artimanhas, para sanar todos os outros casos, ou seja os 99%.

Mas chega de embromação, vamos ver como realmente o sistema trabalha. Mas antes disto, se você não leu o artigo anterior Desenvolvendo um sistema de Replay - Simulação de mercado ( Parte 13 ) - Nascimento do SIMULADOR ( III ), sugiro fortemente que você pare. E leia primeiro o artigo anterior, antes de dar sequencia neste daqui. O motivo é que aqui, irei apenas focar nas mudanças necessárias, e como elas devem ser implementadas. Não irei ficar repetindo as explicações, que foram dadas no artigo anterior. E entender o conteúdo presente lá, será importante para compreender este daqui. Principalmente a parte relacionada a transformar dados em um gráfico. Isto dentro do Excel.

Dado este aviso. Vamos então ao tópico de implementação.


Implementando um RANDOM WALK, de movimentação totalmente livre.

Tudo que precisamos fazer, para transformar uma movimentação aleatória, de pulos, em uma movimentação aleatória, de passos. É mudar a forma, como a função de simulação trabalha. Para fazer isto, vamos ver o código da mesma:

inline void Simulation(const MqlRates &rate, MqlTick &tick[])
                        {
#define macroRandomLimits(A, B) (int)(MathMin(A, B) + (((rand() & 32767) / 32767.0) * MathAbs(B - A)))

                                long il0, max;
                                double v0, v1;
                                
                                ArrayResize(m_Ticks.Rate, (m_Ticks.nRate > 0 ? m_Ticks.nRate + 3 : def_BarsDiary), def_BarsDiary);
                                m_Ticks.Rate[++m_Ticks.nRate] = rate;
                                max = rate.tick_volume - 1;     
                                v0 = 4.0;
                                v1 = (60000 - v0) / (max + 1.0);
                                for (int c0 = 0; c0 <= max; c0++, v0 += v1)
                                {
                                        tick[c0].last = 0;
                                        tick[c0].flags = 0;
                                        il0 = (long)v0;
                                        tick[c0].time = rate.time + (datetime) (il0 / 1000);
                                        tick[c0].time_msc = il0 % 1000;
                                        tick[c0].volume_real = 1.0;
                                }
                                tick[0].last = rate.open;
                                tick[max].last = rate.close;
                                for (int c0 = (int)(rate.real_volume - rate.tick_volume); c0 > 0; c0--)
                                        tick[macroRandomLimits(0, max)].volume_real += 1.0;
                                for (int c0 = 1; c0 < max; c0++)
                                        tick[c0].last = macroRandomLimits(rate.low, rate.high);
                                        tick[c0].last = tick[c0 - 1].last + (m_PointsPerTick * ((rand() & 1) == 1 ? 1 : -1));
                                il0 = (long)(max * (0.3));
                                tick[macroRandomLimits(il0, il0 * 2)].last = rate.low;
                                tick[macroRandomLimits(max - il0, max)].last = rate.high;
                                for (int c0 = 0; c0 <= max; c0++)
                                {
                                        ArrayResize(m_Ticks.Info, (m_Ticks.nTicks + 1), def_MaxSizeArray);
                                        m_Ticks.Info[m_Ticks.nTicks++] = tick[c0];
                                }
#undef macroRandomLimits
                        }                       

Vejam que mudamos, apenas e somente, como a função trabalha. Mas ainda assim, mantivemos a carga total da mesma. Ou seja, vamos utilizar a mesma quantidade de tickets. No entanto, reparem em algo bem especifico, na parte em destaque. Agora prestem bastante atenção, ao seguinte fato: O código que esta RISCADO, deve ser retirado, e no lugar dele entra o código em destaque. Fazendo apenas e somente esta mudança, já seremos capazes de criar um RANDOM WALK. Mas não é um movimento adequado. Não ainda. Pois apesar de em algum raro momento, acontecer de que o movimento, se mantenha dentro do range da barra de 1 minuto, ou seja, ele respeite a máxima e a mínima, e fique contido dentro desta amplitude. Não temos certeza, e nem controle, sobre isto no código acima. E isto pode ser notado, ao se colocar ele, para executar e verificar o gráfico obtido.

Se você estiver utilizando os arquivos contidos no anexo, e não mudar o arquivo de configuração. Irá fazer com que o serviço de replay / simulador, venha a executar o trabalho, apenas na primeira barra. E a barra a ser usada, é justamente esta, que se encontra em destaque, na imagem abaixo:



Notem que os limites são: LIMITE SUPERIOR => 108375 e o LIMITE INFERIOR => 107850. E estes, não são os limites, que você terá, ao observar o gráfico. Mesmo em uma rápida olhada, você notará, que tais limites, não estão sendo respeitados. Para exemplificar melhor, veja a imagem do gráfico de dados, de uma das execuções. Isto pode ser visto logo abaixo.


Figura 04 - Plotagem do RANDOM WALK totalmente livre


Você logo nota, que o limite inferior, esta longe de ter sido respeitado. Novamente, pode acontecer, em algum momento. Muito. Mas muito especifico, que os limites sejam respeitados. Existe um outro problema, que é com relação os pontos isolados, que podem ser vistos no gráfico acima. Mas vamos com calma. Estes pontos, representam outro problema que teremos que resolver. Entretanto, o nosso foco, neste primeiro momento, é de fato, o problema dos limites. Diferente do que pode ser aceitável, quando estamos criando simulações de movimento. Aqui tal aceitação não será e não estará presente. O motivo é que estamos fazendo, simulações baseadas em algum tipo de dado previamente obtido, e temos que respeitar o que nos é informado.

Resolver este problema dos limites, nos força a tornar um sistema livre, em um sistema limitado. Mesmo que muitos possam torcer o nariz para este tipo de abordagem. Não temos outro meio, a não ser de fato criar, algum tipo de testagem, para que os limites, sejam respeitados a todo, e a qualquer o custo. Por conta disto, é importante você ter lido o artigo anterior. Entender como usar o EXCEL, ou qualquer outro programa, para analisar o gráfico gerado pelo sistema de simulação. Não conte com o fato de apenas olhar os dados e achar que estão corretos. É preciso de fato olhar eles em um gráfico.

Mas diferente do que acontece, quando temos um sistema completamente aleatório, baseados em pulos, como mostrado na Figura 01. Onde usar o sistema de plotagem gráfica, do MetaTrader 5, é totalmente inviável. O mesmo não acontece, quando temos como resultado, o que é visto na figura 02, ou mesmo na figura 04. Se bem que em ambas, teremos o problema dos pontos soltos no gráfico. O que irá gerar uma barra estranha. Entretanto, se você não estiver muito afim, de ficar levando os dados da simulação, para dentro do EXCEL, pode fazer algumas mudanças no código, de forma que cada um dos tickets, sejam plotados diretamente no gráfico do MetaTrader 5. Apesar de que isto não deixará o gráfico tão simples de entender. Dada a quantidade de informações que ele terá. Lembre-se: Você deverá colocar tick a tick no gráfico. E não as barras. Se você não sabe como fazer isto, olhe este artigo: Desenvolvendo um EA de negociação do zero (Parte 13): Times And Trade (II), pois nele explico como plotar os ticks que estamos gerando aqui no simulador. Se bem, que o Times And Trade é voltado para olhar os ticks reais de um ativo. Mas nada lhe impede de usar ele para olhar os ticks criados aqui do simulador. É tudo uma questão de adaptar o código mostrado para o Times And Trade.

Isto não é uma tarefa muito complexa. Mas envolverá mudanças, que depois terão que ser desfeitas. Por conta disto, não irei mostrar como fazer. O intuito aqui, é mostrar de forma bem simples, de como fazer o sistema gerar um movimento, de forma a termos uma simulação, de um possível movimento, dentro da barra de 1 minuto. Mas de forma continua, e não aos saltos. Acredito que muitos que estejam lendo, estes artigos, não tem grande conhecimento sobre a forma de programar, tais coisas usando MQL5. E mudar o foco, apenas para satisfação pessoal, foge completamente do escopo deste o de qualquer outro artigo desta sequencia. Devido a isto, continuemos assim o nosso trabalho. Agora vamos adicionar, algumas coisas ao código, de forma que ele irá obedecer aos limites impostos. Estes são dados, pelas informações contidos na barra de 1 minuto, que se encontra em destaque na figura 03.


Implementando um RANDOM WALK de movimentação limitada.

Com base no que foi visto, no tópico anterior. Podemos facilmente ver, o que, e onde deveremos atual. As mudanças podem ser vista no código logo abaixo:

inline void Simulation(const MqlRates &rate, MqlTick &tick[])
                        {
#define macroRandomLimits(A, B) (int)(MathMin(A, B) + (((rand() & 32767) / 32767.0) * MathAbs(B - A)))

                                long    il0, max;
                                double  v0, v1;
                                bool    bLowOk, bHighOk;
                                
                                ArrayResize(m_Ticks.Rate, (m_Ticks.nRate > 0 ? m_Ticks.nRate + 3 : def_BarsDiary), def_BarsDiary);
                                m_Ticks.Rate[++m_Ticks.nRate] = rate;
                                max = rate.tick_volume - 1;     
                                v0 = 4.0;
                                v1 = (60000 - v0) / (max + 1.0);
                                for (int c0 = 0; c0 <= max; c0++, v0 += v1)
                                {
                                        tick[c0].last = 0;
                                        tick[c0].flags = 0;
                                        il0 = (long)v0;
                                        tick[c0].time = rate.time + (datetime) (il0 / 1000);
                                        tick[c0].time_msc = il0 % 1000;
                                        tick[c0].volume_real = 1.0;
                                }
                                tick[0].last = rate.open;
                                tick[max].last = rate.close;
                                for (int c0 = (int)(rate.real_volume - rate.tick_volume); c0 > 0; c0--)
                                        tick[macroRandomLimits(0, max)].volume_real += 1.0;
                                bLowOk = bHighOk = false;
                                for (int c0 = 1; c0 < max; c0++)
                                {                               
                                        v0 = tick[c0 - 1].last + (m_PointsPerTick * ((rand() & 1) == 1 ? 1 : -1));
                                        if (v0 <= rate.high)
                                                v0 = tick[c0].last = (v0 >= rate.low ? v0 : tick[c0 - 1].last + m_PointsPerTick);
                                        else
                                                v0 = tick[c0].last = tick[c0 - 1].last - m_PointsPerTick;
                                        bLowOk = (v0 == rate.low ? true : bLowOk);
                                        bHighOk = (v0 == rate.high ? true : bHighOk);
                                }                                       
                                il0 = (long)(max * (0.3));
                                if (!bLowOk) tick[macroRandomLimits(il0, il0 * 2)].last = rate.low;
                                if (!bHighOk) tick[macroRandomLimits(max - il0, max)].last = rate.high;
                                for (int c0 = 0; c0 <= max; c0++)
                                {
                                        ArrayResize(m_Ticks.Info, (m_Ticks.nTicks + 1), def_MaxSizeArray);
                                        m_Ticks.Info[m_Ticks.nTicks++] = tick[c0];
                                }
#undef macroRandomLimits
                        }                       

Talvez possa lhe parecer, que as mudanças não estão acontecendo, ou que está muito confuso com todas estas marcações. Mas notem que adicionamos duas novas variáveis, para nos ajudar a controlar, um pouco melhor as coisas. Estas são inicializadas, de forma que se as posições, que elas representam, não forem devidamente acessadas, teremos forçosamente, de colocar tais pontos no gráfico. E estes pontos, serão escolhidos de forma randômica. Mas os testes são feitos, dentro do sistema de pesquisa e analise dos limites. Assim podemos ficar focados, apenas e somente, em uma única coisa, manter o RANDOM WALK, dentro dos limites previamente estabelecidos pelas barras de 1 minuto. A primeira coisa que iremos testar, é se o limite superior foi agredido e desrespeitado. Caso isto tenha acontecido, iremos fazer com que o movimento retorne imediatamente para dentro dos limites. Caso ele tenha sido respeitado, faremos um outro teste, em que iremos desta vez, verificar, se o limite inferior foi desrespeitado. Se sim fazemos com que o movimento retorne imediatamente para dentro dos limites. Caso contrário o valor será aceito.

Notem que não mudamos grandes coisas no código. Porém os resultados. Estes sim sofreram grandes mudanças. Veja só o que aconteceu em uma das execuções.


Figura 05 - Movimento RANDOM WALK dentro dos limites


É verdade que foi pura sorte, que o movimento tenha coberto todos os pontos soltos. Mas ainda assim, temos um ponto solto no gráfico. Este ponto, é o ponto que representa o tick de fechamento da barra de 1 minuto. De fato, este é bastante difícil de ser atingido, de maneira precisa, dada a natureza do movimento aleatório, e da forma como estamos fazendo. Mas fora isto, você pode notar que diferente da figura 04, onde os limites não foram respeitados. Na figura 05, eles foram respeitados, e toda a barra de 1 minuto, estará contida dentro dos limites previamente estabelecidos. Então o movimento, esta quase perfeito. E digo quase, pois o resultado da figura 05, foi pura sorte. Na maior parte das vezes, teremos como resultado figura 06, vista abaixo.


Figura 06 - Gráfico típico do movimento dentro dos limites


Notem que também na figura 06, o ponto de fechamento, não foi alcançado no momento desejado, pelo sistema de movimentação aleatória. Mas, e em caso extremamente raros, você pode acabar conseguindo, como resultado, o conteúdo visto na figura 07. Onde você pode notar, que o ponto de fechamento, foi alcançado pelo movimento aleatório.


Figura 07 - Movimento RARO onde o ponto de fechamento foi alcançado.


Mas este tipo e movimentação, é tão rara, que não podemos de fato, contar com ela. Na maior parte das vezes, o ticket anterior ao fechamento, ira estar distante do ponto de fechamento. Isto irá causar um movimento abruto no gráfico do ativo de replay / simulação, que esta sendo plotado pelo MetaTrader 5. Se você não se importa com este tipo de efeito. Beleza, o sistema já pode ser considerado adequado para você utilizar. Mas você deve notar uma outra coisa. Em vários momentos, e isto não é tão raro assim. Os pontos máximo ou mínimos, não são de fato visitados. Ficando assim um segundo ponto, ou terceiro dependendo do caso, em que teremos, um outro movimento brusco, por parte do sistema de plotagem do ativo. De certa forma, isto não é um problema muito grande. Isto em grande parte das vezes. Já que em um mercado real, temos de fato, em alguns momentos, tais movimentações. Mas se ainda assim, o seu desejo, é de criar um sistema, onde estes movimentos não sejam tão recorrentes, temos que adotar uma outra medida. Melhor dizendo, teremos que fazer, mais mudanças no sistema de simulação. No entanto, tais mudanças, não nasceram sem dor. Muito pelo contrário, o nascimento delas, irá ter um parto bastante complicado e difícil de ser entendido por alguns. Ainda mais, se você desejar ter um gráfico, muito parecido com o que é visto na figura 07, teremos que fazer tais mudanças.

Acredito que muitos, já ficaram bastante satisfeitos com os resultados presentados nesta versão. Entretanto ainda assim, podemos melhorar a coisa toda. Para aqueles que acham, que isto já é o suficiente, o próximo artigo pode não lhe parecer necessário. Para aqueles que querem, e desejam ser perfeccionista, tenho uma ultima proposta para se trabalhada. De modo a gerar o RANDOM WALK, onde não teremos pontas soltas. Assim, todos os pontos serão com certeza visitados. Mas por hoje já chega. Irei deixar você digerir o conhecimento contido neste artigo. Você precisará testar o sistema diversas vezes, com diferentes tipos de ativos. Somente assim, irão de fato saber, se apenas utilizando o conceito de RANDOM WALK LIMITADO, os movimentos possíveis dentro de uma barra de 1 minuto, são ou não de fato adequados e representam uma possível realidade de mercado, que você deseja fazer uso.


Considerações finais

Com praticamente nenhuma apresentação de formulas matemáticas complexas, ou falando de uma forma, que ninguém de fato iria conseguir entender. Acredito ter passado para você, caro leitor, um conceito bastante interessante e presente no mercado. O chamado RANDOM WALK. Este sistema apresentado neste artigo, mostra o quando podemos progredir, sem de fato entender conceitos complexo. Se bem que conhecimento, é sempre bom de ser adquirido. Mas por que complicar, se podemos explicar as coisas, de uma forma bastante simples e agradável. Não é mesmo ?!?!

No arquivo em anexo, você terá o sistema no atual estagio de desenvolvimento. Acredito que muitos já devam estar ansiosos por saber quando iremos começar de fato, a ter um sistema de ordens no nosso replay / simulador. Mas não se preocupem, em breve iremos começar a adicionar o sistema de ordens, mas antes de fazer isto, precisamos fazer uma serie de outras coisas. Isto por que o sistema de ordens, será um problema bastante interessante de ser resolvido. Mas primeiro temos que acabar de implementar o serviço de replay / simulador. O que já se mostra estar quase pronto. Pelo menos na sua primeira fase de desenvolvimento. Esta faltando apenas mais uns poucos detalhes, para serem de fato adicionados. Para logo em seguida, podermos começar o desenvolvimento do sistema de ordens. Assim você poderá usar o simulador / replay como se estivesse operando no mercado real. Mas talvez eu mude algumas coisas antes. Mas isto será de fato decidido depois. De qualquer maneira você deve praticar e treinar, para assim ganhar alguma habilidade, como programador, do que estou tentando mostrar como fazer. Então nos vemos no próximo artigo. Pois teremos que acabar de arrumar este RANDOM WALK ainda. Pois ele não está concluído.


Arquivos anexados |
Teoria das Categorias em MQL5 (Parte 3) Teoria das Categorias em MQL5 (Parte 3)
A Teoria das Categorias representa um segmento diversificado e em constante expansão da matemática, que até agora está relativamente pouco explorado na comunidade MQL5. Esta sequência de artigos visa elucidar algumas das suas concepções com o intuito de constituir uma biblioteca aberta e potencializar ainda mais o uso deste notável setor na elaboração de estratégias de negociação.
Desenvolvendo um sistema de Replay - Simulação de mercado (Parte 13): Nascimento do SIMULADOR (III) Desenvolvendo um sistema de Replay - Simulação de mercado (Parte 13): Nascimento do SIMULADOR (III)
Aqui iremos dar uma leve otimizada nas coisas. Isto para facilitar o que iremos fazer no próximo artigo. Mas também irei explicar como você pode visualizar o que o simulador está gerando em termos de aleatoriedade.
Desenvolvimento de um sistema de negociação baseado no Índice de Facilitação do Mercado de Bill Williams Desenvolvimento de um sistema de negociação baseado no Índice de Facilitação do Mercado de Bill Williams
Este é um novo artigo de uma série na qual aprendemos a desenvolver sistemas de negociação baseados em indicadores técnicos conhecidos. Neste novo artigo, analisamos o Índice de Facilitação do Mercado (Market Facilitation Index, MFI), criado por Bill Williams.
Ciência de dados e aprendizado de máquina (Parte 11): Classificador Naive Bayes e teoria da probabilidade na negociação Ciência de dados e aprendizado de máquina (Parte 11): Classificador Naive Bayes e teoria da probabilidade na negociação
A negociação com base em probabilidades pode ser comparada a caminhar sobre uma corda bamba - ela requer precisão, equilíbrio e uma compreensão clara do risco envolvido. No mundo do trading, a probabilidade é fundamental. É ela que determina o resultado: sucesso ou fracasso, lucro ou prejuízo. Ao aproveitar as possibilidades da probabilidade, os traders podem tomar decisões mais fundamentadas, gerenciar os riscos de maneira mais eficiente e alcançar seus objetivos financeiros. Não importa se você é um investidor experiente ou um trader iniciante, entender a probabilidade pode ser a chave para desbloquear seu potencial de negociação. Neste artigo, exploraremos o fascinante mundo do trading baseado em probabilidades e mostraremos como levar seu modo de negociar a um nível superior.