Рэндом писал(а):Не получается.
Отправка запроса на модификацию уровней без фактического их изменения
Если по правилам торговой системы требуется модифировать отложенные ордера или открытые позиции, то перед отправкой торгового запроса на проведение транзакции необходимо убедиться, что запрашиваемая операции действительно изменит параметры ордера или позиции. Отправка торгового запроса, который фактически не делает никаких изменений, считается ошибкой. Торговый сервер в ответ на такое действие вернет код ответа TRADE_RETCODE_NO_CHANGES=10025 (MQL5) или код ERR_NO_RESULT=1 (MQL4)
Пример проверки для MQL5 приведен в скрипте Check_OrderLevels.mq5:
- Код: выделить все
//--- класс для проведения торговых операций
#include <Trade\Trade.mqh>
CTrade trade;
#include <Trade\Trade.mqh>
//--- класс для работы с ордерами
#include <Trade\OrderInfo.mqh>
COrderInfo orderinfo;
//--- класс для работы с позициями
#include <Trade\PositionInfo.mqh>
CPositionInfo positioninfo;
//+------------------------------------------------------------------+
//| проверка новых значений уровней перед модификацией ордера |
//+------------------------------------------------------------------+
bool OrderModifyCheck(ulong ticket,double price,double sl,double tp)
{
//--- выберем ордер по тикету
if(orderinfo.Select(ticket))
{
//--- размер пункта и имя символа, по которому выставлен отложенный ордер
string symbol=orderinfo.Symbol();
double point=SymbolInfoDouble(symbol,SYMBOL_POINT);
int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
//--- проверим - есть ли изменения в цене открытия
bool PriceOpenChanged=(MathAbs(orderinfo.PriceOpen()-price)>point);
//--- проверим - есть ли изменения в уровне StopLoss
bool StopLossChanged=(MathAbs(orderinfo.StopLoss()-sl)>point);
//--- проверим - есть ли изменения в уровне Takeprofit
bool TakeProfitChanged=(MathAbs(orderinfo.TakeProfit()-sl)>tp);
//--- если есть какие-то изменения в уровнях
if(PriceOpenChanged || StopLossChanged || TakeProfitChanged)
return(true); // ордер можно модифицировать
//--- изменений в уровнях открытия, StopLoss и Takeprofit нет
else
//--- сообщим об ошибке
PrintFormat("Ордер #%d уже имеет уровни Open=%.5f SL=.5f TP=%.5f",
ticket,orderinfo.StopLoss(),orderinfo.TakeProfit());
}
//--- дошли до конца, изменений для ордера нет
return(false); // нет смысла модифицировать
}
//+------------------------------------------------------------------+
//| проверка новых значений уровней перед модификацией ордера |
//+------------------------------------------------------------------+
bool PositionModifyCheck(ulong ticket,double sl,double tp)
{
//--- выберем ордер по тикету
if(positioninfo.SelectByTicket(ticket))
{
//--- размер пункта и имя символа, по которому выставлен отложенный ордер
string symbol=positioninfo.Symbol();
double point=SymbolInfoDouble(symbol,SYMBOL_POINT);
//--- проверим - есть ли изменения в уровне StopLoss
bool StopLossChanged=(MathAbs(positioninfo.StopLoss()-sl)>point);
//--- проверим - есть ли изменения в уровне Takeprofit
bool TakeProfitChanged=(MathAbs(positioninfo.TakeProfit()-sl)>tp);
//--- если есть какие-то изменения в уровнях
if(StopLossChanged || TakeProfitChanged)
return(true); // позицию можно модифицировать
//--- изменений в уровнях StopLoss и Takeprofit нет
else
//--- сообщим об ошибке
PrintFormat("Ордер #%d уже имеет уровни Open=%.5f SL=.5f TP=%.5f",
ticket,orderinfo.StopLoss(),orderinfo.TakeProfit());
}
//--- дошли до конца, изменений для ордера нет
return(false); // нет смысла модифицировать
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- уровни цен для ордеров и позиций
double priceopen,stoploss,takeprofit;
//--- тикет текущего ордера и позиции
ulong orderticket,positionticket;
/*
... получим тикет ордера и новые уровни StopLoss/Takeprofit/PriceOpen
*/
//--- проверим уровни перед модификацией отложенного ордера
if(OrderModifyCheck(orderticket,priceopen,stoploss,takeprofit))
{
//--- проверка прошла успешно
trade.OrderModify(orderticket,priceopen,stoploss,takeprofit,
orderinfo.TypeTime(),orderinfo.TimeExpiration());
}
/*
... получим тикет позиции и новые уровни StopLoss/Takeprofit
*/
//--- проверим уровни перед модификацией позиции
if(PositionModifyCheck(positionticket,stoploss,takeprofit))
{
//--- проверка прошла успешно
trade.PositionModify(positionticket,stoploss,takeprofit);
}
//---
}
Пример проверки на языке MQL4 вы найдете в скрипте Check_OrderLevels.mq4:
- Код: выделить все
#property strict
//+------------------------------------------------------------------+
//| проверка новых значений уровней перед модификацией ордера |
//+------------------------------------------------------------------+
bool OrderModifyCheck(int ticket,double price,double sl,double tp)
{
//--- выберем ордер по тикету
if(OrderSelect(ticket,SELECT_BY_TICKET))
{
//--- размер пункта и имя символа, по которому выставлен отложенный ордер
string symbol=OrderSymbol();
double point=SymbolInfoDouble(symbol,SYMBOL_POINT);
//--- проверим - есть ли изменения в цене открытия
bool PriceOpenChanged=true;
int type=OrderType();
if(!(type==OP_BUY || type==OP_SELL))
{
PriceOpenChanged=(MathAbs(OrderOpenPrice()-price)>point);
}
//--- проверим - есть ли изменения в уровне StopLoss
bool StopLossChanged=(MathAbs(OrderStopLoss()-sl)>point);
//--- проверим - есть ли изменения в уровне Takeprofit
bool TakeProfitChanged=(MathAbs(OrderTakeProfit()-sl)>tp);
//--- если есть какие-то изменения в уровнях
if(PriceOpenChanged || StopLossChanged || TakeProfitChanged)
return(true); // ордер можно модифицировать
//--- изменений в уровнях открытия, StopLoss и Takeprofit нет
else
//--- сообщим об ошибке
PrintFormat("Ордер #%d уже имеет уровни Open=%.5f SL=.5f TP=%.5f",
ticket,OrderOpenPrice(),OrderStopLoss(),OrderTakeProfit());
}
//--- дошли до конца, изменений для ордера нет
return(false); // нет смысла модифицировать
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- уровни цен для ордеров и позиций
double priceopen,stoploss,takeprofit;
//--- тикет текущего ордера
int orderticket;
/*
... получим тикет ордeра и новые уровни StopLoss/Takeprofit/PriceOpen
*/
//--- проверим уровни перед модификацией ордера
if(OrderModifyCheck(orderticket,priceopen,stoploss,takeprofit))
{
//--- проверка прошла успешно
OrderModify(orderticket,priceopen,stoploss,takeprofit,OrderExpiration());
}
}
serjloskut писал(а): ...Эта ошибка возникает, если отправляется приказ на модификацию ордера когда уровни остались неизменными (имеются в виду sl и tp). Исправить можно, если прикрутить проверку: изменились уровни стоп-лосс или тейк-профит? Если да, то тогда отправляется приказ на модификацию, если нет, то обрабатывается следующий ордер. Но вот как это написать программно... уже неделю мозг себе парю. Поможете?
Haos писал(а):serjloskut писал(а): ...Эта ошибка возникает, если отправляется приказ на модификацию ордера когда уровни остались неизменными (имеются в виду sl и tp). Исправить можно, если прикрутить проверку: изменились уровни стоп-лосс или тейк-профит? Если да, то тогда отправляется приказ на модификацию, если нет, то обрабатывается следующий ордер. Но вот как это написать программно... уже неделю мозг себе парю. Поможете?
Не пойму, а какие объемы могут модифицироваться? Может или закрываться часть позиции или открываться новая.
Haos писал(а):Т.е. в сове несколько сделок в одном направлении и они должны менять ТП или СЛ в зависимости от условий? Если так, то весь вопрос в том, чтобы идентифицировать каждую позицию.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 238
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения