Características úteis da KimIV - página 12

 

A função IndexByTicket().

Retorna o índice (número ordinal na lista geral de ordens ou posições abertas) da ordem ou posição no bilhete. Se IndexByTicket() não puder encontrar um pedido ou posição com o bilhete requerido, ele retornará -1. Podemos limitar a lista de ordens ou posições a serem verificadas usando os parâmetros da função:

  • sy - Nome do instrumento. Se você especificar este parâmetro, a função só verificará as ordens e posições do instrumento especificado. NULL significa o instrumento atual, e "" (por padrão) significa qualquer instrumento.
  • op - Operação comercial, tipo de ordem ou posição pendente. Valores válidos: OP_BUY, OP_BUYLIMIT, OP_BUYSTOP, OP_SELLL, OP_SELLLLIMIT, OP_SELLSTOP ou -1. O valor padrão de -1 indica qualquer ordem ou posição.
  • mn - Identificador de uma ordem ou posição (MagicNumber). O valor padrão -1 significa qualquer MagicNumber.
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 20.04.2007                                                     |
//|  Описание : Возвращает индекс ордера или позиции по тикету                 |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    ti - тикет ордера, позиции                                              |
//|    sy - наименование инструмента   (""   - любой символ,                   |
//|                                     NULL - текущий символ)                 |
//|    op - операция                   (-1   - любая позиция)                  |
//|    mn - MagicNumber                (-1   - любой магик)                    |
//+----------------------------------------------------------------------------+
int IndexByTicket(int ti, string sy="", int op=-1, int mn=-1) {
  int i, k=OrdersTotal();

  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if ((OrderSymbol()==sy || sy=="") && (op<0 || OrderType()==op)) {
        if ((mn<0 || OrderMagicNumber()==mn) && OrderTicket()==ti) return(i);
      }
    }
  }
  return(-1);
}
 

Eu escrevi a função IndexByTicket() em uma EA personalizada. Lembro-me que não poderia passar sem ele, senão por que o teria escrito? Mas não consigo lembrar como foi usado lá ou porque praticamente o escrevi :-) Procurar o código fonte do consultor é entediante. Há centenas deles.

De qualquer forma, não vejo a utilidade de dar exemplos como os que já dei. Se formos inteligentes, podemos descobrir onde "colocar" os parâmetros. E se alguém tiver uma boa idéia de usar a função IndexByTicket(), poste-a aqui. Tentarei realizá-lo.


Um breve anúncio.

Funções SelectByTicket() e SelectByTicketFromHistory() Aboli-o. Não vou usá-los eu mesmo, por isso não vejo a utilidade de publicá-los. Aqueles que desejam discutir sobre este assunto são sempre bem-vindos. Mostrarei todos os meus delírios como são.

 

A função NumberOfOrders().

Esta função retorna o número de ordens e substitui completamente as Ordens Existentes(). Para substituir a função ExistOrders( ) pela função NumberOfOrders(), é necessário e suficiente verificar o valor de retorno para que ele seja maior que zero. Você pode limitar a lista de ordens a serem verificadas usando os parâmetros da função:

  • sy - Nome do instrumento. Se este parâmetro for dado, a função somente verificará as ordens do instrumento especificado. NULL significa instrumento atual, e "" (por padrão) significa qualquer instrumento.
  • op - Tipo de ordem pendente. Valores válidos: OP_BUYLIMIT, OP_BUYSTOP, OP_SELLLIMIT, OP_SELLSTOP ou -1. O valor padrão de -1 significa qualquer ordem.
  • mn - Identificador do pedido (MagicNumber). O valor padrão -1 significa qualquer MagicNumber.
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 28.11.2006                                                     |
//|  Описание : Возвращает количество ордеров.                                 |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (""   - любой символ,                   |
//|                                     NULL - текущий символ)                 |
//|    op - операция                   (-1   - любой ордер)                    |
//|    mn - MagicNumber                (-1   - любой магик)                    |
//+----------------------------------------------------------------------------+
int NumberOfOrders(string sy="", int op=-1, int mn=-1) {
  int i, k=OrdersTotal(), ko=0, ot;

  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      ot=OrderType();
      if (ot>1 && ot<6) {
        if ((OrderSymbol()==sy || sy=="") && (op<0 || ot==op)) {
          if (mn<0 || OrderMagicNumber()==mn) ko++;
        }
      }
    }
  }
  return(ko);
}
 

Exemplos de como usar a função NumberOfOrders().

  1. Obtenha o valor total de todos os pedidos
    NumberOfOrders();
  2. Obtenha o número de pedidos feitos para o símbolo atual
    NumberOfOrders(NULL);
  3. Obter o número de pedidos de BuyLimit para qualquer símbolo
    NumberOfOrders("", OP_BUYLIMIT);
  4. Obter o número de pedidos SellStop com o número mágico 123456 para EURUSD
    NumberOfOrders("EURUSD", OP_SELLSTOP, 123456);
  5. Obtenha o número de pedidos com um número mágico 2345 para o símbolo atual
    NumberOfOrders(NULL, -1, 2345);

Anexado aqui está novamente um roteiro de trabalho com os exemplos acima.

Arquivos anexados:
 
KimIV:

A função NumberOfOrders().

Esta função retorna o número de ordens e substitui completamente as Ordens Existentes(). Para substituir a função ExistOrders( ) pela função NumberOfOrders(), é necessário e suficiente verificar o valor de retorno para que ele seja maior que zero. Você pode limitar a lista de pedidos a serem verificados usando os parâmetros da função:

  • sy - Nome do instrumento. Se este parâmetro for dado, a função somente verificará as ordens do instrumento especificado. NULL significa instrumento atual, e "" (por padrão) significa qualquer instrumento.
  • op - Tipo de ordem pendente. Valores válidos: OP_BUYLIMIT, OP_BUYSTOP, OP_SELLLIMIT, OP_SELLSTOP ou -1. O valor padrão de -1 significa qualquer ordem.
  • mn - Identificador do pedido (MagicNumber). O valor padrão de -1 significa qualquer MagicNumber.

Estou um pouco confuso. Por alguma razão, eu vejo alguma contradição. Aqui mesmo:

"...é necessário e suficiente verificar se o valor de retorno é maior que zero".

Se você verificar "isto e somente isto", então a função sobre o número de pedidos não tem sentido!

Foi por isso que comecei a me dedicar a isso. Inseri esta função em meu Expert Advisor. Eu defino m=1 em parâmetros e condições para posições abertas.

if (NumberOfOrders("", -1, MagicNumber)<m) {//если открытых позиций МЕНЬШЕ m

Mas é como se o Expert Advisor não visse essa limitação! E abre ordens a cada sinal.

Qual pode ser o problema aqui?

 
rid писал (а):
Estou um pouco confuso. Por alguma razão, eu vejo uma certa contradição. Aqui mesmo:
"...é necessário e suficiente verificar que o valor de retorno seja maior que zero".
Se verificarmos "isto e só isto", então a função para o número de pedidos não tem sentido!

hmm... Você não parece estar prestando atenção à quantidade de informações devolvidas por cada uma das funções ExistOrders() e NumberOfOrders(). A função ExistOrders() retorna apenas informações sobre a existência de pedidos, e a função NumberOfOrders() retorna informações sobre o número de pedidos. As informações sobre o número de pedidos contêm as informações sobre a existência de pedidos. Quando precisamos responder à pergunta se um pedido existe ou não, as informações sobre o número de pedidos são redundantes. É por isso que eu disse que se quisermos substituir a função ExistOrders() pela função NumberOfOrders(), devemos verificar o valor retornado pela função NumberOfOrders() para ter certeza de que ele seja maior que zero. Afinal, é claro que se este valor for igual a zero, não há ordens, e se este valor for maior que zero, as ordens estão presentes. A função ExistOrders() pode ser usada quando não precisamos de informações sobre a quantidade do pedido, enquanto a função NumberOfOrders() pode ser usada quando não precisamos de informações sobre a quantidade do pedido e quando precisamos dela. Neste sentido, a função NumberOfOrders() substitui completamente a função ExistOrders().

livrar:

Eis porque comecei a pesquisar. Inseri esta função em meu Expert Advisor. Eu defino m=1 em parâmetros e condições para posições abertas.

if (NumberOfOrders("", -1, MagicNumber)<m) {//если открытых позиций МЕНЬШЕ m

Mas parece que o Expert Advisor não vê esta restrição! E abre ordens a cada sinal.

Qual pode ser o problema aqui?

Então... e aqui você parece estar confundindo posições com mandados. Para mim, elas são coisas diferentes. O que são posições? São operações OP_BUY e OP_SELL, enquanto as ordens, no meu entendimento, são operações OP_BUYLIMIT, OP_BUYSTOP, OP_SELLLLIMIT e OP_SELLSTOP. Eu abro posições e estabeleço ordens. E o que você abre? A função NumberOfOrders() é projetada para trabalhar com pedidos.
 

Obrigado. Consegui tudo. Tanto na primeira pergunta quanto na segunda.

Em outras palavras, a função NumberOfOrders() "estendida" já inclui essencialmente a função IndexByTicket()

Sim, de fato. Eu abri OP_BUY e OP_SELL !

Resta dar um exemplo de sua próxima função, que funciona exatamente com as posições. (não com ordens).

Lembro que você já postou isso em algum lugar neste fórum. Não consigo encontrá-lo.

 
rid писал (а):
Resta dar um exemplo de sua próxima função, que funciona exatamente com as posições. (não com pedidos)

Já terminei com as funções para pedidos. A seguir estão as funções para os cargos. Há cerca de 30 deles.


rid escreveu (a):
Eu me lembro de algum lugar no fórum que você já postou. Não consigo encontrá-lo.

pesquisa

 

Caro Igor, estou pedindo sua ajuda! Preciso acrescentar um EA para que ele possa tomar posições sobre vários instrumentos. Há 2 EAs funcionando, MACD padrão e Ema, cada um com 6 posições, mas apenas uma posição abre... Li seus comentários sobre isso, mas como não sou bom com a língua, não consigo entender onde acrescentar o que... Se você não se importa, por favor, ajude... copiado Ema conselheiro... Obrigado!



//+
+
//| Parabolic.mq4 |
//| Vitalik | //| ------------------------------------------------------------------ | wwwita@mail.ru //+
+
extern double Lots=0.1;
double externo Pip=5;
double externo MoveBack=3;
extern int chk=0;
extern double SL=20;
//+
+
//|
//+ + int start()
{
double hi=High[1];
double lo=Low[1];
duplo EMA, EMA1, EMA2, EMA3;
int cnt=0, ticket, total;
EMA=iMA(0,0,5,0,MODE_EMA,PRICE_MEDIAN,1);
EMA1=iMA(0,0,10,0,MODE_EMA,PRICE_MEDIAN,1)
EMA2=iMA(0,0,5,0,MODE_EMA,PRICE_MEDIAN,0);
EMA3=iMA(0,0,10,0,MODE_EMA,PRICE_MEDIAN,0);
total=OrdensTotal();
if(total<1)
{
if(AccountFreeMargin()<(1000*Lots))
{
Imprimir("Você não tem dinheiro. Fundos livres = ", AccountFreeMargin());
return(0);
}
if(((EMA>EMA1) && (EMA2<EMA3)) || ((EMA<EMA1) && (EMA2>EMA3))
{
chk=1;
Print("Position is possible!");
}
if(chk==1)
{
if(EMA3-EMA2>2*Point && Bid>=(lo+MoveBack*Point))
{
ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,0,
"EMA position:",16385,0,Red);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
Imprimir("SELL order open : ",OrderOpenPrice());
chk=0;
}
else
{
Print("Error opening SELL order : ",GetLastError());
return(0);
}
}
if(EMA2-EMA3>2*Point && Ask<==(hi-MoveBack*Point))
{
ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,0,
"EMA position:",16385,0,Green);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
Imprimir("BUY order open : ",OrderOpenPrice());
chk=0;
}
else
{
Print("Order BUY open error : ",GetLastError());
return(0);
}
}
}
return(0);
}
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderType()<=OP_SELLL && // esta é uma posição aberta? OP_BUY ou OP_SELL
OrderSymbol()==Symbol()) // combinação de ferramentas?
{
if(OrderType()==OP_BUY) // posição longa aberta
{
// vamos verificar se já é hora de fechar?
if(Bid>=(OrderOpenPrice()+Pip*Point))
{
chk=0;
OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // fechar posição
return(0); // sair
}
if(Bid<=(OrderOpenPrice()-SL*Point))
{
chk=0;
OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // fechar posição
return(0); // sair
}
}
else // otherwise this is a short position
{
// check if it is already time to close?
if(Ask<==(OrderOpenPrice()-Pip*Point))
{
chk=0;
OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); // fechar posição
return(0); // sair
}
if(Ask>=(OrderOpenPrice()+SL*Point))
{
chk=0;
OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); // fechar posição
return(0); // sair
}
}
}
}
return(0);
}
//+------------------------------------------------------------------+
 

Igor, eu lhe fiz uma pergunta na 'Biblioteca de funções para trabalhar com arquivos INI', mas não obtive resposta :(

Razão: