Discussão do artigo "Escrevendo um consultor especialista utilizando a abordagem de programação orientada a objeto do MQL5" - página 2

[Excluído]  
Yedelkin:
Se o lance na abertura estiver em 1,2695, já teremos 5 pips de perda automaticamente. Se, ao mesmo tempo, o SL for de 50 pips, de acordo com a ideia do desenvolvedor, mais 45 pips terão de passar na direção desfavorável antes que ele seja acionado. Ou seja, quando o stop loss for acionado, o Bid não deverá estar em 1,2645, mas em 1,2650; e o Ask, respectivamente, em 1,2655.

1. Sobre a perda de 5 pips na abertura.

Você está certo sobre a perda, se fecharmos a posição no mesmo momento (condicionalmente), teremos uma perda no valor do spread, os mesmos 5 pips.

Como as posições compradas são fechadas no preço de compra (contra).

Pelo menos logicamente, nesse caso, deveríamos obter essa perda (e ela está correta).

Isso também se aplica ao fechamento com uma ordem contrária. Que resultado você acha que obteremos quando a ordem contrária for acionada ao preço de 1,2695 (que é onde a oferta está no momento)?

Bem, você não alegará que o preço de abertura das posições CURTAS é Ask?

2. Vamos lidar com o fechamento da BU

Lembramos que abrimos na compra a 1,27 (esse preço agora é um nível BU para nós).

É razoável supor que o fechamento do BU ocorrerá se o preço Bid atingir 1,27 (ou seja, subirá exatamente 5 pips).

Vamos verificar nossa afirmação fechando a CU com a ajuda de uma ordem contrária. O preço de abertura dessa posição deve estar em 1,27 e, como sabemos, as ordens de venda são colocadas no Bid. Atualmente, a oferta está em 1,2695. Portanto, para fechar na BU, é necessário passar 5 pips, de modo que não há erro nos cálculos e a afirmação está correta.

3. Sobre SL e TP

Duas afirmações prevalecem aqui:

а. As posições compradas abrem na opção Ask e fecham na opção Bid; as posições vendidas abrem na opção Bid e fecham na opção Ask.

б. A distância para TP e SL é calculada a partir do preço de abertura, o cálculo leva em consideração a direção da posição.


Exatamente de acordo com a segunda afirmação, determinaremos os preços SL e TP para nosso exemplo. No preço de abertura de 1,27, SL = 1,2650 e TP = 1,28 (de acordo com as condições descritas acima).

De acordo com a primeira declaração, o LONG (e no exemplo é o LONG) será aberto com a condição de que o Ask seja igual a 1,27 (e o Bid seja igual a 1,2695, com base no spread de 5 pips). 4.

4. agora vamos determinar em que condições nosso SL e TP serão acionados.

Nossa posição será fechada quando uma das condições for atendida (se não houver outros fatores):

No TP - Se o Bid atingir 1,28 (100 pips de 1,27), o Ask nesse momento estará em 1,2805 (a primeira declaração e o tamanho da regra de spread aqui).

Vamos verificar nossa declaração fechando no TP usando uma posição contrária. O preço de abertura dessa posição deve estar em 1,28 e, como sabemos, as ordens de venda são colocadas no Bid. Atualmente, a oferta está em 1,2695. Portanto, para fechar no TP, é necessário passar 5 pips (para cobrir as perdas no spread) + 100 pips para fixar o lucro.

No SL - Se o preço atingir o nível do SL, igual a 1,2650, como lembramos.


Agora vamos entender qual será o preço. Logicamente, deve ser o preço Bid (que corresponde ao preço de abertura da ordem contrária).

Lembramos que, no momento (de acordo com a condição de abertura da posição), o Bid está em 1,2695. Portanto, o preço precisa passar 45 pips antes que o SL seja acionado.

Assim, registraremos uma perda igual ao spread (5 pips) + 45 pips que o preço teve tempo de passar antes do acionamento do SL.

Desse ponto de vista, você está certo

Vamos verificar nossa afirmação fechando no SL usando uma posição contrária. O preço de abertura dessa posição deve ser de 1,2650 e, como sabemos, as ordens de venda abrem no Bid. Atualmente, a oferta está em 1,2695. Portanto, para fechar na SL, é necessário passar 45 pips. Quando o SL for acionado, será registrada uma perda de 50 pips (5 pips no spread + 45 pips no movimento contra nós).

PS

Mas, desse ponto de vista, esse exemplo para MQL4 não está muito claro para mim.

int ticket;

  if(iRSI(NULL,0,14,PRICE_CLOSE,0)<25)
    {
     ticket=OrderSend(Symbol(),OP_BUY,1,Ask,3,Bid-25*Point,Ask+25*Point,"My order #"+counter,16384,0,Green);
     if(ticket<0)
       {
        Print("OrderSend failed with error #",GetLastError());
        return(0);
       }
    }

Mais precisamente, não estou muito claro com base em qual lógica e quais declarações o SL e somente ele são considerados.

Mas com base nesse exemplo (e somente nele), obtive o seguinte

/Exemplo básico
ticket=OrderSend(Symbol(),OP_BUY,1,Ask,3,SL = Bid-Loss*Point,TP = Ask+Profit*Point,"My order #"+counter,16384,0,Green);
//Ordem para abrir uma posição de mercado
ticket=OrderSend(Symbol(),OP_BUY,1,1.27,3,1.2645 = 1.2695-50*Point,1.28 = 1.27+100*Point);

Com base nos valores Open = 1,27, SL = 1,2645 e TP = 1,28, entendo o seguinte:

1. A posição é aberta quando a Ask atinge o preço de 1,27 (no nosso caso, ela já está lá);

2. O nível BU está localizado no preço de 1,27 e, para fechar nele, a taxa do símbolo (no nosso caso, EUR) deve crescer pelo tamanho do spread (no nosso caso, 5 pips);

3. No momento da abertura, obtemos imediatamente uma perda no valor do spread (no caso de fecharmos a posição IMEDIATAMENTE), porque a posição aberta, com base em declarações lógicas, deve ser fechada com uma ordem contrária. No código MQL4, essa operação terá a seguinte aparência

/Exemplo básico
ticket=OrderSend(Symbol(),OP_SELL,1,Bid,3,0,0);
/Fechar uma posição no mercado com uma ordem contrária
ticket=OrderSend(Symbol(),OP_SELL,1,1.2695,3,0,0);

4. O TP é acionado depois que o preço atinge o nível de 1,28. Logicamente, esse deve ser o preço Bid, já que a ordem contrária é aberta a esse preço (a operação é executada quando o preço Bid atinge o valor de 1,28). Com base nisso, o fechamento no código MQL4 deve ter a seguinte aparência

/Fechar uma posição de TP com uma ordem de mercado (ordem contrária)
ticket=OrderSend(Symbol(),OP_SELL,1,1.28,3,0,0);
/Fechar uma posição com uma ordem pendente de contador (limitador)
ticket=OrderSend(Symbol(),OP_SELLLIMIT,1,1.28,3,0,0);

5. O SL será acionado depois que a taxa do símbolo que está sendo negociado (no nosso caso, EUR) cair 50 pips a partir do momento da abertura.


Agora o mais interessante

Vamos verificar a abertura de uma posição de mercado com base no mesmo exemplo da Ajuda da MQL4 (um exemplo clássico, que provavelmente já foi usado por milhares de pessoas).

Usaremos este código para verificar isso

//+------------------------------------------------------------------+
double PriceOpen,PriceSL,PriceTP;
int ticket;
//+------------------------------------------------------------------+
//Formular preços para o pedido
PriceOpen = Ask;
PriceSL   = Bid-500*Point;
PriceTP   = PriceOpen+1000*Point;
//Ordem para abrir uma posição de mercado
ticket = OrderSend(Symbol(),OP_BUY,0.10,PriceOpen,5,PriceSL,PriceTP);
//+------------------------------------------------------------------+

Ao executar esse código no servidor da Alpari (usando cotações reais), obtemos o seguinte resultado

2010.08.24 09:12:47 '******': instant order buy 0.10 EURUSD at 1.26292 sl: 1.25776 tp: 1.27292

É fácil adivinhar que, nesse caso, obteremos os seguintes tamanhos SL = 516 (ou 51 pips para 4 dígitos) TP = 1000 (ou 100 pips para 4 dígitos)

PPS

Vamos dar uma olhada na Ajuda da MQL4:

Parâmetros:
símbolo - Nome do instrumento financeiro, com o qual a operação de negociação é realizada.
cmd - Operação de negociação. Pode ser qualquer um dos valores da operação de negociação.
volume - Número de lotes.
preço - Preço de abertura.
derrapagem - Desvio máximo de preço permitido para ordens de mercado (ordens de compra ou venda).
stoploss - Preço de fechamento da posição quando o nível de perda é atingido (0 no caso de não haver nível de perda).
takeprofit - Preço de fechamento da posição quando o nível de lucratividade é atingido (0 no caso de ausência de nível de lucratividade).
Comentário - Texto do comentário da ordem. A última parte do comentário pode ser alterada pelo servidor de negociação.
mágica - Número mágico do pedido. Pode ser usado como um identificador definido pelo usuário.
expiração - Período de expiração da ordem pendente.
arrow_colour - Cor da seta de abertura no gráfico. Se o parâmetro estiver ausente ou seu valor for CLR_NONE, a seta de abertura não será exibida no gráfico.
Exemplo:
  int ticket; if(iRSI(NULL,0,14,PRICE_CLOSE,0)<25) { ticket=OrderSend(Symbol(),OP_BUY,1,Ask,3,Bid-25*Point,Ask+25*Point, "My order #"+counter,16384,0,Green); if(ticket<0) { Print("OrderSend failed with error #",GetLastError()); return(0); } }

"Diga-me aqui onde está a verdade, irmão?"...?

OrderSend - Документация на MQL4
  • docs.mql4.com
OrderSend - Документация на MQL4
[Excluído]  
Yedelkin:

Não entendo a seguinte parte do código:

// Copiar o preço de fechamento da barra anterior (barra 1) para a variável correspondente do Expert Advisor
   Cexpert.setCloseprice(mrate[1].close);  // preço de fechamento da barra 1
//--- Verificar se há uma posição de compra
   if (Cexpert.checkBuy()==true)
   {
      if (Buy_opened) 
         {
            Alert("Já temos uma posição para comprar!!!"); 
            return;    // Não adicione à posição longa
         }
      double aprice = NormalizeDouble(latest_price.ask,_Digits);
      double stl    = NormalizeDouble(latest_price.ask - STP*_Point,_Digits);
      double tkp    = NormalizeDouble(latest_price.ask + TKP*_Point,_Digits);
      int    mdev   = 100;
      // fazer o pedido
      Cexpert.openBuy(ORDER_TYPE_BUY,Lot,aprice,stl,tkp,mdev);
   }
Se formos abrir uma posição de compra, devemos nos concentrar no preço latest_price.ask, mas ao definir um Stop Loss e Take Profit para essa posição - no preço latest_price.bid. Isso está correto? Por que o Stop Loss e o Take Profit são definidos com base no preço de venda no texto do código? É um erro de impressão ou uma peculiaridade de uma estratégia específica (o código tem uma construção semelhante para abrir uma posição de venda)?

Essa parte do código deve ser entendida com base nas seguintes afirmações:

а. Longa - abrir na opção Ask e fechar na opção Bid; Curta - abrir na opção Bid e fechar na opção Ask;

б. As posições são fechadas por ordens contrárias;

в. O nível BU está no preço de abertura;

г. A distância para TP e SL é calculada a partir do preço de abertura (nível CU);

д. O TP será acionado quando o preço Bid atingir um nível igual ao preço de abertura + tamanho do lucro;

e. SL será acionado quando o título atingir o nível de Bid igual ao Open Price - Loss size.

O autor do Expert Advisor provavelmente foi guiado por declarações semelhantes em seu trabalho. Para deixar tudo o mais claro possível, apresento uma ilustração do que foi dito acima com a ajuda da tela a seguir (estamos interessados no retângulo vermelho).


 
Interesting:

e. O SL será acionado quando o preço Bid atingir um nível igual ao Open Price - Loss size.

Obrigado, entendi a lógica. Mas, ainda assim, de acordo com o ponto "e", acontece que, quando o stoploss é acionado, o Bid não deve estar em 1,2645, mas em 1,2650; e o Ask, respectivamente, em 1,2655.

[Excluído]  
Yedelkin:

Obrigado, eu entendo a lógica. Mas ainda assim, de acordo com o ponto "e", acontece que, quando um stop loss é acionado, o Bid não deve estar em 1,2645, mas em 1,2650; e o Ask, respectivamente, em 1,2655.

Pode ser que seja assim, você precisa verificar o que acontece exatamente quando o mercado aciona um stop-loss (bem, ou ajustar o modelo da matriz levando em conta todas as possibilidades de fechamento disponíveis)....


Para o ponto "e" (como eu o entendo)

No caso de contar a partir do Open (Ask), será 1,27-50 = 1,2650 (o preço passará 45 pips e a pose será fechada), se eu entendi corretamente. Nesse caso, acho que o SL deve funcionar em Bid 1,2650 e Ask 1,2655.

Outra coisa, se contarmos a partir do Bid, obteremos o preço 1,2695-50 - 1,2645 (não se pode discutir com a matemática). Se calcularmos o SL a partir do Bid, obteremos 1,27-1,2645 = 55 pips (o que, pelo que entendi, não fazia parte de nossos planos).

PS

Pelo menos, esse modelo nos permite quebrar corretamente os níveis de SL e TP a partir do preço de abertura (na minha opinião, corretamente)...

É claro que seria interessante ouvir a opinião oficial dos desenvolvedores sobre como os preços devem ser calculados na realidade (não apenas SL e TP).

 

Pergunta.


100 greenbacks - é em rublo ou u.e.? ;)

 
que foi prometido para desaparecer.
 
Jager:

Pergunta.


100 greenbacks - é em rublo ou u.e.? ;)

Esse é o valor de tempo limite em milissegundos. Esse parâmetro já foi removido de todas as funções de negociação.
 

Olá, obrigado pelo exemplo bem apresentado.

Mas tenho que perguntar se isso está certo.

No EA, ele está verificando se há uma oportunidade de negociação no início de cada nova barra.

Na função de classe getbuffers(), ele recupera os dados das últimas 3 barras, começando pela barra 0 atual, que acabou de ser formada e, portanto, o valor está incorreto.

void MyExpert::getBuffers()
{
if(CopyBuffer(ADX_handle,0,0,3,ADX_val)<0 || CopyBuffer(ADX_handle,1,0,3,plus_DI)<0
|| CopyBuffer(ADX_handle,2,0,3,minus_DI)<0 || CopyBuffer(MA_handle,0,0,3,MA_val)<0)

Ele não deveria estar recuperando os dados do indicador das últimas 3 barras a partir da posição 1?

Obrigado

 

Ótimo artigo, Samuel

Agradeço desde já por esse artigo de valor inestimável,

Então, com base nesse artigo, poderíamos incluir funções como IsNewBar ou Buy_opened na classe e apenas chamá-las a partir do EA.

Mais uma vez, obrigado,

Espero ver mais artigos seus,

Hamed,

 

Por favor, me ajude a entender algo que não entendo:

No início do EA , a função é chamada de:

  Cexpert.doInit(ADX_Period,MA_Period);
при этом для ее корректного выполнения требуются уже установленные параметры symbol  и period :
//+-----------------------------------------------------------------------+
// FUNÇÕES PÚBLICAS DE NOSSA CLASSE 
//+-----------------------------------------------------------------------+
/*
 Inicializando 
*/
void MyExpert::doInit(int adx_period,int ma_period)
{
   //--- Obter o identificador do indicador ADX
   ADX_handle=iADX(symbol,period,adx_period);
  //--- Obter o identificador do indicador de média móvel
   MA_handle=iMA(symbol,period,ma_period,0,MODE_EMA,PRICE_CLOSE);
однако, заполнение этих параметров конкретными значениями происходит позже, уже после Cexpert.doInit :
//--- iniciar a função de inicialização
   Cexpert.doInit(ADX_Period,MA_Period);
//--- definindo todas as variáveis necessárias para nosso objeto de classe
   Cexpert.setPeriod(_Period);     // define o período
   Cexpert.setSymbol(_Symbol);     // especifica o símbolo (par de moedas)
   
   Никак не пойму, как может правильно выполниться Cexpert.doInit, если переменной symbol пока не присвоено
значение (или как-то присвоено ?) Застрял тут и дальше никак . Спасибо.