Вы используете устаревший браузер. Этот и другие сайты могут отображаться в нем неправильно. Необходимо обновить браузер или попробовать использовать другой.
Ну обычно этим не пользуются по неграмотности.
Можно конечно и в старт запихнуть, но зачем перезаписывать массив теми-же самыми переменными? Достаточно сделать это только один раз при запуске советника.
Вообще логично! Когда я читал тот же учебник, я как-то об этом не думал, и не всё допонимал. А теперь уже уяснил этот момент полностью. И всё стало на свои места.
Возникла проблема.
Эта функция подтягивает СЛ по индикатору. Ввёл условие для дальнейшей роботы что СЛ должен не равнятся тому что показывает индикатор. Смотрел через Алерт. При совпадении СЛ и показаний индикатора всё ровно функция пытается установить СЛ на уже установлённом СЛ-е.
Возникла проблема.
Эта функция подтягивает СЛ по индикатору. Ввёл условие для дальнейшей роботы что СЛ должен не равнятся тому что показывает индикатор. Смотрел через Алерт. При совпадении СЛ и показаний индикатора всё ровно функция пытается установить СЛ на уже установлённом СЛ-е.
Вот статья: _http://articles.mql4.com/ru/330
Я вот сколько не смотрю на код, вижу что по ходу тут канкретная логическая ошибка.
Суть в том, что Есть 2, например куска кода:
PHP:
//| удаление лишних ордеров |
int cnt_del;
if(pos_buy==0)
{
for (cnt_del=0; cnt_del<OrdersTotal(); cnt_del++)
{
if (!(OrderSelect(cnt_del, SELECT_BY_POS, MODE_TRADES))) continue;
if(OrderSymbol()==Symbol())
{
if (OrderType()==OP_BUYSTOP && OrderMagicNumber()==MagicNumber2) OrderDelete(OrderTicket());
}
}
}
PHP:
//| поиск открытых ордеров по паре |
int pos_sell=0;
for (int i_op_sell=OrdersTotal()-1; i_op_sell>=0; i_op_sell--)
{
if (!OrderSelect(i_op_sell,SELECT_BY_POS,MODE_TRADES)) break;
if (Symbol()==OrderSymbol()
&&OrderMagicNumber()==MagicNumber1
&&(OrderType()==OP_SELL))
{
pos_sell=1; break;
}
}
Сразу видно, что в одном случает автор выходит из цикла как только какой-то из ордеров не выбран, а во-втором случает пропускает эту выборку и дальше проверяет..
Логически абсурдно. А по факту спрашиваю у присуствующих.. Сам не въезжаю.
int GMToffset, Myoffset, LoclTime;
#import "kernel32.dll"
void GetLocalTime(int& a0[]);
int GetTimeZoneInformation(int& a0[]);
#import
потом есть такая функция:
Код:
int AutoGMTOffset()
{
int Timezone[43];
int offset1 = -420;
int offset2 = GetTimeZoneInformation(Timezone);
if (offset2 != 0) offset1 = Timezone[0];
if (offset2 == 2) offset1 += Timezone[42];
LoclTime = TimeLocal() + 60 * offset1;
GMToffset = (TimeCurrent() - LoclTime) / 3500;
Myoffset = + ((TimeLocal() - LoclTime) / 3500);
return (0);
}
Понимаю так что в начале у винды запрашивается локальное время и локальная тайм-зона.
=====================================================
Далее пишу построчно как я думаю(наверно неправильно)...
1) инициализируется массив Timezone размером 43 ячейки
2) инициализируется переменная offset1 со значением -420(почему такое значение? откуда? непонятно...)
3) в offset2 заносится значение из виндовой длл (локальная тайм-зона), в каком формате? в часах +3? или +10800 в секундах?
4) и вот тут я уже вообще не понимаю - если offset2 не равен нулю(то есть получается - если я не живу в ЖМТ=0, то offset1 будет равен значению из ячейки 0 массива Timezone - а чему оно равно? мы его что? уже чем то заполнили? когда? чем?
5) тут еще хуже - если offset2 равен 2 то offset1 будет равен... и тут я тоже не понимаю (я не знаю что значит += Timezone[42] - это что, значение offset1 равно самому себе плюс значение из ячейки 42 массива? или как?)
6) переменная LoclTime равна лок.время + offset1 умноженное на 60(чтобы получить часы) - вычисления понятны, не понятно для чего
7) и 8) не понимаю почему делится на 3500 а не на 3600, ведь если хотят получить часы из секунд надо делить на 3600?
и еще - в 8) опять есть такое выражение "= +" это что значит? и равнозначно ли оно предыдущему "+=" как было написано в 5)?
Прошу помощи у гуру - распишите мне тупому построчно (как примерно я выше) что значит каждая строчка в функции...
А то советник работает в тестере, эти значения подставляются из этой функции(для этого она и была написана автором) а на демо-счете не работает, не ставит уровни, не открывает ордера.
Вот статья: _http://articles.mql4.com/ru/330
Я вот сколько не смотрю на код, вижу что по ходу тут канкретная логическая ошибка.
Суть в том, что Есть 2, например куска кода:
PHP:
//| удаление лишних ордеров |
int cnt_del;
if(pos_buy==0)
{
for (cnt_del=0; cnt_del<OrdersTotal(); cnt_del++)
{
if (!(OrderSelect(cnt_del, SELECT_BY_POS, MODE_TRADES))) continue;
if(OrderSymbol()==Symbol())
{
if (OrderType()==OP_BUYSTOP && OrderMagicNumber()==MagicNumber2) OrderDelete(OrderTicket());
}
}
}
PHP:
//| поиск открытых ордеров по паре |
int pos_sell=0;
for (int i_op_sell=OrdersTotal()-1; i_op_sell>=0; i_op_sell--)
{
if (!OrderSelect(i_op_sell,SELECT_BY_POS,MODE_TRADES)) break;
if (Symbol()==OrderSymbol()
&&OrderMagicNumber()==MagicNumber1
&&(OrderType()==OP_SELL))
{
pos_sell=1; break;
}
}
Сразу видно, что в одном случает автор выходит из цикла как только какой-то из ордеров не выбран, а во-втором случает пропускает эту выборку и дальше проверяет..
Логически абсурдно. А по факту спрашиваю у присуствующих.. Сам не въезжаю.
В этом никакого абсурда нет. Всё зависит от конкретной ситуации.
для начала нужно разобраться почему ордер может не выбраться. Причина может быть одна, это отсутствие ордера. То есть, пока выполнялся код, какой то ордер закрылся. В итоге реалное количество ордеров не совпадает с значением OrdersTotal();
По этому надо задуматься, а как лучше поступить в каждом конкретном случае, перейти к следующему ордеру или прекратить работу цикла.
Тем не менее ошибка в верхнем коде есть. Перебирать ордера нужно в от последнего к первому. Иначе могут не все ордера удалиться. Ибо нумерация динамическая.
народ как правильно придать цветность комментарию?
- а то еле видно светло серым вверху в уголке
{
Comment ("\n","Риск = ", DoubleToStr(Risk,2),", Лот = ",DoubleToStr(Lot,2));
}
спсб...
народ как правильно придать цветность комментарию?
- а то еле видно светло серым вверху в уголке
{
Comment ("\n","Риск = ", DoubleToStr(Risk,2),", Лот = ",DoubleToStr(Lot,2));
}
спсб...
Вот статья: _http://articles.mql4.com/ru/330
Я вот сколько не смотрю на код, вижу что по ходу тут канкретная логическая ошибка.
Суть в том, что Есть 2, например куска кода:
PHP:
//| удаление лишних ордеров |
int cnt_del;
if(pos_buy==0)
{
for (cnt_del=0; cnt_del<OrdersTotal(); cnt_del++)
{
if (!(OrderSelect(cnt_del, SELECT_BY_POS, MODE_TRADES))) continue;
if(OrderSymbol()==Symbol())
{
if (OrderType()==OP_BUYSTOP && OrderMagicNumber()==MagicNumber2) OrderDelete(OrderTicket());
}
}
}
PHP:
//| поиск открытых ордеров по паре |
int pos_sell=0;
for (int i_op_sell=OrdersTotal()-1; i_op_sell>=0; i_op_sell--)
{
if (!OrderSelect(i_op_sell,SELECT_BY_POS,MODE_TRADES)) break;
if (Symbol()==OrderSymbol()
&&OrderMagicNumber()==MagicNumber1
&&(OrderType()==OP_SELL))
{
pos_sell=1; break;
}
}
Сразу видно, что в одном случает автор выходит из цикла как только какой-то из ордеров не выбран, а во-втором случает пропускает эту выборку и дальше проверяет..
Логически абсурдно. А по факту спрашиваю у присуствующих.. Сам не въезжаю.
В этом никакого абсурда нет. Всё зависит от конкретной ситуации.
для начала нужно разобраться почему ордер может не выбраться. Причина может быть одна, это отсутствие ордера. То есть, пока выполнялся код, какой то ордер закрылся. В итоге реалное количество ордеров не совпадает с значением OrdersTotal();
По этому надо задуматься, а как лучше поступить в каждом конкретном случае, перейти к следующему ордеру или прекратить работу цикла.
Тем не менее ошибка в верхнем коде есть. Перебирать ордера нужно в от последнего к первому. Иначе могут не все ордера удалиться. Ибо нумерация динамическая.
я понимаю, что какой-то ордер уже к моменту выборки может отсуствовать. Но, скажем так, ордер который уже закрылся был где-то 5-ый из 10. Выборка будет по очереди, если от последнего 10,9, 8, 7, 6 ... вот мы наткнулись на 5-ый.. если продолжим как в первом верхнем варианте, то мы пропустим 5-ую выборку и дальше пойдёт 4,3,2,1 и 0.
Но если мы пойдём по пути второму нижнему, то на 5-ом ордере (если он уже закрыт), будет выход из цикла, так как там стоит оператор break.
Так? Значит всё-таки ошибка это как ни крути..
я понимаю, что какой-то ордер уже к моменту выборки может отсуствовать. Но, скажем так, ордер который уже закрылся был где-то 5-ый из 10. Выборка будет по очереди, если от последнего 10,9, 8, 7, 6 ... вот мы наткнулись на 5-ый.. если продолжим как в первом верхнем варианте, то мы пропустим 5-ую выборку и дальше пойдёт 4,3,2,1 и 0.
Но если мы пойдём по пути второму нижнему, то на 5-ом ордере (если он уже закрыт), будет выход из цикла, так как там стоит оператор break.
Так? Значит всё-таки ошибка это как ни крути..
Нет, не может отсутствовать №5 ордер из десяти. Здесь нумерация динамическая. Если из 10 ордеров один отсутствует, не важно какой он был по счёту, то их станет 9. №0...№8. Они всегда по порядку. Значит не станет №9 ордера.
Нет, не может отсутствовать №5 ордер из десяти. Здесь нумерация динамическая. Если из 10 ордеров один отсутствует, не важно какой он был по счёту, то их станет 9. №0...№8. Они всегда по порядку. Значит не станет №9 ордера.
Я так понимаю, если б мы выборку делали с истории к последней позиции, то дыра могла быть.. А раз мы перебираем от последней позиции к самой первой т.е. идёт от настоящего к истории.. то дыр не будет. Верно?
Я так понимаю, если б мы выборку делали с истории к последней позиции, то дыра могла быть.. А раз мы перебираем от последней позиции к самой первой т.е. идёт от настоящего к истории.. то дыр не будет. Верно?
По простому. Допустим 5 ордеров, №0-№4. Если удалять в порядке возрастания. Удалили №0, следующим будет удаляться №1.
Стало 4 ордера, №0-№3. То есть бывший №1 стал №0, бывший №2 стал №1.
Так как следующим удаляется №1, то №0 (Бывший №1) будет пропущен.
И так при каждом удалении.
Если же удалять от последнего к первому, никаких сдвигов номеров не будет, а значит все ордера удалятся.
Ugar, по-моему более грамотно будет выборку призвоить по тикету, тогда не нужно будет думать о том, чтоб с конца начинать или первого открытого. Согласен?
Ugar, по-моему более грамотно будет выборку призвоить по тикету, тогда не нужно будет думать о том, чтоб с конца начинать или первого открытого. Согласен?
А от куда программа узнает тикеты всех открытых ордеров?
Можно конечно извернуться. Создать массив, длинной равной количеству ордеров. В цикле перебрать ордера по номерам, в любом порядке, записать их тикеты в массив. Потом, ещё в одном цикле, перебирать ячейки массива по номерам, в любом порядке, извлекать тикет. Выбирать ордера по тикету и удалять их.
Только вот, кажется мне, что это как то выглядит через задницу, хотя на самом деле через массив.
Думал я что сказать.. Опыта ещё нет, чтоб ответить сразу. Но выборка по тикету это же дефолтовская функция, зачем так всё усложнять массивами?
Если в документации есть такой вариант выборки, значит должно быть проще по логике.
Думал я что сказать.. Опыта ещё нет, чтоб ответить сразу. Но выборка по тикету это же дефолтовская функция, зачем так всё усложнять массивами?
Если в документации есть такой вариант выборки, значит должно быть проще по логике.
Вот как-раз для определения тикета ордера и перебирают их по порядку. Можно конечно при открытии ордера записать тикет в переменную и потом его использовать, но если открывается не один ордер то заморочек больше чем перебрать открытые ордера и выбрать необходимый.
AlexeyVik, видимо это с опытом приходит. На данный момент я вот уже почти начал понимать что да как, перед тем как начать программировать. Потому и вопросы бывают не такие логичные.
Я попутно смотрю на функцию Кима:
PHP:
void SimpleTrailing(string sy="", int op=-1, int mn=-1) {
double po, pp;
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)) {
po=MarketInfo(OrderSymbol(), MODE_POINT);
if (mn<0 || OrderMagicNumber()==mn) {
if (OrderType()==OP_BUY) {
pp=MarketInfo(OrderSymbol(), MODE_BID);
if (!TSProfitOnly || pp-OrderOpenPrice()>TStop.Buy*po) {
if (OrderStopLoss()<pp-(TStop.Buy+TrailingStep-1)*po) {
ModifyOrder(-1, pp-TStop.Buy*po, -1);
}
}
}
if (OrderType()==OP_SELL) {
pp=MarketInfo(OrderSymbol(), MODE_ASK);
if (!TSProfitOnly || OrderOpenPrice()-pp>TStop.Sell*po) {
if (OrderStopLoss()>pp+(TStop.Sell+TrailingStep-1)*po || OrderStopLoss()==0) {
ModifyOrder(-1, pp+TStop.Sell*po, -1);
}
}
}
}
}
}
}
}
Тут у меня вопрос появился.
В данном участке кода:
PHP:
if (!TSProfitOnly || pp-OrderOpenPrice()>TStop.Buy*po)
{ if (OrderStopLoss()<pp-(TStop.Buy+TrailingStep-1)*po)
!TSProfitOnly означает, что если режим траал только после достижения безубыточности т.е. это траал только в профитной зоне.
Но тут идёт вариант TSProfitOnly со знаком !, т.е. наоборот выходит, что эта функция не включена. А дальше условие, которое как-раз должно соблюдаться, чтоб TSProfitOnly было в TRUE.
Смысл в том, что получается, что переменная TSProfitOnly. А условие с этой переменной есть только для варианта FALSE, а для TRUE условия нет.