Usando a função TesterWithdrawal() para Modelar as Retiradas de Lucro

Andriy Voitenko | 27 janeiro, 2014

Introdução

O objetivo de negociação especulativa é a obtenção de lucro. Habitualmente, quando o sistema de negócio é testado, todos os aspectos são analisados, a exceção do seguinte - retirada de parte do dinheiro ganhado para viver. Mesmo que o negócio não seja a única fonte de dinheiro para o comerciante, as perguntas sobre o lucro planejado para um período de comércio (mês, trimestre, ano) surgem cedo ou tarde. A função TesterWithdrawal() no MQL5 é a pretendida para emular as retiradas de dinheiro da conta.


1. O que nós podemos checar?

Existem opiniões sobre as negociações, assim como sistemas de negociação que implicam a retirada do excesso de dinheiro em uma situação de risco. Apenas uma pequena parte do capital total está na conta de negociação, esta é uma proteção contra perder todo o dinheiro em razão de alguma circunstância inesperada.

Praticamente, este é um exemplo de estratégia da administração de dinheiro. Vários fundos aceitam investimentos para administração dada uma cerca cota (uma parte do capital total) para cada comerciante, mas todo o capital nunca é dado a comerciantes. Em outras palavras, em adição aos limites no volume de posições abertas, existem limitações no capital que um comerciante pode comandar. No fim, cada comerciante tem o acesso apenas a uma parte pequena dos ativos para realizar especulações de risco.

Outro problema é o reinvestimento agressivo dos ativos lucrados durante testes. Negociadores pretendem fazer as linhas de balanço e equidade subirem verticalmente durante a otimização. Embora todo mundo entenda que existam certas regras a cada nível de dinheiro; não existe ponto em crer que um sistema lucrativo em comércio com 0.1 lotes seja bom quando negociando com 100 lotes.

Em adição existe um problema psicológico - cada negociante praticante pode confessar a intervenção no trabalho do sistema de negociação em um certo nível de dinheiro na conta, embora eles tenham prometido não fazer isto. Assim, deste ponto de vista, retirar os excessos é um fator estabilizante em comércio.

Existe uma função no MQL5 intencionada para implementar a retirada de dinheiro durante testes de um Conselheiro Especialista. A próxima sessão é dedicada a isto.


2. Como usar a função?

A função TesterWithdrawal() é intencionada apenas para modelagem do dinheiro retirado da conta no testador estratégico e não afeta o trabalho do Conselheiro Especialista no modo normal.

bool TesterWithdrawal(double money);

O parâmetro de entrada "money" é intencionado para especificar a quantidade de dinheiro a ser retirado no depósito de moedas. Pelo valor retornado você pode detectar se a operação foi bem sucedida. Cada operação de retirada realizada durante os testes é demonstrada com a entrada correspondente na aba "Diário", bem como a aba "Resultados", como é demonstrado na figura 1.

Entradas sobre a retirada bem sucedidas de ativos durante testes

Figura 1. Entradas sobre a retirada bem sucedidas de ativos durante testes

No caso, o tamanho da retirada excede o tamanho da margem livre e a retirada não é realizada, a seguinte entrada aparece no "Diário".

Entrada sobre a operação de retirada mal sucedida durante testes

Figura 2. Entrada sobre a operação de retirada mal sucedida durante testes

Ao chamar esta função, o tamanho do balanço e equidade atuais diminuem pela quantidade do dinheiro retirado. Entretanto, o testador estratégico não considera a retirada quando calculando o lucro e o prejuízo, mas ele calcula o somatório total de retiradas na taxa "Retirada", como mostrado na figura 3.

Taxa de somatório total de retiradas no relatório

Figura 3. Taxa de somatório total de retiradas no relatório

Deve ser notado que uma função reversa de depositar ativos para uma conta de negócios não existe ainda no MQL5, e é improvável que será implementada. Quem precisa de sistemas que requerem aumentos constantes de depósitos?

A próxima sessão é dedicada ao exemplo de um Conselheiro Especialista não apenas com uma estratégia de negociação implementada, mas com um conjunto de ferramentas para modelagem de retiradas de dinheiro usando a função que nós observamos.


3. Uma cobaia para testes


Nós conduziremos os testes em um Conselheiro Especialista bastante simples. Aqueles que estão interessados nos princípios da operação do Conselheiro Especialista, podem achar a descrição de seu sistema de trocas abaixo.

Os valores máximos e mínimos do preço são calculados em um período específico de 5M de dados, o qual é configurado usando a variável de entrada PERIOD. Níveis calculados formam um canal horizontal com linhas de suporte (variável CalcLow) e resistência (variável CalcHigh). Pedidos pendentes são colocados nas extremidades do canal. O jogo é jogado na perfuração do canal.

Um pedido pendente é colocado quando o preço vai para dentro do canal por não menos que o valor da variável de entrada INSIDE_LEVEL. Em adição, apenas uma posição ou pedido pendente pode ser aberto em uma direção.

Se o canal se tornar mais estreito, os níveis são recalculados e o preço continua dentro dele, então, o pedido pendente é movido mais próximo ao preço de mercado. O passo de movimentação de pedidos pendentes é configurado usando a variável de entrada ORDER_STEP.

O tamanho do lucro de um negócio é especificado na variável de entrada TAKE_PROFIT, e o prejuízo máximo é especificado usando STOP_LOSS.

O Conselheiro Especialista implica movimento do Stop Loss com um passo especificado na variável de entrada TRAILING_STOP.

Você pode trocar ambos com um lote fixo ou com um calculado como uma percentagem do depósito. O valor do lote é configurado usando a variável de entrada LOT, e o método de cálculo é configurado usando a variável LOT_TYPE. Existe uma possibilidade de correção do lote (LOT_CORRECTION = true). No caso, você negocia com um tamanho fixo de lote e se seu tamanho excede o permitido para abertura de uma posição, o tamanho do lote é corrigido para o valor mais próximo permitido.

Para a sintonização do algoritmo do Conselheiro Especialista, você pode ligar a função de escrever o relatório (WRITE_LOG_FILE = true). Para que, então, as entradas sobre todas as operações de negociação sejam escritas ao próximo arquivo de relatório de texto log.txt.

Vamos adicionar várias variáveis de entrada ao Conselheiro Especialista para administração das retiradas de dinheiro.

O primeiro parâmetro será usado como uma bandeira para a possibilidade de retirada de ativos.

input bool WDR_ENABLE = true; // Allow withdrawal

O segundo parâmetro determinará a periodicidade das retiradas.

enum   wdr_period
  {
   days      = -2, // Day
   weeks     = -1, // Week 
   months    =  1, // Month  
   quarters  =  3, // Quarter
   halfyears =  6, // Half a year    
   years     = 12  // Year    
  };
input wdr_period WDR_PERIOD = weeks; // Periodicity of withdrawals
O terceiro parâmetro configurará a quantidade de dinheiro a ser retirada.
input double WDR_VALUE = 1; // Amount of money to be withdrawn

O quarto parâmetro determinará o método de cálculo da quantidade a ser retirada.

enum lot_type 
   {
      fixed,  // Fixed
      percent // Percentage of deposit
   };
input lot_type WDR_TYPE = percent; // Method of calculation of the withdrawal amount

Para calcular a quantidade de uma retirada única de dinheiro da conta, é usado o wdr_value. A variável wdr_summa é usada para calcular o total da quantidade de dinheiro a ser retirada.

Nós também podemos calcular o número total de operações de retiradas bem sucedidas usando a variável wdr_count. Os valores destas variáveis são necessários para formar o nosso próprio relatório sobre os resultados dos testes. Toda a funcionalidade da retirada de dinheiro é implementada na função abaixo.

//--- Function of withdrawing assets from the account
//+------------------------------------------------------------------+
bool TimeOfWithDrawal()
//+------------------------------------------------------------------+
  {
   if(!WDR_ENABLE) return(false); // exit if withdrawal is prohibited
   
   if( tick.time > dt_debit + days_delay * DAY) // periodic withdrawals with specified period
     {
      dt_debit = dt_debit + days_delay * DAY;
      days_delay = Calc_Delay();// Updating the value of period-number of days between withdrawal operations
      
      if(WDR_TYPE == fixed) wdr_value = WDR_VALUE;
      else wdr_value = AccountInfoDouble(ACCOUNT_BALANCE) * 0.01 * WDR_VALUE;

      if(TesterWithdrawal(wdr_value))
        {
         wdr_count++;
         wdr_summa = wdr_summa + wdr_value;
         return(true);
        }
     }
   return(false);
  }

Agora nós precisamos preparar o nosso Conselheiro Especialista para testes no modo de otimização. Haverão vários parâmetros, então, vamos declarar uma variável de entrada usando o que nós escolheremos para o parâmetro necessário.

enum opt_value
{
   opt_total_wdr,      // Total sum of withdrawal
   opt_edd_with_wdr,   // Drawdown with consideration of withdrawal
   opt_edd_without_wdr // Drawdown without consideration of withdrawal
};
input opt_value OPT_PARAM = opt_total_wdr; // Optimization by the parameter

Também precisamos adicionar outra função significativa ao Conselheiro Especialista OnTester(); o valor retornado desta função determina o critério de otimização.

//--- Displaying information about testing
//+------------------------------------------------------------------+
double OnTester(void)
//+------------------------------------------------------------------+
  {
   //--- Calculation of parameters for the report
   CalculateSummary(initial_deposit);
   CalcEquityDrawdown(initial_deposit, true, false);
   //--- Creation of the report
   GenerateReportFile("report.txt");

   //--- Returned value is the optimization criterion
   if (OPT_PARAM == opt_total_wdr) return(wdr_summa);
   else return(RelEquityDrawdownPercent);
  }

A próxima sessão é devotada para considerações detalhadas dos testes do nosso Conselheiro Especialista.


4. Testando o Expert Advisor

Para a integridade do teste, primeiro de tudo nós precisamos obter os resultados dos testes do nosso Conselheiro Especialista com a função de retirada desabilitada. Para fazer isto, antes de testar, configure o parâmetro "Allow withdrawal" (permitir retirada) para "false" como mostrado na figura 5.

Para aqueles que estejam interessados em repetir os resultados dos testes, as configurações e valores dos parâmetros de entrada do Conselheiro Especialista são dados abaixo nas figuras 4 e 5.

Configurando para testar o Conselheiro Especialista

Figura 4. Configurando para testar o Conselheiro Especialista

Parâmetros do Conselheiro Especialista com a função de retirada desabilitada

Figura 5. Parâmetros do Conselheiro Especialista com a função de retirada desabilitada

Os resultados obtidos no final dos testes são demonstrados nas figuras 6 e 7.

Mudança de balanço por 6 meses de trabalho teste do Conselheiro Especialista

Figura 6. Mudança de balanço por 6 meses de trabalho do teste do Conselheiro Especialista

A tabela de resultados de trabalho do Conselheiro Especialista

Figura 7. A tabela de resultados de trabalho do Conselheiro Especialista

O parâmetro que é interessante para nós é a redução relativa de equidade. Neste caso, é igual a 4,75%.

Agora vamos checar como este parâmetro muda se nós habilitarmos a retirada de dinheiro. Vamos conduzir testes com quantidades e periodicidades diferentes de retiradas.

A figura 8 demonstra os parâmetros do Conselheiro Especialista com otimização e retiradas habilitadas; e a figura 9 demonstra os resultados de tais testes.

O parâmetro do Conselheiro Especialista com otimização e retiradas habilitadas

Figura 8. O parâmetro do Conselheiro Especialista com otimização e retiradas habilitadas

Os resultados dos cálculos da redução relativa de equidade

Figura 9. Os resultados dos cálculos da redução relativa de equidade

Os resultados dos testes são um pouco surpreendentes, uma vez que as quedas são menores com a periodicidade de retiradas de um dia, ou uma semana, do que com as retiradas totalmente desabilitadas.

Em adição, a linha de redução diária aumenta para 100% e depois volta para 8% e continua decrescendo. Para interpretar estes resultados corretamente, você necessita saber como a redução relativa de equidade é calculada no testador de estratégia. Este é o assunto da próxima sessão.


5. Cálculo da redução da equidade

Mentes investigativas estarão curiosas para saber como o cálculo da equidade é realizado no testador de estratégia, e como calcular este parâmetro por conta própria.

Se a função TesterWithdrawal() não é usada no seu Conselheiro Especialista, então, o cálculo do parâmetro que nós analisamos não tem diferença do seu cálculo no MetaTrader 4; está descrito no artigo "O que os números no relatório de testes do especialista significam"; e seu código-fonte e vários outros parâmetros do relatório do teste resultante são dados no artigo "Como avaliar os resultados de testes do especialista".

Uma descrição visual do cálculo da redução relativa e máxima no testador de estratégia é a figura 10, abaixo.

Cálculo das quedas de equidade sem consideração das retiradas

Figura 10. Cálculo das quedas de equidade sem consideração das retiradas

Durante o seu funcionamento, o testador de estratégia determina os máximo e mínimos valores relativos de equidade. Com o aparecimento de uma nova equidade máxima, a qual é marcada no gráfico com a marca azul, as quedas máximas e mínimas são recalculadas e o maior valor é salvo para ser demonstrado no relatório resultante.

O importante é o último recálculo dos parâmetros no final do teste, porque pode surgir uma situação quando o último extremo de equidade não registrado dá o valor máximo de redução. Mudanças de valores máximos de redução são demonstrados com as cores azul e vermelho respectivamente. A cor cinza representa a redução registrada no momento de surgimento de um novo máximo.

Deve ser notado que a nomeação da função TesterWithDrawal() muda o algoritmo de cálculo das quedas no testador de estratégia. A diferença das variantes anteriores é o recálculo dos valores de redução não apenas no ponto de surgimento de um novo máximo de equidade, mas também na retirada de ativos. A demonstração visual disto está na figura 11.

Cálculo de quedas considerando retiradas

Figura 11. Cálculo de quedas considerando retiradas

O momento de retirada de ativos é demonstrado com as marcas verdes na figura acima. Retiradas de dinheiro são muito frequentes, assim, ele não permite que os valores máximos de redução, determinados pelos extremos no gráfico, sejam fixos. Como resultado, a redução resultante com a consideração de retiradas pode ser menor que a sem a consideração, o que foi notado na figura 9.

Se as retiradas de dinheiro forem muito maiores que o crescimento da equidade como resultado da obtenção de lucros, isto pode levar a baixas taxas de retiradas. A razão pela qual esta situação não permite os extremos a se formarem no gráfico; e no limite eles parecerão como uma linha diretamente descendente, aonde as retiradas relativas tendem a zero. Este efeito é decorrente de retiradas diárias de mais de 1000$ como mostrou o gráfico da figura 9.

Vamos reproduzir o cálculo das reduções máximas e relativas de equidade no MQL5 combinando todo o algoritmo no processo único CalcEquityDrawdown como descrito abaixo.

double RelEquityDrawdownPercent; // relative drawdown of equity in percentage terms
double MaxEquityDrawdown;        // maximal drawdown of equity
//--- Calculation of the drawdown of equity
//+------------------------------------------------------------------+
void CalcEquityDrawdown(double initial_deposit, // initial deposit
                        bool finally)          // flag of calculation that registers extremums
//+------------------------------------------------------------------+
  {
   double drawdownpercent;
   double drawdown;
   double equity;
   static double maxpeak = 0.0, minpeak = 0.0;

   //--- exclusion of consideration of profit withdrawals for the calculation of drawdowns
   if(wdr_ignore) equity = AccountInfoDouble(ACCOUNT_EQUITY) + wdr_summa;
   else equity = AccountInfoDouble(ACCOUNT_EQUITY);

   if(maxpeak == 0.0) maxpeak = equity;
   if(minpeak == 0.0) minpeak = equity;

   //--- check of conditions of extremum
   if((maxpeak < equity)||(finally))
    {
      //--- calculation of drawdowns
      drawdown = maxpeak - minpeak;
      drawdownpercent = drawdown / maxpeak * 100.0;

      //--- Saving maximal values of drawdowns
      if(MaxEquityDrawdown < drawdown) MaxEquityDrawdown = drawdown;
      if(RelEquityDrawdownPercent < drawdownpercent) RelEquityDrawdownPercent = drawdownpercent;
    
      //--- nulling the values of extremums
      maxpeak = equity;
      minpeak = equity;
    }

   if(minpeak > equity) minpeak = equity;
 }

Para manter os cálculos precisos, nós precisamos nomear o processo escrito acima do corpo do nosso Conselheiro Especialista cada vez que um novo turno começar e com os parâmetros dados abaixo.

CalcEquityDrawdown(initial_deposit, false);

Em adição, para obter valores confiáveis de quedas, também devem ser nomeados, no final do Conselheiro Especialista, na função OnTester(), os parâmetros finally = true que indicam que o cálculo terminou. E se a redução não corrigida atual for maior que o máximo registrado, ela substituirá a máxima e será demonstrada no relatório resultante.

CalcEquityDrawdown(initial_deposit, true);

Se o algoritmo de retiradas for implementado em um Conselheiro Especialista, então para o cálculo correto de quedas você deve nomear a função CalcEquityDrawdown com o parâmetro finally=true toda vez que uma retirada for realizada. A ordem de nomeação pode ser como a seguinte:

//--- Withdrawing assets and calculating drawdowns of equity
if(TimeOfWithDrawal())
    CalcEquityDrawdown(initial_deposit, true);
else 
    CalcEquityDrawdown(initial_deposit, false);

Para ter certeza na correção da metodologia descrita acima, vamos comparar o dado calculado com o dado do testador de estratégia. Para fazer isto, você precisa fazer a função OnTester() retornar o valor do parâmetro que nós queremos checar - a redução relativa de equidade que é armazenada na variável RelEquityDrawdownPercent.

Ela é implementada no código do Conselheiro Especialista pela configuração do valor da "redução como consideração de retirada" pelo parâmetro de entrada "Otimização pelo parâmetro". O resto dos parâmetros devem ser deixados sem mudanças como demonstrado na figura 8. Os resultados de tais testes são demonstrados na figura 12.

Comparação dos resultados dos nossos cálculos com os dados do testador de estratégia

Figura 12. Comparação dos resultados dos nossos cálculos com os dados do testador de estratégia

A comparação dos resultados obtidos prova que o algoritmo de cálculo da redução relativa está correto.

Vamos adicionar outra variante ao cálculo da redução. Nela, nós excluiremos a influência da retirada de dinheiro na equidade; e observaremos a mudança da redução relativa de equidade.

Para este propósito, vamos adicionar uma variável ao Conselheiro Especialista, nós usaremos ela para determinar se é necessário considerar as retiradas quando calculando os parâmetros do Conselheiro Especialista.

bool wdr_ignore; // calculation of rate without the consideration of withdrawals

O valor de wdr_ignore é igual a true se a variável "Otimização pelo parâmetro" está configurada para "redução sem consideração da retirada".

Além disto, você deve corrigir o processo CalcEquityDrawdown de cálculo da redução adicionando o processamento deste parâmetro a ele como demonstrado abaixo.

if (wdr_ignore) 
  equity = AccountInfoDouble(ACCOUNT_EQUITY) + wdr_summa;
else 
  equity = AccountInfoDouble(ACCOUNT_EQUITY);

Agora que tudo está pronto para a obtenção de novos valores de quedas, vamos realizar testes com o novo algoritmo de cálculo habilitado. Os resultados dos testes são demonstrados na figura 13.

Os resultados do cálculo de quedas sem a consideração de retiradas

Figura 13. Os resultados do cálculo de quedas sem a consideração de retiradas

Os resultados mostram que nem o fato da retirada de ativos, nem a quantidade de dinheiro retirada depende da redução. Assim, nós obtivemos um fator puro que não é afetado pela função TesterWithDrawal(). Entretanto, para usar este tipo de cálculo, nós necessitamos corrigir os valores de lucro e prejuízo, porque seus valores reais mudaram, e estes fatores não são corrigidos no relatório resultante do testador.

Vamos calcular o lucro, prejuízo e sua taxa (lucratividade) e salvar os valores obtidos em um relatório em um arquivo de texto. O procedimento de cálculo dos parâmetros listados é dado baixo.

double SummaryProfit;     // Total net profit
double GrossProfit;       // Gross profit
double GrossLoss;         // Gross loss
double ProfitFactor;      // Profitability
//--- Calculation of parameters for the report
//+------------------------------------------------------------------+
void CalculateSummary(double initial_deposit)
//+------------------------------------------------------------------+
  {
   double drawdownpercent, drawdown;
   double maxpeak = initial_deposit, 
          minpeak = initial_deposit, 
          balance = initial_deposit;
          
   double profit = 0.0;
   
   //--- Select entire history
   HistorySelect(0, TimeCurrent());
   int trades_total = HistoryDealsTotal();

   //--- Searching the deals in the history
   for(int i=0; i < trades_total; i++)
     {
      long ticket = HistoryDealGetTicket(i);
      long type   = HistoryDealGetInteger(ticket, DEAL_TYPE);

      //--- Initial deposit is not considered
      if((i == 0)&&(type == DEAL_TYPE_BALANCE)) continue;

      //--- Calculation of profit
      profit = HistoryDealGetDouble(ticket, DEAL_PROFIT) +
                 HistoryDealGetDouble(ticket, DEAL_COMMISSION) +
               HistoryDealGetDouble(ticket, DEAL_SWAP);
      
      balance += profit;

      if(minpeak > balance) minpeak = balance;

      //---
      if((!wdr_ignore)&&(type != DEAL_TYPE_BUY)&&(type != DEAL_TYPE_SELL)) continue;

      //---
      if(profit < 0) GrossLoss   += profit;
      else           GrossProfit += profit;
      SummaryProfit += profit;
     }

   if(GrossLoss < 0.0) GrossLoss *= -1.0;
   //--- Profitability
   if(GrossLoss > 0.0) ProfitFactor = GrossProfit / GrossLoss;
  }

A função para gerar o relatório em um arquivo de texto é dada abaixo.

//--- Forming the report  
//+------------------------------------------------------------------+
void GenerateReportFile(string filename)
//+------------------------------------------------------------------+
  {
   string str, msg;

   ResetLastError();
   hReportFile = FileOpen(filename, FILE_READ|FILE_WRITE|FILE_TXT|FILE_ANSI);
   if(hReportFile != INVALID_HANDLE)
     {

      StringInit(str,65,'-'); // separator

      WriteToReportFile(str);
      WriteToReportFile("| Period of testing: " + TimeToString(first_tick.time, TIME_DATE) + " - " +
                        TimeToString(tick.time,TIME_DATE) + "\t\t\t|");
      WriteToReportFile(str);

      //----
      WriteToReportFile("| Initial deposit \t\t\t"+DoubleToString(initial_deposit, 2));
      WriteToReportFile("| Total net profit    \t\t\t"+DoubleToString(SummaryProfit, 2));
      WriteToReportFile("| Gross profit     \t\t\t"+DoubleToString(GrossProfit, 2));
      WriteToReportFile("| Gross loss      \t\t\t"+DoubleToString(-GrossLoss, 2));
      if(GrossLoss > 0.0)
         WriteToReportFile("| Profitability       \t\t\t"+DoubleToString(ProfitFactor,2));
      WriteToReportFile("| Relative drawdown of equity \t"+
                        StringFormat("%1.2f%% (%1.2f)", RelEquityDrawdownPercent, MaxEquityDrawdown));

      if(WDR_ENABLE)
        {
         StringInit(msg, 10, 0);
         switch(WDR_PERIOD)
           {
            case day:     msg = "day";    break;
            case week:    msg = "week";  break;
            case month:   msg = "month";   break;
            case quarter: msg = "quarter"; break;
            case year:    msg = "year";     break;
           }

         WriteToReportFile(str);
         WriteToReportFile("| Periodicity of withdrawing       \t\t" + msg);

         if(WDR_TYPE == fixed) msg = DoubleToString(WDR_VALUE, 2);
         else msg = DoubleToString(WDR_VALUE, 1) + " % from deposit " + DoubleToString(initial_deposit, 2);

         WriteToReportFile("| Amount of money withdrawn     \t\t" + msg);
         WriteToReportFile("| Number of withdrawal operations \t\t" + IntegerToString(wdr_count));
         WriteToReportFile("| Withdrawn from account          \t\t" + DoubleToString(wdr_summa, 2));
        }

      WriteToReportFile(str);
      WriteToReportFile(" ");

      FileClose(hReportFile);
     }
  }

O resultado da execução desta função é a criação de um arquivo de texto preenchido com informação como demonstrado na figura 14.

Arquivo do relatório gerado pelo processo GenerateReportFile

Figura 14. Arquivo do relatório gerado pelo processo GenerateReportFile

A função é escrita de uma maneira a adicionar cada novo relatório ao conteúdo existente do arquivo. Devido a este fato, nós podemos comparar os valores dos resultados dos testes com diferentes parâmetros de entrada do Especialista Conselheiro.

Como você pode ver pelo relatório, quando calculando sem a consideração de retiradas (tabela inferior) o lucro total de rede é menor e o prejuízo bruto é maior pela quantidade de dinheiro retirada, comparando aos cálculos do testador (tabela superior). Deve ser notado que para obter o valor real de lucro e prejuízo quando retirando ativos no testador de estratégia, você deve subtrair o valor do parâmetro "Withdrawal" do lucro total de rede e adicionar ele ao prejuízo bruto.


6. Análise do Resultado

Na base dos resultados obtidos por todos os experimentos conduzidos, nós podemos tomar diversas conclusões.

  1. Usando a função TesterWithDrawal() leva a mudanças no algoritmo de cálculo das quedas no testador de estratégia. Comparar diversos Conselheiros Especialistas diferentes pelo valor da redução relativa pode ser incorreto se um deles contém um mecanismo de retirada de dinheiro. Usando esta função você pode fazer um cálculo pragmático de quanto dinheiro você pode tirar periodicamente da sua conta, dependendo da porcentagem aceitável especificada da redução de equidade.
  2. O uso dessa função pode ser implementado como um fator desestabilizador sintético de comércio usado para checar a estabilidade de funcionamento do seu Conselheiro Especialista e ajustando a lógica do código responsável pela administração de dinheiro. Se o seu Conselheiro Especialista tem uma lógica de tomar decisões com base em níveis de equilíbrio ou de capital próprio, em seguida, o uso desta função dá oportunidades adicionais para testes e ajustes.
  3. Quando recalcular a redução relativa sem a consideração de retiradas, usando o algoritmo descrito no artigo, você pode obter um valor puro da redução relativa o qual não é afetado pelo uso desta função.


Conclusão

Este artigo cobre o uso da função TesterWithdrawal() para modelar o processo de retirada de ativos de uma conta, e sua influência no algoritmo de cálculo de queda de equidade no testador de estratégia.