помочь с кодом для эксперта - страница 2

 

Скомпоновал коды и исправил ошибку в своём коде:

//+------------------------------------------------------------------+
//|                                                         Test.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//---
#include<Trade\Trade.mqh>        // подключаем CTrade - торговый класс стандартной библиотеки
// Переменные, изменяемые программно
int            Corr;             // автоматический корректор котировок, 10 для 5-значных котировок и 1 для 4-значных
int            TwoDigCorr;       // корректор для работы с двухзначными котировками
bool           New_Bar=false;    // флаг образования нового бара
int            Oppoz;            // флаг выставления противоположной отложки при СЛ
int            TradeFlag;        // флаг возможности открытия сделок
//--- input parameter
input double   InpPips=20;
input double   Lot=0.01;
//---
CTrade         my_trade;         // объект класса CTrade
bool           first_start=true; // флаг первого старта
double         ExtLot=0;         // значение лота
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
// Проверка необходимых для работы условий
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
      Alert("Проверьте в настройках терминала разрешение на автоматическую торговлю!");
   else
     {
      if(!MQLInfoInteger(MQL_TRADE_ALLOWED))
         Alert("Автоматическая торговля запрещена в свойствах программы для ",__FILE__);
     }

   if(!AccountInfoInteger(ACCOUNT_TRADE_EXPERT))
      Alert("Автоматическая торговля запрещена для счета ",AccountInfoInteger(ACCOUNT_LOGIN),
            " на стороне торгового сервера");

   if(!AccountInfoInteger(ACCOUNT_TRADE_ALLOWED))
      Comment("Торговля запрещена для счета ",AccountInfoInteger(ACCOUNT_LOGIN),
              ".\n Возможно, подключение к торговому счету произведено по инвест паролю.",
              "\n Проверьте журнал терминала, есть ли там такая запись:",
              "\n\'",AccountInfoInteger(ACCOUNT_LOGIN),"\': trading has been disabled - investor mode.");

// Проверка пользовательских объемов
   double Mlot=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
   if(Lot<Mlot)
     {
      Alert("Недопустимо маленькое значение объема сделок. Объем установлен на допустимый минимум!");
      Print("Недопустимо маленькое значение объема сделок. Объем установлен на допустимый минимум!");
      ExtLot=Mlot;
     }
   else
      ExtLot=Lot;
// Инициализация первичных данных
   if(Point()==0.0001)
      Corr=1;
   else
      Corr=10;

   if(Digits()==2)
      TwoDigCorr=10;
   else
      TwoDigCorr=1;

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   static double prev_price=0;
   double price=0;
//---
   MqlTick last_tick;
//--- 
   if(!first_start)
     {
      if(SymbolInfoTick(Symbol(),last_tick))
        {
         price=last_tick.bid;

         double temp=prev_price-price;
         double rezult=temp*MathPow(10,Digits());
         prev_price=price;

         if(rezult>InpPips)
           {
            my_trade.Buy(ExtLot);// открываем бай
           }
        }
      else
         Print("SymbolInfoTick() failed, error = ",GetLastError());
     }
  }
//+------------------------------------------------------------------+

Здесь вводится переменная "ExtLot" - в ней и будет храниться минимальный объём. Также, для удобства и облегчения написания торговых операций выполнено подключение класса CTrade - торгового класса стандартной библиотеки.

Файлы:
Test.mq5  8 kb
 
Karputov Vladimir:

Чтобы получить из цены пункты нужно разницу между двумя ценами умножить на 10 в степени Digits(). Для примера имеем две цены: 1.20302 и 1.20281. Как видите здесь пять разрядов после запятой. Разница между этими двумя ценами будет равна 0.00021. Чтобы перевести 0.00021 в пункты, нужно это число умножить на 10 в степени 5:

rezult==21.

Ещё можно и десятичный логарифм прикрутить...

double pnt=_Point;
double log10_val=MathLog10(pnt);
double temp=NormalizeDouble(1.20302-1.20281,_Digits);
double rezult=temp*MathPow(10,-1.*log10_val);

Но зачем так сложно? :-))

Когда проще так:

temp=NormalizeDouble(1.20302-1.20281,_Digits);
double new_res=temp;
if(_Point>0.)
   new_res=temp/_Point;
 

Кирил посмотрите вот эту коду  ,думаю она вас заинтересует,,,,,,,,, https://www.mql5.com/ru/code/9049

как прикрутить уже готовое на много проще объяснить

NDA_e
NDA_e
  • голосов: 7
  • 2016.06.14
  • //www.mql5.com/ru/users/satop">
  • www.mql5.com
Индикатор, позволяющий визуально и на слух контролировать скорость прохождения тика и их объемы
 
Dennis Kirichenko:

Ещё можно и десятичный логарифм прикрутить...

Но зачем так сложно? :-))

Когда проще так:

Дык... ноу-хау :))))

А потом люди думают - чего это индикаторы тормозят так...

Ну да ладно. "Секрет" про /Point() раскрыт. А жаль... народ следил затаив дыхание...

 
Artyom Trishkin:

Дык... ноу-хау :))))

А потом люди думают - чего это индикаторы тормозят так...

Ну да ладно. "Секрет" про /Point() раскрыт. А жаль... народ следил затаив дыхание...

Индикаторы тормозят если делать неэкономный пересчёт на каждом тики :). А про скорость выполнения - так Вам и карты в руки - сказали "А", говорит и "Б" - приведите тест скорости выполнения с двумя вариантами кода (с MathPow и с делением на Point()).
 
Karputov Vladimir:
Индикаторы тормозят если делать неэкономный пересчёт на каждом тики :). А про скорость выполнения - так Вам и карты в руки - сказали "А", говорит и "Б" - приведите тест скорости выполнения с двумя вариантами кода (с MathPow и с делением на Point()).
   double result=Point()>0?(prev_price-price)/Point():0;

Проводить эксперименты - вы же любите. Проведите. У меня на это времени нету к сожалению.

 
Artyom Trishkin:

Проводить эксперименты - вы же любите. Проведите. У меня на это времени нету к сожалению.

Я таки провёл серию тестов - результаты оказались очень интересные. Сравниваются три вида вычисления дельты между двумя ценами:

//+------------------------------------------------------------------+
//|                                                         Test.mq5 |
//|                              Copyright © 2016, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.000"
#property script_show_inputs
//---
input bool reverse=false;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   Print("");
   int lim=2147483647;
   ulong ul=0;
   if(!reverse)
     {
      ul=GetMicrosecondCount();
      func1(lim);
      Print("MathPow : ",GetMicrosecondCount()-ul," msec\n");

      ul=GetMicrosecondCount();
      func2(lim);
      Print("/Point : ",GetMicrosecondCount()-ul," msec\n");

      ul=GetMicrosecondCount();
      func3(lim);
      Print("? : ",GetMicrosecondCount()-ul," msec\n");
     }
   else
     {
      ul=GetMicrosecondCount();
      func3(lim);
      Print("? : ",GetMicrosecondCount()-ul," msec\n");

      ul=GetMicrosecondCount();
      func2(lim);
      Print("/Point : ",GetMicrosecondCount()-ul," msec\n");

      ul=GetMicrosecondCount();
      func1(lim);
      Print("MathPow : ",GetMicrosecondCount()-ul," msec\n");
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void func1(const int limit)
  {
   int count=0;
   int count_error=0;   // колчиство ошибок при которых result==0
   for(int i=0;i<limit;i++)
     {
      count=i;
      double temp=1.20302-1.20281;
      double rezult=temp*MathPow(10,Digits());
      if(rezult==0)
         count_error++;
     }
   Print(count,", error: ",count_error);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void func2(const int limit)
  {
   int count=0;
   int count_error=0;   // колчиство ошибок при которых result==0
   for(int i=0;i<limit;i++)
     {
      count=i;
      double temp=NormalizeDouble(1.20302-1.20281,Digits());
      double rezult=temp;
      if(Point()>0.0)
         rezult=temp/Point();
      if(rezult==0)
         count_error++;
     }
   Print(count,", error: ",count_error);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void func3(const int limit)
  {
   int count=0;
   int count_error=0;   // колчиство ошибок при которых result==0
   for(int i=0;i<limit;i++)
     {
      count=i;
      double rezult=(Point()>0.0) ?((1.20302-1.20281)/Point()) : 0;
      if(rezult==0)
         count_error++;
     }
   Print(count,", error: ",count_error);
  }
//+------------------------------------------------------------------+

Результаты:

2016.09.27 13:37:32.278 Test (GBPAUD,M5)        2147483646, error: 0
2016.09.27 13:37:32.278 Test (GBPAUD,M5)        MathPow : 134889270 msec
2016.09.27 13:37:32.278 Test (GBPAUD,M5)        
2016.09.27 13:37:57.687 Test (GBPAUD,M5)        2147483646, error: 0
2016.09.27 13:37:57.687 Test (GBPAUD,M5)        /Point : 25409297 msec
2016.09.27 13:37:57.687 Test (GBPAUD,M5)        
2016.09.27 13:37:57.688 Test (GBPAUD,M5)        2147483646, error: 0
2016.09.27 13:37:57.688 Test (GBPAUD,M5)        ? : 6 msec
2016.09.27 13:37:57.688 Test (GBPAUD,M5)        

 

Самый мегаскоростной метод оказался:

double rezult=(Point()>0.0) ?((1.20302-1.20281)/Point()) : 0;

выполняется можно сказать мгновенно.

Файлы:
Test.mq5  7 kb
 

Наглядно приведено.

Единственно, всё же упомяну, что мне не удалось представить ситуацию в "реале", когда тот же MathPow(10,Digits()) требовалось бы вызывать в цикле каждый раз "по новой". /*Это ни в коей мере не какой-либо упрёк или "подколка" с моей стороны. "На скорую руку" приближенное к "идеальному" сложно сконструировать.*/ .

Поэтому я чуток изменила тестовый код. В т.ч., убрала функцию func2.

Вариант с моими изменениями так же "на скорую руку" и так же не идеален.

#property version   "1.001"
#property script_show_inputs
//---
input bool    i_reverse=false;
input double  i_value_1=1.20302;
input double  i_value_2=1.20281;
//---
double g_point_pow;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   int   lim=2147483647;
   ulong ul=0;
//---
   g_point_pow=MathPow(10,Digits());
//---
   if(!i_reverse)
     {
      ul=GetMicrosecondCount();
      func1(lim,i_value_1,i_value_2,g_point_pow);
      Print("MathPow : ",GetMicrosecondCount()-ul," msec\n");
      //---
      ul=GetMicrosecondCount();
      func3(lim,i_value_1,i_value_2);
      Print("? : ",GetMicrosecondCount()-ul," msec\n");
     }
   else
     {
      ul=GetMicrosecondCount();
      func3(lim,i_value_1,i_value_2);
      Print("? : ",GetMicrosecondCount()-ul," msec\n");
      //---
      ul=GetMicrosecondCount();
      func1(lim,i_value_1,i_value_2,g_point_pow);
      Print("MathPow : ",GetMicrosecondCount()-ul," msec\n");
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void func1(const int    limit,
           const double value_1,
           const double value_2,
           const double point_pow)
  {
   double result=0;
   int    count=0;
   int    count_error=0;   // количество ошибок при которых result==0
//---
   for(int i=0;i<limit;i++)
     {
      count=i;
      result=MathAbs((value_1-value_2)*point_pow);
      //---
      if(result==0){count_error++;}
     }
   Print(count,", error: ",count_error);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void func3(const int    limit,
           const double value_1,
           const double value_2)
  {
   double result=0;
   int    count=0;
   int    count_error=0;   // количество ошибок при которых result==0
//---
   for(int i=0;i<limit;i++)
     {
      count=i;
      result=(Point()>0.0) ? MathAbs((value_1-value_2)/Point()) : 0;
      //---
      if(result==0){count_error++;}
     }
   Print(count,", error: ",count_error);
  }
//+------------------------------------------------------------------+

Результаты при замерах получаются "зависимыми" от i_reverse:

Если i_reverse=false:

2016.09.28 02:01:45.079 Test__3 (EURAUD,M3)     ? : 9 msec
2016.09.28 02:01:45.079 Test__3 (EURAUD,M3)     2147483646, error: 0

2016.09.28 02:01:45.079 Test__3 (EURAUD,M3)     MathPow : 39 msec
2016.09.28 02:01:45.079 Test__3 (EURAUD,M3)     2147483646, error: 0

Если i_reverse=true:

2016.09.28 02:01:53.783 Test__3 (EURAUD,M3)     MathPow : 8 msec
2016.09.28 02:01:53.783 Test__3 (EURAUD,M3)     2147483646, error: 0

2016.09.28 02:01:53.783 Test__3 (EURAUD,M3)     ? : 39 msec
2016.09.28 02:01:53.783 Test__3 (EURAUD,M3)     2147483646, error: 0
При этом (при неоднократных замерах) количество msec может немного различаться от приведённых цифр.


 
Karputov Vladimir:

Я таки провёл серию тестов - результаты оказались очень интересные. Сравниваются три вида вычисления дельты между двумя ценами:

Результаты:

 

Самый мегаскоростной метод оказался:

выполняется можно сказать мгновенно.

такая мегаскорость наводит на мысль об ошибочно поставленном эксперименте 
 
Artyom Trishkin:

Дык... ноу-хау :))))

P./S.: Артём, sorry, но применение MathPow(10,Digits()) для получения разницы в пунктах - так-то не ноу-хау.

Я, например, давно такое применяю. /* По тому же символу - так это один раз вычисление в OnInit(), затем расчёты на основе вычисленного значения при новом баре. Т.е., и дальнейшие вычисления - не на каждом тике. <=Это просто уточнение, в связи с тем, что в своей практике не применяла никаким из вышеприведённых способов расчёты на каждом тике.*/

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

P./S.: Если память мне не изменяет, и у тебя где-то это встречалось на четвёртом(?) форуме. Но, насколько помню, не MathPow(), а аналог этой функции (pow()).


Хотя может я в чём-то тебя не поняла в текущей теме.

Причина обращения: