Ошибки, баги, вопросы - страница 804

 

ilunga:

P.S. Я правильно понимаю, что в моем (и вашем) коде bar_info[1] - это максимум текущего бара?

А про текущий никто не говорил. :)

Я просто ваш пример переделал. если вам нужен именно текущий то нужно:

1. Определить направление серии массива (0 бар -текущий или самый певый).

если как у нас массив вынесен, то можно сделать один раз в блоке инициализации. Если прячем массив в функцию, то определяем по месту.

2. если массив как серия объявлен то текущий бар будет нулевым, а закрытый до этого 1.

По крайней мере как я помню.

 

Возможно я что-то упустил, но для того чтобы по текущему бару открывать (с учетом всех дополнений) нужно так.

Массив перенес в функцию!

//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:

А про текущий никто не говорил. :)

Я просто ваш пример переделал. если вам нужен именно текущий то нужно:

1. Определить направление серии массива (0 бар -текущий или самый певый).

если как у нас массив вынесен, то можно сделать один раз в блоке инициализации. Если прячем массив в функцию, то определяем по месту.

2. если массив как серия объявлен то текущий бар будет нулевым, а закрытый до этого 1.

По крайней мере как я помню.

Расширил массив до 3 элементов. Получил несостыковку текущей цены и того, что в нем находится. Скорее всего причина в этом

#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));
}

Результаты (тестирование проводилось на 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  

Получаем, что и Ask и Bid больше чем максимум нулевого и больше чем максимум второго бара


Если же тест запустить на EURUSD, то все нормально:

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  


Такое ощущение,  что при тесте "не по своей" паре получилась ситуация "информация по барам обновилась, а тика еще нету".

 
ilunga:

Расширил массив до 3 элементов. Получил несостыковку текущей цены и того, что в нем находится. Скорее всего причина в этом

Результаты:

Получаем, что и Ask и Bid больше чем максимум нулевого и больше чем максимум второго бара

Вы серийность массивов не учитываете, в своем коде. Не кто не поручиться за то что при таком исходе что 0 бар не окажется скажем в 2000 году.

Я код выше дал он для всех ТФ подходит при варианте с массивом.

Там вот этот код не зря дан

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

Если же вам нужен только дневной ТФ (D1) для определения максимума бара и вовсе не нужно возится с массивом, просто меняем первую часть функции на эту

//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:

Вы серийность массивов не учитываете, в своем коде. Не кто не поручиться за то что при таком исходе что 0 бар не окажется скажем в 2000 году.

Я код выше дал он для всех ТФ подходит при варианте с массивом.

Там вот этот код не зря дан

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

Вы серийность массивов не учитываете, в своем коде. Не кто не поручиться за то что при таком исходе что 0 бар не окажется скажем в 2000 году.

Я код выше дал он для всех ТФ подходит при варианте с массивом.

Там вот этот код не зря дан

ок, делаем массив динамическим.

#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));
}

Вместо ххх ставим по очереди true и false.

Результаты:

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  

Порядок в массиве изменился, результат нет. Bid больше, чем максимум [0]-го бара массива

 
ilunga:
ArraySetAsSeries только для динамических массивов вроде?

Не помню если честно. Но результат того кода что я выше привел совпадает с тем что вот так получаем (По Евре цена открытия 1.24516 по Фунту 1.56721)

High = SymbolInfoDouble(symbol,SYMBOL_BIDHIGH);

Хотя да, без ArraySetAsSeries нормально работает при таком раскладе

//+------------------------------------------------------------------+
//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

т.е. если вам нужно получить текущий бар вы совершенно зря копируете в массив три бара вот в этой строке

//Это не правильно
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

т.е. если вам нужно получить текущий бар вы совершенно зря копируете в массив три бара вот в этой строке

Спасибо! Данный вариант отрабатывается без ошибок и его полностью хватает в данном случае.


Однако остался подвисшим вопрос чуть выше, каким образом Bid может быть больше максимума =(

 

ilunga:

Однако остался подвисшим вопрос чуть выше, каким образом Bid может быть больше максимума =(

Для начала нужно определить за какой период берется этот максимум.

Если массив объявлен как double bar_info[n] то текущий бар в нем будет самым большим индексом.

при n = 2 вот этот код будет работать со вчерашним дневным баром

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

а вот этот с текущим

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

Т.е. в вашем случае при копировании нескольких баров для того чтобы достать текущий бар нужно устроить что-то вроде этого (хотя могут понадобиться доп. проверки на количество баров которые были скопированы в массив)

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

Для начала нужно определить за какой период берется этот максимум.

Если массив объявлен как double bar_info[n] то текущий бар в нем будет самым большим индексом.

Так на предыдущей странице есть код, там массив из 3 элементов. При выводе Print-ами получаем, что Bid = 1.29709, а в bar_info[n-1] хранится 1.29220
Причина обращения: