Jump to content

Общие вопросы по языку MQL


Recommended Posts

sviter

Добрый вечер! Подскажите как лучше реализовать следующую идею....

Брать последние фракталы и когда цена их пробивает, то открывать ордера...
 
Беру фракталы стандартными кодами от kimiva, а вот как правильно сравнивать не понятно, то ли сравнивать по цене, то ли по барам???
Link to post
Share on other sites
  • Replies 7.6k
  • Created
  • Last Reply

Top Posters In This Topic

  • AntFX

    577

  • sergey1294

    569

  • Ugar68

    517

  • Programmer

    419

Top Posters In This Topic

Popular Posts

Ну, в данном случае мне стоило бы сразу соблюдать простейшие приёмы защитного программирования, то есть проверять, не равна ли нулю переменная, оказавшаяся под знаком деления. Ведь она "чужая", то ест

На счёт проверок, это правильно. Я больше очень практикую, то же нарывался. Но в моём случае у меня советник открывал ордер минимальным лотом вместо нормального, когда замечал, доливаться было поздно.

Основной советник выставляет "сигнальный" отложенный ордер далеко от текущей цены и каждую например, минуту модифицирует у него время экспирации: это может быть текущее время плюс 1 час, или плюс 1 су

Posted Images

Ugar68
14.12.2018 в 02:56, sviter сказал:

Добрый вечер! Подскажите как лучше реализовать следующую идею....

Брать последние фракталы и когда цена их пробивает, то открывать ордера...
 
Беру фракталы стандартными кодами от kimiva, а вот как правильно сравнивать не понятно, то ли сравнивать по цене, то ли по барам???

В вопросе же ответ, "когда цена их пробивает", значит по цене.

А что за стандартные коды от kimiva? Что то я не слышал о таких стандартах.


Пишу советники и индикаторы по вашим алгоритмам. Пишите в личку.
Чужие программы не переделываю.

Link to post
Share on other sites
sviter

Граждане помогите!
Хочу сделать пробитие фрактала ценой на той же свече (как на картинке)!
14784326_.png.29c342b70ad2c8bba63af0ce96ce65fc.png

но не получается!!!
Я получаю цены фракталов так, и сравниваю их, но мне надо конкретное пробитие ценой на той же свече!!
Не подскажите как?
 

   if(findFractal(1, MODE_UPPER, Period()) < findFractal(0, MODE_UPPER, Period()))
     {
      int ticket=OrderSend(NULL,OP_BUY,Lots,Ask,30,0,Bid+Tprof*_Point,NULL,Magik,0,clrBlue);
     }

   if(findFractal(1, MODE_LOWER, Period()) > findFractal(0, MODE_LOWER, Period()))
     {
      int ticket=OrderSend(NULL,OP_SELL,Lots,Bid,30,0,Ask-Tprof*_Point,NULL,Magik,0,clrRed);
     }

double findFractal(int nbr, int mode, int timeframe)
{
   int i=3, n;
   for(n=0;n<=nbr;n++)
   {
      while(iFractals(Symbol(),timeframe,mode,i) == 0)
         i++;
      if(n<nbr)
         i++;
   }
   return(iFractals(Symbol(),timeframe,mode,i));
}

 

Link to post
Share on other sites
БорисMQL4

Пример работы с фракталами.

//Идея.
//Брать последние фракталы и когда цена их пробивает, то открывать ордера.

int i,up=-1,dn=-1,tt;
double fr;

for(i=3; i<Bars; i++)
   {
   fr=iFractals(NULL,0,MODE_UPPER,i);
   if(fr!=0)
      {
      up=i;
      break;
      }
   }

for(i=3; i<Bars; i++)
   {
   fr=iFractals(NULL,0,MODE_LOWER,i);
   if(fr!=0)
      {
      dn=i;
      break;
      }
   }

if(OrdersTotal()==0 && up>0 && dn>0)
   {
   if(Open[0]<High[up] && Close[0]>High[up])
      {
      tt=OrderSend(Symbol(),OP_BUY,0.1,Ask,5,0,0,"1",1,0,clrBlue);
      }
   if(Open[0]>Low[dn] && Close[0]<Low[dn])
      {
      tt=OrderSend(Symbol(),OP_SELL,0.1,Bid,5,0,0,"1",1,0,clrRed);
      }
   }

При реализации важно понимать как движется цена перед тем как пробить крайний фрактал, а также нужно учитывать ордера, текущие и прошлые, запрашивая и подставляя нужную информацию в условия входа. В данном случае мы получаем смещение последних фракталов на графике и подставляем это смещение для получения цен High и Low, но можно получать сразу цену, это зависит от идеи в целом. 


Пишу на заказ — советники, индикаторы, скрипты и другое ПО для терминала MetaTrader 4.
Сделать заказ

Link to post
Share on other sites
sviter
20.12.2018 в 21:02, БорисMQL4 сказал:

Пример работы с фракталами.


//Идея.
//Брать последние фракталы и когда цена их пробивает, то открывать ордера.

int i,up=-1,dn=-1,tt;
double fr;

for(i=3; i<Bars; i++)
   {
   fr=iFractals(NULL,0,MODE_UPPER,i);
   if(fr!=0)
      {
      up=i;
      break;
      }
   }

for(i=3; i<Bars; i++)
   {
   fr=iFractals(NULL,0,MODE_LOWER,i);
   if(fr!=0)
      {
      dn=i;
      break;
      }
   }

if(OrdersTotal()==0 && up>0 && dn>0)
   {
   if(Open[0]<High[up] && Close[0]>High[up])
      {
      tt=OrderSend(Symbol(),OP_BUY,0.1,Ask,5,0,0,"1",1,0,clrBlue);
      }
   if(Open[0]>Low[dn] && Close[0]<Low[dn])
      {
      tt=OrderSend(Symbol(),OP_SELL,0.1,Bid,5,0,0,"1",1,0,clrRed);
      }
   }

При реализации важно понимать как движется цена перед тем как пробить крайний фрактал, а также нужно учитывать ордера, текущие и прошлые, запрашивая и подставляя нужную информацию в условия входа. В данном случае мы получаем смещение последних фракталов на графике и подставляем это смещение для получения цен High и Low, но можно получать сразу цену, это зависит от идеи в целом. 

Вот бывают такие моменты, когда цена пробила фрактал и открылся ордер, и следующий свечи тоже пробивают этот фрактал и открываются еще ордера! как сделать так, что бы если цена пробила фрактал, то ордер открывался один раз, а другие свечи игнорировались!  и так каждый раз????

Link to post
Share on other sites
Ugar68
1 час назад, sviter сказал:

Вот бывают такие моменты, когда цена пробила фрактал и открылся ордер, и следующий свечи тоже пробивают этот фрактал и открываются еще ордера! как сделать так, что бы если цена пробила фрактал, то ордер открывался один раз, а другие свечи игнорировались!  и так каждый раз????

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


Пишу советники и индикаторы по вашим алгоритмам. Пишите в личку.
Чужие программы не переделываю.

Link to post
Share on other sites
БорисMQL4
5 часов назад, sviter сказал:

Вот бывают такие моменты, когда цена пробила фрактал и открылся ордер, и следующий свечи тоже пробивают этот фрактал и открываются еще ордера! как сделать так, что бы если цена пробила фрактал, то ордер открывался один раз, а другие свечи игнорировались!  и так каждый раз????

Вариант решения который предложил Ugar68, это оптимальное решение. Время сохраняйте точно также как получаете цены, по смещению (Time[up] и Time[dn]). Сохранять предпочтительнее в GV (GlobalVariableSet("UP",Time[up]), для dn аналогично), таким образом будете иметь две глобальные переменные с временем последнего сигнального (пробитого) фрактала вверх и вниз соответственно.


Пишу на заказ — советники, индикаторы, скрипты и другое ПО для терминала MetaTrader 4.
Сделать заказ

Link to post
Share on other sites
sviter
3 часа назад, БорисMQL4 сказал:

Вариант решения который предложил Ugar68, это оптимальное решение. Время сохраняйте точно также как получаете цены, по смещению (Time[up] и Time[dn]). Сохранять предпочтительнее в GV (GlobalVariableSet("UP",Time[up]), для dn аналогично), таким образом будете иметь две глобальные переменные с временем последнего сигнального (пробитого) фрактала вверх и вниз соответственно.

Граждане! Спасибо огромное за вашу бесценную помощь! Ну не понимаю я как сделать эту проверку! Вот хоть убейте меня! Смешно, зато правда)))!!!

что с чем проверять? перед открытием нового ордера проверять не запомнен ли пробиваемый врактал, это как??

Link to post
Share on other sites
Ugar68
9 часов назад, sviter сказал:

Граждане! Спасибо огромное за вашу бесценную помощь! Ну не понимаю я как сделать эту проверку! Вот хоть убейте меня! Смешно, зато правда)))!!!

что с чем проверять? перед открытием нового ордера проверять не запомнен ли пробиваемый врактал, это как??

Открытие ордера по пробитию фрактала? Этот фрактал на каком то баре. У этого бара есть время открытия.

Сравнить это время с запомненным, если не совпадает открыть ордер и запомнить время фрактала.


Пишу советники и индикаторы по вашим алгоритмам. Пишите в личку.
Чужие программы не переделываю.

Link to post
Share on other sites
БорисMQL4
15 часов назад, sviter сказал:

Ну не понимаю я как сделать эту проверку! Вот хоть убейте меня! Смешно, зато правда)))!!!

Вариант реализации с проверкой.
 

#property strict

int OnInit()
{
if(IsTesting())
   {
   GlobalVariableDel("UP");
   GlobalVariableDel("DN");
   }
return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
}

void OnTick()
{
// Идея.
// Брать последние фракталы и когда цена их пробивает, то открывать ордера.
// По каждому сигнальному фракталу открывать только один ордер.

int i,up=-1,dn=-1,tt;
double fr;

for(i=3; i<Bars; i++)
   {
   fr=iFractals(NULL,0,MODE_UPPER,i);
   if(fr!=0)
      {
      up=i;
      break;
      }
   }

for(i=3; i<Bars; i++)
   {
   fr=iFractals(NULL,0,MODE_LOWER,i);
   if(fr!=0)
      {
      dn=i;
      break;
      }
   }

if(OrdersTotal()==0 && up>0 && dn>0)
   {
   if(Open[0]<High[up] && Close[0]>High[up] && Time[up]>GlobalVariableGet("UP"))
      {
      tt=OrderSend(Symbol(),OP_BUY,0.1,Ask,5,Ask-50*Point,Ask+50*Point,"1",1,0,clrBlue);
      if(tt>0) GlobalVariableSet("UP",Time[up]);
      }
   if(Open[0]>Low[dn] && Close[0]<Low[dn] && Time[dn]>GlobalVariableGet("DN"))
      {
      tt=OrderSend(Symbol(),OP_SELL,0.1,Bid,5,Bid+50*Point,Bid-50*Point,"1",1,0,clrRed);
      if(tt>0) GlobalVariableSet("DN",Time[dn]);
      }
   }
}

 


Пишу на заказ — советники, индикаторы, скрипты и другое ПО для терминала MetaTrader 4.
Сделать заказ

Link to post
Share on other sites
  • 2 weeks later...
torgf

Хочу модифицировать сетку отложенных ордеров.

Как действовать?

Один ордер модифицирую так:

void TrailingOrders()
  {
   int i;

   for(i=0; i<OrdersTotal(); i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {

         if(OrderType()==OP_SELLSTOP)
           {
            if(Bid-OrderOpenPrice()>TrailingStop*Point)
              {
               if(OrderOpenPrice()<Bid-(TrailingStop+TrailingStep-1)*Point)
                 {
                  double newpr=Bid-TrailingStop*Point;
                  ModStopOrders(newpr,OP_SELLSTOP);
                 }
              }
           }
         if(OrderType()==OP_BUYSTOP)
           {
            if(OrderOpenPrice()-Ask>TrailingStop*Point)
              {
               if(OrderOpenPrice()>Ask+(TrailingStop+TrailingStep-1)*Point)
                 {
                  double newprBS=Ask+TrailingStop*Point;
                  ModStopOrders(newprBS,OP_BUYSTOP);
                 }
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
//|   Модификация отл.ордера                                         |
//+------------------------------------------------------------------+
void ModStopOrders(double newprice,string OP)
  {
   bool   fm;
   double SL=OrderStopLoss();
   if(OP==OP_BUYSTOP)
     {
      SL=SL+TrailingStep*Point;
     }
   if(OP==OP_SELLSTOP)
     {
      SL=SL-TrailingStep*Point;
     }
   fm=OrderModify(OrderTicket(),newprice,0,0,0,Red);
   if(fm && UseSound) {PlaySound(NameFileSound); }
  }

 

Link to post
Share on other sites
Ugar68

Почти так же. Но в сетке ордера на разных уровнях. Значит надо определиться какой ордер двигать на заданном трейлинге. Например самый нижний или самый верхний. Найти его. Дальше, передвинуть этот ордер, если он передвинулся успешно, посчитать на сколько пунктов он был передвинут и остальные ордера в сетке двинуть на столько же пунктов.

Edited by Ugar68
  • Upvote 1

Пишу советники и индикаторы по вашим алгоритмам. Пишите в личку.
Чужие программы не переделываю.

Link to post
Share on other sites
torgf
37 минут назад, Ugar68 сказал:

. Найти его. Дальше, передвинуть этот ордер, если он передвинулся успешно, посчитать на сколько пунктов он был передвинут и остальные ордера в сетке двинуть на столько же пунктов.

В этом, для меня и есть сложность. Как узнать какой ордер на какую цену переставлять.  Например модифицирую ордер, самый ближний к цене закрытия первого бара на расстоянии 50 пипс. Как в цикле для второго ордера изменить цену открытия newpr ?

Link to post
Share on other sites
AntFX

Ребята, я понимаю, что это супер-сложно, но убирайте длинные коды под спойлеры. Если "код" под спойлер убрать не получится, отправляйте как простой текст под спойлером. Или в виде файлов mq4, что ещё лучше

Edited by AntFX

1

Link to post
Share on other sites
Ugar68

1. В цикле, сравнивая цены открытия, ищите самый нижний BuyStop и самый верхний SellStop, запоминаете тикеты.

2. Выбираете по тикету найденный ордер, проверяете надо ли его модифицировать, так же как делали это в цикле, но теперь только для одного ордера. Если нужно, то модифицируете, но предварительно считаете разницу между ценой открытия и ценой куда переставляете. Если перемещение ордера успешно, переходите к следующему пункту.

3. В цикле перебирает ордера и перемещаете все на столько же на сколько переместили ордер в пункте 2. Пропуская ордер, который переместили в пункте 2.

  • Thanks 1

Пишу советники и индикаторы по вашим алгоритмам. Пишите в личку.
Чужие программы не переделываю.

Link to post
Share on other sites
torgf
08.01.2019 в 19:49, Ugar68 сказал:

 

Спасибо, из всех пунктов я могу только найти тикет ближайших ордеров. Дальше ступор, не понимаю, что как делать, помогите кодом, где запомнить в переменную, разницу между ценой открытия и ценой куда переставлять, как потом её использовать, где обнулять значение?

так нахожу ближние:

int Ticket_(string sy="", int op=-1, int mn=-1) {
  double mi, p;
  int    i, k=OrdersTotal(), pp=0, ti=0;

  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if ((OrderSymbol()==sy || sy=="") && (op<0 || OrderType()==op)) {
        if (OrderType()==OP_BUYSTOP || OrderType()==OP_SELLSTOP) {
          if (mn<0 || OrderMagicNumber()==mn) {
            if (OrderType()==OP_BUYSTOP)  mi=MarketInfo(OrderSymbol(), MODE_ASK);
            if (OrderType()==OP_SELLSTOP) mi=MarketInfo(OrderSymbol(), MODE_BID);
            p=MarketInfo(OrderSymbol(), MODE_POINT);
            if (p==0) if (StringFind(sy, "JPY")<0) p=0.0001; else p=0.01;
            if (pp==0 || pp>MathAbs(OrderOpenPrice()-mi)/p) {
              pp=MathAbs(OrderOpenPrice()-mi)/p;
              ti=OrderTicket();
            }
          }
        }
      }
    }
  }
  return(ti);
}

 

Edited by torgf
Link to post
Share on other sites
Ugar68
1 час назад, torgf сказал:

Спасибо, из всех пунктов я могу только найти тикет ближайших ордеров. Дальше ступор, не понимаю, что как делать.

так нахожу ближние:

Не понял что это. Зачем это.

Скрытый текст

//+------------------------------------------------------------------+
//| Функция от Ugar eMail:[email protected]                               |
/*+------------------------------------------------------------------+
Функция трейлинга сетки стоповых ордеров. Бюджетная.
magic - идентификатор ордеров
distance - дистанция трейлинга
step - шаг трейлинга*/
void TrailingNetStopOrders(int magic, uint distance, uint step)
   {
   int i, total=OrdersTotal(), Type;
   double oop, op, MoveBS=0, MoveSS=0, MinOOPBS=0, MaxOOPSS=0;
   //Поиск самого нижнего BuyStop и самого верхнего SellStop ордеров
   for(i=total-1; i>=0; i--)
      {
      if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         {
         Print(__FUNCTION__," Ошибка выбора ордера ",_LastError);
         return;
         }
      if(OrderSymbol()!=_Symbol || OrderMagicNumber()!=magic)continue;
      Type=OrderType();
      if(Type==OP_BUYSTOP)
         {
         oop=OrderOpenPrice();
         if(MinOOPBS>oop || MinOOPBS<_Point)MinOOPBS=oop;
         }
      if(Type==OP_SELLSTOP)
         {
         oop=OrderOpenPrice();
         if(MaxOOPSS<oop)MaxOOPSS=oop;
         }
      }
      
   //Вычислить на сколько надо тралить самый нижний BuyStop ордер
   if(MinOOPBS>_Point && MinOOPBS-Ask>(distance+step)*_Point)
      MoveBS=MinOOPBS-Ask-distance*_Point;
   //Вычислить на сколько надо тралить самый верхний SellStop ордер
   if(MaxOOPSS>_Point && Bid-MaxOOPSS>(distance+step)*_Point)
      MoveSS=Bid-MaxOOPSS-distance*_Point;
   
   //Трейлинг сетки
    for(i=total-1; i>=0; i--)
      {
      if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         {
         Print(__FUNCTION__," Ошибка выбора ордера ",_LastError);
         continue;
         }
      if(OrderSymbol()!=_Symbol || OrderMagicNumber()!=magic)continue;
      Type=OrderType();
      op=0;
      if(Type==OP_BUYSTOP && MoveBS>_Point)
         {
         oop=OrderOpenPrice();
         op=oop-MoveBS;
         }
      if(Type==OP_SELLSTOP && MoveSS>_Point)
         {
         oop=OrderOpenPrice();
         op=oop+MoveSS;
         }
      if(op>_Point)
         {
         if(!OrderModify(OrderTicket(),NormalizeDouble(op,_Digits),0,0,0))
            {
            Print(__FUNCTION__," Ошибка модификации ордера ",_LastError);
            }
         }
      }
   }

 

Написал упрощенный вариант (бюджетный) функции. Не проверял. Разбирайтесь. Справочник в помощь.

Edited by Ugar68
  • Thanks 1

Пишу советники и индикаторы по вашим алгоритмам. Пишите в личку.
Чужие программы не переделываю.

Link to post
Share on other sites
AntFX
28.09.2018 в 08:18, kazakov.v сказал:

 

Указатель - это просто цифирь, по сути базовый (элементарный) тип данных.

Для базовых типов перегружать операторы нельзя, да и бессмысленно. Я так думаю)

 

Либо я туплю, либо что-то подкрутили за последние 3 месяца. Вот так теперь работает. А может и раньше работало?...

class A{
   public:
      bool operator==(A *a){  Print("a==a?"); return(false); }
};

void OnStart(){
   A *a;
   A *b;
   Print(*a==b); }

 


1

Link to post
Share on other sites
Mighty Mouse

Как очистить график от результатов работы удаленного с него скрипта или советника?

Индикатор и советник выводили комментарии и текстовые метки, которые теперь ни мышью ни через меню объектов удалить нельзя.

Обновление графика и смена ТФ не помогают, а пересоздавать гемор.

Link to post
Share on other sites
Ugar68
15 минут назад, Mighty Mouse сказал:

Как очистить график от результатов работы удаленного с него скрипта или советника?

Индикатор и советник выводили комментарии и текстовые метки, которые теперь ни мышью ни через меню объектов удалить нельзя.

Обновление графика и смена ТФ не помогают, а пересоздавать гемор.

От комментария помогает Comment("");

Текстовые метки это объекты. Их можно поудалять. Желательно знать их имена, маску, тип.. Что нибуть по чему отличить ненужные объекты от остальных. Если вообще никаких не жалко то вообще просто ObjectsDeleteAll(); без аргументов.

  • Thanks 1

Пишу советники и индикаторы по вашим алгоритмам. Пишите в личку.
Чужие программы не переделываю.

Link to post
Share on other sites
Mighty Mouse
15.01.2019 в 01:20, Ugar68 сказал:

Желательно знать их имена, маску, тип

 

Тогда придется в чужой код лезть, а не всегда такая возможность есть.

Метки почему-то выделить не могу, похоже что какое-то свойство установлено, это как-то проверить можно?

 

 

 

Link to post
Share on other sites
Ugar68
1 час назад, Mighty Mouse сказал:

 

Тогда придется в чужой код лезть, а не всегда такая возможность есть.

Метки почему-то выделить не могу, похоже что какое-то свойство установлено, это как-то проверить можно?

Да, конечно. Что бы не дать выделить объект ставится атрибут OBJPROP_HIDDEN.

В терминале, при отображении всех объектов, такие будут в списке, только если нажать кнопку Все. Там же их можно удалить вручную.

Если это именно текстовые метки, можно удалить программно все текстовые метки ObjectsDeleteAll(0,OBJ_LABEL);

  • Thanks 1

Пишу советники и индикаторы по вашим алгоритмам. Пишите в личку.
Чужие программы не переделываю.

Link to post
Share on other sites
Mighty Mouse
4 часа назад, Ugar68 сказал:

Что бы не дать выделить объект ставится атрибут OBJPROP_HIDDEN.

 

Меня еще вот какой вопрос занимает.

Мне очень трудно воспринимать пятизнак, сделал отдельный вывод на график 4 знака бид. Потом захотелось чтобы по нажатию на колесо появлялась метка с ценой 4 знака и следовала за курсором чтобы не пользоваться системным пятизнаком. Прописал это в OnCHartEvent, но при нажатии на колесо метка не появляется, а только после того как начинаю двигать мышью. Все то же самое сделаное в советнике через комментарий работает сразу, но комменты находятся в углу, куда смотреть неудобно. Как эту фичу лучше реализовать? Есть предположение что обработка события в индюке происходит с некоторыми интервалами и для подобных целей не предназначена, а куча советников на каждом чарте возможно начнет жрать ресурсы. Может сделать через скрипт? Но я пока не знаю как они работают тк ни одного не написал.

Link to post
Share on other sites
sviter

Здравствуйте! Где то читал статью про то что mql4 или 5 стал предлогать шифровать своим сервисом коды советников....подскажите где конкретнее про это почитать и что за сервис?

Link to post
Share on other sites
Mighty Mouse
15.01.2019 в 03:07, Ugar68 сказал:

Да, конечно

 

Имеется дата, время некоего бара, можно узнать его OHLC не вычисляя сдвиг относительно края, что требуется для iOpen, iClose и тд?

Есть ли более простое и элегантное решение?

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    No registered users viewing this page.


×
×
  • Create New...