//+------------------------------------------------------------------+//| 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 parameterinputdouble InpPips=20;
inputdouble Lot=0.01;
//---
CTrade my_trade; // объект класса CTradebool first_start=true; // флаг первого стартаdouble ExtLot=0; // значение лота//+------------------------------------------------------------------+//| expert initialization function |//+------------------------------------------------------------------+intOnInit()
{
// Проверка необходимых для работы условий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 |//+------------------------------------------------------------------+voidOnTick()
{
//---staticdouble 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);// открываем бай
}
}
elsePrint("SymbolInfoTick() failed, error = ",GetLastError());
}
}
//+------------------------------------------------------------------+
Здесь вводится переменная "ExtLot" - в ней и будет храниться минимальный объём. Также, для удобства и облегчения написания торговых операций выполнено подключение класса CTrade - торгового класса стандартной библиотеки.
Чтобы получить из цены пункты нужно разницу между двумя ценами умножить на 10 в степени Digits(). Для примера имеем две цены: 1.20302 и 1.20281. Как видите здесь пять разрядов после запятой. Разница между этими двумя ценами будет равна 0.00021. Чтобы перевести 0.00021 в пункты, нужно это число умножить на 10 в степени 5:
А потом люди думают - чего это индикаторы тормозят так...
Ну да ладно. "Секрет" про /Point() раскрыт. А жаль... народ следил затаив дыхание...
Индикаторы тормозят если делать неэкономный пересчёт на каждом тики :). А про скорость выполнения - так Вам и карты в руки - сказали "А", говорит и "Б" - приведите тест скорости выполнения с двумя вариантами кода (с MathPow и с делением на Point()).
Karputov Vladimir: Индикаторы тормозят если делать неэкономный пересчёт на каждом тики :). А про скорость выполнения - так Вам и карты в руки - сказали "А", говорит и "Б" - приведите тест скорости выполнения с двумя вариантами кода (с MathPow и с делением на Point()).
2016.09.2713:37:32.278 Test (GBPAUD,M5) 2147483646, error: 02016.09.2713:37:32.278 Test (GBPAUD,M5) MathPow : 134889270 msec
2016.09.2713:37:32.278 Test (GBPAUD,M5)
2016.09.2713:37:57.687 Test (GBPAUD,M5) 2147483646, error: 02016.09.2713:37:57.687 Test (GBPAUD,M5) /Point : 25409297 msec
2016.09.2713:37:57.687 Test (GBPAUD,M5)
2016.09.2713:37:57.688 Test (GBPAUD,M5) 2147483646, error: 02016.09.2713:37:57.688 Test (GBPAUD,M5) ? : 6 msec
2016.09.2713:37:57.688 Test (GBPAUD,M5)
Единственно, всё же упомяну, что мне не удалось представить ситуацию в "реале", когда тот же MathPow(10,Digits()) требовалось бы вызывать в цикле каждый раз "по новой". /*Это ни в коей мере не какой-либо упрёк или "подколка" с моей стороны. "На скорую руку" приближенное к "идеальному" сложно сконструировать.*/ .
Поэтому я чуток изменила тестовый код. В т.ч., убрала функцию func2.
Вариант с моими изменениями так же "на скорую руку" и так же не идеален.
#property version"1.001"#property script_show_inputs//---inputbool i_reverse=false;
inputdouble i_value_1=1.20302;
inputdouble i_value_2=1.20281;
//---double g_point_pow;
//+------------------------------------------------------------------+//| Script program start function |//+------------------------------------------------------------------+voidOnStart()
{
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(constint limit,
constdouble value_1,
constdouble value_2,
constdouble 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(constint limit,
constdouble value_1,
constdouble 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:
P./S.: Артём, sorry, но применение MathPow(10,Digits()) для получения разницы в пунктах - так-то не ноу-хау.
Я, например, давно такое применяю. /* По тому же символу - так это один раз вычисление в OnInit(), затем расчёты на основе вычисленного значения при новом баре. Т.е., и дальнейшие вычисления - не на каждом тике. <=Это просто уточнение, в связи с тем, что в своей практике не применяла никаким из вышеприведённых способов расчёты на каждом тике.*/
После того, как путём "проб и ошибок" открыла для себя такой способ, обнаружила на четвёртом форуме, что и я являюсь далеко не первооткрывателем в этом.
P./S.: Если память мне не изменяет, и у тебя где-то это встречалось на четвёртом(?) форуме. Но, насколько помню, не MathPow(), а аналог этой функции (pow()).
Хотя может я в чём-то тебя не поняла в текущей теме.
Скомпоновал коды и исправил ошибку в своём коде:
Здесь вводится переменная "ExtLot" - в ней и будет храниться минимальный объём. Также, для удобства и облегчения написания торговых операций выполнено подключение класса CTrade - торгового класса стандартной библиотеки.
Чтобы получить из цены пункты нужно разницу между двумя ценами умножить на 10 в степени Digits(). Для примера имеем две цены: 1.20302 и 1.20281. Как видите здесь пять разрядов после запятой. Разница между этими двумя ценами будет равна 0.00021. Чтобы перевести 0.00021 в пункты, нужно это число умножить на 10 в степени 5:
rezult==21.
Ещё можно и десятичный логарифм прикрутить...
Но зачем так сложно? :-))
Когда проще так:
Кирил посмотрите вот эту коду ,думаю она вас заинтересует,,,,,,,,, https://www.mql5.com/ru/code/9049
как прикрутить уже готовое на много проще объяснить
Ещё можно и десятичный логарифм прикрутить...
Но зачем так сложно? :-))
Когда проще так:
Дык... ноу-хау :))))
А потом люди думают - чего это индикаторы тормозят так...
Ну да ладно. "Секрет" про /Point() раскрыт. А жаль... народ следил затаив дыхание...
Дык... ноу-хау :))))
А потом люди думают - чего это индикаторы тормозят так...
Ну да ладно. "Секрет" про /Point() раскрыт. А жаль... народ следил затаив дыхание...
Индикаторы тормозят если делать неэкономный пересчёт на каждом тики :). А про скорость выполнения - так Вам и карты в руки - сказали "А", говорит и "Б" - приведите тест скорости выполнения с двумя вариантами кода (с MathPow и с делением на Point()).
Проводить эксперименты - вы же любите. Проведите. У меня на это времени нету к сожалению.
Проводить эксперименты - вы же любите. Проведите. У меня на это времени нету к сожалению.
Я таки провёл серию тестов - результаты оказались очень интересные. Сравниваются три вида вычисления дельты между двумя ценами:
Результаты:
Самый мегаскоростной метод оказался:
выполняется можно сказать мгновенно.
Наглядно приведено.
Единственно, всё же упомяну, что мне не удалось представить ситуацию в "реале", когда тот же MathPow(10,Digits()) требовалось бы вызывать в цикле каждый раз "по новой". /*Это ни в коей мере не какой-либо упрёк или "подколка" с моей стороны. "На скорую руку" приближенное к "идеальному" сложно сконструировать.*/ .
Поэтому я чуток изменила тестовый код. В т.ч., убрала функцию func2.
Вариант с моими изменениями так же "на скорую руку" и так же не идеален.
Результаты при замерах получаются "зависимыми" от i_reverse:
Если i_reverse=false:
Если i_reverse=true:
При этом (при неоднократных замерах) количество msec может немного различаться от приведённых цифр.Я таки провёл серию тестов - результаты оказались очень интересные. Сравниваются три вида вычисления дельты между двумя ценами:
Результаты:
Самый мегаскоростной метод оказался:
выполняется можно сказать мгновенно.
Дык... ноу-хау :))))
P./S.: Артём, sorry, но применение MathPow(10,Digits()) для получения разницы в пунктах - так-то не ноу-хау.
Я, например, давно такое применяю. /* По тому же символу - так это один раз вычисление в OnInit(), затем расчёты на основе вычисленного значения при новом баре. Т.е., и дальнейшие вычисления - не на каждом тике. <=Это просто уточнение, в связи с тем, что в своей практике не применяла никаким из вышеприведённых способов расчёты на каждом тике.*/
После того, как путём "проб и ошибок" открыла для себя такой способ, обнаружила на четвёртом форуме, что и я являюсь далеко не первооткрывателем в этом.
P./S.: Если память мне не изменяет, и у тебя где-то это встречалось на четвёртом(?) форуме. Но, насколько помню, не MathPow(), а аналог этой функции (pow()).
Хотя может я в чём-то тебя не поняла в текущей теме.