Перейти к содержанию

Обучение языку MQL4 под MetaTrader 4


Рекомендуемые сообщения

Обучение языку MQL4 под MetaTrader 4 Опубликовано

 Здравствуйте! Помогите пожалуйста, найти ошибку по уроку где показывают как писать мартенгейл. Компелируеться без ошибок и предупреждению.
  Сам пересмотрел урок уже дважды и в голове все плывет.
  Какие бы параметры не выставлял, выдает плюс- минус одно и тоже. Как на скриншоте, совсем ни как на уроке.

  Может у кого то, есть свой код с урока

//+------------------------------------------------------------------+
//|                                                          4.1.mq4 |
//|        советники на мартингейле.                               j |
//|                                                      https://www |
//+------------------------------------------------------------------+
 
#property copyright "j"
#property link      "https://www"
#property version   "1.00"
#property strict

extern double Lots       = 0.01;
extern int    TakeProfit = 50;     
extern int    Step       = 60; 
extern double multipler  = 2;  
extern int    Magic      = 123;

extern int maPeriod  = 14;
extern int ma_shift  = 0;
extern int ma_method = 1;
extern int ma_price  = 0;

int ticket;
double tp, price, lastlot;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
     if( Digits == 3 || Digits == 5)
         TakeProfit   *=10;
         Step         *=10;
     return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {    
  
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()  
  {
      double ima_1 = iMA(Symbol(), NULL, maPeriod, ma_shift, ma_method, ma_price, 0);   
       
      if(CountTrades()==0)
        {                                                                
          if(Ask > ima_1)
            { 
             tp=NormalizeDouble(Ask + TakeProfit *Point, Digits); 
             ticket=OrderSend(Symbol(), OP_BUY, Lots, Ask, 10, 0, tp, "", Magic, 0, Blue);
            }
           else 
            {
              tp=NormalizeDouble(Bid - TakeProfit *Point, Digits);
              ticket=OrderSend(Symbol(), OP_SELL, Lots, Bid, 10, 0, tp, "", Magic, 0, Red);
            } 
        } 
      else     
        {   
         int order_type = FindLastOrderType();
         if(order_type==OP_BUY) 
           {
            price = FindLastOrderPrice(OP_BUY); 
            if(Ask <= price-Step *_Point) 
              {
               lastlot=FindLastLots(OP_BUY);
               lastlot= NormalizeDouble(lastlot *multipler, 2); 
               ticket = OrderSend(Symbol(), OP_BUY, lastlot, Ask, 10, 0, 0, "", Magic, 0, Blue); //TakeProfit пока 0, так как его еще надо будет модифицировать с учетом всех открытых ордеров  
               if(ticket < 1)   
                  Print("Ошибка открития ордера на покупку");
                  ModifyOrders(OP_BUY);                                                                      
              }
           } 
         if(order_type==OP_SELL) 
           {
            price = FindLastOrderPrice(OP_SELL);
            if(Bid >= price + Step *Point)
              { 
               lastlot=FindLastLots(OP_SELL);
               lastlot= NormalizeDouble(lastlot * multipler, 2);
               ticket = OrderSend(Symbol(), OP_SELL, lastlot, Bid, 10, 0, 0, "", Magic, 0, Red);
               if(ticket < 1)
                  Print("Ошибка открытие ордера на продажу");
                  ModifyOrders(OP_SELL); 
              }
           }
      } 
 } // OnTick()
 
  
//-------------------------------------------------------------1) считаем ордера в рынке
int CountTrades()
 {
     int count = 0;
     for(int i= OrdersTotal()-1; i>=0; i--)  
        { 
        if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
         {
          if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic) 
          if(OrderType() == OP_BUY || OrderType() == OP_SELL ) 
             count++;
         }       
       } 
    return(count);              
 }    
//---------------------------------------------------------------2) Находим тип последнего ордера, BUY или SELL
int FindLastOrderType() 
 {
   for(int i= OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
       {
        if(OrderSymbol()== OrderSymbol() && OrderMagicNumber() == Magic)  
        return(OrderType());
                                
       }
     }                                 
   return(-1);
 }
//----------------------------------------------------------3) Находим цену последнего ордера    
double FindLastOrderPrice(int otype)                                        
 {
    int oldticket; 
    double oldopenprice = 0; 
    ticket = 0;
   
    for(int cnt=OrdersTotal()-1; cnt>=0; cnt--)
       {  
        if(OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES))
          {
           if(OrderSymbol()== Symbol() && OrderMagicNumber() == Magic && OrderType()== otype)
             {                                
              oldticket = OrderTicket();
              if(oldticket > ticket)
                {
                 ticket = oldticket;
                 oldopenprice = OrderOpenPrice();
                 
                }}}}
                
    return(oldopenprice);
 }
//--------------------------------------------------4) Находим сколько пунктов прошел последний закрытый ордер
double FindLastOrderProfit(int otype) 
 {
    int oldticket; 
    double oldorderProfit = 0;
    int bticket = 0;
   
    for(int cnt=OrdersTotal(); cnt>=0; cnt--)
       {  
        if(OrderSelect(cnt, SELECT_BY_POS, MODE_HISTORY))
          {
           if(OrderSymbol()== Symbol() && OrderMagicNumber() == Magic && OrderType()== otype)
             {                                  
              oldticket = OrderTicket();
              if(oldticket > bticket)
                {
                 bticket = oldticket;
                 oldorderProfit = OrderProfit(); 
                }}}}
    return(oldorderProfit);
 }    
//--------------------------------------------------5) Наход объем лота последнего открытого ордера
double FindLastLots(int otype) 
 { 
      int oldticket; 
      double oldlots = 0;
      ticket = 0; 
    
    for(int cnt=OrdersTotal()-1; cnt>=0; cnt--)
       { 
        if(OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES))
          {                                            
           if(OrderSymbol()== OrderSymbol() && OrderMagicNumber() == Magic && OrderType() == otype)
             {
              oldticket = OrderTicket();
              if(oldticket > ticket)
                {
                 ticket = oldticket;
                 oldlots = OrderLots();
                 
                }}}}
                
    return(oldlots);
 }                 
//----------------------------------------------6) Модифиция TakeProfit
void ModifyOrders(int otipe)  
  {
       double avg_price, order_lots=0;  
       price = 0; 
   
     for(int i=OrdersTotal()-1; i>=0; i--)
        { 
         if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
           {
            if(OrderSymbol()== Symbol() && OrderMagicNumber()==Magic && OrderType()==otipe) 
              {
                price += OrderOpenPrice() *OrderLots();  
                order_lots += OrderLots();  
             }                         
           } 
        }
          
     avg_price = NormalizeDouble(price / order_lots, Digits); 
     if(otipe == OP_BUY)  tp = NormalizeDouble(avg_price + TakeProfit, Digits); 
     if(otipe == OP_SELL) tp = NormalizeDouble(avg_price - TakeProfit, Digits);
                              
    for(int i=OrdersTotal()-1; i>=0; i--)
       {  
        if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
          {
           if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic && OrderType()==otipe) 
             {
              if(OrderModify( OrderTicket(), OrderOpenPrice(), 0, tp, 0))
                 Print("ордера успешно модифицированы");                   
            else Print("ошибка модификации ордеров");                                                                                                                                         
            }
          }                                                              
       } 
 }//void ModifyOrders        
//--------------------------------------------------------------- 

 

ScreenShot_marten.png

Изменено пользователем Ar4i
Ссылка на сообщение
Поделиться на другие сайты

  • Ответов 6,8k
  • Создано
  • Последний ответ

Популярные авторы

Популярные авторы

Популярные посты

Смотрим видео-уроки, изучаем MQL:       Скачать видеокурс «MQL программирование. Как самому написать форекс советник/ индикатор/ скрипт»   P.S. Тема про Обучение MQ

Перейти

Циклы цикл for Иногда необходимо повторять одно и то же действие несколько раз подряд. Для этого используют циклы. К примеру, мы хотим проанализировать последние 10 баров и выяснить наименьшую цен

Перейти

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

Перейти
Обучение языку MQL4 под MetaTrader 4 Опубликовано
В 06.12.2023 в 17:03, Ar4i сказал:

 Здравствуйте! Помогите пожалуйста, найти ошибку по уроку где показывают как писать мартенгейл. Компелируеться без ошибок и предупреждению.
  Сам пересмотрел урок уже дважды и в голове все плывет.
  Какие бы параметры не выставлял, выдает плюс- минус одно и тоже. Как на скриншоте, совсем ни как на уроке.

  Может у кого то, есть свой код с урока

//+------------------------------------------------------------------+
//|                                                          4.1.mq4 |
//|        советники на мартингейле.                               j |
//|                                                      https://www |
//+------------------------------------------------------------------+
 
#property copyright "j"
#property link      "https://www"
#property version   "1.00"
#property strict

extern double Lots       = 0.01;
extern int    TakeProfit = 50;     
extern int    Step       = 60; 
extern double multipler  = 2;  
extern int    Magic      = 123;

extern int maPeriod  = 14;
extern int ma_shift  = 0;
extern int ma_method = 1;
extern int ma_price  = 0;

int ticket;
double tp, price, lastlot;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
     if( Digits == 3 || Digits == 5)
         TakeProfit   *=10;
         Step         *=10;
     return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {    
  
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()  
  {
      double ima_1 = iMA(Symbol(), NULL, maPeriod, ma_shift, ma_method, ma_price, 0);   
       
      if(CountTrades()==0)
        {                                                                
          if(Ask > ima_1)
            { 
             tp=NormalizeDouble(Ask + TakeProfit *Point, Digits); 
             ticket=OrderSend(Symbol(), OP_BUY, Lots, Ask, 10, 0, tp, "", Magic, 0, Blue);
            }
           else 
            {
              tp=NormalizeDouble(Bid - TakeProfit *Point, Digits);
              ticket=OrderSend(Symbol(), OP_SELL, Lots, Bid, 10, 0, tp, "", Magic, 0, Red);
            } 
        } 
      else     
        {   
         int order_type = FindLastOrderType();
         if(order_type==OP_BUY) 
           {
            price = FindLastOrderPrice(OP_BUY); 
            if(Ask <= price-Step *_Point) 
              {
               lastlot=FindLastLots(OP_BUY);
               lastlot= NormalizeDouble(lastlot *multipler, 2); 
               ticket = OrderSend(Symbol(), OP_BUY, lastlot, Ask, 10, 0, 0, "", Magic, 0, Blue); //TakeProfit пока 0, так как его еще надо будет модифицировать с учетом всех открытых ордеров  
               if(ticket < 1)   
                  Print("Ошибка открития ордера на покупку");
                  ModifyOrders(OP_BUY);                                                                      
              }
           } 
         if(order_type==OP_SELL) 
           {
            price = FindLastOrderPrice(OP_SELL);
            if(Bid >= price + Step *Point)
              { 
               lastlot=FindLastLots(OP_SELL);
               lastlot= NormalizeDouble(lastlot * multipler, 2);
               ticket = OrderSend(Symbol(), OP_SELL, lastlot, Bid, 10, 0, 0, "", Magic, 0, Red);
               if(ticket < 1)
                  Print("Ошибка открытие ордера на продажу");
                  ModifyOrders(OP_SELL); 
              }
           }
      } 
 } // OnTick()
 
  
//-------------------------------------------------------------1) считаем ордера в рынке
int CountTrades()
 {
     int count = 0;
     for(int i= OrdersTotal()-1; i>=0; i--)  
        { 
        if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
         {
          if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic) 
          if(OrderType() == OP_BUY || OrderType() == OP_SELL ) 
             count++;
         }       
       } 
    return(count);              
 }    
//---------------------------------------------------------------2) Находим тип последнего ордера, BUY или SELL
int FindLastOrderType() 
 {
   for(int i= OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
       {
        if(OrderSymbol()== OrderSymbol() && OrderMagicNumber() == Magic)  
        return(OrderType());
                                
       }
     }                                 
   return(-1);
 }
//----------------------------------------------------------3) Находим цену последнего ордера    
double FindLastOrderPrice(int otype)                                        
 {
    int oldticket; 
    double oldopenprice = 0; 
    ticket = 0;
   
    for(int cnt=OrdersTotal()-1; cnt>=0; cnt--)
       {  
        if(OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES))
          {
           if(OrderSymbol()== Symbol() && OrderMagicNumber() == Magic && OrderType()== otype)
             {                                
              oldticket = OrderTicket();
              if(oldticket > ticket)
                {
                 ticket = oldticket;
                 oldopenprice = OrderOpenPrice();
                 
                }}}}
                
    return(oldopenprice);
 }
//--------------------------------------------------4) Находим сколько пунктов прошел последний закрытый ордер
double FindLastOrderProfit(int otype) 
 {
    int oldticket; 
    double oldorderProfit = 0;
    int bticket = 0;
   
    for(int cnt=OrdersTotal(); cnt>=0; cnt--)
       {  
        if(OrderSelect(cnt, SELECT_BY_POS, MODE_HISTORY))
          {
           if(OrderSymbol()== Symbol() && OrderMagicNumber() == Magic && OrderType()== otype)
             {                                  
              oldticket = OrderTicket();
              if(oldticket > bticket)
                {
                 bticket = oldticket;
                 oldorderProfit = OrderProfit(); 
                }}}}
    return(oldorderProfit);
 }    
//--------------------------------------------------5) Наход объем лота последнего открытого ордера
double FindLastLots(int otype) 
 { 
      int oldticket; 
      double oldlots = 0;
      ticket = 0; 
    
    for(int cnt=OrdersTotal()-1; cnt>=0; cnt--)
       { 
        if(OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES))
          {                                            
           if(OrderSymbol()== OrderSymbol() && OrderMagicNumber() == Magic && OrderType() == otype)
             {
              oldticket = OrderTicket();
              if(oldticket > ticket)
                {
                 ticket = oldticket;
                 oldlots = OrderLots();
                 
                }}}}
                
    return(oldlots);
 }                 
//----------------------------------------------6) Модифиция TakeProfit
void ModifyOrders(int otipe)  
  {
       double avg_price, order_lots=0;  
       price = 0; 
   
     for(int i=OrdersTotal()-1; i>=0; i--)
        { 
         if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
           {
            if(OrderSymbol()== Symbol() && OrderMagicNumber()==Magic && OrderType()==otipe) 
              {
                price += OrderOpenPrice() *OrderLots();  
                order_lots += OrderLots();  
             }                         
           } 
        }
          
     avg_price = NormalizeDouble(price / order_lots, Digits); 
     if(otipe == OP_BUY)  tp = NormalizeDouble(avg_price + TakeProfit, Digits); 
     if(otipe == OP_SELL) tp = NormalizeDouble(avg_price - TakeProfit, Digits);
                              
    for(int i=OrdersTotal()-1; i>=0; i--)
       {  
        if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
          {
           if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic && OrderType()==otipe) 
             {
              if(OrderModify( OrderTicket(), OrderOpenPrice(), 0, tp, 0))
                 Print("ордера успешно модифицированы");                   
            else Print("ошибка модификации ордеров");                                                                                                                                         
            }
          }                                                              
       } 
 }//void ModifyOrders        
//--------------------------------------------------------------- 

 

ScreenShot_marten.png

В тестере есть журнал, в него имеет смысл заглядывать.

В вашем случае не работает модификация ордеров:
image.png.29e5ad7a04f01e9db8bf91b811158295.png

 

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

 

Ошибка в функции ModifyOrders: вы забыли умножить TakeProfit (который в пунктах) на величину пункта.

Замените текст функции вот та это и будет вам счастье:

//----------------------------------------------6) Модифиция TakeProfit
void ModifyOrders(int otipe)  
  {
       double avg_price, order_lots=0;  
       price = 0; 
   
     for(int i=OrdersTotal()-1; i>=0; i--)
        { 
         if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
           {
            if(OrderSymbol()== Symbol() && OrderMagicNumber()==Magic && OrderType()==otipe) 
              {
                price += OrderOpenPrice() *OrderLots();  
                order_lots += OrderLots();  
             }                         
           } 
        }
          
     avg_price = NormalizeDouble(price / order_lots, Digits); 
     if(otipe == OP_BUY)  tp = NormalizeDouble(avg_price + TakeProfit * Point(), Digits); 
     if(otipe == OP_SELL) tp = NormalizeDouble(avg_price - TakeProfit * Point(), Digits);
    for(int i=OrdersTotal()-1; i>=0; i--)
       {  
        if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
          {
           if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic && OrderType()==otipe) 
             {
              if(OrderModify( OrderTicket(), OrderOpenPrice(), 0, tp, 0))
                 Print("ордера успешно модифицированы");                   
            else Print("ошибка модификации ордеров");                                                                                                                                         
            }
          }                                                              
       } 
 }//void ModifyOrders        
//--------------------------------------------------------------- 

 

 

А еще мне кажется, что вот такое условие на первый вход будет куда более логичным для простого мартина:

Спойлер

image.png.5571f58a480c8881e30dce81e4965567.png

 

  • Лайк 3
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
1 час назад, Rigal сказал:

Ошибка в функции ModifyOrders: вы забыли умножить TakeProfit (который в пунктах) на величину пункта.

Да, в журнале видел что твориться. Но не знал что с этим делать. Спасибо большое за решение. Так найти такую мелкую ошибку это "мощно" конечно!

 

1 час назад, Rigal сказал:

А еще мне кажется, что вот такое условие на первый вход будет куда более логичным для простого мартина:

У меня никак не получалось применить изначальный вариант

  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Ваша версия также не позволит использовать нецелые множители с минимальным лотом: если множитель, например, 1.4 - умножаться не будет совсем. А если 1.5 и больше - первое умножение будет на двойку. Второе уже на 1.5 - но в итоге получится тройка, что не соответствует вашим ожиданиям (1.5 в квадрате - это 2.25).

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

MartinLessonX.mq4

Все нужные нам параметры уже открытой позиции мы собираем в одном цикле.

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

Например, я прогнал евродоллар на часе с 2010 случайными настройками:

Спойлер

image.thumb.png.a6ba8281bce4da336643f14e7bd99b58.png

Дерзайте

  • Лайк 1
  • Спасибо 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

 Да это интересно что вы сделали. Надо еще посидеть и сам код/механизм понять.
   Еще к уроку по мартенгейлу было одно из домашних заданий. Добавить внешний параметр MaxOrders и доработать советник таким образом, чтобы он не открывал ордеров больше, чем указано в этой переменной. 
  Это я так понимаю надо писать отдельную функцию, для которой нужен будет либо Стоп-лосс по аналогии с ModifyOrders(где была ошибка). Или считать убыточные ордера. Как думаете что лучше. Мне кажется Стоп-лосс на "вырост"  интересней 

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
33 минуты назад, Ar4i сказал:

 Да это интересно что вы сделали. Надо еще посидеть и сам код/механизм понять.
   Еще к уроку по мартенгейлу было одно из домашних заданий. Добавить внешний параметр MaxOrders и доработать советник таким образом, чтобы он не открывал ордеров больше, чем указано в этой переменной. 
  Это я так понимаю надо писать отдельную функцию, для которой нужен будет либо Стоп-лосс по аналогии с ModifyOrders(где была ошибка). Или считать убыточные ордера. Как думаете что лучше. Мне кажется Стоп-лосс на "вырост"  интересней 

Зачем?
У вас уже есть функция, которая считает, сколько ордеров открыто - вы ее в самом начале вызываете, сразу после машки.
Если ордеров больше, или равно заданному ограничению - можно просто выходить из OnTick сразу.

  • Спасибо 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

    Вы наверное имеете в виду if(CountTrades()==0) изменить ее допустим на if(CountTrades()<3)..?  

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

Изменено пользователем Ar4i
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
56 минут назад, Ar4i сказал:

Вы наверное имеете в виду if(CountTrades()==0) изменить ее допустим на if(CountTrades()<3)..?  

Я имею в виду

int countTrades = CountTrades();

if(countTrades >= MaxOrders)

   return;

if(countTrades == 0)... ну и далее по тексту.

58 минут назад, Ar4i сказал:

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

Это сильно другая задача. Тоже решаемая, конечно. Много занятностей. Например, сколько сделок у вас будет октрыто одновременно зависит от взаимного отношения величины шага, тейка и стопа. И нужно продумать и выписать, как вы будете обрабатывать набор открытых позиций и те, что закрылись, в профит, или в убыток.

Как я уже сказал: дерзайте. Дорогу осилит идущий.

  • Спасибо 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

 А если так? Я вижу что мне нужна одна функция Lot() которую я вставлю прямо в OrderSend. А в этой функции уже будет расчет мартенгейла. То есть если подряд  ряд проигрышей(MaxOrders) лот увеличивается. Иначе, если плюс - то лот базовый

Изменено пользователем Ar4i
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
В 08.12.2023 в 12:09, Ar4i сказал:

 А если так? Я вижу что мне нужна одна функция Lot() которую я вставлю прямо в OrderSend. А в этой функции уже будет расчет мартенгейла. То есть если подряд  ряд проигрышей(MaxOrders) лот увеличивается. Иначе, если плюс - то лот базовый

Вы, возможно, не прочитали. Или пока не поняли.

Но вы пробуйте, тестируйте в визуале - станет понятнее.

  • Спасибо 1
Ссылка на сообщение
Поделиться на другие сайты

  • 5 weeks later...
Обучение языку MQL4 под MetaTrader 4 Опубликовано

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

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
6 часов назад, diodio сказал:

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

А что вы хотели заметить?

Есть смысл приводить фрагменты кода. Иначе сложно сориентироваться, чего вы ждете.

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Подскажите, плиз, как перевести своп из валюты в пункты.

 

Допустим, на фунте у меня стоит тейк на бай на 1.27618.
При этом накопился своп, например, -245. Это на центовом счете.

И я бы хотела пересчитать тейк, увеличив его на сумму свопа.
Вот как перевести сумму свопа в нужные пункты? )) На этом конкретном примере.


Заранее извиняюсь за дилетантство.

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
11 часов назад, neurolynx сказал:

Подскажите, плиз, как перевести своп из валюты в пункты.

 

Допустим, на фунте у меня стоит тейк на бай на 1.27618.
При этом накопился своп, например, -245. Это на центовом счете.

И я бы хотела пересчитать тейк, увеличив его на сумму свопа.
Вот как перевести сумму свопа в нужные пункты? )) На этом конкретном примере.


Заранее извиняюсь за дилетантство.

У пункта есть цена:
double tickvalue = SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE);

 

Такую прибыль сделка объемом один лот приносит на пробег длиной TickSize (как правило Point(), но лучше опереться на настоящую величину SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_SIZE);

 

Соответственно, вам нужно подвинуть тейк на 


 

double delta = -OrderSwap() / SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE) / OrderLots() * SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_SIZE);
double new_tp = NormalizeDouble(OrderTakeProfit() + delta, Digits);

 

  • Лайк 1
  • Огонь! 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
8 часов назад, Rigal сказал:

 

double delta = -OrderSwap() / SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE) / OrderLots() * SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_SIZE);
double new_tp = NormalizeDouble(OrderTakeProfit() + delta, Digits);

 

 

Спасибо огромное, я чем больше читала об этом вопросе, тем больше запутывалась. Теперь стало понятно. 

 

Ну... и раз уж вы отвечаете...

 

Мне бы хотелось сделать визуальную линию безубытка, как у вас в Ступидо - золотую двойную )) Безубыток у меня посчитан и назван, допустим для наглядности, golden line. 

 

Вы не могли бы помочь с этим кусочком кода? Я нашла в интернете несколько вариантов (еще не пробовала), но они все очень громоздкие, там много лишнего, сделанного на всякий случай.

Изменено пользователем neurolynx
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
13 часов назад, neurolynx сказал:

 

Спасибо огромное, я чем больше читала об этом вопросе, тем больше запутывалась. Теперь стало понятно. 

 

Ну... и раз уж вы отвечаете...

 

Мне бы хотелось сделать визуальную линию безубытка, как у вас в Ступидо - золотую двойную )) Безубыток у меня посчитан и назван, допустим для наглядности, golden line. 

 

Вы не могли бы помочь с этим кусочком кода? Я нашла в интернете несколько вариантов (еще не пробовала), но они все очень громоздкие, там много лишнего, сделанного на всякий случай.

В этой задаче двумя строчками не обойдешься. Я поэтому накидал пример советника, который:

  • При инициализации создает три объекта линий: покупки, продажи, полная совокупность. Есть стандартная библиотека в метатрейдере, ChartObjects/ChartObjectsLines.mqh - сильно упрощает работу с линиями. В той же папочке куча оберток для других графических объектов, можно покопаться. К сожалению, документировано оно неидеально
  • При де-инициализации он их удалит с графика
  • Реализован один метод, который посчитает безубыток покупок, продаж и общий.
    • Если нет покупок - линия спрячется (убираем ее на уровень цены 0.0)
    • То же самое для продаж
    • Общий безубыток рисуется только если есть и покупки и продажи и их вес отличается (если он равен - это хедж и у нас нет точки, где вся позиция выйдет в безубыток: куда бы ни пошла цена - нам становится только хуже от копящихся свопов). В противном случае тоже прячем в ноль
  • Метод принимает магик в качестве аргумента, по умолчанию -1. Если передать магик - посчитает только для позиций с этим магиком.

Я там немного накомментировал по тексту. Например, формулы для расчета безубытка явно пометил.

 

Все считается с учетом свопов и комиссий.

 

Занятное оказалось упражнение. Я все это уже года три назад реализовал в библиотеки и забыл довольно прочно :)

 

ChartLineSandbox.mq4

Изменено пользователем Rigal
  • Лайк 1
  • Огонь! 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
12 часов назад, Rigal сказал:

В этой задаче двумя строчками не обойдешься.

Спасибо большое, буду со старанием вникать. Хотя выражения типа "double profit[2] = {0.0, 0.0}" для меня за гранью пока что. Квадратные скобочки - это я вообще в первый раз встречаю в коде )) Гугл говорит, что это для индексации массивов. Ух! Я программирование изучала с полного нуля сугубо по урокам этого форума, думала, что этого хватит )) Спасибо вам огромное еще раз!

 

 

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
13 часов назад, neurolynx сказал:

Спасибо большое, буду со старанием вникать. Хотя выражения типа "double profit[2] = {0.0, 0.0}" для меня за гранью пока что. Квадратные скобочки - это я вообще в первый раз встречаю в коде )) Гугл говорит, что это для индексации массивов. Ух! Я программирование изучала с полного нуля сугубо по урокам этого форума, думала, что этого хватит )) Спасибо вам огромное еще раз!

 

 

Если опереться вот прямо на тот вопрос, что вы исходно задали, вот на этот:

 

 

В 12.01.2024 в 23:48, neurolynx сказал:

Мне бы хотелось сделать визуальную линию безубытка, как у вас в Ступидо - золотую двойную )) Безубыток у меня посчитан и назван, допустим для наглядности, golden line

То код будет выглядеть гораздо проще:

#include <ChartObjects/ChartObjectsLines.mqh>

CChartObjectHLine breakEvenTotalLine;

int OnInit() {
  /*
  что там у вас уже в OnInit
  */
   breakEvenTotalLine.Create(0, "BreakevenTotalLine", 0, 0.0);
   breakEvenTotalLine.Width(2);
   breakEvenTotalLine.Color(clrGold);
   breakEvenTotalLine.Description("Total breakeven");
}
  
void OnDeinit(const int reason){
  /*
  что там у вас уже в OnDeinit
  */
   breakEvenTotalLine.Delete();  
}

void OnTick() {
  /*
  что там у вас уже в OnTick
  */
  breakEvenTotalLine.Price(0, goldenLine); //вот тут мы передвигаем линию в посчитанную позицию goldenLine
}

 

Что касается массивов в моем коде: я просто считаю нужные мне величины для покупок и продаж за один цикл перебора по ордерам. В этом здорово помогает тот факт, что константа типа ордера покупок (OP_BUY) равна нулю, а продаж - единице. То есть мы можем просто завести переменную в виде массива из двух элементов и обращаться к "покупковой" и "продажной" части просто по типу ордера.

 

Скажем, мне нужно посчитать плавающую прибыль по покупкам и продажам раздельно, а также общую.
Это можно завести две разных переменных, profitBuy и profitSell, а внутри цикла делать if(OrderType() == OP_BUY) profitBuy += OrderProfit(); else profitSell += OrderProfit();

 

Или сделать, как я: завели массив profit из двух элементов. Нулевой - покупки, первый - продажи.
И тогда profit[OrderType()] += OrderProfit();

Компактнее и меньше шансов на ошибку, особенно в более сложных конструкциях.

 

если уложить эту технику в голове, то дальше из нее вырастает множество красивых конструкций-сверток.

Например, объявим массив "знака":

int sgn[2] = {1, -1};

 

Теперь, чтобы выставить тейк у открытого ордера на расстояние tp от цены открытия, можно написать:

   OrderModify(OrderTicket(), 
               OrderOpenPrice(), 
               OrderStopLoss(), 
               NormalizeDouble(OrderOpenPrice() + sgn[OrderType()] * tp, Digits));

И мы получим тейк для покупок на tp выше цены открытия, а для продаж - ниже

 

или, например, проверить пересечение машки ценой... Скажем, мы хотим для продаж поймать момент, когда цена пересекает машку снизу вверх, а для покупок - сверху вниз (ну просто для примера).

Предположим, закрытие последнего бара у нас в переменной close, а машка в переменной ma.

 

И вот мы выбираем некий ордер и в типичном подходе мы напишем:

if(OrderType() == OP_BUY) {
	if(close < ma)
      Print("MA Crossed");
} else {
	if(close > ma)
      Print("MA Crossed");
}

Используя трюк с sgn[OrderType()] это можно свернуть вот в такую простенькую проверку

if(sgn[OrderType()] * (ma - close) > 0)
	Print("MA Crossed");

Для покупок выполнится только если ma > close, для продаж - только если close > ma

  • Лайк 1
  • Спасибо 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
8 часов назад, Rigal сказал:

Если опереться вот прямо на тот вопрос, что вы исходно задали, вот на этот

То код будет выглядеть гораздо проще

Большущее спасибо за упрощение )) Вникать было долго, а безубыток хочется видеть "прям счас".

 

Кроме шуток, вы не думали написать руководство по mql? Для чайников, желательно ))

  • Лол 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
13 часов назад, neurolynx сказал:

Кроме шуток, вы не думали написать руководство по mql? Для чайников, желательно )

Нет, спасибо.

Много времени, и чукча больше читатель. Я сдуюсь на первой главе.

 

Ну и программирование на mql от программирования на, например, С++, отличается довольно небогатым API метатрейдера. Все остальное уже написано для чайников для множества языков программирования.

  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

  • 2 weeks later...
Обучение языку MQL4 под MetaTrader 4 Опубликовано
В 15/4/2021 в 12:21, Lexa000 сказал:

Locomotora v1.01 (7).mq4 56,99\u043a\u0411 · 11 descargas

Necesito colocar una cabina en la locomotora, pero estoy confundido. ¿Alguien puede decirme cómo hacer esto más fácilmente? ¿Debo crear una regla separada o cómo debo escribir variables?

EA - Budak Ubat v1.51.mq4 44.16\u043a\u0411 · 18 descargas

Do you have v1.62 mql4?

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
20 минут назад, Lexa000 сказал:

Easier in what sense?

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
22 часа назад, estebaanm98 сказал:

Easier in what sense?

MarketInsider_v1.2.ex4 Для этого индикатора нужна регистрация на сайте продавца, без регистрации советник торговать не будет

Ссылка на сообщение
Поделиться на другие сайты

  • 3 months later...
Обучение языку MQL4 под MetaTrader 4 Опубликовано

Доброго дня!  Может кто научить как реализовать возможность управление советником с одного терминала - советником второго терминала??? Или кто то встречал подобную реализацию или подскажите где копать.  Суть такая. На одном терминале первый советник строит сетку ордеров. Когда советник открывает например шестую сделку, то он должен отправить команду другому советнику стоящему на другом счете, другом терминале, о том что можно открывать первую сделку по той же паре. Классический копировальщик тут как то не подошел.. Любая информация во благо!!!

Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

  • Специальное предложение


  • Рекомендуемые брокеры

  • ×
    ×
    • Создать...