Добрый день! Уважаемые программисты. Вопрос по MQL5
Как сделать контроль позиций в эксперте?. Чтобы на одном баре была, только одна открытая позиция. То есть закрытие позиции неважно где - на каком баре, но вот открытие должно быть только на одном баре.
этот код полностью игнорируется в чём ошибка, не пойму.
Ошибка: Вы смешали в кучу мух и котлеты - Вы смешали ОТЛОЖЕННЫЕ ОРДЕРА и ПОЗИЦИИ.
Чтобы не путаться, пожалуйста ознакомьтесь со справкой: Общие принципы
Выше предложили простой способ - при открытии позиции запоминаете время открытия текущего бара. Дальше, если Вы хотите открыть новую позицию, Вы сверяете сохранённое время и время открытия текущего бара.
Запоминать время открытия позиции удобно в OnTradeTransaction:
//+------------------------------------------------------------------+//| TradeTransaction function |//+------------------------------------------------------------------+voidOnTradeTransaction(constMqlTradeTransaction &trans,
constMqlTradeRequest &request,
constMqlTradeResult &result)
{
//--- get transaction type as enumeration valueENUM_TRADE_TRANSACTION_TYPE type=trans.type;
//--- if transaction is result of addition of the transaction in historyif(type==TRADE_TRANSACTION_DEAL_ADD)
{
if(HistoryDealSelect(trans.deal))
m_deal.Ticket(trans.deal);
elsereturn;
if(m_deal.Symbol()==m_symbol.Name() && m_deal.Magic()==InpMagic)
{
if(m_deal.DealType()==DEAL_TYPE_BUY || m_deal.DealType()==DEAL_TYPE_SELL)
{
if(m_deal.Entry()==DEAL_ENTRY_IN || m_deal.Entry()==DEAL_ENTRY_INOUT)
m_last_deal_in=iTime(m_symbol.Name(),InpTimeFrame,0);int size_need_position=ArraySize(SPosition);
if(size_need_position>0)
{
for(int i=0; i<size_need_position; i++)
{
if(SPosition[i].waiting_transaction)
if(SPosition[i].waiting_order_ticket==m_deal.Order())
{
Print(__FUNCTION__," Transaction confirmed");
SPosition[i].transaction_confirmed=true;
break;
}
}
}
}
}
}
}
и при возникновении сигнала сверять время:
//+------------------------------------------------------------------+//| Search trading signals |//+------------------------------------------------------------------+bool SearchTradingSignals(void)
{
if(m_prev_bars==m_last_deal_in) // on one bar - only one dealreturn(true);
Перед тем как приступить к изучению торговых функций платформы, необходимо создать четкое представление об основных терминах: ордер, сделка и позиция. — это распоряжение брокерской компании купить или продать финансовый инструмент. Различают два основных типа ордеров: рыночный и отложенный. Помимо них существуют специальные ордера Тейк Профит и...
Сложнова-то....как-то. На первом этапе проблем никаких " запоминаете время открытия текущего бара"
Вот запомнил:
if (PositionsTotal()==1) // Здесь проверяю, что открыта одна позиция
{
datetime Cu=iTime(NULL,_Period,0); // Здесь в переменную - время открытия бара при открытой позиции
Но здесь " Вы сверяете сохранённое время и время открытия текущего бара." проблемы.
Я вот примерно тоже самое доработал.Вот посмотрите:
if (PositionsTotal()==1) // Здесь проверяю, что открыта одна позиция (или была открыта, неважно, любое торговое действие)
{
datetime Cu=iTime(NULL,_Period,0); // Здесь в переменную - время открытия бара при открытой позицииint hd=+iBarShift(Symbol(),_Period,Cu)+1; // Здесь в переменную - бар на котором произошло открытие позиции if (hd>=1) //Здесь проверяем - если этих баров, больше чем один, то.......
{
return; //....то зацикливанием программу, НО проблема только в return
}
}
Здесь мне только всего лишь нужно зациклить прогу типа "return(-1)" Но из-за void присваивать выражение ретурну нельзя. Как обойти этот момент.? Как зациклить но не return?
Тикет позиции. Уникальное число, которое присваивается каждой вновь открытой позиции. Как правило, соответствует тикету ордера, в результате которого она была открыта, за исключением случаев изменения тикета в результате служебных операций на сервере. Например, начисления свопов переоткрытием позиции. Для нахождения ордера, которым была открыта...
datetime PR=iTime(NULL,_Period,0); // проверяю время открытие бараif (PositionsTotal()==1)
{
datetime TK=iTime(NULL,_Period,0); // время открытия бара при открытой позиции if (PR==TK) // сравниваю
{
return(true); // НЕ катит true - ошибка
}
}
Сложнова-то....как-то. На первом этапе проблем никаких " запоминаете время открытия текущего бара"
Вот запомнил:
Но здесь " Вы сверяете сохранённое время и время открытия текущего бара." проблемы.
Я вот примерно тоже самое доработал.Вот посмотрите:
Здесь мне только всего лишь нужно зациклить прогу типа "return(-1)" Но из-за void присваивать выражение ретурну нельзя. Как обойти этот момент.? Как зациклить но не return?
За зацикливание программ применяется лечение: рубание рук по самую шею. Чтобы впредь не повадно было.
Вот, что Вам нужно - полное тело программы, Вам только нужно оформить получение сигнала:
//+------------------------------------------------------------------+//| Example One position on one bar.mq5 |//| Copyright 2020, MetaQuotes Software Corp. |//| https://www.mql5.com |//+------------------------------------------------------------------+#property copyright"Copyright 2020, MetaQuotes Software Corp."#property link"https://www.mql5.com"#property version"1.00"//---#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\DealInfo.mqh>
//---
CPositionInfo m_position; // object of CPositionInfo class
CTrade m_trade; // object of CTrade class
CSymbolInfo m_symbol; // object of CSymbolInfo class
CDealInfo m_deal; // object of CDealInfo class//--- input parametersinputulong InpMagic = 200; // Magic number//---datetime m_prev_bars = 0; // "0" -> D'1970.01.01 00:00';datetime m_last_deal_in = 0; // "0" -> D'1970.01.01 00:00';//+------------------------------------------------------------------+//| Expert initialization function |//+------------------------------------------------------------------+intOnInit()
{
//---if(!m_symbol.Name(Symbol())) // sets symbol name
{
Print(__FILE__," ",__FUNCTION__,", ERROR: CSymbolInfo.Name");
return(INIT_FAILED);
}
RefreshRates();
//---return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+//| Expert deinitialization function |//+------------------------------------------------------------------+voidOnDeinit(constint reason)
{
//---
}
//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+voidOnTick()
{
//--- we work only at the time of the birth of new bardatetime time_0=iTime(m_symbol.Name(),Period(),0);
if(time_0==m_prev_bars)
return;
m_prev_bars=time_0;
if(!RefreshRates())
{
m_prev_bars=0;
return;
}
//--- search for trading signalsif(!SearchTradingSignals())
{
m_prev_bars=0;
return;
}
}
//+------------------------------------------------------------------+//| TradeTransaction function |//+------------------------------------------------------------------+voidOnTradeTransaction(constMqlTradeTransaction &trans,
constMqlTradeRequest &request,
constMqlTradeResult &result)
{
//--- get transaction type as enumeration valueENUM_TRADE_TRANSACTION_TYPE type=trans.type;
//--- if transaction is result of addition of the transaction in historyif(type==TRADE_TRANSACTION_DEAL_ADD)
{
if(HistoryDealSelect(trans.deal))
m_deal.Ticket(trans.deal);
elsereturn;
if(m_deal.Symbol()==m_symbol.Name() && m_deal.Magic()==InpMagic)
{
if(m_deal.DealType()==DEAL_TYPE_BUY || m_deal.DealType()==DEAL_TYPE_SELL)
{
if(m_deal.Entry()==DEAL_ENTRY_IN || m_deal.Entry()==DEAL_ENTRY_INOUT)
m_last_deal_in=iTime(m_symbol.Name(),Period(),0);
}
}
}
}
//+------------------------------------------------------------------+//| Search trading signals |//+------------------------------------------------------------------+bool SearchTradingSignals(void)
{
if(m_prev_bars==m_last_deal_in) // on one bar - only one dealreturn(true);
//--- signal//---return(false);
}
//+------------------------------------------------------------------+//| Refreshes the symbol quotes data |//+------------------------------------------------------------------+bool RefreshRates()
{
//--- refresh ratesif(!m_symbol.RefreshRates())
{
Print(__FILE__," ",__FUNCTION__,", ERROR: ","RefreshRates error");
return(false);
}
//--- protection against the return value of "zero"if(m_symbol.Ask()==0 || m_symbol.Bid()==0)
{
Print(__FILE__," ",__FUNCTION__,", ERROR: ","Ask == 0.0 OR Bid == 0.0");
return(false);
}
//---return(true);
}
//+------------------------------------------------------------------+
переменная 'm_prev_bars' хранит время открытия текущего бара, а переменная 'm_last_deal_in' - время открытия бара, на котором была открыта позиция.
Сравнение этих двух переменных производится в блоке получения сигналов 'SearchTradingSignals'.
Правда пришлось подшаманить чуть-чуть. Ещё проще даже получилось, без (true). Правда объяснить не смогу эту хитро-запутанную логику MQL.)
Вот так внедрил:
datetime timeBar = iTime(_Symbol,PERIOD_CURRENT, 0);// период можно поставить по своему усмотрениюdatetimestatic timeOpen = 0;
if((PositionsTotal()==0)&&(c0>h1)&&(rGENUP>0.30)&&(timeBar > timeOpen)) // Условие для открытия позиции.
{
MqlTradeRequest request;
MqlTradeResult result;
request.action =TRADE_ACTION_DEAL; // тип торговой операции
request.symbol =Symbol(); // символ
request.volume =1; // объем в 1 лот
request.type =ORDER_TYPE_BUY; // тип ордера
request.price =SymbolInfoDouble(Symbol(),SYMBOL_ASK); // цена для открытия
request.deviation=3;
request.sl = NormalizeDouble(Ask-50*_Point,_Digits);
request.tp = NormalizeDouble(Ask+50*_Point,_Digits);
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // если отправить запрос не удалось, вывести код ошибки//--- информация об операцииPrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order);
// допустимое отклонение от цены
timeOpen = timeBar;
}
Я вот офигеваю, почему такой большой код в MQL5 для открытия позиции. В отличие от MQL4. В 4-ке одна строчка всего лишь. Тут же...Можно ли сократить? Например убрать обработчик ошибок?
Торговая деятельность в платформе связана с формированием и отсылкой рыночных и отложенных ордеров для исполнения брокером, а также с управлением текущими позициями путем их модификации или закрытия. Платформа позволяет удобно просматривать торговую историю на счете, настраивать оповещения о событиях на рынке и многое другое. Открытие позиций...
Правда пришлось подшаманить чуть-чуть. Ещё проще даже получилось, без (true). Правда объяснить не смогу эту хитро-запутанную логику MQL.)
Вот так внедрил:
Я вот офигеваю, почему такой большой код в MQL5 для открытия позиции. В отличие от MQL4. В 4-ке одна строчка всего лишь. Тут же...Можно ли сократить? Например убрать обработчик ошибок?
Используйте торговые классы. И код будет очень корокий.
Пример:
//+------------------------------------------------------------------+//| Only_one_purchase.mq5 |//+------------------------------------------------------------------+#property version"1.003"#property script_show_inputs#include <Trade\Trade.mqh>
CTrade m_trade; // trading object//--- input parametersinputENUM_POSITION_TYPE InpPositionType = POSITION_TYPE_BUY; // Position Typeinputdouble InpVolume = 0.0; // Volumeinputulong m_magic = 15489; // magic number//+------------------------------------------------------------------+//| Script program start function |//+------------------------------------------------------------------+voidOnStart()
{
m_trade.SetExpertMagicNumber(m_magic);
//--- open a positionif(InpPositionType==POSITION_TYPE_BUY)
m_trade.Buy(InpVolume);
else
m_trade.Sell(InpVolume);
}
//+------------------------------------------------------------------+
Правда пришлось подшаманить чуть-чуть. Ещё проще даже получилось, без (true). Правда объяснить не смогу эту хитро-запутанную логику MQL.)
Вот так внедрил:
Я вот офигеваю, почему такой большой код в MQL5 для открытия позиции. В отличие от MQL4. В 4-ке одна строчка всего лишь. Тут же...Можно ли сократить? Например убрать обработчик ошибок?
Так если у вас в условии есть
if((PositionsTotal()==0)&&
то зачем ещё проверки на новый бар? Или есть вариант, что позиция закроется на этом-же баре и надо запретить второе открытие?
Правда пришлось подшаманить чуть-чуть. Ещё проще даже получилось, без (true). Правда объяснить не смогу эту хитро-запутанную логику MQL.)
Вот так внедрил:
Я вот офигеваю, почему такой большой код в MQL5 для открытия позиции. В отличие от MQL4. В 4-ке одна строчка всего лишь. Тут же...Можно ли сократить? Например убрать обработчик ошибок?
Знаете, когда-то давно, когда был MQL4, люди с возмущением говорили, что не дают им более низкоуровневого доступа - чтобы можно было что-то по-своему делать.
Ну вот, дали - теперь к составляющим OrderSend() в MQL4 дали доступ - так сказать развернули в MQL его логику - делайте что просили. Так нет - теперь возмущения, что слишком сложно.
Сложно? Не вопрос - нате вам торговые классы в СБ - практически то же самое, что и в MQL4 стандартные торговые функции. Считайте, что в MQL4 такие классы - это и есть торговые функции. А в MQL5 - всё с открытым доступом.
Знаете, когда-то давно, когда был MQL4, люди с возмущением говорили, что не дают им более низкоуровневого доступа - чтобы можно было что-то по-своему делать.
Ну вот, дали - теперь к составляющим OrderSend() в MQL4 дали доступ - так сказать развернули в MQL его логику - делайте что просили. Так нет - теперь возмущения, что слишком сложно.
Сложно? Не вопрос - нате вам торговые классы в СБ - практически то же самое, что и в MQL4 стандартные торговые функции. Считайте, что в MQL4 такие классы - это и есть торговые функции. А в MQL5 - всё с открытым доступом.
Добрый день! Уважаемые программисты. Вопрос по MQL5
Как сделать контроль позиций в эксперте?. Чтобы на одном баре была, только одна открытая позиция. То есть закрытие позиции неважно где - на каком баре, но вот открытие должно быть только на одном баре.
этот код полностью игнорируется в чём ошибка, не пойму.
Ошибка: Вы смешали в кучу мух и котлеты - Вы смешали ОТЛОЖЕННЫЕ ОРДЕРА и ПОЗИЦИИ.
Чтобы не путаться, пожалуйста ознакомьтесь со справкой: Общие принципы
Выше предложили простой способ - при открытии позиции запоминаете время открытия текущего бара. Дальше, если Вы хотите открыть новую позицию, Вы сверяете сохранённое время и время открытия текущего бара.
Запоминать время открытия позиции удобно в OnTradeTransaction:
и при возникновении сигнала сверять время:
Пример взят из кода OHLC Check 2
Сложнова-то....как-то. На первом этапе проблем никаких " запоминаете время открытия текущего бара"
Вот запомнил:
Но здесь " Вы сверяете сохранённое время и время открытия текущего бара." проблемы.
Я вот примерно тоже самое доработал.Вот посмотрите:
Здесь мне только всего лишь нужно зациклить прогу типа "return(-1)" Но из-за void присваивать выражение ретурну нельзя. Как обойти этот момент.? Как зациклить но не return?
Такой вариант тоже не прокатил.
Сложнова-то....как-то. На первом этапе проблем никаких " запоминаете время открытия текущего бара"
Вот запомнил:
Но здесь " Вы сверяете сохранённое время и время открытия текущего бара." проблемы.
Я вот примерно тоже самое доработал.Вот посмотрите:
Здесь мне только всего лишь нужно зациклить прогу типа "return(-1)" Но из-за void присваивать выражение ретурну нельзя. Как обойти этот момент.? Как зациклить но не return?
За зацикливание программ применяется лечение: рубание рук по самую шею. Чтобы впредь не повадно было.
Вот, что Вам нужно - полное тело программы, Вам только нужно оформить получение сигнала:
переменная 'm_prev_bars' хранит время открытия текущего бара, а переменная 'm_last_deal_in' - время открытия бара, на котором была открыта позиция.
Сравнение этих двух переменных производится в блоке получения сигналов 'SearchTradingSignals'.
Такой вариант тоже не прокатил.
До чего-же барабашка любит километровые коды…
Ваша проблема решается в ШЕСТЬ строк кода, с учётом объявления переменных.
Надеюсь с переменной signal разберётесь.
О! Заработало! Спасибо, товарищи за идеи!
Правда пришлось подшаманить чуть-чуть. Ещё проще даже получилось, без (true). Правда объяснить не смогу эту хитро-запутанную логику MQL.)
Вот так внедрил:
Я вот офигеваю, почему такой большой код в MQL5 для открытия позиции. В отличие от MQL4. В 4-ке одна строчка всего лишь. Тут же...Можно ли сократить? Например убрать обработчик ошибок?О! Заработало! Спасибо, товарищи за идеи!
Правда пришлось подшаманить чуть-чуть. Ещё проще даже получилось, без (true). Правда объяснить не смогу эту хитро-запутанную логику MQL.)
Вот так внедрил:
Я вот офигеваю, почему такой большой код в MQL5 для открытия позиции. В отличие от MQL4. В 4-ке одна строчка всего лишь. Тут же...Можно ли сократить? Например убрать обработчик ошибок?Используйте торговые классы. И код будет очень корокий.
Пример:
О! Заработало! Спасибо, товарищи за идеи!
Правда пришлось подшаманить чуть-чуть. Ещё проще даже получилось, без (true). Правда объяснить не смогу эту хитро-запутанную логику MQL.)
Вот так внедрил:
Я вот офигеваю, почему такой большой код в MQL5 для открытия позиции. В отличие от MQL4. В 4-ке одна строчка всего лишь. Тут же...Можно ли сократить? Например убрать обработчик ошибок?Так если у вас в условии есть
то зачем ещё проверки на новый бар? Или есть вариант, что позиция закроется на этом-же баре и надо запретить второе открытие?
О! Заработало! Спасибо, товарищи за идеи!
Правда пришлось подшаманить чуть-чуть. Ещё проще даже получилось, без (true). Правда объяснить не смогу эту хитро-запутанную логику MQL.)
Вот так внедрил:
Я вот офигеваю, почему такой большой код в MQL5 для открытия позиции. В отличие от MQL4. В 4-ке одна строчка всего лишь. Тут же...Можно ли сократить? Например убрать обработчик ошибок?Знаете, когда-то давно, когда был MQL4, люди с возмущением говорили, что не дают им более низкоуровневого доступа - чтобы можно было что-то по-своему делать.
Ну вот, дали - теперь к составляющим OrderSend() в MQL4 дали доступ - так сказать развернули в MQL его логику - делайте что просили. Так нет - теперь возмущения, что слишком сложно.
Сложно? Не вопрос - нате вам торговые классы в СБ - практически то же самое, что и в MQL4 стандартные торговые функции.
Считайте, что в MQL4 такие классы - это и есть торговые функции. А в MQL5 - всё с открытым доступом.
Пользуйтесь.
Знаете, когда-то давно, когда был MQL4, люди с возмущением говорили, что не дают им более низкоуровневого доступа - чтобы можно было что-то по-своему делать.
Ну вот, дали - теперь к составляющим OrderSend() в MQL4 дали доступ - так сказать развернули в MQL его логику - делайте что просили. Так нет - теперь возмущения, что слишком сложно.
Сложно? Не вопрос - нате вам торговые классы в СБ - практически то же самое, что и в MQL4 стандартные торговые функции.
Считайте, что в MQL4 такие классы - это и есть торговые функции. А в MQL5 - всё с открытым доступом.
Пользуйтесь.
Доцент, а Доцент. Ты почему такой злой (сегодня) ©