Обучение языку MQL4 под MetaTrader 4📌

От xbms, 13 апреля, 2013 в Уголок Программиста

#1551


Crik1978
1. Цикл у Вас по i, а в внутри почему-то Li_52? - это так задумано?
2. high_88 = High[Li_52 + 1] - это хай предыдущего бара (который перед Li_52)
3. Надо что-то делать с этими хаями - иначе цикл не оправдан.



Да это "описка" скажем так.

Спасибо за пояснение.
#1552

А как создать условие, чтобы на одной свече не открывались два ордера одного типа?
Подскажите пожалуйста, не соображу никак

Проверка индикаторов и условий на каждом тике должна быть, поэтому
static int newHour;
if (newHour == Hour()) return;
newHour = Hour();
проблему не решает

#1553
oleguitar Самое простое решение это установка флага:
bool fl_Buy = false, fl_Sell = false;
...
if(is_Buy && !fl_Buy) {fl_Buy = true; Open_Buy();}
для селл тоже
...
static int newHour;
if (newHour == Hour()) return;
newHour = Hour();
fl_Buy = false; fl_Sell = false;
#1554


oleguitar Самое простое решение это установка флага:
bool fl_Buy = false, fl_Sell = false;
...
if(is_Buy && !fl_Buy) {fl_Buy = true; Open_Buy();}
для селл тоже
...
static int newHour;
if (newHour == Hour()) return;
newHour = Hour();
fl_Buy = false; fl_Sell = false;



Не понял ничего :(

Что означает переменная fl_Buy и fl_Sell?

if(is_Buy && !fl_Buy) {fl_Buy = true; Open_Buy();} // а что такое is_Buy? это как CountBuy()? B Open_Buy() - это код, отправляющий ордер?

Open_Buy()
{
OrderSend....
}

И возможно ли проверять, были ли на текущей свече открытые позиции? И если да, то новых не открывать
#1555

fl_Buy - флаг открытия позиции на текущей свече = false - не открыта, true - открыта.
is_Buy - Ваше условие (индюки) на открытие бай ордера.
таким образом (перевожу с mql на русский):
if(is_Buy && !fl_Buy) {fl_Buy = true; Open_Buy();}
если условие_Бай и НЕ флаг_открыта, то флаг_открыта = true, открыть_Бай.
Флаг_открыта - это и есть проверка открытия ордера на текущей свече.
после закрытия свечи - сбрасываем флаг в false.

Честно говоря думал Вы уже хорошо разбираетесь в логике mql

#1556


fl_Buy - флаг открытия позиции на текущей свече = false - не открыта, true - открыта.
is_Buy - Ваше условие (индюки) на открытие бай ордера.
таким образом (перевожу с mql на русский):
if(is_Buy && !fl_Buy) {fl_Buy = true; Open_Buy();}
если условие_Бай и НЕ флаг_открыта, то флаг_открыта = true, открыть_Бай.
Флаг_открыта - это и есть проверка открытия ордера на текущей свече.
после закрытия свечи - сбрасываем флаг в false.

Честно говоря думал Вы уже хорошо разбираетесь в логике mql



То есть, как я понимаю, вот эту часть

static int newHour;
if (newHour == Hour()) return;
newHour = Hour();
fl_Buy = false; fl_Sell = false

нужно ставить в самый конец кода, чтобы не мешать проверке ордеров на каждом тике?

А то, что мы вначале кода объявляем bool fl_Buy = false, fl_Sell = false - при проверке на новом тике, флаг не приобретет значение false?
#1557
oleguitar, я Вам бы порекомендовал посмотреть в индюках ту часть кода, что отвечает за алерт, а именно, что бы не сигналить на каждом тике, а только раз на свече. То, что предлагает 0ll именно так и реализовано в алертах, что и применимо в данном случае.
#1558


А то, что мы вначале кода объявляем bool fl_Buy = false, fl_Sell = false - при проверке на новом тике, флаг не приобретет значение false?

Приобретёт. Это надо делать на глобальном уровне или static.
Сброс флага по закрытию свечи в конце или если вот так, то в любом месте:
static int newHour;
if (newHour {
newHour = Hour();
fl_Buy = false; fl_Sell = false;
}

mobidik он хочет с 0-бара значения индюков брать. на мои советы этого не делать - не реагирует.
#1559


oleguitar, я Вам бы порекомендовал посмотреть в индюках ту часть кода, что отвечает за алерт, а именно, что бы не сигналить на каждом тике, а только раз на свече. То, что предлагает 0ll именно так и реализовано в алертах, что и применимо в данном случае.



Я использую индикатор Parabolic SAR, который может изменить свое значение пока рисуется свеча, и сразу же после этого нужно выполнять условия.
Как такового алерта там, как я понимаю, нет, и как реагировать на изменения показаний индикатора просто не знаю.

Цитата

Приобретёт. Это надо делать на глобальном уровне или static.



То есть можно просто сделать fl_Buy и fl_Sell переменными типа "static"?
#1560


Я использую индикатор Parabolic SAR, который может изменить свое значение пока рисуется свеча, и сразу же после этого нужно выполнять условия.
Как такового алерта там, как я понимаю, нет, и как реагировать на изменения показаний индикатора просто не знаю.



как-то не понятно, после чего:

после этого нужно выполнять условия.



как будет сигнал индикатора или закроется свеча? На нулевом баре входить это, как по мне, большой риск получить ложный вход. На закрытом - это уже другое дело, но при сильных движениях, цена может сильно улететь. Тут все зависит от стратегии, самого алгоритма и качества индикаторов.
А на счет алерта, так возьмите любой индюк и разберите его работу алерта, станет многое понятно.
Но вернемся к вопросу:


А как создать условие, чтобы на одной свече не открывались два ордера одного типа?
Подскажите пожалуйста, не соображу никак

Проверка индикаторов и условий на каждом тике должна быть, поэтому
static int newHour;
if (newHour == Hour()) return;
newHour = Hour();
проблему не решает



еще как решает, в начале объявляем: static int newHour;
затем:
//----------------------------------------------------------------------------------------------------------------------------------------------------------------
int start()

if (newHour ==Time[0]) return(0);
*******
*******
*******
условие на бай
if(OrderSend(Symbol(),OP_BUY, LOT(),NormalizeDouble(Ask,Digits),Slippage,SL,TP,"Sova",Magic,0,Red)!=-1) newHour =Time[0];

условие на сел
if (OrderSend(Symbol(),OP_SELL,LOT(),NormalizeDouble(Bid,Digits),Slippage,SL,TP,"Sova",Magic,0,Red)!=-1) newHour =Time[0];
//----------------------------------------------------------------------------------------------------------------------------------------------------------------
т.е., что имеем: пока не открыт ни один ордер, на текущей свече, newHour равен "0" или уже истории и код работает на каждом тике, все считается. Как только выполнится одно из условий входа и будет открыт ордер - newHour станет равен времени текущей свече. На следующем тике, дабы снова не выполнилось условие и не открылся еще один ордер, ставим проверку на время по свече, если оно не изменилось - возвращаемся к началу и так до тех пор, пока не появится новая свеча. Но вот здесь снова может открыться ордер, все зависит от условий входа. Если, например, по условию две МА поменялись местами - ордера будут открываться на каждом новом баре, а если задали в условии только пересечение двух МА, то следующий ордер откроется только при повторном, уже обратном, пересечении МА.
Пробуй.
#1561

mobidik,

я уже создал стат. переменные, логика такая же, все получилось

Цитата

как будет сигнал индикатора или закроется свеча? На нулевом баре входить это, как по мне, большой риск получить ложный вход. На закрытом - это уже другое дело, но при сильных движениях, цена может сильно улететь. Тут все зависит от стратегии, самого алгоритма и качества индикаторов.



Как только сигнал появится
Если есть возможность проверять показания индикаторов, скажем, раз в час, то так и делаю, просто тут ситуация другая
#1562

Всё! ~x( надоело всё!!! Все эти советники по индикаторам, стратегии, всё это чушняк, все они бегают в след за ценой, а в последнюю очередь Мы в след за индикаторами! Надоело! Всё одна и та же история! Тесты прибыльные, красивые! А на реале ничё не фурычит! Стабильной прибыльной индикаторной стратегии не существует! Единственная прибыль которую получил из всего этого это введение в программирование! Очень понравилось! Учу SWIFT >:d

#1563

Пытаюсь добавить расчет лота в советник, делал все как в уроке, но не получается...

Спойлер



double LotsByRisk(int op_type, double risk, int sl)
{
double lot_min = MarketInfo(Symbol(), MODE_MINLOT);
double lot_max = MarketInfo(Symbol(), MODE_MAXLOT);
double lot_step = MarketInfo(Symbol(), MODE_LOTSTEP);
double lotcost = MarketInfo(Symbol(), MODE_TICKVALUE);

double lot = 0;
double UsdPerPip = 0;

lot = AccountBalance()*risk/100;
UsdPerPip = lot/sl;

lot = NormalizeDouble(UsdPerPip/lotcost,2);
lot = NormalizeDouble(lot/lot_step,0)*lot_step;

if(lot if(lot
if( AccountFreeMarginCheck(Symbol(), op_type,lot) {
Alert("Order can not be opened. Reason: not enough money. ");
return(-1);
}
return(lot);
}

//---------------

Print(" Stoploss = " +Stoploss);
Print(" Lot = " + DoubleToStr(LotsByRisk(OP_SELL, Risk, Stoploss)),2);
ticket = OrderSendX(Symbol(), OP_SELL, LotsByRisk(OP_SELL, Risk, Stoploss), Bid, Slippage, 0, 0, "", Magic, 0, Red);




выдает ошибку

Спойлер



Не пойму никак в чем дело...
#1564
oleguitar может из-за этого:
if(lot
#1565


oleguitar может из-за этого:
if(lot



Точно! :)
#1566

Всем привет!

с целью дальнейшего закрытия двух разнонаправленных ордеров при достижении общего суммарного профита необходимо найти ордер с наибольшим объемом.

попробовал что-то написать в функции, прошу посмотреть
double maxLots()
{
lot=0;

for(int i=OrdersTotal()-1; i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic && OrderType()==OP_BUY || OrderType()==OP_SELL)
{
nextlot=OrderLots();
if (nextlot>lot)
{
ticket=OrderTicket();
lot=nextlot;
}
}
}
}
return(ticket);
}


#1567
Crik1978, а почему просто не закрыть по вычисленному суммарному профиту?
#1568


Crik1978, а почему просто не закрыть по вычисленному суммарному профиту?



да хотел что бы первым закрывался ордер с наибольшим объемом , т.к. у него больше профит - чем у ордера с меньшим объемом.
#1569

Ну в общем должно работать, если ticket и lot объявлены на глобальном уровне и наименование функции вместо double нужно сделать int, мы же получаем номер тикета, а он является целочисленным.

#1570


Ну в общем должно работать, если ticket и lot объявлены на глобальном уровне и наименование функции вместо double нужно сделать int, мы же получаем номер тикета, а он является целочисленным.



ну да, согласен. ошибся.
в функции закрытия ордеров нужно как-то указывать что первым закрыть ордер с наибольшим объемом?
#1571
Crik1978
1. Ваш код работать не будет из-за нарушения приоритета выполнения логических операций:
эту часть кода нужно взять в скобки (OrderType()==OP_BUY || OrderType()==OP_SELL)

2. Согласен с chistaia-rodina - не занимайтесь ерундой. Закрывайте ордера без дополнительных проверок в той последовательности в которой будете цикл на перебор делать.
#1572

В функции закрытия придётся пожалуй сделать два цикла, в первом с проверкой на соответствие тикету, а во втором всё остальное. Просто сохраняешь значение функции maxLots() к примеру в переменную ticket, а затем при переборе ордеров добавляешь строчку if(OrderTicket() == ticket). Правда не уверен что так будет лучше и быстрее по исполнению.

0ll, опередил, только хотел дописать что ещё двух скобочек не хватает.

#1573


В функции закрытия придётся пожалуй сделать два цикла, в первом с проверкой на соответствие тикету, а во втором всё остальное. Просто сохраняешь значение функции maxLots() к примеру в переменную ticket, а затем при переборе ордеров добавляешь строчку if(OrderTicket() == ticket). Правда не уверен что так будет лучше и быстрее по исполнению.

0ll, опередил, только хотел дописать что ещё двух скобочек не хватает.



если при вызове функции закрытия ордеров поставить следующее:
CloseOrdersbuy; - функция закрытия баев
CloseOrderssell; - функция закрятия селлов

закрытие ордеров так и будет выполняться- сначала закрытие баев, а потом закрытие селлов???
#1574

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

#1575


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



void ClosePlusOrdersBuy()
{
for (int i = OrdersTotal() - 1; i >= 0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
{
if (OrderType() == OP_BUY)
{
if (OrderClose(OrderTicket(), OrderLots(), NormalizeDouble(Bid,Digits), Slippage, Blue))
{
Print ("Ордер на покупку закрыт");
}
else Print ("Ордер на покупку не закрыт");
}
}
}
}

}
//----------------------------------------------------------------------------------------------------------------------------------------------------------
// Вызов функции закрытие ордеров Sell |
//----------------------------------------------------------------------------------------------------------------------------------------------------------

void ClosePlusOrdersSell()
{
for (int i = OrdersTotal() - 1; i >= 0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
{
if (OrderType() == OP_SELL)
{
if (OrderClose(OrderTicket(), OrderLots(), NormalizeDouble(Ask,Digits), Slippage, Red))
{
Print ("Ордер на продажу закрыт");
}
else Print ("Ордер на продажу не закрыт");
}
}
}
}

}

Для публикации сообщений создайте учётную запись или авторизуйтесь

Перейти к списку тем
Форум · 2.0.20260627.0025