Насколько я понимаю, Вы хотите закрыть все открытые позиции, а пытаетесь закрывать ордера. Ордер - заявка на совершение сделки, при исполнении порождает сделку, сделка, в свою очередь, открывает, изменяет или закрывает позицию по инструменту. Работайте с позициями. Проще использовать класс CTrade (Trade.mqh) стандартной библиотеки.
вот так правильно ?
void CloseAllPosition() { CTrade m_trade; //trading object string sy; int all=PositionsTotal(); for(int i=all-1; i>=0;i--) { sy=PositionGetSymbol(i); m_trade.PositionClose(sy,-1); //Print("i=",i," all=",all," ",sy," ",_LastError); } }
в #include <Trade\Trade.mqh>
есть строка
m_request.deviation =(deviation==ULONG_MAX) ? m_deviation : deviation;
Что она означает ?
в #include <Trade\Trade.mqh>
есть строка
m_request.deviation =(deviation==ULONG_MAX) ? m_deviation : deviation;
Что она означает ?
if(deviation==ULONG_MAX)
m_request.deviation=m_deviation;
else
m_request.deviation=deviation;
m_request.deviation =(deviation==ULONG_MAX) ? m_deviation : deviation;
Что она означает ?
Тут, наверное, вводит в недоумение использование константы ULONG_MAX в качестве признака отсутствия параметра deviation в функции PositionClose(const string symbol,ulong deviation=ULONG_MAX).
С таким же успехом можно было вместо ULONG_MAX использовать -1, как мы привыкли в MQL4, заодно бы проверили на неотрицательность заданную deviation:
m_request.deviation =(deviation<0) ? m_deviation : deviation;
Но тут интересно другое: при закрытии позиции мы можем как явно задать проскальзывание, так и использовать значение по-умолчанию, а вот при открытии - только значение по-умолчанию.
Если учесть, что при создании объекта CTrade m_deviation устанавливается в 10, то при 5-значных котировках этого явно недостаточно, и нам необходимо принудительно устанавливать m_deviation
в нужное значение с помощью метода SetDeviationInPoints(ulong deviation), прежде,чем открывать позицию.
Можно, конечно, внести свои исправления, но библиотека-то стандартная, и нужно чтобы не было разночтений в трактовании терминов.
Установка допустимого проскальзывания (Slippage) при исполнение ордера. (Если вопрос не о синтаксисе).
Вопросов очень много(и о синтаксисе тоже), ответ нигде не могу найти. Метод тыка не помогает. Нужны знания разработчиков.
Раньше (Slippage) максимальный был равен 10 пунктам (если я не ошибаюсь) больше не было смысла задавать. Теперь как ?
То что я записал -1 вот тут
if(sy!="") m_trade.PositionClose(sy,-1);
Это правильно ? Цель закрыть по любой цене, как можно быстрее, с любым проскальзыванием.
Раньше в советниках я использовал разработки (KimIV, http://www.kimiv.ru) очень хочу перевести их на MQL5 но не хватает знаний. Если с этими структурами и классами у меня еще есть надежда разобраться (очень жду статьи), то вот с обработкой ошибок...
Вот 2 функции. Очень нужен их аналог на MQL5. Без знания разработчиков их не написать. Нужно уметь получать результаты торговой операции и корректно их обрабатывать
//+----------------------------------------------------------------------------+ //| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru | //+----------------------------------------------------------------------------+ //| Версия : 19.02.2008 | //| Описание: Закрытие одной предварительно выбранной позиции | //+----------------------------------------------------------------------------+ void ClosePosBySelect() { bool fc; color clClose; double ll, pa, pb, pp; int err, it; if (OrderType()==OP_BUY || OrderType()==OP_SELL) { for (it=1; it<=NumberOfTry; it++) { if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) break; while (!IsTradeAllowed()) Sleep(5000); RefreshRates(); pa=MarketInfo(OrderSymbol(), MODE_ASK); pb=MarketInfo(OrderSymbol(), MODE_BID); if (OrderType()==OP_BUY) { pp=pb; clClose=clCloseBuy; } else { pp=pa; clClose=clCloseSell; } ll=OrderLots(); fc=OrderClose(OrderTicket(), ll, pp, Slippage, clClose); if (fc) { if (UseSound) PlaySound(NameFileSound); break; } else { err=GetLastError(); if (err==146) while (IsTradeContextBusy()) Sleep(1000*11); Print("Error(",err,") Close ",GetNameOP(OrderType())," ",ErrorDescription(err),", try ",it); Print(OrderTicket()," Ask=",pa," Bid=",pb," pp=",pp); Print("sy=",OrderSymbol()," ll=",ll," sl=",OrderStopLoss(), " tp=",OrderTakeProfit()," mn=",OrderMagicNumber()); Sleep(1000*5); } } } else Print("Некорректная торговая операция. Close ",GetNameOP(OrderType())); }
и вторая
//+----------------------------------------------------------------------------+ //| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru | //+----------------------------------------------------------------------------+ //| Версия : 21.03.2008 | //| Описание : Открывает позицию и возвращает её тикет. | //+----------------------------------------------------------------------------+ //| Параметры: | //| sy - наименование инструмента (NULL или "" - текущий символ) | //| op - операция | //| ll - лот | //| sl - уровень стоп | //| tp - уровень тейк | //| mn - MagicNumber | //+----------------------------------------------------------------------------+ int OpenPosition(string sy, int op, double ll, double Sl=0, double Tp=0, int mn=0) { color clOpen; datetime ot; double pa, pb, po, price, sl, tp, min_sl; int dg, err, it, ticket=0, mult; string lsComm=WindowExpertName()+" "+GetNameTF(Period()); if (sy=="" || sy=="0") sy=Symbol(); if (op==OP_BUY) clOpen=clOpenBuy; else clOpen=clOpenSell; for (it=1; it<=NumberOfTry; it++) { if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) { Print("OpenPosition(): Остановка работы функции"); break; } while (!IsTradeAllowed()) Sleep(5000); RefreshRates(); dg=MarketInfo(sy, MODE_DIGITS); pa=MarketInfo(sy, MODE_ASK); pb=MarketInfo(sy, MODE_BID); po=MarketInfo(sy, MODE_POINT); min_sl=MarketInfo(sy,MODE_STOPLEVEL); // Print("Минимальный Sl-----",min_sl); // ----- расчет лота и проверка минимума средств if(!IsTesting() && ll!=0.1) ll=CalculateVolume(); if(ll<MarketInfo(sy,MODE_MINLOT)) break; if (op==OP_BUY) { price = pa; mult = 1; } else { price = pb; mult = -1; } // расчет sl и tp if(Sl!=0) { if(Sl>min_sl) sl = price - mult*Sl*Point; else sl = price - mult*min_sl*Point; } if(Tp!=0) tp = price + mult*Tp*Point; price=NormalizeDouble(price, dg); sl =NormalizeDouble(sl , dg); tp =NormalizeDouble(tp , dg); ot=TimeCurrent(); ticket=OrderSend(sy, op, ll, price, Slippage, sl, tp, lsComm, mn, 0, clOpen); if (ticket>0) { if (UseSound) PlaySound(NameFileSound); break; } else { err=GetLastError(); if (pa==0 && pb==0) Message("Проверьте в Обзоре рынка наличие символа "+sy); // Вывод сообщения об ошибке Print("Error(",err,") opening position: ",ErrorDescription(err),", try ",it); Print("Ask=",pa," Bid=",pb," sy=",sy," ll=",ll," op=",GetNameOP(op), " price=",price," sl=",sl," tp=",tp," mn=",mn); // Блокировка работы советника if (err==2 || err==64 || err==65 || err==133) { gbDisabled=True; break; } // Длительная пауза if (err==4 || err==131 || err==132) { Sleep(1000*300); break; } if (err==128 || err==142 || err==143) { Sleep(1000*66.666); if (ExistPositions(sy, op, mn, ot)) { if (UseSound) PlaySound(NameFileSound); break; } } if (err==140 || err==148 || err==4110 || err==4111) break; if (err==141) Sleep(1000*100); if (err==145) Sleep(1000*17); if (err==146) while (IsTradeContextBusy()) Sleep(1000*11); if (err!=135) Sleep(1000*7.7); } } return(ticket); }
Заранее спасибо.
З.Ы. Да и еще одно. Я понимаю, что тут многие «англичане», но хотелось бы получать сообщения терминала и на родном русском языке.
Я это реализовал так:
void CloseAllPosSell()
{
int pos=PositionsTotal(); // получим количество открытых позиций
for(int ip=0;ip<=pos;ip++)
{
string sSymbol=PositionGetSymbol(ip);
if(PositionSelect(sSymbol)==true)
CloseAllPosSellF(sSymbol,ip);
}
}
void CloseAllPosSellF(string sSymbol,int ip)
{
MqlTradeRequest request; // структура запроса
MqlTradeResult result; // структура ответа
request.symbol = sSymbol;
request.volume = PositionGetDouble( POSITION_VOLUME );
request.action=TRADE_ACTION_DEAL; // операция с рынка
request.tp=0;
request.sl=0;
request.deviation=(ulong) ((SymbolInfoDouble(sSymbol,SYMBOL_ASK)-SymbolInfoDouble(sSymbol,SYMBOL_BID))/SymbolInfoDouble(sSymbol,SYMBOL_POINT)) ; // по спреду
request.type_filling=ORDER_FILLING_CANCEL;
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
{
request.type=ORDER_TYPE_SELL;
request.price=SymbolInfoDouble(sSymbol,SYMBOL_BID);
}
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
{
request.type=ORDER_TYPE_BUY;
request.price=SymbolInfoDouble(sSymbol,SYMBOL_ASK);
}
if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL){ OrderSend(request,result);}
}
То что я записал -1 вот тут
Это правильно ? Цель закрыть по любой цене, как можно быстрее, с любым проскальзыванием.
Я это реализовал так:
void CloseAllPosSell()
{
int pos=PositionsTotal(); // получим количество открытых позиций
for(int ip=0;ip<=pos;ip++)
{
...
}
}
...
if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL){ OrderSend(request,result);}
}
При закрытии позиций порядок перебора переменной цикла должен быть обратный, т.е. в Вашем случае
for(int ip=pos-1;ip>=0;ip--) {
так как после закрытия очередной, список позиций и PositionsTotal() корректируются и закрыть удастся только половину позиций.
Последняя строчка вообще непонятна, OrderSend(...) и для buy и для sell должен быть.

- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Подскажите как реализовать эту функцию из четверки
Я сделал так, но что-то не работает...