Jump to content
Programmer

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

Recommended Posts

ZeleBoba

Подскажите пожалуйста, что-то туплю

есть функция в которую в качестве аргумента может передаваться массив, но не всегда.

как внутри функции проверить, что произошло обращение с массивом, а не без него ?

 

// возможные варианты вызова

int arrA[10];

вариант 1: func( NULL );
вариант 2: func( arrA );

 

// функция с параметром-массивом
void func( int &arr[] )
  { if( <???> == NULL )
      { // действие 1 }
    else
      { // действие 2 }
  }
  


Лучше маленький профит, чем большие рога.

Share this post


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

как внутри функции проверить, что произошло обращение с массивом, а не без него ?

Вы так не передадите, но можно написать 2 разных функции для массива и переменной 

 

// функция с параметром-массивом
void func( int &arr[] )
  { 
    // действие 2
  }
  
// функция с параметром-переменной
void func( int var )
  { 
    // действие 2
  }
 


1

Share this post


Link to post
Share on other sites
ZeleBoba
Posted (edited)
37 минут назад, AntFX сказал:

2 разных функции для массива и переменной 

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

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

Т.е. действие по условию "массив или нет" очень незначительное по объему кода, а остальная часть функции весьма велика.

Видимо придется делать доп.функцию-надстройку.

 

Edited by ZeleBoba

Лучше маленький профит, чем большие рога.

Share this post


Link to post
Share on other sites
ZeleBoba

Оч. жаль, что в MQL нет способа проверить на валидность указатель, полученный функцией, в качестве аргумента (параметра),

ну, или просто проверить указатель массива.


Лучше маленький профит, чем большие рога.

Share this post


Link to post
Share on other sites
AntFX
Posted (edited)
3 часа назад, ZeleBoba сказал:

Оч. жаль, что в MQL нет способа проверить на валидность указатель, полученный функцией, в качестве аргумента (параметра),

ну, или просто проверить указатель массива.

Начать можно с того, что в МКЛ нет указателей. Есть только дескрипторы, и только для объектов. 

Закончить можно тем, что Вы сами не понимаете, чего хотите. Попробуйте сделать такое на том же С++, покажите результат.

Edited by AntFX

1

Share this post


Link to post
Share on other sites
laxander
5 часов назад, ZeleBoba сказал:

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

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

Т.е. действие по условию "массив или нет" очень незначительное по объему кода, а остальная часть функции весьма велика.

Видимо придется делать доп.функцию-надстройку.

 

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

Share this post


Link to post
Share on other sites
laxander
10 минут назад, AntFX сказал:

Начать можно с того, что в МКЛ нет указателей. Есть только дескрипторы, и только для объектов. 

Закончить можно тем, что Вы сами не понимаете, чего хотите. Попробуйте сделать такое на том же С++, покажите результат.

В чем проблема сделать такое в С++? Ну в смысле передать указатель на массив, в теле функции проанализировать его на NULL и в зависимости от этого плясать дальше.

  • Upvote 1

Share this post


Link to post
Share on other sites
AntFX
Только что, laxander сказал:

В чем проблема сделать такое в С++? Ну в смысле передать указатель на массив, в теле функции проанализировать его на NULL и в зависимости от этого плясать дальше.

В одну и ту же функцию передать указатель, который может быть и простым int, и указателем на массив? Ну может быть и возможно, я давно на "чистом" С++ не писал. Но мне кажется там все равно проблемы при попытке это сделать будут, поэтому и попросил привести конкретный код. Тогда как минимум стало бы понятно, что конкретно и как предполагается сделать.


1

Share this post


Link to post
Share on other sites
laxander
4 минуты назад, AntFX сказал:

В одну и ту же функцию передать указатель, который может быть и простым int, и указателем на массив? Ну может быть и возможно, я давно на "чистом" С++ не писал. Но мне кажется там все равно проблемы при попытке это сделать будут, поэтому и попросил привести конкретный код. Тогда как минимум стало бы понятно, что конкретно и как предполагается сделать.

Никаких проблем. Это же С. Он позволяет стрелять в ногу очень легко и непринужденно.

void func(int *ptr) {
	if (ptr == NULL) {
		printf("data is missing, find alternative data\r\n");
		//но лучше так не делать. func должен заниматься своим делом, т.е. если это анализ данных, то пусть анализирует,
		//а данные вытаскиваются где-то в другом месте.
	} else {
		printf("data provided, use it\r\n");
	}
}

//варианты использования
int data[1];
func(data);

func(NULL);

 

Share this post


Link to post
Share on other sites
AntFX
Posted (edited)
13 минут назад, laxander сказал:

Никаких проблем. Это же С. Он позволяет стрелять в ногу очень легко и непринужденно.

Я тут не вижу обращения к одной и той же ф-йии с передачей параметра типа int и типа int[]. Мне просто интересно, как потом в ней отвечая на изначальный вопрос автора эта разница будет определяться.

Edited by AntFX

1

Share this post


Link to post
Share on other sites
laxander
Posted (edited)
14 минут назад, AntFX сказал:

Я тут не вижу обращения к одной и той же ф-йии с передачей параметра типа int и типа int[]. Мне просто интересно, как потом в ней отвечая на изначальный вопрос автора эта разница будет определяться.

Это какая-то неоригинальная задача. ) В оригинале задача была
 

Цитата

 

есть функция в которую в качестве аргумента может передаваться массив, но не всегда.

как внутри функции проверить, что произошло обращение с массивом, а не без него ?

 

Человеку надо передавать в функцию массив, но не всегда. :) Т.е. подразумевается ленивая инициализация - возможность инициализации массива внутри функции альтернативными данными, если извне пришло NULL. Что в общем-то косяк подхода, т.к. следует все-таки стремиться отделять инициализацию от работы с данными. Но тут уж если человеку так хочется, то почему бы и да.

Edited by laxander
  • Thanks 1

Share this post


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

Человеку надо передавать в функцию массив, но не всегда. :) Т.е. подразумевается ленивая инициализация - возможность инициализации массива внутри функции альтернативными данными, если извне пришло NULL. Что в общем-то косяк подхода, т.к. следует все-таки стремиться отделять инициализацию от работы с данными. Но тут уж если человеку так хочется, то почему бы и да.

Если в С нет разницы при передаче аргумента, передавать ссылку на массив или на простую переменную то Вы правы. В МКЛ так сделать не получится.

  • Thanks 1

1

Share this post


Link to post
Share on other sites
ZeleBoba
Posted (edited)

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

Edited by ZeleBoba
  • Upvote 1

Лучше маленький профит, чем большие рога.

Share this post


Link to post
Share on other sites
ZeleBoba
Posted (edited)
15 часов назад, AntFX сказал:

Начать можно с того, что в МКЛ нет указателей. Есть только дескрипторы, и только для объектов. 

 

Меня сбила с толку инфа из документации по МКЛ

"В MQL4 параметры простых типов можно передавать как по значению, так и по ссылке, в то время как параметры сложных типов всегда передаются по ссылке. Для указания компилятору на необходимость передачи параметра по ссылке, перед именем параметра ставится знак амперсанда &.

Передача параметра по ссылке означает передачу адреса переменной."

Следовательно хотелось проверить этот адрес, полученный в виде параметра.

 

Edited by ZeleBoba

Лучше маленький профит, чем большие рога.

Share this post


Link to post
Share on other sites
Ugar68
04.03.2019 в 23:32, sviter сказал:

Можете помочь? ато я что то вообще не понял где косяк!

Для начала. В справочнике написано что OrderSelect возвращает  false в случае ошибки. Значит это вполне возможно. А теперь подумайте что будет если эта функция не выберет последний ордер? FindLastOrderPrice вернёт цену предпоследнего или даже 0.

А FindLastOrderType, FindLastLot так же перебирают и выбирают ордера? Если ошибка при выборе ордера произойдёт только в одной из них, то она вернёт параметр другого ордера. Это не оптимально, зачем делать одно и тоже много раз в каждой функции. Это не стабильно, из за возможных ошибок в одной из функций.

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


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

Share this post


Link to post
Share on other sites
sviter
Posted (edited)

Здраствуйте! есть стандартный индикатор iEnvelopes!
Ни как не могу его заставить работать так как мне нужно!
Тоесть, нужно чтобы когда свеча коснулась или прошла линию на текущей свече UP, то открылся BUY и свеча коснулась или пересекла линию на текущей свече DOWN, то открылся SELL.....и происходило это один раз (сигнал-сработало и все, еще сигнал-сработало и все и так постоянно)!
 

    Inv_0_1 = iEnvelopes(_Symbol, time2_method, envel, envel_method, envelshag, envel_Price, envelproc, MODE_UPPER, 0);
    Inv_0_11 = iEnvelopes(_Symbol, time2_method, envel, envel_method, envelshag, envel_Price, envelproc, MODE_UPPER, 1);
    
    Inv_0_2 = iEnvelopes(_Symbol, time2_method, envel, envel_method, envelshag, envel_Price, envelproc, MODE_LOWER, 0);
    Inv_0_21 = iEnvelopes(_Symbol, time2_method, envel, envel_method, envelshag, envel_Price, envelproc, MODE_LOWER, 1);

    if(High[0] > Inv_0_2 && High[0] < Inv_0_21)
      {
      TP = NormalizeDouble(Bid - tpt * _Point, _Digits);
         ticketZK = OpenOrder(_Symbol, OP_SELL, lot, Bid, slippage, 0, TP, comment, Magic, 0, clrRed);
         if(ticketZK > 0)
         Print("Ордер на SELL успешно открыт! ");
         return;
      } 
    
      
    if(Low[0] < Inv_0_1 && Low[0] > Inv_0_11)
      {
      TP = NormalizeDouble(Ask + tpt * _Point, _Digits);
         ticketZK = OpenOrder(_Symbol, OP_BUY, lot, Ask, slippage, 0, TP, comment, Magic, 0, clrBlue);
         if(ticketZK > 0)
         Print("Ордер на BUY успешно открыт! ");
         return;
      } 

Помогите плиз!

Edited by sviter

Share this post


Link to post
Share on other sites
Blin_aa

Пол дня создавал советник. Создал !!! Вот код:

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
  Print("Размер контракта в базовой валюте инструмента=",MarketInfo(Symbol(),MODE_LOTSIZE)); 
  Print("Размер минимального изменения цены инструмента в валюте депозита=",MarketInfo(Symbol(),MODE_TICKVALUE)); 

  return(INIT_SUCCEEDED);
}

А вот результат работы советника на графике и в тестере. Счет центовый. На стандарте данные корректные.

 

Куда рыть? Правда сейчас рынок закрыт на выходные. Возможно как то с этим связано.

test.PNG

Share this post


Link to post
Share on other sites
Ugar68

Круто. У меня всё норм.

Вот код и картинка. Может у тебя счёт цетовый и тестер этого не понял.

Print("Пункт в валюте депозита=",MarketInfo(Symbol(),MODE_TICKVALUE)," ",SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE));

Вот результаты в на счёте и тестере

 

Безымянный.jpg


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

Share this post


Link to post
Share on other sites
sviter

Здраствуйте! 
Есть в советнике функция получения текста из ссылки....получаю ее вот этой библиотекой: https://github.com/sergeylukin/mql4-http"]https://github.com/sergeylukin/mql4-http
Все отлично и вопросов к ней нет!
Проблема в следующем:
В этой ссылке текст систематически обновляется, а терминал этого не воспринимает, даже когда сбрасывает сову с графика и ставишь заново! Помогает только закрытие и открытие терминала вовсе! Может кто знает как это можно исправить?

Share this post


Link to post
Share on other sites
sviter

Здравствуйте! В настройках терминала Сервис-Настройки-Советники можно добавить ссылку в доверенную зону в WebRequest.....скажите ее можно потом как нить удалить оттуда? Просто она даже после редактирования все ровно работает и никак не удаляется из терминала...

Share this post


Link to post
Share on other sites
sviter

Есть дата текущая тада(15.04.2019) и дата указанная вручную например 26.04.2019.... как расчитать количество дней с высчитом выходных, что бы получилочь 10 дней???

Share this post


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

Есть дата текущая тада(15.04.2019) и дата указанная вручную например 26.04.2019.... как расчитать количество дней с высчитом выходных, что бы получилочь 10 дней???

Проще использовать дневные свечи. 10 свечей посчитать не сложно.


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

Share this post


Link to post
Share on other sites
sviter

Здраствуйте!!! Использую данный код для транслирования ссылки в коммент, но систематически раз в день он мне выдает ошибку: web error 5203 (ERR_WEBREQUEST_REQUEST_FAILED. Ошибка в результате выполнения HTTP запроса)

Может как нить можно исправить это? 

 

string Web(string url)
{
string headers, ret;
char post[], result[];
int res, timeout=5000;
res= WebRequest("GET",url,NULL,timeout,post,result,head ers);
if(d3 != 1 && res < 0)
{
MessageBox("4060 Добавите ссылку в доверенную зону (Сервис-Настройки-Советники-Разрешить URL)", "Внимание", MB_OK);
Print("Web-Error: ",GetLastError()," (4060 Добавите ссылку в доверенную зону (Сервис-Настройки-Советники-Разрешить URL");
ExpertRemove();
d3 = 1;
return("");
}
ret = CharArrayToString(result, 0, -1);
return(ret);
}

 

Share this post


Link to post
Share on other sites
Melady

Здравствуйте.

Подскажите пожалуйста, почему не работает функция Alert?

Вот в таком виде у меня:

 

Alert (" Price ",Price,"  Lot ",Lots,"   SL ",SL,"  TP ",TP);

 

Я ее всегда включала при тестировании советника, а сейчас сообщение не выводится. Только в журнале видно.

 


Невозможно победить того, кто не сдается. (Бейб Рут)   

Для инвесторов, желающих вложить крупные суммы, я открываю персональный непубличный ПАММ. (обращаться в личные сообщения).

Share this post


Link to post
Share on other sites
AntFX
Posted (edited)
5 часов назад, Melady сказал:

Я ее всегда включала при тестировании советника, а сейчас сообщение не выводится. Только в журнале видно.

При работе в тестере стратегий функция Alert() не выполняется.

Edited by AntFX

1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×