Ваши вопросы по языку MQL4

Leonup

Новичок форума
Как минимум, после 85 строки вставьте переменную: Tip=-1; каждый раз, перед новым входом в цикл, данные нужно обнулять, т.к. при Tip=0 будет соответствовать позиции на бай, то "обнуление" в данном случае равно -1.
Спасибо, что ответили. Tip=-1; вставил на 86-ю строку. Теперь при обратном пересечении после правильного закрытия ордера тут же, в ту же минуту, постоянно открывает и мгновенно закрывает очередной ордер. И таким образом в тестере за 22 минуты открыл и закрыл более 3-х тысяч ордеров! Ну и естественно слил депозит:).
 
Последнее редактирование:

mobidik

-----
Все верно, в таком виде все работает согласно коду. Как писал ранее:
каждый раз, перед новым входом в цикл, данные нужно обнулять
Вот смотри: как войти в туалет - включаем свет, по выходу - выключаем, делаем это вручную или автоматика.
В данном случае, автоматика, но работает только на включение. Теперь по коду: имеем 4 флага:
Cls_B=false, // Критерий для закрытия Buy
Cls_S=false, // Критерий для закрытия Sell
Opn_B=false, // Критерий для открытия Buy
Opn_S=false; // Критерий для открытия Sell

работают они по парно, например, сработало сперва условие на сел, имеем: Cls_B=true; и Opn_S=true; - получили тейк, тут же, т.к. условие все еще выполняется, установили новый ордер - состояние данных флагов не изменилось. Затем, тренд развернулся, выполняется условие на установку позиции в бай, т.е. имеем: Opn_B=true; и Cls_S=true; - установили позицию в бай. Все верно, согласно задуманному, но, когда устанавливали перед этим позиции в сел, флаг по закрытию позиций в бай был установлен в true, смотрим выше по тексту. Есть открытая позиция в бай и есть поднятый флаг на закрытие позиции бай - все верно работает, по написанному. Вот и подумайте: где и как "опустить" эти флаги. И помните, что имеет значение где и что нужно инициализировать в коде.
 

fox92

Прохожий
День добрый, форумчане!!! Только начинаю изучать всю эту нелегкую рутину в написании советников и не могу разобраться возможно с самым простейшим( Помогите кто может. Хочу написать код, чтобы работал так:
1) Если уже есть открытая позиция, то ничего непредпринемать.
2) Если не было еще ни одной позиции, то открыть ордер на покупку с лотом 0,01.
3) Если уже была открыта хотя бы одна позиция и последняя была на покупку и она была прибыльной, то открыть сделку на покупку с определенным лотом или если уже была открыта одна позиция и последняя была на продажу и она была прибыльной, то открыть сделку на продажу с определенным лотом.
4) Если уже была открыта хотя бы одна позиция и последняя была на покупку и ее она была убыточной и ее убыток был меньше 30 пунктов (то есть ушла в противоположную от цены открытия на 30 пунктов), то открыть сделку на продажу с определенным лотом или если уже была открыта хотя бы одна позиция и последняя была на продажу и она была убыточной и ее убыток был меньше 30 пунктов (то есть ушла в противоположную сторону от цены открытия на 30 пунктов), то открыть сделку на покупку.
 

Ugar

Гуру форума
День добрый, форумчане!!! Только начинаю изучать всю эту нелегкую рутину в написании советников и не могу разобраться возможно с самым простейшим( Помогите кто может. Хочу написать код, чтобы работал так:
1) Если уже есть открытая позиция, то ничего непредпринемать.
2) Если не было еще ни одной позиции, то открыть ордер на покупку с лотом 0,01.
3) Если уже была открыта хотя бы одна позиция и последняя была на покупку и она была прибыльной, то открыть сделку на покупку с определенным лотом или если уже была открыта одна позиция и последняя была на продажу и она была прибыльной, то открыть сделку на продажу с определенным лотом.
4) Если уже была открыта хотя бы одна позиция и последняя была на покупку и ее она была убыточной и ее убыток был меньше 30 пунктов (то есть ушла в противоположную от цены открытия на 30 пунктов), то открыть сделку на продажу с определенным лотом или если уже была открыта хотя бы одна позиция и последняя была на продажу и она была убыточной и ее убыток был меньше 30 пунктов (то есть ушла в противоположную сторону от цены открытия на 30 пунктов), то открыть сделку на покупку.
Это похоже на просьбу написать советник, а не вопросы по языку. https://forexsystemsru.com/threads/predlozhenija-po-avtomatizacii-torgovli.65203/
 

fox92

Прохожий
нет это лишь малая часть из всего советника. И даже стем, что писал уже разобрался почти со всем.
осталось два вопроса: 1) if (OrderSelect(-1,SELECT_BY_POS,MODE_TRADES)==true
вот так будет выглядеть, что есть уже хотя бы одна закрывшаяся сделка?
2) и второй все же ни как не могу разобраться как выяснить на что (покупку или продажу) была открыта сделка и с какой прибылью или убытком она завершилась
думаю начинать так: if (OrderSelect(OrdersHistoryTotal()-1, SELECT_BY_POS, MODE_HISTORY)) то есть выбрал последний закрывшийся ордер, а как потом узнать, с какой прибылью он закрылся и какая сделка была (покупка или продажа)??

Помогите плизззз кто-нить ужее голову сломал
 

блондинка

Элитный участник
Пожалуйста, посоветуйте как написать строчки кода под такие условия для стрелки
в индикаторе всего 8 сигнальных буферов
каждый буфер может принимать значение либо 1, либо -1
____________________________________________________________________
для стрелки вверх:
7 штук любых этих буферов равны 1, а только один (любой) равняется -1
для стрелки вниз:
7 штук любых этих буферов равны 1, а только один (любой)
равняется 1
____________________________________________________________________
если значения буферов в разнобой-стрелок нет
заранее спасибо кто откликнется
извиняюсь за некорректность изложения)
Удачи всем!
 

Ugar

Гуру форума
нет это лишь малая часть из всего советника. И даже стем, что писал уже разобрался почти со всем.
осталось два вопроса: 1) if (OrderSelect(-1,SELECT_BY_POS,MODE_TRADES)==true
вот так будет выглядеть, что есть уже хотя бы одна закрывшаяся сделка?
Это условие всегда будет false. Просто потому что нельзя выбрать открытый ордер с индексом -1.
if(OrdersHistoryTotal()>0) Вот это означает что хотя бы один закрытый ордер есть в истории. Это простейший вариант. Для тестера потянет.
2) и второй все же ни как не могу разобраться как выяснить на что (покупку или продажу) была открыта сделка и с какой прибылью или убытком она завершилась
думаю начинать так: if (OrderSelect(OrdersHistoryTotal()-1, SELECT_BY_POS, MODE_HISTORY)) то есть выбрал последний закрывшийся ордер, а как потом узнать, с какой прибылью он закрылся и какая сделка была (покупка или продажа)??
Правильно. Это простейший вариант. Для тестера потянет.
 

блондинка

Элитный участник
Пожалуйста, посоветуйте как написать строчки кода под такие условия для стрелки
в индикаторе всего 8 сигнальных буферов
каждый буфер может принимать значение либо 1, либо -1
____________________________________________________________________
для стрелки вверх:
7 штук любых этих буферов равны 1, а только один (любой) равняется -1
для стрелки вниз:
7 штук любых этих буферов равны 1, а только один (любой)
равняется 1
____________________________________________________________________
если значения буферов в разнобой-стрелок нет
заранее спасибо кто откликнется
извиняюсь за некорректность изложения)
Удачи всем!
Спасибо,уже придумала)))
Просьбу снимаю.
 

fox92

Прохожий
Не могу понять почему не срабатывает и не закрывает(
Суть в том, что хочу чтобы сделки закрывались когда 80 пунктов наберут. Вытащил кусок где сделка открыта на покупку
if ( Ask>=(Open[0]+0.00080))
OrderClose( OrderTicket(), OrderLots(), Ask, 3, CLR_NONE )

Помогите кто может, пожалуйста. Заранее благодарен!
 

AlexeyVik

Программист mql4 mql5
Не могу понять почему не срабатывает и не закрывает(
Суть в том, что хочу чтобы сделки закрывались когда 80 пунктов наберут. Вытащил кусок где сделка открыта на покупку
if ( Ask>=(Open[0]+0.00080))
OrderClose( OrderTicket(), OrderLots(), Ask, 3, CLR_NONE )

Помогите кто может, пожалуйста. Заранее благодарен!
1. Open[0] это цена открытия бара, а не цена открытия ордера.
2. Перед тем как пытаться ордер закрыть его надо выбрать функцией OrderSelect()
 

yurecwa

Активный участник
Здравствуйте. Может кто посмотрит. Есть функция подсчета прибыли и убытка. Но когда ее добавляю в любой советник, он сильно тормозит в тестере.
double SummaryProfit()
{
double Sum = 0;
//Суммарный профит по всем открытым ордерам
for(int i=0;i < OrdersTotal();i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
if(OrderType() < 2 && OrderSymbol() == _Symbol && OrderMagicNumber() == Magik)
Sum += OrderProfit()+ OrderSwap() + OrderCommission(); //включая своп и комиссию
}
//Сумма по ордерам, закрытым сегодня:
for( int i=OrdersHistoryTotal()-1;i>=0;i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
{
if(
OrderType() < 2 //
&& TimeYear(OrderCloseTime()) == TimeYear(TimeCurrent()) //Год
&& TimeDayOfYear(OrderCloseTime()) == TimeDayOfYear(TimeCurrent()) //и День соотвествуют текущему
&& OrderSymbol() == _Symbol //По текущему символу
&& OrderMagicNumber() == Magik ) //По заданному магику
Sum += OrderProfit()+ OrderSwap() + OrderCommission();
}
}
return(Sum);
}
 
Последнее редактирование:

Ugar

Гуру форума
Здравствуйте. Может кто посмотрит. Есть функция подсчета прибыли и убытка. Но когда ее добавляю в любой советник, он сильно тормозит в тестере.
double SummaryProfit()
{
double Sum = 0;
//Суммарный профит по всем открытым ордерам
for(int i=0;i < OrdersTotal();i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
if(OrderType() < 2 && OrderSymbol() == _Symbol && OrderMagicNumber() == Magik)
Sum += OrderProfit()+ OrderSwap() + OrderCommission(); //включая своп и комиссию
}
//Сумма по ордерам, закрытым сегодня:
for( int i=OrdersHistoryTotal()-1;i>=0;i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
{
if(
OrderType() < 2 //
&& TimeYear(OrderCloseTime()) == TimeYear(TimeCurrent()) //Год
&& TimeDayOfYear(OrderCloseTime()) == TimeDayOfYear(TimeCurrent()) //и День соотвествуют текущему
&& OrderSymbol() == _Symbol //По текущему символу
&& OrderMagicNumber() == Magik ) //По заданному магику
Sum += OrderProfit()+ OrderSwap() + OrderCommission();
}
}
return(Sum);
}
Нужно помнить что каждая функция, это код, а переменная, это ячейки памяти. Если есть возможность лишний раз не выполнять функцию, надо писать так. Вызвал функцию один раз, поместил результат в переменную и юзай её сколько надо.
 

yurecwa

Активный участник
Нужно помнить что каждая функция, это код, а переменная, это ячейки памяти. Если есть возможность лишний раз не выполнять функцию, надо писать так. Вызвал функцию один раз, поместил результат в переменную и юзай её сколько надо.
Спасибо за ответ. То есть, предположим, вызов SummaryProfit() при открытие новой свечи.
 

yurecwa

Активный участник
Сколько раз выполняется TimeCurrent() ? А можно выполнить один раз. И такого, что можно сократить много.
Код:
double SummaryProfit()
{
   double Sum = 0;
   //Суммарный профит по всем открытым ордерам
   for(int i=0;i < OrdersTotal();i++)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
         if(OrderType() < 2 && OrderSymbol() == _Symbol && OrderMagicNumber() == Magik) //Только для рыночных ордеров по текущему символу и с магиком совы - что не нужно просто удалаяем
            Sum += OrderProfit()+ OrderSwap() + OrderCommission();  //включая своп и комиссию
     }
  //Сумма по ордерам, закрытым сегодня:
  for( int i=OrdersHistoryTotal()-1;i>=0;i--)
    {
     if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
       {
        if(
            OrderType() < 2 //
        &&  TimeYear(OrderCloseTime()) ==   TimeYear(TimeCurrent())           //Год
        &&  TimeDayOfYear(OrderCloseTime()) == TimeDayOfYear(TimeCurrent())   //и День соотвествуют текущему
        &&  OrderSymbol() == _Symbol                                          //По текущему символу
        && OrderMagicNumber() == Magik )                                      //По заданному магику
         Sum += OrderProfit()+ OrderSwap() + OrderCommission();
       }
    }   
     return(Sum);
}
Судя по коду TimeCurrent() выполняется 2 раза. При удалении строчки 18. Время сокращается в 2 раза. А что еще можно сократить?
 

Ugar

Гуру форума
Код:
double SummaryProfit()
{
   double Sum = 0;
   //Суммарный профит по всем открытым ордерам
   for(int i=0;i < OrdersTotal();i++)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
         if(OrderType() < 2 && OrderSymbol() == _Symbol && OrderMagicNumber() == Magik) //Только для рыночных ордеров по текущему символу и с магиком совы - что не нужно просто удалаяем
            Sum += OrderProfit()+ OrderSwap() + OrderCommission();  //включая своп и комиссию
     }
  //Сумма по ордерам, закрытым сегодня:
  for( int i=OrdersHistoryTotal()-1;i>=0;i--)
    {
     if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
       {
        if(
            OrderType() < 2 //
        &&  TimeYear(OrderCloseTime()) ==   TimeYear(TimeCurrent())           //Год
        &&  TimeDayOfYear(OrderCloseTime()) == TimeDayOfYear(TimeCurrent())   //и День соотвествуют текущему
        &&  OrderSymbol() == _Symbol                                          //По текущему символу
        && OrderMagicNumber() == Magik )                                      //По заданному магику
         Sum += OrderProfit()+ OrderSwap() + OrderCommission();
       }
    }  
     return(Sum);
}
Судя по коду TimeCurrent() выполняется 2 раза. При удалении строчки 18. Время сокращается в 2 раза. А что еще можно сократить?
Нет, TimeCurrent() выполняется количество рыночных ордеров в истории умножить на 2. А можно выполнять 1 раз. TimeYear(), TimeDayOfYear(), OrderCloseTime() можно выполнять в 2 раза меньше раз. Используйте переменные вместо лишних вызовов функций.
 

yurecwa

Активный участник
Нет, TimeCurrent() выполняется количество рыночных ордеров в истории умножить на 2. А можно выполнять 1 раз. TimeYear(), TimeDayOfYear(), OrderCloseTime() можно выполнять в 2 раза меньше раз. Используйте переменные вместо лишних вызовов функций.
Спасибо. Попробую.
 

yurecwa

Активный участник
Здравствуйте. Написал условия для советника. Для остановки работы советника взамен функции. Но что не так(. Помогите разобраться.
Спасибо.
Код:
datetime day;

  double Balanse=0;
  if (day!=TimeDay(TimeCurrent()))
  {
   Balanse=NormalizeDouble( AccountBalance(),Digits);         
   day=TimeDay(TimeCurrent());     
   }
   if((AccountEquity() < (Balanse-maxLoss)) || (AccountEquity() > (maxProfit+Balanse)))
   {CloseOrder();return;}
 

lsv107

Почетный гражданин
Здравствуйте. Написал условия для советника. Для остановки работы советника взамен функции. Но что не так(. Помогите разобраться.
Спасибо.
Код:
datetime day;

  double Balanse=0;
  if (day!=TimeDay(TimeCurrent()))
  {
   Balanse=NormalizeDouble( AccountBalance(),Digits);        
   day=TimeDay(TimeCurrent());    
   }
   if((AccountEquity() < (Balanse-maxLoss)) || (AccountEquity() > (maxProfit+Balanse)))
   {CloseOrder();return;}

А что именно не так? Немного не понятно, что вы хотите сделать, но с точки зрения работоспособности, ваш код должен функционировать. Единственно, переменная day должна быть глобальной или лучше static
Позволю свой вариант:
JavaScript:
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void StopTrade(double maxProfit, double maxLoss)
  {
   static MqlDateTime tdDay= {0};

   MqlDateTime tdCurrent;
   TimeToStruct(TimeCurrent(),tdCurrent);

   if(tdDay.day!=tdCurrent.day)
     {
      tdDay=tdCurrent;

      double Balanse=NormalizeDouble(AccountBalance(),Digits);
      if((AccountEquity() < (Balanse-maxLoss)) || (AccountEquity() > (maxProfit+Balanse)))
        {
         CloseOrder();
         return;
        }
     }
  }

Но мне кажется, что вы хотите сделать закрытие текущих ордеров по некоему условию, которое проверяете раз в день с наступлением новых суток.
Для этого принято проверять факт открытия нового бара на D1:
JavaScript:
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void StopTradeByNewDay(double maxProfit, double maxLoss)
  {
   static datetime dtLastbarD1=0;
   datetime dtCurrentBarD1=iTime(_Symbol,PERIOD_D1,0);

   if(dtLastbarD1!=dtCurrentBarD1)
     {
      dtLastbarD1=dtCurrentBarD1;
      double Balanse=NormalizeDouble(AccountBalance(),Digits);
      if((AccountEquity() < (Balanse-maxLoss)) || (AccountEquity() > (maxProfit+Balanse)))
        {
         CloseOrder();
         return;
        }
     }

  }
Это если я всё правильно понял, конечно.
 

yurecwa

Активный участник
А что именно не так? Немного не понятно, что вы хотите сделать, но с точки зрения работоспособности, ваш код должен функционировать. Единственно, переменная day должна быть глобальной или лучше static
Позволю свой вариант:
JavaScript:
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void StopTrade(double maxProfit, double maxLoss)
  {
   static MqlDateTime tdDay= {0};

   MqlDateTime tdCurrent;
   TimeToStruct(TimeCurrent(),tdCurrent);

   if(tdDay.day!=tdCurrent.day)
     {
      tdDay=tdCurrent;

      double Balanse=NormalizeDouble(AccountBalance(),Digits);
      if((AccountEquity() < (Balanse-maxLoss)) || (AccountEquity() > (maxProfit+Balanse)))
        {
         CloseOrder();
         return;
        }
     }
  }

Но мне кажется, что вы хотите сделать закрытие текущих ордеров по некоему условию, которое проверяете раз в день с наступлением новых суток.
Для этого принято проверять факт открытия нового бара на D1:
JavaScript:
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void StopTradeByNewDay(double maxProfit, double maxLoss)
  {
   static datetime dtLastbarD1=0;
   datetime dtCurrentBarD1=iTime(_Symbol,PERIOD_D1,0);

   if(dtLastbarD1!=dtCurrentBarD1)
     {
      dtLastbarD1=dtCurrentBarD1;
      double Balanse=NormalizeDouble(AccountBalance(),Digits);
      if((AccountEquity() < (Balanse-maxLoss)) || (AccountEquity() > (maxProfit+Balanse)))
        {
         CloseOrder();
         return;
        }
     }

  }
Это если я всё правильно понял, конечно.
Здравствуйте. Спасибо за ответ. Вы правы, условия работают. Ошибка была в переменной Balanse. Ваш вариант тоже интересный, завтра попробую.

Рабочий вариант.
Код:
input double maxLoss = 500; //Максимальный убыток за день
input double maxProfit = 500; //Максимальный профит за день

datetime day;
double Balanse=0;

void OnTick()
{  
     if (day!=TimeDay(TimeCurrent()))
      {
       Balanse=NormalizeDouble( AccountBalance(),Digits);        
       day=TimeDay(TimeCurrent());    
      }


if((AccountEquity() < (Balanse-maxLoss)) || (AccountEquity() > (maxProfit+Balanse))) {CloseMarketOrder();return;}
//  
//  
Условия...
//
}
 
Верх