Помощь в кодировании - страница 39

 

Я написал следующую строку кода.

int TriggerChart = PERIOD_H4;

int FastMACDPeriod = 12;

int SlowMACDPeriod = 26 ;

int SignalPeriod = 9;

MacdCurrent = iMACD(Symbol(), TriggerChart, FastMACDPeriod,SlowMACDPeriod,SignalPeriod, PRICE_CLOSE, MODE_MAIN, 1);

С этими вставленными переменными мне интересно, способен ли советник определить, что TriggerChart - это 'int timeframe', а остальные используются для int периодов? Может ли быть так, что когда они все вместе, он смотрит, например, на TriggerChart и FastMACDPeriod и думает, что они оба имеют отношение к int таймфрейму, и путается? В какой момент советник распознает, какая переменная относится к какой части iMACD?

 

...

Короче говоря: нет, она не может запутаться (компьютеры хороши в этом, они не думают, а выполняют одни и те же вещи снова и снова без интерпретации) Только кодеры путаются время от времени.

Когда вы вызываете функцию, она принимает параметры в определенном порядке (месте (например: первый параметр - символ, второй - таймфрейм, и так далее) Совершенно неважно, как вы объявляете (типы) переменных при вызове функции: они используются строго в зависимости от их места в списке вызова параметров

crsnape@btinternet.com:
Я написал следующую строку кода.

int TriggerChart = PERIOD_H4;

int FastMACDPeriod = 12;

int SlowMACDPeriod = 26 ;

int SignalPeriod = 9;

MacdCurrent = iMACD(Symbol(), TriggerChart, FastMACDPeriod,SlowMACDPeriod,SignalPeriod, PRICE_CLOSE, MODE_MAIN, 1);

С этими вставленными переменными мне интересно, способен ли советник определить, что TriggerChart - это 'int timeframe', а остальные используются для int периодов? Может ли быть так, что там, где они все вместе, он смотрит, например, на TriggerChart и FastMACDPeriod и думает, что они оба имеют отношение к int таймфрейму, и путается? В какой момент советник распознает, какая переменная относится к какой части iMACD?
 

Спасибо, Младен. Звучит логично.

В этом коде я объявил BarsGV как 0 в функции int init(). Но, как вы правильно сказали, если я получаю ошибку, она все равно возвращает false. Я просто подумал, что вместо того, чтобы объявлять 0 в int init(), я мог бы сбросить его в 1. Что вы думаете? У меня есть 200SMA, и если Bars меньше 200, он все равно выдает ошибку.

Так что вместо этого:

int init()

{

//---

GlobalVariableSet (BarsGV, 0);

//---

return(0);

}

ЭТО ПОД INT START()

if ((GlobalVariableGet (BarsGV) == 0) || (GlobalVariableGet (BarsGV) < Bars))

{

GlobalVariableSet(HasOrderedGV, false);

GlobalVariableSet(BarsGV, Bars);

}

//--- Проверка возможности длинной позиции (BUY)

if (GlobalVariableGet (HasOrderedGV) == false)

{

Измените на это:

int init()

{

//---

GlobalVariableSet (BarsGV, 1);

//---

return(0);

}

ЭТО ПОД INT START()

if (GlobalVariableGet (BarsGV) == 0);

{

Print("Ошибка с глобальной переменной BarsGV", GetLastError());

return(0);

}

if (GlobalVariableGet (BarsGV) < Bars)

{

GlobalVariableSet(HasOrderedGV, false);

GlobalVariableSet(BarsGV, Bars);

}

//--- Проверка возможности длинной позиции (BUY)

if (GlobalVariableGet (HasOrderedGV) == false)

{

Что вы думаете?

 

...

Измените его на это:

int BarsGV;

bool HasOrderedGV;

int init()

{

//---

BarsGV=0;

HasOrderedGV=false;

//---

return(0);

}

THIS IS UNDER INT START()

if (BarsGV < Bars)

{

HasOrderedGV=false;

BarsGV=Bars;

}

//--- Check for long position (BUY) possibility

if (HasOrderedGV == false)

{[/PHP]

That way you are going to avoid other EA interference and you will keep the variables to only one instance of Ea (they can not mix at all). Much better to do it that way (even from the speed of execution point of view). But you still risk of opening a new order on a same bar this way. The best way is to use a function to count orders opened at the current bar and then allow or disallow ner order opening

Here is a function that can do that (it will check currently opened as well as already closed orders if they have been opened on a current bar) :

bool uniqueOnBar(int MagicNumber)

{

datetime startTime = Time[0];

datetime endTime = startTime+60*Period();

for (int i=OrdersTotal()-1; i>=0; i--)

{

if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;

if (OrderSymbol() != Symbol()) continue;

if (OrderMagicNumber() != MagicNumber) continue;

if (OrderOpenTime()endTime) continue;

return(false);

}

for (i=OrdersHistoryTotal()-1; i>=0; i--)

{

if (!OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) continue;

if (OrderSymbol() != Symbol()) continue;

if (OrderMagicNumber() != MagicNumber) continue;

if (OrderOpenTime()endTime) continue;

return(false);

}

return(true);

}

Checking would be very simple :

[PHP]if (uniqueOnBar(MagicNumber)) .... you can open an a new order

Таким образом, вы не будете зависеть ни от каких переменных, а только от ордеров, и это единственный 100% надежный способ.

crsnape@btinternet.com:
Спасибо mladen. Звучит логично.

В этом коде я объявил BarsGV как 0 в функции int init(). Но, как вы правильно сказали, если я получаю ошибку, она все равно возвращает false. Я просто подумал, что вместо того, чтобы объявлять 0 в int init(), я мог бы сбросить его в 1. Что вы думаете? У меня есть 200SMA, и если Bars меньше 200, он все равно выдает ошибку.

Так что вместо этого:

int init()

{

//---

GlobalVariableSet (BarsGV, 0);

//---

return(0);

}

ЭТО ПОД INT START()

if ((GlobalVariableGet (BarsGV) == 0) || (GlobalVariableGet (BarsGV) < Bars))

{

GlobalVariableSet(HasOrderedGV, false);

GlobalVariableSet(BarsGV, Bars);

}

//--- Проверка возможности длинной позиции (BUY)

if (GlobalVariableGet (HasOrderedGV) == false)

{

Измените на это:

int init()

{

//---

GlobalVariableSet (BarsGV, 1);

//---

return(0);

}

ЭТО ПОД INT START()

if (GlobalVariableGet (BarsGV) == 0);

{

Print("Ошибка с глобальной переменной BarsGV", GetLastError());

return(0);

}

if (GlobalVariableGet (BarsGV) < Bars)

{

GlobalVariableSet(HasOrderedGV, false);

GlobalVariableSet(BarsGV, Bars);

}

//--- Проверка возможности длинной позиции (BUY)

if (GlobalVariableGet (HasOrderedGV) == false)

{

Что вы думаете?
 

Суперзвезда. Спасибо.

 

Привет, Младен,

Эта часть:

datetime EndTime = StartTime + 60 * Period();

Period() - это в данном случае таймфрейм графика. Так скажем H4 (240) * 60, потому что EndTime записывается в секундах, так что преобразование 240minutes в секунды, чтобы соответствовать минутам Периода (240)?

Я правильно понял?

Может ли это также быть записано:

datetime EndTime = (StartTime / 60) + Period();?

 

...

Да, вы все правильно поняли.

Что касается другой формы: вы не можете ее использовать, поскольку OrderOpenTime() имеет стандартный формат времени, что означает, что в EndTime должно быть количество секунд, прошедших с 1 января 1970 года, а то, как вы написали, содержит минуты - metatrader будет считать, что это секунды, и выдаст неверные результаты.

crsnape@btinternet.com:
Hi mladen,

Эта часть:

datetime EndTime = StartTime + 60 * Period();

Period() - это таймфрейм графика. Так скажем, H4 (240) * 60, потому что EndTime записывается в секундах, поэтому преобразование 240 минут в секунды соответствует минутам Периода (240)?

Правильно ли я понимаю?

Может ли это также быть написано:

datetime EndTime = (StartTime / 60) + Period();?
 

Привет, mladen, выбирает ли цикл for здесь последний открытый или отложенный ордер?

bool UniqueOnBar (int MagicNumber)

{

datetime StartTime = Time[0];

datetime EndTime = StartTime + 60 * Period (TriggerChart);

for (int i = OrdersTotal() - 1; i >= 0; i--)

{

if (!OrderSelect (i, SELECT_BY_POS, MODE_TRADES)) continue;

if (OrderSymbol() != Symbol()) continue;

if (OrderMagicNumber() != MagicNumber) continue;

if (OrderOpenTime() endTime) continue;

return (false);

}

Итак, где восклицательный знак интерпретируется как "не", я думаю, что это не подходит для моего случая, потому что я хочу:

- Выбрать последний открытый или отложенный ордер, поэтому удалите ! чтобы оставить OrderSelect?

- OrderSymbol() быть таким же, как Symbol()

- OrderMagicNumber() должен быть равен MagicNumber, так что... остается вот это:

intTriggerChart = PERIOD_H4;

int MagicNumber = 42;

bool UniqueOnBar (int MagicNumber)

{

datetime StartTime = Time[0];

datetime EndTime = StartTime + 60 * Period(TriggerChart);

for (int i = OrdersTotal() - 1; i >= 0; i--)

{

if (OrderSelect (i, SELECT_BY_POS, MODE_TRADES)) continue;

if (OrderSymbol() == Symbol()) continue;

if (OrderMagicNumber() == MagicNumber) continue;

if (OrderOpenTime() endTime) continue;

return (false);

}

 

Моя оплошность. Теперь я понимаю, что когда выражение возвращает true, ни один открытый ордер не подхватывается на текущем баре.

 

...

Да, так и есть. Так что если она возвращает tru, вы можете открыть новый ордер.

Также, если вы хотите проверить таймфрейм, отличный от текущего, если ордер был открыт на текущем баре целевого таймфрейма, то функцию можно изменить на что-то вроде этого:

bool UniqueOnBar (int MagicNumber, int timeFrame=0)

{

if (timeFrame==0) timeFrame=Period();

datetime StartTime = iTime(NULL,timeFrame,0);

datetime EndTime = StartTime + 60*timeFrame;

for (int i=OrdersTotal()-1; i>=0; i--)

{

if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;

if (OrderSymbol() == Symbol()) continue;

if (OrderMagicNumber() == MagicNumber) continue;

if (OrderOpenTime() EndTime) continue;

return(false);

}

return(true);

}

[/PHP]

And then the call to it would be for your example 2 posts ago

[PHP]if (UniqueOnBar(MagicNumber,TriggerChart) ... open an order

PS: Вы убрали проверку закрытых ордеров из примера. Если вы хотите проверить и закрытые ордера, то используйте вторую часть оригинальной формы функции.

crsnape@btinternet.com:
Моя оплошность. Теперь я понимаю, что когда выражение возвращает true, то на текущем баре нет открытых ордеров.