Erros, bugs, perguntas - página 804

 

ilunga:

P.S. Estou correcto ao assumir que no meu (e no seu) código bar_info[1] é o máximo da barra actual?

Ninguém disse nada sobre o bar actual. :)

Acabei de refazer o seu exemplo. Se quiser exactamente o bar actual, tem de o fazer:

1. definir a direcção da série de séries (0 bar - corrente ou a primeira).

Se, como no nosso caso, a matriz for deslocada, pode fazê-lo uma vez no bloco de inicialização. Se escondermos a matriz numa função, definimo-la no lugar.

2. se a matriz for declarada como uma série, a barra actual será zero, e a barra fechada antes de ser 1.

Pelo menos, se bem me lembro.

 

Posso ter perdido alguma coisa, mas para abrir no bar actual (tendo em conta todas as adições) deveria ser assim.

Mova a matriz para a função!

//Function BUY_pending
bool BUY_pending(string symbol,ENUM_TIMEFRAMES period,double volume,ulong magic = 0)
{
//----------------------------------------------------------------------------//
//Work variables
double price = 0, sl = 0, tp = 0; //Prices: Open, Sell stop, Take profit
int ResCopy = -1; //Result of copying the data into an array
int Dig     = 0;  //Digits

double bar_info[1];

bool Result = true; //Returned importance
//----------------------------------------------------------------------------//

ResetLastError();

//Checking the signal to stopping the trading system
  if(IsStopped()) return(false);
//Preparation of array
ArraySetAsSeries(bar_info,true);
//Preparation of structures
ZeroMemory(TradeRequest);
ZeroMemory(TradeResult);
ZeroMemory(CheckResult);
//Copying the data into an array
ResCopy = CopyHigh(symbol,period,0,1,bar_info);

  if(ResCopy==-1)return(false); 
//Calculations
Dig   = (int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);

price = NormalizeDouble(bar_info[0] + 500*_Point,Dig);
sl    = NormalizeDouble(price - 200*_Point,Dig);
tp    = NormalizeDouble(price + 1000*_Point,Dig);
//Preparation of request
TradeRequest.type_filling = ORDER_FILLING_FOK;
TradeRequest.action       = TRADE_ACTION_PENDING;
TradeRequest.type         = ORDER_TYPE_BUY_STOP; 
TradeRequest.deviation    = 10;
TradeRequest.symbol = symbol;
TradeRequest.magic  = magic;
TradeRequest.volume = volume;
TradeRequest.price  = price;
TradeRequest.sl     = sl;
TradeRequest.tp     = tp;
//Checking
Result = OrderCheck(TradeRequest,CheckResult);

  if(!Result)
  //Print message for user
  {
  PrintFormat("retcode=%d",CheckResult.retcode);

  PrintFormat("%s %s at %G Ask=%G  Bid=%G  ",
              EnumToString(TradeRequest.type),symbol,TradeRequest.price,SymbolInfoDouble(symbol,SYMBOL_ASK),
              SymbolInfoDouble(symbol,SYMBOL_BID));                  
  Print("------------");
  }

  if((!Result)||(CheckResult.retcode!=0))return(false);
//OrderSend
Result = OrderSend(TradeRequest,TradeResult);
//Checking for presence of the errors
  if(_LastError!=0){Result = false;}
//----------------------------------------------------------------------------//
return(Result);
//----------------------------------------------------------------------------//
}
 
Interesting:

E ninguém disse nada sobre o actual. :)

Acabei de retrabalhar o seu exemplo. Se precisar de um actual, tem de o fazer:

1. definir a direcção da série de séries (0 bar - corrente ou a mais recente).

Se, como no nosso caso, a matriz for deslocada, pode fazê-lo uma vez no bloco de inicialização. Se escondermos a matriz numa função, definimo-la no lugar.

2. se o conjunto for declarado como uma série, a barra actual será zero, e a barra fechada antes disso será 1.

Pelo menos, se bem me lembro.

Expandi a matriz para 3 elementos. Tenho um desajuste entre o preço actual e o que nele está dentro. Esta é, muito provavelmente, a razão.

#include <Trade\SymbolInfo.mqh>
double bar_info[3];

CSymbolInfo m_sym1;
CSymbolInfo m_sym2;

bool a;
int OnInit()
{
   SymbolSelect("EURUSD",true);
   SymbolSelect("GBPUSD",true);
   a = false;   
   return(0);
}

void OnTick()
{
   if (a) return;
   a = true;
   int ResCopy = CopyHigh("EURUSD",PERIOD_D1,0,3,bar_info);
   if(ResCopy==-1)return;
   Print("bar_info[0] = " + DoubleToString(bar_info[0]));
   Print("bar_info[1] = " + DoubleToString(bar_info[1]));
   Print("bar_info[2] = " + DoubleToString(bar_info[2]));
   PrintFormat("Ask=%G  Bid=%G  ", SymbolInfoDouble("EURUSD",SYMBOL_ASK), SymbolInfoDouble("EURUSD",SYMBOL_BID));
}

Resultados (os testes foram feitos em GBPUSD):

FR      0       test3 (GBPUSD,H1)       13:12:59        2012.01.02 09:00:00   bar_info[0] = 1.29591000
LH      0       test3 (GBPUSD,H1)       13:12:59        2012.01.02 09:00:00   bar_info[1] = 1.29987000
OF      0       test3 (GBPUSD,H1)       13:12:59        2012.01.02 09:00:00   bar_info[2] = 1.29220000
QN      0       test3 (GBPUSD,H1)       13:12:59        2012.01.02 09:00:00   Ask=1.29722  Bid=1.29709  

Percebemos que tanto o Ask como o Bid são maiores que o máximo de zero e maiores que o máximo da segunda barra


Se fizermos o teste no EURUSD, está tudo bem:

FL      0       test3 (EURUSD,H1)       13:21:09        2012.01.02 09:00:00   bar_info[0] = 1.29591000
LJ      0       test3 (EURUSD,H1)       13:21:09        2012.01.02 09:00:00   bar_info[1] = 1.29987000
OP      0       test3 (EURUSD,H1)       13:21:09        2012.01.02 09:00:00   bar_info[2] = 1.29220000
CO      0       test3 (EURUSD,H1)       13:21:09        2012.01.02 09:00:00   Ask=1.29241  Bid=1.2922  


Tenho a sensação de que ao testar "não o meu" par, a situação "a informação sobre barras foi actualizada, mas o tick ainda está ausente".

 
ilunga:

Expandi a matriz para 3 elementos. Fico com incoerência entre o preço actual e o conteúdo da matriz. Essa é muito provavelmente a razão.

Resultados:

Obtemos que Ask e Bid são ambos maiores do que a barra zero máxima e maiores do que a segunda barra máxima

Não considera a seriedade das matrizes, no seu código. Ninguém pode garantir que com este resultado 0 barra não será, digamos, o ano 2000.

Dei o código acima que é adequado para todas as TFs na variante de matriz.

Este código está lá por uma razão.

//Preparation of array
ArraySetAsSeries(bar_info,true);

Se precisar apenas de um período de tempo diário (D1) para identificar o máximo da barra não precisa de lidar com a matriz, basta alterar a primeira parte da função para esta

//Function BUY_pending
bool BUY_pending(string symbol,double volume,ulong magic = 0)
{
//----------------------------------------------------------------------------//
//Work variables
double price = 0, sl = 0, tp = 0; //Prices: Open, Sell stop, Take profit
double High  = 0; //The maximum value of bid for the current day

int Dig     = 0; //Digits

bool Result = true; //Returned importance
//----------------------------------------------------------------------------//

ResetLastError();

//Checking the signal to stopping the trading system
  if(IsStopped()) return(false);
//Preparation of structures
ZeroMemory(TradeRequest);
ZeroMemory(TradeResult);
ZeroMemory(CheckResult);
//Calculations
High = SymbolInfoDouble(symbol,SYMBOL_BIDHIGH);
Dig  = (int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);

price = NormalizeDouble(High + 500*_Point,Dig);
sl    = NormalizeDouble(price - 200*_Point,Dig);
tp    = NormalizeDouble(price + 1000*_Point,Dig);
 
Interesting:

Não considera a seriedade dos arrays no seu código. Ninguém pode garantir que neste resultado 0 barra não estará, digamos, no ano 2000.

Dei o código acima que é adequado para todas as TFs na variante de matriz.

Este código está lá por uma razão

ArraySetAsSeries apenas para arrays dinâmicos?
Документация по MQL5: Основы языка / Типы данных / Объект динамического массива
Документация по MQL5: Основы языка / Типы данных / Объект динамического массива
  • www.mql5.com
Основы языка / Типы данных / Объект динамического массива - Документация по MQL5
 
Interesting:

Não considera a seriedade dos arrays no seu código. Ninguém pode garantir que neste resultado 0 barra não estará, digamos, no ano 2000.

Dei o código acima que é adequado para todas as TFs na variante de matriz.

Este código está lá por uma razão.

Ok, tornar a matriz dinâmica.

#include <Trade\SymbolInfo.mqh>
double bar_info[];

CSymbolInfo m_sym1;
CSymbolInfo m_sym2;

bool a;
int OnInit()
{
   ArrayResize(bar_info, 3);
   ArraySetAsSeries(bar_info,ххх);
   SymbolSelect("EURUSD",true);
   SymbolSelect("GBPUSD",true);
   a = false;   
   return(0);
}

void OnTick()
{
   if (a) return;
   a = true;
   int ResCopy = CopyHigh("EURUSD",PERIOD_D1,0,3,bar_info);
   if(ResCopy==-1)return;
   Print("bar_info[0] = " + DoubleToString(bar_info[0]));
   Print("bar_info[1] = " + DoubleToString(bar_info[1]));
   Print("bar_info[2] = " + DoubleToString(bar_info[2]));
   PrintFormat("Ask=%G  Bid=%G  ", SymbolInfoDouble("EURUSD",SYMBOL_ASK), SymbolInfoDouble("EURUSD",SYMBOL_BID));
}

Em vez de xxx, pomos verdadeiro e falso.

Os resultados:

FF      0       test3 (GBPUSD,H1)       13:25:47        2012.01.02 09:00:00   bar_info[0] = 1.29220000
GL      0       test3 (GBPUSD,H1)       13:25:47        2012.01.02 09:00:00   bar_info[1] = 1.29987000
OJ      0       test3 (GBPUSD,H1)       13:25:47        2012.01.02 09:00:00   bar_info[2] = 1.29591000
FR      0       test3 (GBPUSD,H1)       13:25:47        2012.01.02 09:00:00   Ask=1.29722  Bid=1.29709  

и

JP      0       test3 (GBPUSD,H1)       13:26:07        2012.01.02 09:00:00   bar_info[0] = 1.29591000
PN      0       test3 (GBPUSD,H1)       13:26:07        2012.01.02 09:00:00   bar_info[1] = 1.29987000
KD      0       test3 (GBPUSD,H1)       13:26:07        2012.01.02 09:00:00   bar_info[2] = 1.29220000
MP      0       test3 (GBPUSD,H1)       13:26:07        2012.01.02 09:00:00   Ask=1.29722  Bid=1.29709  

A ordem na matriz é alterada, o resultado não é. A oferta é maior do que a barra máxima [0]-th do conjunto

 
ilunga:
ArraySetAsSeries apenas para arrays dinâmicos?

Não me lembro de ter sido honesto. Mas o resultado desse código, que citei acima, coincide com o que obtemos (preço aberto 1,24516 por EUR, preço aberto 1,56721 por GBP)

High = SymbolInfoDouble(symbol,SYMBOL_BIDHIGH);

Embora sim, funciona bem sem o ArraySetAsSeries neste momento

//+------------------------------------------------------------------+
//Function BUY_pending
bool BUY_pending(string symbol,ENUM_TIMEFRAMES period,double volume,ulong magic = 0)
{
//----------------------------------------------------------------------------//
//Work variables
double price = 0, sl = 0, tp = 0; //Prices: Open, Sell stop, Take profit
int ResCopy = -1; //Result of copying the data into an array
int Dig     = 0;  //Digits

double bar_info[1];

bool Result = true; //Returned importance
//----------------------------------------------------------------------------//

ResetLastError();

//Checking the signal to stopping the trading system
  if(IsStopped()) return(false);
//Preparation of structures
ZeroMemory(TradeRequest);
ZeroMemory(TradeResult);
ZeroMemory(CheckResult);
//Copying the data into an array
ResCopy = CopyHigh(symbol,period,0,1,bar_info);

  if(ResCopy==-1)return(false); 
//Calculations
Dig   = (int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);

price = NormalizeDouble(bar_info[0] + 500*_Point,Dig);

PS

Isto é, se quiser obter a barra actual, copie desnecessariamente três barras para a matriz nesta linha.

//Это не правильно
int ResCopy = CopyHigh("EURUSD",PERIOD_D1,0,3,bar_info);
//так правильно
int ResCopy = CopyHigh("EURUSD",PERIOD_D1,0,1,bar_info);

//если PERIOD_D1 не меняется вот идеальный вариант
 High = SymbolInfoDouble(symbol,SYMBOL_BIDHIGH);
 
Interesting:

PS

Isto é, se precisar de obter a barra actual, copie absolutamente em vão três barras nesta linha para a matriz

Obrigado! Esta opção funciona sem erros e é totalmente suficiente neste caso.


Contudo, a questão deixada suspensa logo acima é como a Proposta pode ser maior do que o máximo =(

 

ilunga:

No entanto, a questão que se coloca acima é como a Proposta pode ser maior do que o máximo =(

Antes de mais, precisamos de determinar para que período este máximo é tomado.

Se o array for declarado como double bar_info[n], então a barra actual nele será o maior índice.

se n = 2 este código irá funcionar com a barra diária de ontem

int ResCopy = CopyHigh("EURUSD",PERIOD_D1,0,2,bar_info);
price = NormalizeDouble(bar_info[0] + 500*_Point,Dig);

e este com a barra actual

int ResCopy = CopyHigh("EURUSD",PERIOD_D1,0,2,bar_info);
price = NormalizeDouble(bar_info[1] + 500*_Point,Dig);

Isto é, se copiar várias barras, deve arranjar algo como isto para obter a barra actual (embora possa necessitar de verificações adicionais de quantas barras foram copiadas para a matriz)

price = NormalizeDouble(bar_info[ResCopy-1] + 500*_Point,Dig);
Документация по MQL5: Доступ к таймсериям и индикаторам / Bars
Документация по MQL5: Доступ к таймсериям и индикаторам / Bars
  • www.mql5.com
Доступ к таймсериям и индикаторам / Bars - Документация по MQL5
 
Interesting:

A primeira coisa a fazer é definir para que período este máximo é tomado.

Se o array for declarado como double bar_info[n], então a barra actual nele será o maior índice.

Assim, existe um código na página anterior onde existe um conjunto de 3 elementos. Ao produzi-lo com impressões, obtemos que Bid = 1.29709, enquanto bar_info[n-1] armazena 1.29220