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

allisbob

Прохожий
Ребят, подскажите, пожалуйста.

имеется условие: if (Profit<0) {мартинимся} else {лот - начальный}
как вместо проверки прибыли корректно оформить условие "последний ордер закрылся по SL"?
Дело в том что по-моему сравнивать OrderClosePrise() и OrderStopLoss() напрямую нельзя(вроде a==b, хотя в "тостере" ,наверное, так и работает), ведь закрытие проскальзывает и не происходит прям на месте выставленного SL.
А тут еще и вопрос как правильно отобрать эти "закритие" и "лосс"?
Вот как это происходит у меня:

PHP:
  int Magic=0, CloseTime=0; 
  double ocp=0.0, osl=0.0;
  for(int j=0;j<OrdersHistoryTotal();j++)
   { 
    if(!OrderSelect(j,SELECT_BY_POS,MODE_HISTORY)) continue;
    if(OrderMagicNumber()!=Magic) continue;
    if(closetime<OrderCloseTime())
     { 
      CloseTime=(int)OrderCloseTime(); 
      ocp=NormalizeDouble(OrderClosePrice(),Digits);
      osl=NormalizeDouble(OrderStopLoss(),Digits);
     } 
   }

потом появляется искушение сделать так:

PHP:
  int Result=0;
  if (ocp==osl) Result=1;

и дальше:

PHP:
  if (Result==1) 
   {Loss++; if (Loss>=NumberLoss) {LOT=NormalizeDouble(Lot*K, 2); Loss=0;}} 
  else 
   {Loss=0; LOT=LotStart; }

но потом за SL следует не увеличенный лот, а начальный... что не так?
 

iBoss

Заблокирован
но потом за SL следует не увеличенный лот, а начальный... что не так?
Вам сначала нужно узнать профит последней закрытой сделки

Функция

Код:
double LastProfit()
{double profit=0;
datetime dt=0;
for(int i=OrdersHistoryTotal()-1;i>=0;i--)
 if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
  {if(Symbol()==OrderSymbol() && OrderMagicNumber()==Magic) 
   {if(OrderOpenTime()>dt)
   {dt=OrderOpenTime();
    profit=OrderProfit()+OrderSwap()+OrderCommission();}}}
return(profit);}

А далее в старте вызывать эту функцию и сравнивать профит

if(LastProfit()<0) {Мартиним;}
if(LastProfit()>=0) {Не мартиним;}
 

mobidik

-----
Ребят, подскажите, пожалуйста.

имеется условие: if (Profit<0) {мартинимся} else {лот - начальный}
как вместо проверки прибыли корректно оформить условие "последний ордер закрылся по SL"?
Дело в том что по-моему сравнивать OrderClosePrise() и OrderStopLoss() напрямую нельзя(вроде a==b, хотя в "тостере" ,наверное, так и работает), ведь закрытие проскальзывает и не происходит прям на месте выставленного SL.
А тут еще и вопрос как правильно отобрать эти "закритие" и "лосс"?
Вот как это происходит у меня:
PHP:
  int Magic=0, CloseTime=0; 
  double ocp=0.0, osl=0.0;
  for(int j=0;j<OrdersHistoryTotal();j++)
   { 
    if(!OrderSelect(j,SELECT_BY_POS,MODE_HISTORY)) continue;
    if(OrderMagicNumber()!=Magic) continue;
    if(closetime<OrderCloseTime())
     { 
      CloseTime=(int)OrderCloseTime(); 
      ocp=NormalizeDouble(OrderClosePrice(),Digits);
      osl=NormalizeDouble(OrderStopLoss(),Digits);
     } 
   }

потом появляется искушение сделать так:

PHP:
  int Result=0;
  if (ocp==osl) Result=1;

и дальше:

PHP:
  if (Result==1) 
   {Loss++; if (Loss>=NumberLoss) {LOT=NormalizeDouble(Lot*K, 2); Loss=0;}} 
  else 
   {Loss=0; LOT=LotStart; }

но потом за SL следует не увеличенный лот, а начальный... что не так?


Если Вам нужен вход по мартину только при условии, что профит последней позиции меньше "0" - тогда iBoss верно ответил, можно сразу получить значение профита последнего закрытого ордера в истории. А если по стоплосу, тогда сравнивать нужно не на "==", а из-за проскальзывания, на ">=" или "<=" между значениями OrderStopLoss() и OrderClosePrice(), но предварительно узнать тип последнего закрытого ордера для выбора нужного условия.
 

allisbob

Прохожий
Спасибо за помощь. И впрямь, так как закрытие по SL может произойти и в положительной зоне(SL тянется за ценой) то сверять прибыль не будет корректным. Вот, что вышло:

PHP:
  for(int j=OrdersHistoryTotal()-1;j>=0;j--) 
   {
    if(OrderSelect(j,SELECT_BY_POS,MODE_HISTORY)==true && OrderSymbol()==Symbol()) 
    if(OrderCloseTime()<TimeCurrent()-3600) break; 
    else 
     { 
      if ((OrderType()==OP_BUY && OrderStopLoss()-OrderClosePrice()>=-Point/10) 
       || (OrderType()==OP_SELL && OrderClosePrice()-OrderStopLoss()>=-Point/10))
       {
        { действуем }
      else
        { отбой }
     }
   }

пересчет с конца, мне выдается, ускоряет процесс. В сове работает, возможно что-то не учел - поправьте, пожалуйста.

И еще, прошу подсказать как реализовать сравнение депо до открытия начальной сделки и текущий баланс эквити. Сова - все тот же мартин. Речь идет не о банальной разнице AccountEquity() и AccountBalance(), а о разнице AccountEquity() и того первого значения AccountBalance() в самом начале серии "догона". Понятно, что здесь не обойтись без массивов, потому прошу подсказать направление, а лучше с примерами кода, если не затруднит.
 

eevviill2

Местный знаток
Спасибо за помощь. И впрямь, так как закрытие по SL может произойти и в положительной зоне(SL тянется за ценой) то сверять прибыль не будет корректным. Вот, что вышло:

...
В ордера закрытого по СЛ в кометарие имеется [sl]
 

ivansss

Новичок форума
Добрый день. Подскажите есть ли возможность курсор мыши привязать к сове мт4, и по сигналам, на сайте БО брокера шла торговля? Средствами mql это реализуемо?
 

well72

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

alexshell

Элитный участник
Добрый вечер.
Мастера, подскажите хитрость. Как перевести пункты в цену я знаю. Но вот как перевести разницу между ценами открытия и стопа в пункты - никак не могу понять.
Надо для вычисления динамического лота.

Да вроде просто все. пункты в цену: *Point, а разницу цены в пункты: /Point
 

Ugar

Гуру форума
Добрый вечер.
Мастера, подскажите хитрость. Как перевести пункты в цену я знаю. Но вот как перевести разницу между ценами открытия и стопа в пункты - никак не могу понять.
Надо для вычисления динамического лота.
Предварительно надо выбрать ордер
Код:
int StopLossPoint=0;
if(OrderType()==OP_BUY && OrderStopLoss()>0)
StopLossPoint=(OrderOpenPrice()-OrderStopLoss())/_Point;

if(OrderType()==OP_SELL && OrderStopLoss()>0)
StopLossPoint=(OrderStopLoss()-OrderOpenPrice())/_Point;
 

Milord

Местный знаток
А зачем вам стоплосс?

Ребят, подскажите, пожалуйста.

имеется условие: if (Profit<0) {мартинимся} else {лот - начальный}
как вместо проверки прибыли корректно оформить условие "последний ордер закрылся по SL"?
Дело в том что по-моему сравнивать OrderClosePrise() и OrderStopLoss() напрямую нельзя(вроде a==b, хотя в "тостере" ,наверное, так и работает), ведь закрытие проскальзывает и не происходит прям на месте выставленного SL.
А тут еще и вопрос как правильно отобрать эти "закритие" и "лосс"?
Вот как это происходит у меня:

PHP:
  int Magic=0, CloseTime=0; 
  double ocp=0.0, osl=0.0;
  for(int j=0;j<OrdersHistoryTotal();j++)
   { 
    if(!OrderSelect(j,SELECT_BY_POS,MODE_HISTORY)) continue;
    if(OrderMagicNumber()!=Magic) continue;
    if(closetime<OrderCloseTime())
     { 
      CloseTime=(int)OrderCloseTime(); 
      ocp=NormalizeDouble(OrderClosePrice(),Digits);
      osl=NormalizeDouble(OrderStopLoss(),Digits);
     } 
   }


потом появляется искушение сделать так:

PHP:
  int Result=0;
  if (ocp==osl) Result=1;

и дальше:

PHP:
  if (Result==1) 
   {Loss++; if (Loss>=NumberLoss) {LOT=NormalizeDouble(Lot*K, 2); Loss=0;}} 
  else 
   {Loss=0; LOT=LotStart; }

но потом за SL следует не увеличенный лот, а начальный... что не так?

по моему все проще пишется, мартингейл открывает ордера всегда в убыток,в надежде на откат, то есть для ордеров SELL сравниваем цену Bid(в данный момент) и (открытия ордера+PipStep),где PipStep - шаг открытия новых ордеров при просадке,для ордеров BUY все аналогично,но меняем знаки на противоположные и сравниваем с ценой Ask,кусок кода будет примерно таким:
PHP:
for (int i = 0; i < OrdersTotal(); i++)
     { 
      if(OrderSelect( i, SELECT_BY_POS, MODE_TRADES))
       {
        if (OrderMagicNumber()==MagicNumber)
         {
         if(OrderType()==OP_SELL)
          {
          if(Bid>OrderOpenPrice()+PipStep*Point)
           {
           OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,Bid-TakeProfit*Point,"",MagicNumber,0,Green);
           }
          }
         if(OrderType()==OP_BUY)
          {
          if(Ask<OrderOpenPrice()-PipStep*Point)
           {
           OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,"",MagicNumber,0,Green);
           }
          }
         }
        }
       }
 
Последнее редактирование:

vladradon

Программист
PHP:
for(int j=OrdersHistoryTotal()-1;j>=0;j--)  
   { 
    if(OrderSelect(j,SELECT_BY_POS,MODE_HISTORY)==true && OrderSymbol()==Symbol())  
    if(OrderCloseTime()<TimeCurrent()-3600) break;  
    else  
     {  
      if ((OrderType()==OP_BUY && OrderStopLoss()-OrderClosePrice()>=-Point/10)  
       || (OrderType()==OP_SELL && OrderClosePrice()-OrderStopLoss()>=-Point/10)) 
       { 
        { действуем } 
      else 
        { отбой } 
     } 
   }
пересчет с конца, мне выдается, ускоряет процесс. В сове работает, возможно что-то не учел - поправьте, пожалуйста.
Я бы так сделал:
PHP:
for(int j=OrdersHistoryTotal()-1;j>=0;j--)  
   { 
    if(OrderSelect(j,SELECT_BY_POS,MODE_HISTORY)==true && OrderSymbol()==Symbol())  
    if(OrderCloseTime()<TimeCurrent()-3600) break;  
    else  
     {  
      if (MathAbs(OrderStopLoss()-OrderClosePrice())<=_Point*Slip) 
        { действуем } 
      else 
        { отбой } 
     } 
   }
где Slip - проскальзывание в пунктах, т.к. проскальзывание может быть в любом направлении.
А по поводу эквити - какие признаки окончания цикла (при каких условиях)? Может тебе проще там, где происходит обнуление Loss или лота в начальный, добавить переменную, запоминающую текущий баланс, а дальше уже ее сравнивать с текущим эквити.
 
Последнее редактирование:

AlanTrade

Интересующийся
Уважаемые коллеги, подскажите, как решить вопрос.

При загрузке терминала МТ4 индикатор инициализируется до обновления котировок.

Т.к. в нем много графических объектов, которые нет необходимости трогать далее в Start-е, соответственно, они отображаются неправильно.

Как выйти из положения?

Заранее благодарен.
 

vladradon

Программист
Уважаемые коллеги, подскажите, как решить вопрос.

При загрузке терминала МТ4 индикатор инициализируется до обновления котировок.

Т.к. в нем много графических объектов, которые нет необходимости трогать далее в Start-е, соответственно, они отображаются неправильно.

Как выйти из положения?
Как вариант можно попробовать перенести команды вывода графики в конец основного кода (после обработкти индикаторных всех расчетов) только под управление какой-нибудь флаговой переменной и граф команды заключить в кривые скобки, а эту переменную проверять: при инициализации переменная обнуляется (или если буловская, то true), а в основном коде делаем проверку типа:
PHP:
if("переменная" !=true)
 {
  <<...графические команды>>
  "переменная"=false
 }
При таком раскладе прорисовка графики будет происходить один раз при первом запуске, если, конечно, там еще каких-то в коде мелочей нет, для которых нужны дополнительные проверки.
 

AlanTrade

Интересующийся
Инициализация индикатора

Спасибо за ответ.
Как понимаю, код из блока OnInit индикатора переноситься в OnCalculate, где на каждом тике проверяется условие однократного исполнения.
Одно сравнение на тик, конечно, немного, но, если учесть, что котировки у меня "льются", жалко, всё-таки времени терминала. Да и вопрос хотелось бы решить "законным" способом.
Неужели разработчик не понимает некорректности работы инициализирующего блока и не предусмотрел "выпрямления" этой ситуации?
Еще раз благодарен за содействие.
 

mobidik

-----
...Неужели разработчик не понимает некорректности работы инициализирующего блока и не предусмотрел "выпрямления" этой ситуации?

Вам бы следовало предоставить свой код, вот тогда будет предметный разговор, а так это ни о чем, экстрасенсы нынче в отпуске...
А на счет "некорректности работы инициализирующего блока и не предусмотрел "выпрямления" этой ситуации" - все в руках самого прогера - что сделал, то и имеет.
 

vladradon

Программист
Как понимаю, код из блока OnInit индикатора переноситься в OnCalculate, где на каждом тике проверяется условие однократного исполнения.
Одно сравнение на тик, конечно, немного, но, если учесть, что котировки у меня "льются", жалко, всё-таки времени терминала. Да и вопрос хотелось бы решить "законным" способом.
Я имел ввиду использование флаговой переменной, которая при первом запуске меняет свое значение и при следующих тиках уже не дает выполняться графике, т.к. этот блок запускается только при первом запуске, когда переменная обнулена и в конце блока (в кривых скобках) меняет свое значение, которое уже не пройдет проверку при следующем тике командой if и эта команда будет единственной доп нагрузкой на тик абсолютно не значимой для быстродействия индикатора. Только это не поможет, если индикатор запускается из сова или в оптимизаторе - там лучше ввести еще одну входную переменную, которая в ручном режиме будет отключать графику, чтобы не было тормозов. Но я согласен с Мобидиком, что проще один раз код проанализировать, чем гадать что и как там нужно поправить.
 
Последнее редактирование:

malojorsk

Новичок форума
Спецы, подскажите пожалуйста, не знаю как написать условие -
нужно закрыть ордер одновременно с закрытием текущей свечи
 

vladradon

Программист
Спецы, подскажите пожалуйста, не знаю как написать условие -
нужно закрыть ордер одновременно с закрытием текущей свечи
Можно по времени открытия:
PHP:
datetime Top=0;
void OnTick()
{
 if (Top<=0.0) Top=iTime(_Symbol,0,0);
 if (Top>0 && Top<iTime(_Symbol,0,0))
  {
   Top=iTime(_Symbol,0,0);
   Команда закрытия ордера;
  }
//Другие команды кода
}
где Тор - переменная, хранящая время открытия последнего бара.
 

remembaaa

Прохожий
Здравствуйте. Подскажите как программно установить параметр у индикатора, и/или передать параметр из одного индикатора в другой :)

Например. Имеем две ЕМА, одна с периодом 25 вторая 50. Допустим получаем расстояние между ними в 34пп. Как сделать что бы у третьей ЕМА стал период 34, и чтобы период изменялся так как две другие средние постоянно сходятся и расходятся.
 
Верх