Ваши вопросы по языку MQL4

_Fatal_

Активный участник
Здравствуйте, есть индикаторый на Thinkoswim, ктото может их переделать под MT4
 

vlad_123

Местный знаток
Этой функцией я пользовался.. Но мне нужно более универальное решение. Чтобы можно было вместо хая бара подставить, например, значение какого-то расчёта. Поэтому я и ищу решение альтернативное.
ArrayMaximum/ArrayMinimum

Но стрелки то рисуются не там где нужно. Почему? Я вообще в шоке :facepalm:. Пишу вещи на порядок сложнее в логике, но индикаторов не писал раньше. И вот застрял на этом месте... Просьба направить в требуемом направлении..
_http://forum.mql4.com/ru/57685

Код:
double buf_1[];
double buf_2[];
...
int init() {
 SetIndexBuffer(0, buf_1);
 SetIndexBuffer(1, buf_2);
 //---- Стиль исполнения графика 
 //---- DRAW_ARROW - стрелки(символы)
 SetIndexStyle (0, DRAW_ARROW, STYLE_SOLID, 3);
 SetIndexStyle (1, DRAW_ARROW, STYLE_SOLID, 3);
 SetIndexArrow (0, 233);
 SetIndexArrow (1, 234);
 //---- установка значений индикатора, которые не будут видимы на графике
 SetIndexEmptyValue(0,0.0);
 SetIndexEmptyValue(1,0.0);
...
int start() {
...
//---- проверка условий по вашим правилам и отрисовка стрелки
 if (MA_Fast_1 > MA_Slow_1 && MA_Fast_2 <= MA_Slow_2) buf_1[i+1] = Low[i+1] - 10 * Point;
 if (MA_Fast_1 < MA_Slow_1 && MA_Fast_2 >= MA_Slow_2) buf_2[i+1] = High[i+1] + 10 * Point;
...
 

Viko2000

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

if (AccountEquity()>=AccountBalance()+AccountBalance()/100*PercentProfit)
{Close_all();
}
как только убираю этот код, закрытие не происходит и бот работает дальше.
Так как же будет выглядеть правильно закрытие всего по проценту прибыли Эквити.

Молчат все как партизаны.);) Допёр же, ну крут же, жалко не Скрудж.)))):D

if (AccountEquity()>=AccountBalance()+AccountCredit()+OrderSwap()+AccountBalance()/100*PercentProfit)
{Close_all();
}

Во как надо. Чёртов грёбанный кредит.:embrace: Так же и посидеть можно.))))
Так что други, на будущие не забываем вписывать в логику срабатывания всё что присутствует в цифрах.) *hi*
 

hoz

Активный участник
ArrayMaximum/ArrayMinimum


_http://forum.mql4.com/ru/57685

Код:
double buf_1[];
double buf_2[];
...
int init() {
 SetIndexBuffer(0, buf_1);
 SetIndexBuffer(1, buf_2);
 //---- Стиль исполнения графика 
 //---- DRAW_ARROW - стрелки(символы)
 SetIndexStyle (0, DRAW_ARROW, STYLE_SOLID, 3);
 SetIndexStyle (1, DRAW_ARROW, STYLE_SOLID, 3);
 SetIndexArrow (0, 233);
 SetIndexArrow (1, 234);
 //---- установка значений индикатора, которые не будут видимы на графике
 SetIndexEmptyValue(0,0.0);
 SetIndexEmptyValue(1,0.0);
...
int start() {
...
//---- проверка условий по вашим правилам и отрисовка стрелки
 if (MA_Fast_1 > MA_Slow_1 && MA_Fast_2 <= MA_Slow_2) buf_1[i+1] = Low[i+1] - 10 * Point;
 if (MA_Fast_1 < MA_Slow_1 && MA_Fast_2 >= MA_Slow_2) buf_2[i+1] = High[i+1] + 10 * Point;
...

Если через буфер я понимаю. Но это всё можно и без буфера реализовать. Почему нет? Вы этого не понимаете тоже?
Ведь буфер тут нет необходимости заводить т.к. хранить информацию не нужно.
Выполнилось условие - создали объект! Выполнилось ещё раз условие - создали объект! И т.д. Объекты не удаляются в процессе выполнения программы. Логично?
Тогда должно и так работать? В чём загвоздка?
 

sega111

Заблокирован
Помощь

ребят подскажите пожалуйста чего тут не хватает в коде (закрытие всех ордеров по эквии) чтобы код вставить в советник
extern double Profit = 1;
extern double Loss = 1000000;
double Last_Equity;

Last_Equity = AccountEquity( );

double Equity,Diff_Profit,Diff_Loss;
Equity = AccountEquity( );
Diff_Profit = Equity - Last_Equity;
Diff_Loss = Last_Equity - Equity;
if(Diff_Profit > Profit || Diff_Loss > Loss)

я так понимаю саму функцию закрытия
 

AlexeyVik

Программист mql4 mql5
Этой функцией я пользовался.. Но мне нужно более универальное решение. Чтобы можно было вместо хая бара подставить, например, значение какого-то расчёта. Поэтому я и ищу решение альтернативное.


Согласен. Буфер MaxSize, на данный момент, не используется. Но лишь потому, что мне нада написать условие, чтоб стрелка рисовалась после 3 увеличивающихся хаём баров. А дальше уже займусь передачей в буфер данных.

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

PHP:
//+---------------------------------------------------------------------------------------------------------------------------------------+//|                                          Определение наличия увеличивающегося размера бара                                            |//+---------------------------------------------------------------------------------------------------------------------------------------+bool ExistencePositiveSequence (int fi_Index){   if (High[fi_Index] > High[fi_Index - 1])   {      sequenceCount++;            return (true);   }   sequenceCount = 0;         return (false);}//+---------------------------------------------------------------------------------------------------------------------------------------+//|                                               Custom indicator iteration function                                                     |//+---------------------------------------------------------------------------------------------------------------------------------------+int OnCalculate (const int rates_total,         // размер входных таймсерий                 const int prev_calculated,     // обработано баров на предыдущем вызове                 const datetime &time[],                 const double &open[],                 const double &high[],                 const double &low[],                 const double &close[],                 const long &tick_volume[],                 const long &volume[],                 const int &spread[]){   int limit = rates_total - prev_calculated;      if (prev_calculated == 0) limit--;      else limit++;      for (int i = 0; i < limit; i++)   {      if (ExistencePositiveSequence (i) == true)      {           if (sequenceCount == 3)           CDraw.DrawObject (_Symbol, _Period,  OBJ_ARROW_UP, i, Time[i], Open[i]);      }   }      return (rates_total);
Но стрелки то рисуются не там где нужно. Почему? Я вообще в шоке :facepalm:. Пишу вещи на порядок сложнее в логике, но индикаторов не писал раньше. И вот застрял на этом месте... Просьба направить в требуемом направлении..
Привет, Виктор. Я даже и не подумал что здесь -http://forum.mql4.com/ru/69388 это твоя тема.
К коду много вопросов. Например, зачем рисовать стрелки если можно загнать их в буфер такими-же стрелками. Но это фигня учитывая неопытность написания индикаторов.
На мой взгляд лучше строить цикл на уменьшение номера бара
for (int i = limit; i >= 0; i--)
Потом я-бы подсчёт количества баров поставил-бы в функцию ExistencePositiveSequence и соответственно или return(true) или обнуление переменной sequenceCount если после двух, например или даже одного раза выполнения условия вдруг нарушение и надо начинать подсчёт с начала...
Сейчас посмотрел ещё раз, а ты там исправил строку CDraw.DrawObject (_Symbol, _Period, OBJ_ARROW_UP, i, Time, Open);
где было Time[0], Open[0])
В общем копай в сторону обнуления переменной sequenceCount если условие выполнено меньше заданного количества раз.

Если через буфер я понимаю. Но это всё можно и без буфера реализовать. Почему нет? Вы этого не понимаете тоже?
Ведь буфер тут нет необходимости заводить т.к. хранить информацию не нужно.
Выполнилось условие - создали объект! Выполнилось ещё раз условие - создали объект! И т.д. Объекты не удаляются в процессе выполнения программы. Логично?
Тогда должно и так работать? В чём загвоздка?

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

vlad_123

Местный знаток
Если через буфер я понимаю. Но это всё можно и без буфера реализовать. Почему нет? Вы этого не понимаете тоже?
Ведь буфер тут нет необходимости заводить т.к. хранить информацию не нужно.
Использование SetIndexBuffer не наталкивает на размышления? ;)
Индикаторы так и работают - рисуют линии/стрелки/и т.д. используя данные из назначенных буферов.
Вам же, почему-то, хочется переделать стандартный механизм на что-то оригинальное. Причем, бенефиты от этого совсем неочевидны, а потенциальшых граблей - море.
 

Viko2000

Почетный гражданин
капец! тут чего нет специалистов

Не расстраивайся. )));) Главная тема этой ветки не в помощи, а в развитии собственного потенциала.:D Ну а специи здесь, это все те, задающие вопросы и в последствии сами всё решающие. _)))) :embrace:Красотища.))):D
И кстати, как то у тебя всё за мудрено, может подойдет как с поста 4183.
 
Последнее редактирование:

yurez83

Активный участник
здравствуйте. ребята, может кто то подскажет мне в одном вопросе. склепал советник, который закрывает ордера, с минимальным профитом n-пунктов при пересечении мувинга с низу вверх или с верху вниз. всё прекрасно работает, кроме одного - при инициализации сова сначала срабатывает закрытие ордеров. :facepalm:

для определения пересечения мувинга написал функцию Proverka, в которой обьявил статические переменные last и current и присвоил значение ноль. функция передаёт значение 1 или 2 при пересечении цены мувинга, при инициализации сова должно передаваться значении 0, но походу это не так и ордера как уже и написал закрываются..

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

Вложения

  • Profit.mq4
    4,2 КБ · Просмотры: 22

Yurkov

Почетный гражданин
Добрый день!
Подскажите, есть ли код для реверса? Т.е. если сигнал на покупку, откроется Sell и наоборот.
 

RoboMaks

Элитный участник
всё прекрасно работает, кроме одного - при инициализации сова сначала срабатывает закрытие ордеров. :facepalm:

для определения пересечения мувинга написал функцию Proverka, в которой обьявил статические переменные last и current и присвоил значение ноль. функция передаёт значение 1 или 2 при пересечении цены мувинга, при инициализации сова должно передаваться значении 0, но походу это не так и ордера как уже и написал закрываются..

Ошибки такого рода происходят из-за того, что при инициализации сова не сразу выдаются точные показания вызываемых индюков - т.е. до полной инициализации индюка его значение может быть равным нулю или очень большому значению ( значительно больше значения цены). Чтобы избежать этой ошибки добавьте проверку значения индюка
if ( значение индюка > 0 && значение индюка < 100000 )
 

AlexeyVik

Программист mql4 mql5
добавил.. к сожалению - без изменений. :disappointed:
А ты попробуй посчитать вручную что возвращает твоя функция int Proverka (double znah1 , double znah2) при первом обращении к ней.

Самый простой вариант обойти твою проблему, вызвать эту функцию из инита.
 

AlexeyVik

Программист mql4 mql5
Ошибки такого рода происходят из-за того, что при инициализации сова не сразу выдаются точные показания вызываемых индюков - т.е. до полной инициализации индюка его значение может быть равным нулю или очень большому значению ( значительно больше значения цены). Чтобы избежать этой ошибки добавьте проверку значения индюка
if ( значение индюка > 0 && значение индюка < 100000 )
Вот это самое "очень большое значение" называется EMPTY_VALUE (пустое значение). Тогда получается правильное сравнение
значение индюка != EMPTY_VALUE
 

hoz

Активный участник
здравствуйте. ребята, может кто то подскажет мне в одном вопросе. склепал советник, который закрывает ордера, с минимальным профитом n-пунктов при пересечении мувинга с низу вверх или с верху вниз. всё прекрасно работает, кроме одного - при инициализации сова сначала срабатывает закрытие ордеров. :facepalm:

для определения пересечения мувинга написал функцию Proverka, в которой обьявил статические переменные last и current и присвоил значение ноль. функция передаёт значение 1 или 2 при пересечении цены мувинга, при инициализации сова должно передаваться значении 0, но походу это не так и ордера как уже и написал закрываются..

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


Потому что условие кривое.

PHP:
   iProverka=Proverka(MA,BA);                             // Проверка прохода через машку
        if(iProverka == 1 || iProverka == 2)
     {
   for (int i=OrdersTotal()-1; i>=0; i--)
    {OrderSelect(i,SELECT_BY_POS,MODE_TRADES);   // выбор ордера
                                                                                                       
          
      if (OrderType()==OP_BUY && OrderSymbol()==Symbol()) // проверка инструмента
      {
         point=MarketInfo(OrderSymbol(),MODE_POINT);
         if (point==0) break;
         bid=MathRound(MarketInfo(OrderSymbol(),MODE_BID)/point);
         open=MathRound(OrderOpenPrice()/point);
         if (bid-open<Profit) continue;
         OrderClose(OrderTicket(),OrderLots(),bid*point,slippage);
      }
      if (OrderType()==OP_SELL&& OrderSymbol()==Symbol())
      {
         point=MarketInfo(OrderSymbol(),MODE_POINT);
         if (point==0) break;
         ask=MathRound(MarketInfo(OrderSymbol(),MODE_ASK)/point);
         open=MathRound(OrderOpenPrice()/point);
         if (open-ask<Profit) continue;
         OrderClose (OrderTicket(),OrderLots(),ask*point,slippage);     
      
     }
      
    }
   }


Если машка пересечена, т.е. Proverka возвратит 1 или 2, то по-любому вызовется условие:

PHP:
if (OrderType()==OP_BUY && OrderSymbol()==Symbol())


или

PHP:
if (OrderType()==OP_BUY && OrderSymbol()==Symbol())


А дальше на примере выбора позиции на покупку, вызовется:

PHP:
if (bid-open<Profit) continue;


В водных параметрах в комментах написано, типа это прибыль в пунктах. А тут нет пунктов. Должно быть типа:

PHP:
if (bid-open<Profit * ПУНКТ) continue;


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

hoz

Активный участник
Вот это самое "очень большое значение" называется EMPTY_VALUE (пустое значение). Тогда получается правильное сравнение
значение индюка != EMPTY_VALUE

Если индюк возвратил значение, то па факту оно не будет "пустым".
 

AlexeyVik

Программист mql4 mql5
Если индюк возвратил значение, то па факту оно не будет "пустым".
Нет, в этом ты не прав. Индикатор при запросе возвращает то, что содержится в запрашиваемом буфере на том баре который нас интересует. Соответственно если там пустое значение, то и получим мы пустое значение.
 

hoz

Активный участник
Привет, Виктор. Я даже и не подумал что здесь -http://forum.mql4.com/ru/69388 это твоя тема.


Здарова Алексей. Моя видимо :) Долбусь уже несколько дней, вот и написал в пару мест.

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


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

На мой взгляд лучше строить цикл на уменьшение номера бара
for (int i = limit; i >= 0; i--)


Я уже это понял. Но это если будет один цикл, а если с вложенным, то разницы нет, как я вижу.

Потом я-бы подсчёт количества баров поставил-бы в функцию ExistencePositiveSequence и соответственно или return(true) или обнуление переменной sequenceCount если после двух, например или даже одного раза выполнения условия вдруг нарушение и надо начинать подсчёт с начала...


А вот это очень странно. Смысла нет пересчитывать условие на всех барах, которые мы сравниваем. Это не логично. Если сравниваем 100 баров, то проще сравнивать на каждом расчётном баре текущий и предыдущий. А не все сравниваемые. Как-то мне такой вариант вообще не нравится...
 
Верх