Perguntas de Iniciantes MQL5 MT5 MetaTrader 5 - página 953

 
fxsaber:

Onde o utilizaria?

Toda esta ideia é que digamos que tenho directórios com ficheiros para processamento no endereço "...MQL5Files00dir_01". Usando o vosso maravilhoso código, obtenho o caminho para estas pastas numa matriz e quero aceder a estes ficheiros, sabendo exactamente que ficheiros devem ser processados, e tenho de escrever o caminho para eles, por exemplo "MQL5Files00dir_01Atest".csv" e o código retorna "MQL5\Files\00\dir_01\A", e eu pergunto se posso modificá-lo para devolver o caminho óptimo que será aplicável em código posterior.

 
Aleksey Vyazmikin:

Onde o utilizaria?

Toda esta ideia é que digamos que tenho directórios com ficheiros para processamento no endereço "...\MQL5Files=00dir_01". Usando o vosso maravilhoso código, obtenho o caminho para estas pastas numa matriz e quero aceder a estes ficheiros, sabendo exactamente que ficheiros preciso de processar, e preciso de definir o caminho para estes ficheiros, por exemplo "MQL5Files=00dir_01A test".csv" e o código devolve "MQL5\Files\00\dir_01\A", e pergunto se pode ser modificado de modo a devolver o caminho óptimo que será aplicável em código posterior.

Só não se compreende o que é uma barra dupla - é um carácter que é denotado por dois na sintaxe: primeiro comando de barra, segundo barra o quê.

\n, r, t, t," e "são personagens que são definidos por esta regra. Ou seja, há sempre uma barra no caminho.

 
fxsaber:

Só não se compreende o que é uma barra dupla - é um carácter, que em sintaxe é denotado por dois: o primeiro comando de barra, o segundo o que é a barra.

\n, r, t, t," e "são personagens que são definidos por esta regra. Ou seja, há sempre um corte no caminho.

Não excluo que me esteja a faltar algo, mas preciso de dois cortes para gerar o caminho do ficheiro, não de um.

 
Aleksey Vyazmikin:

Não excluo que esteja a interpretar mal algo, mas preciso de dois cortes para gerar o caminho do ficheiro, não de um.

Não são necessárias duas barras.

void OnStart()
{
  uchar Array[1] = {'\\'};
  
  Print(CharArrayToString(Array));
}
Tentar imprimir um, dois, ou três cortes no tronco. Talvez então compreenda.
 
fxsaber:

Não é necessário dois cortes.

Tentar imprimir uma, duas, ou três cortes no tronco. Talvez então compreenda.

Sim, compreendo que a barra é um comando, mas preciso de escrever o caminho, e utilizo a barra dupla para isso.

Aqui está o caminho.

int zz=FileOpen(" 00\\dir_01\\A\\ZZ_Analiz_Open.bin",FILE_BIN|FILE_READ);

Tenho um fio na matriz Folders[0]:

00\dir_01\A\

Quero aceder a um ficheiro com o mesmo nome, mas em directórios diferentes, alterando o índice da matriz.

int zz=FileOpen(Folders[0]+"ZZ_Analiz_Open.bin",FILE_BIN|FILE_READ);

mas este comando vai receber um erro, não vai?

 
E no ficheiro principal, um dos métodos é criado объект класса incluído e um dos métodos é chamado de ficheiro.

Isso é um desperdício.

 

Olá!

Estou a tentar mudar de MQL4 para MQL5 e não consigo encontrar a última posição fechada.
Na MQL5, quando enviamos uma ordem, é uma ordem, e quando é aberta torna-se uma posição, e logicamente deve ser colocada no histórico de posições e as ordens pendentes apagadas devem ser colocadas no histórico de ordens, mas tudo o que vejo é o histórico de ordens de negócios, por isso não sei onde encontrar uma posição fechada.

Tentei desta forma:

ulong GetLastCloseTicket()
{
    datetime to=TimeCurrent();
    datetime from=to-3*PeriodSeconds(PERIOD_D1);
    HistorySelect(from,to);    
    int Htotal=HistoryOrdersTotal();
    ulong lastOrders[2];
    ulong ticket;
    ArrayInitialize(lastOrders, 0);
 
    for (uint j = 0; j < Htotal; j++)
    {           
        if(ticket= HistoryOrderGetTicket(j)) {            
            if (HistoryOrderGetInteger(ticket,ORDER_TYPE)== ORDER_TYPE_BUY || HistoryOrderGetInteger(ticket,ORDER_TYPE)== ORDER_TYPE_SELL) {
                Print("ticket = " +ticket+";");
                Print("ORDER_TYPE = " +ORDER_TYPE+";");                
                // хранить самый последний (недавно закрытый) ордер в lastOrders[1]
                // а предпоследний в lastOrders[0]
                if (ticket > lastOrders[0]) {
                    if (ticket > lastOrders[1]) {
                        lastOrders[0] = lastOrders[1];
                        lastOrders[1] = ticket;                   
                    } else {
                        lastOrders[0] = ticket;
                    }
                }
            }
        }
    }
    Print("lastOrders[1] = " +lastOrders[1]+";");
    return (lastOrders[1]);   
} 

Mas apresenta números tanto de posições abertas como fechadas. O ORDER_TYPE mostra sempre 4, o que também não é claro.

Tentei alterar a ORDEM para DEAL, mas também não funciona.
Por favor, ajude-me, o que é que se passa?

 
vladzeit:

Vladimir, obrigado.Já estou familiarizado com a funçãoRefreshRates da classeCSymbolInfo .Vi-o nas vossas obras e li numa cartilha.

O apelo desta função noOnTick e a produção de valores de preços noComentário também me são claros a partir do exemplo. O procedimento noOnInit para verificar o símbolo actual também é claro para mim.

Enquanto espero pelo exemplo com o novo bar, vou tentar pôr em prática com o vosso exemplo, não o utilizei na prática. Vou experimentá-lo.


Portanto, este exemplo só funciona no momento em que nasce um novo bar.

Este exemplo utiliza variáveis estáticasPrevBars,prev_ask eprev_bid. A essência das variáveis estáticas é.

As variáveis locais declaradas com a palavra-chave estática mantêm os seus valores duranteo tempo de vida da função. Em cada chamada subsequente da função, estas variáveis locais contêm os valores que tinham na chamada anterior.

Assim, as nossas três variáveis estáticas(PrevBars,prev_ask eprev_bid) são variáveis locais declaradas dentro da função OnTick e armazenam os seus valores, que tinham quando introduziram a função OnTick anteriormente.

PrevBars armazena o tempo do bar anterior. Este tempo é comparado com otempo_0, o tempo da barra actual. Desde quePrevBars seja igual aotempo_0, estamos na barra actual e saímos da função OnTick. O mesmo acontece com as variáveis que armazenam os preços do bar anterior: primeiro exibimos os preços anteriores e actuais e depois escrevemos os preços actuais nas variáveisprev_ask eprev_bid.

//+------------------------------------------------------------------+
//|                                      Display previous prices.mq5 |
//|                              Copyright © 2018, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2018, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.000"
//---
#include <Trade\SymbolInfo.mqh>  
CSymbolInfo    m_symbol;                     // symbol info object
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   if(!m_symbol.Name(Symbol())) // sets symbol name
      return(INIT_FAILED);
   RefreshRates();
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- we work only at the time of the birth of new bar
   static datetime PrevBars=0;
   datetime time_0=iTime(m_symbol.Name(),Period(),0);
   if(time_0==PrevBars)
      return;
   PrevBars=time_0;
   if(!RefreshRates())
     {
      PrevBars=0;
      return;
     }
//---
   static double prev_ask=0.0;
   static double prev_bid=0.0;
   Comment("       Previous | Current","\n",
           "Ask: ",DoubleToString(prev_ask,m_symbol.Digits())," | ",DoubleToString(m_symbol.Ask(),m_symbol.Digits()),"\n",
           "Bid:  ",DoubleToString(prev_bid,m_symbol.Digits())," | ",DoubleToString(m_symbol.Bid(),m_symbol.Digits()));
   prev_ask=m_symbol.Ask();
   prev_bid=m_symbol.Bid();
  }
//+------------------------------------------------------------------+
//| Refreshes the symbol quotes data                                 |
//+------------------------------------------------------------------+
bool RefreshRates(void)
  {
//--- refresh rates
   if(!m_symbol.RefreshRates())
     {
      Print("RefreshRates error");
      return(false);
     }
//--- protection against the return value of "zero"
   if(m_symbol.Ask()==0 || m_symbol.Bid()==0)
      return(false);
//---
   return(true);
  }
//+------------------------------------------------------------------+
Arquivos anexados:
 

Fórum sobre Comércio, Sistemas de Comércio Automatizados e Testes de Estratégia

FAQ de Iniciantes MQL5 MT5 MetaTrader 5

Aleksey Vyazmikin, 2018.12.05 00:39

Eu sei que é um comando cortante, mas preciso de escrever o caminho.

Aqui está o caminho, digamos

int zz=FileOpen(" 00\\dir_01\\A\\ZZ_Analiz_Open.bin",FILE_BIN|FILE_READ);

Tenho um fio em Folders[0] array:

00\dir_01\A\

Quero aceder a um ficheiro com o mesmo nome, mas em directórios diferentes, alterando o índice da matriz.

int zz=FileOpen(Folders[0]+"ZZ_Analiz_Open.bin",FILE_BIN|FILE_READ);

mas este comando vai receber um erro, não vai?


Não haverá erro. Ainda não percebeu o que é um corte duplo.

 
Aleksey Vyazmikin:

Sim, compreendo que a barra é um comando, mas preciso de escrever o caminho, e utilizo a barra dupla para isso.

Aqui está o caminho, por exemplo

Tenho um fio na matriz Folders[0]:

Quero aceder a um ficheiro com o mesmo nome, mas em directórios diferentes, alterando o índice da matriz.

mas este comando vai receber um erro, não vai?

Alexey, pegue um exemplo da documentação

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- неправильный способ открытия файла
   string terminal_data_path=TerminalInfoString(TERMINAL_DATA_PATH);
   string filename=terminal_data_path+"\\MQL5\\Files\\"+"fractals.csv";
   int filehandle=FileOpen(filename,FILE_WRITE|FILE_CSV);
   if(filehandle<0)
     {
      Print("Неудачная попытка открыть файл по абсолютному пути");
      Print("Код ошибки ",GetLastError());
     }
//--- правильный способ работы в "файловой песочнице"
   ResetLastError();
   filehandle=FileOpen("fractals.csv",FILE_WRITE|FILE_CSV);
   if(filehandle!=INVALID_HANDLE)
     {
      FileWrite(filehandle,TimeCurrent(),Symbol(), EnumToString(_Period));
      FileClose(filehandle);
      Print("FileOpen OK");
     }
   else Print("Операция FileOpen неудачна, ошибка ",GetLastError());
//--- еще один пример с созданием вложенной директории в MQL5\Files\
   string subfolder="Research";
   filehandle=FileOpen(subfolder+"\\fractals.txt",FILE_WRITE|FILE_CSV);
      if(filehandle!=INVALID_HANDLE)
     {
      FileWrite(filehandle,TimeCurrent(),Symbol(), EnumToString(_Period));
      FileClose(filehandle);
      Print("Файл должен быть создан в папке "+terminal_data_path+"\\"+subfolder);
     }
   else Print("Операция FileOpen неудачна, ошибка ",GetLastError());
  }

e imprimir as duas variáveis de string destacadas no código de exemplo. Encontrar as diferenças e compreender que a barra dupla só é escrita no código do programa, mas só uma é deixada em tempo de compilação e uma é utilizada no caminho do ficheiro.

Документация по MQL5: Файловые операции / FileOpen
Документация по MQL5: Файловые операции / FileOpen
  • www.mql5.com
[in]  Имя открываемого файла, может содержать подпапки. Если файл открывается для записи, то указанные подпапки будут созданы в случае их отсутствия. [in]  значение, используемое в качестве разделителя в txt или csv-файле. Если для csv-файла разделитель не указан, то по умолчанию используется символ табуляции. Если для txt-файла разделитель не...
Razão: