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

От xbms, 13 апреля, 2013 в Уголок Программиста

#6551
1 минуту назад, Гладиoлус сказал:

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

Я боюсь, "не работает" - слишком расплывчатая формулировка.

Что именно работает не так, как вы ожидаете?

#6552

#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

// CloseDate = Date1
// OpenDate = Date2
extern datetime Date1=D'2021.12.15 19:00';
extern datetime Date2=D'2021.12.16 13:05';

extern int Amount = 19;
   double sumHigh;
    double sumLow;
    double x;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{

   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
 
    
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{

   
   GetMiddleSize();
   Comment("\n" + "\n" + "\n" + "\n" "Сред. значение: " + DoubleToString((sumHigh - sumLow)/Amount, 6));
   
}
//+------------------------------------------------------------------+
double GetMiddleSize()
{
    sumHigh = 0.0;
     sumLow = 0.0;
    x = 0.0;
    int OpenShift = iBarShift(Symbol(),0,Date2); 
    int CloseShift = iBarShift(Symbol(),0,Date1);
    
    for (int i = OpenShift; i <= CloseShift; i++)
    {
         //int RangePeriod = i; //считаем по CountBars начиная с StartBar
         sumHigh += iHigh(Symbol(), Period(), i);
         sumLow += iLow(Symbol(), Period(), i);
         x = (sumHigh - sumLow)/Amount;
    }
    return(x);
}
//+------------------------------------------------------------------+

#6553

вот этот индикатор работает на всех валютных парах но к сожалению на сырье он не вычисляет среднее значени

#6554

я сперва подумал что это из того что золото у брокера отображается как GOLD поэтому перешел на другого где золото как XAUUSD но результат тот же

 

#6555
26 минут назад, Гладиoлус сказал:

я сперва подумал что это из того что золото у брокера отображается как GOLD поэтому перешел на другого где золото как XAUUSD но результат тот же

 

меня интересует не код, а результат, который вас не устраивает.

Что значит "не вычисляет средние значения"? Что отображается в комменте?

#6556
2 минуты назад, Rigal сказал:

Что отображается в комменте?

А что он может при таком коде отображать? Нифига...

Функция расчета среднего значения возвращает double, но ничему это значение не присваивается.

Зато локальные переменные внесены в коммент

#6557
33 минуты назад, Гладиoлус сказал:

    for (int i = OpenShift; i <= CloseShift; i++)
    {
         //int RangePeriod = i; //считаем по CountBars начиная с StartBar
         sumHigh += iHigh(Symbol(), Period(), i);
         sumLow += iLow(Symbol(), Period(), i);
         x = (sumHigh - sumLow)/Amount;
    }
    return(x);

К слову:

Если вы пытаетесь вычислить среднее значение, есть смысл делить на количество баров, которые вы посчитали. То есть ваш Amount = OpenShift - CloseShift + 1

Кроме того, нет никакого смысла выполнять деление на каждой итерации цикла.

Можно выкинуть переменную и строчку с делением на эту переменную и возвращать результат вот так:

return ((sumHigh-sumLow)/(CloseShift-OpenShift + 1));

При этом полезно убедиться, что CloseShift != (OpenShift + 1) - и если они равны, возвращать пустое значение.

 

#6558
7 минут назад, usver73 сказал:

А что он может при таком коде отображать? Нифига...

Функция расчета среднего значения возвращает double, но ничему это значение не присваивается.

Зато локальные переменные внесены в коммент

Ну эти переменные не локальные, глобальные. Они поэтому будут все же вычислены

 

Изменено 24 декабря, 2021 пользователем Rigal

#6559

Подразумевалось, видимо, вот что:

#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

// CloseDate = Date1
// OpenDate = Date2
extern datetime Date1=D'2021.12.15 19:00';
extern datetime Date2=D'2021.12.16 13:05';

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{

   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
 
    
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{

   Comment("\n" + "\n" + "\n" + "\n" "Сред. значение: " + DoubleToString(GetMiddleSize(), 6));
   
}
//+------------------------------------------------------------------+
double GetMiddleSize()
{
    double sumHigh = 0.0;
    double sumLow = 0.0;
    int OpenShift = iBarShift(Symbol(),Period(),Date2); 
    int CloseShift = iBarShift(Symbol(),Period(),Date1);
    
    for (int i = OpenShift; i <= CloseShift; i++)
    {
         sumHigh += iHigh(Symbol(), Period(), i);
         sumLow += iLow(Symbol(), Period(), i);
    }
    return(CloseShift >= OpenShift ? (sumHigh - sumLow) / (CloseShift - OpenShift + 1) : 0.0);
}
//+------------------------------------------------------------------+

 

#6560
29 минут назад, Rigal сказал:

Ну эти переменные не локальные, глобальные.

А, ну, да- не увидел, что он их зачем то вынес..

#6561
56 минут назад, usver73 сказал:

А, ну, да- не увидел, что он их зачем то вынес..

а иначе бы не скомпилировалось :)

#6562
1 час назад, Rigal сказал:
return(CloseShift >= OpenShift ? (sumHigh - sumLow) / (CloseShift - OpenShift + 1) : 0.0);

Такая конструкция для начинающего очень сложна для восприятия.

И вообще, практичнее считать сумму разницы хай-лоу. Вдруг завтра захочется посчитать ЕМА.. 

ИМХО

#6563
1 час назад, usver73 сказал:

Такая конструкция для начинающего очень сложна для восприятия.

Не спорю, но тут тонкий баланс между научить и сделать.

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

А сделать - тут не очено важно, как, вопрос компактности.

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

И вообще, практичнее считать сумму разницы хай-лоу. Вдруг завтра захочется посчитать ЕМА.

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

#6564

Спасибо большое, безмерно вам благодарен, еще немного и я закончу свой индикатор. Это мне так облегчит жизнь а то на excel постоянно делать миллион вычислений ужасно утомляет.

#6565
1 час назад, Гладиoлус сказал:

, еще немного и я закончу свой индикатор

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

#6566

Помогите, пожалуйста. Есть свой индикатор (назовем его Std_devma), который показывает две линии: первая линия - индикатор  iStdDev, вторая - MA, рассчитанная из массива iStdDev:

 

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 Blue
#property indicator_color2 Red


extern int STD_Period=20;
extern int STD_Shift=0;
extern int MA_Period=7;
extern int MA_Shift=0;
double B1[], B2[], B3[];

//----
int ExtCountedBars=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
//---- drawing settings
   SetIndexStyle(0, DRAW_LINE);
   SetIndexStyle(1, DRAW_LINE);
   SetIndexBuffer(0,B1);
   SetIndexBuffer(1,B2);
   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
//---- indicator short name
   IndicatorShortName("STD_DEV+MA");
   ArraySetAsSeries(B1,true);
   ArraySetAsSeries(B2,true);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   
   int    pos=Bars-2;
   int i;   
   if(ExtCountedBars>2) pos=Bars-ExtCountedBars-1;
//---- main calculation loop
   for(i=0;i<Bars;i++)
      {
      B1[i] = iStdDev(Symbol(),Period(),STD_Period,STD_Shift,MODE_LWMA,PRICE_CLOSE,i);
      }
   for(i=0;i<Bars;i++)
      {
      
      B2[i]= iMAOnArray(B1,0,MA_Period,MA_Shift,MODE_SMA,i);
      }  
   return(0);
   }

 

Как мне в советнике вызвать данный индикатор и получить его данные?

#6567
1 час назад, VitChel сказал:

Как мне в советнике вызвать данный индикатор и получить его данные?

Посмотрите справку на iCustom()

#6568

Здравствуйте.У меня почемуто в перестал работать тестер стратегий.В журнале пишет тэст генератор файл ерор.Что это значит?

#6569

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

Например по х беру дату а по у цену. Длина трендовой линии не имеет значения. Помогите пожалуйста с кодом.   

#6570

Screenshot_1.thumb.png.4d1cc22ecc81795fea89ec2a531dd87f.png

#6571

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

Изменено 30 декабря, 2021 пользователем Гладиoлус

#6572
4 часа назад, Гладиoлус сказал:

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

а вы уже попробовали что-то?

В метатрейдере есть удобная библиотека для работы с линиями, ChartObjects/ChartObjectsLines.mqh

Используя эту библиотеку можно написать, например, так:

//+------------------------------------------------------------------+
//|                                                    TrendLine.mq4 |
//|                      Copyright 2021, Igor Ryabchikov (aka Rigal) |
//|                     /profile/109537-rigal/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, Igor Ryabchikov (aka Rigal)"
#property link      "/profile/109537-rigal/"
#property version   "1.00"
#property strict

input int RangePeriod = 12; //период на графике, на котором считаем High/Low
#include <ChartObjects/ChartObjectsLines.mqh>

CChartObjectTrend highLine, lowLine;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit() {
   //создаем линии 
   //время левой и правой точек выбираем, просто для примера, на три бара назад и текущее
   //цену задаем в ноль - "прячем" внизу до поры до времени (пока не понадобятся они нам)
   highLine.Create(0, "MyHighLine", 0, iTime(Symbol(), Period(), 3), 0.0, TimeCurrent(), 0.0);
   highLine.RayLeft(false);   //выключаем луч влево. Вправо - так же, только RayRight
   highLine.Color(clrRed);
   highLine.Width(2);         //чуть толще

   lowLine.Create(0, "MyLowLine", 0, iTime(Symbol(), Period(), 3), 0.0, TimeCurrent(), 0.0);
   lowLine.RayLeft(false); //выключаем луч влево. Вправо - так же, только RayRight
   lowLine.Color(clrBlue);
   lowLine.Width(2);         //чуть толще
   
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick() {
   int highestBarInRange = iHighest(Symbol(), Period(), MODE_HIGH, RangePeriod);
   datetime highestTime = iTime(Symbol(), Period(), highestBarInRange);
   double highestPrice = iHigh(Symbol(), Period(), highestBarInRange);
   //обновняем линию high
   highLine.Time(0, highestTime); //точка 0 (левая)
   highLine.Price(0, highestPrice);   
   highLine.Time(1, TimeCurrent()); //точка 1 (правая)
   highLine.Price(1, highestPrice);   
   
   //повторяем для Low
   int lowestBarInRange = iLowest(Symbol(), Period(), MODE_LOW, RangePeriod);
   datetime lowestTime = iTime(Symbol(), Period(), lowestBarInRange);
   double lowestPrice = iLow(Symbol(), Period(), lowestBarInRange);
   //обновняем линию high
   lowLine.Time(0, lowestTime); //точка 0 (левая)
   lowLine.Price(0, lowestPrice);   
   lowLine.Time(1, TimeCurrent()); //точка 1 (правая)
   lowLine.Price(1, lowestPrice);   
}
//+------------------------------------------------------------------+

Советник будет таскать линии за максимумом и минимумом заданного периода баров

Получится вот так:

Спойлер

image.png.2d44b436955d531f3ae1b5b7173c75c9.png

 

Я, понятно, совершенно неоптимально считаю это все на каждом тике, ну и все такое, это просто пример.

#6573
16 часов назад, Rigal сказал:

а вы уже попробовали что-то?

В метатрейдере есть удобная библиотека для работы с линиями, ChartObjects/ChartObjectsLines.mqh

Используя эту библиотеку можно написать, например, так:

//+------------------------------------------------------------------+
//|                                                    TrendLine.mq4 |
//|                      Copyright 2021, Igor Ryabchikov (aka Rigal) |
//|                     /profile/109537-rigal/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, Igor Ryabchikov (aka Rigal)"
#property link      "/profile/109537-rigal/"
#property version   "1.00"
#property strict

input int RangePeriod = 12; //период на графике, на котором считаем High/Low
#include <ChartObjects/ChartObjectsLines.mqh>

CChartObjectTrend highLine, lowLine;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit() {
   //создаем линии 
   //время левой и правой точек выбираем, просто для примера, на три бара назад и текущее
   //цену задаем в ноль - "прячем" внизу до поры до времени (пока не понадобятся они нам)
   highLine.Create(0, "MyHighLine", 0, iTime(Symbol(), Period(), 3), 0.0, TimeCurrent(), 0.0);
   highLine.RayLeft(false);   //выключаем луч влево. Вправо - так же, только RayRight
   highLine.Color(clrRed);
   highLine.Width(2);         //чуть толще

   lowLine.Create(0, "MyLowLine", 0, iTime(Symbol(), Period(), 3), 0.0, TimeCurrent(), 0.0);
   lowLine.RayLeft(false); //выключаем луч влево. Вправо - так же, только RayRight
   lowLine.Color(clrBlue);
   lowLine.Width(2);         //чуть толще
   
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick() {
   int highestBarInRange = iHighest(Symbol(), Period(), MODE_HIGH, RangePeriod);
   datetime highestTime = iTime(Symbol(), Period(), highestBarInRange);
   double highestPrice = iHigh(Symbol(), Period(), highestBarInRange);
   //обновняем линию high
   highLine.Time(0, highestTime); //точка 0 (левая)
   highLine.Price(0, highestPrice);   
   highLine.Time(1, TimeCurrent()); //точка 1 (правая)
   highLine.Price(1, highestPrice);   
   
   //повторяем для Low
   int lowestBarInRange = iLowest(Symbol(), Period(), MODE_LOW, RangePeriod);
   datetime lowestTime = iTime(Symbol(), Period(), lowestBarInRange);
   double lowestPrice = iLow(Symbol(), Period(), lowestBarInRange);
   //обновняем линию high
   lowLine.Time(0, lowestTime); //точка 0 (левая)
   lowLine.Price(0, lowestPrice);   
   lowLine.Time(1, TimeCurrent()); //точка 1 (правая)
   lowLine.Price(1, lowestPrice);   
}
//+------------------------------------------------------------------+

Советник будет таскать линии за максимумом и минимумом заданного периода баров

Получится вот так:

  Показать контент

image.png.2d44b436955d531f3ae1b5b7173c75c9.png

 

Я, понятно, совершенно не оптимально считаю это все на каждом тике, ну и все такое, это просто пример.

Понял, а вот можно что бы линия была отрезком?

#6574
16 часов назад, Rigal сказал:

а вы уже попробовали что-то?

В метатрейдере есть удобная библиотека для работы с линиями, ChartObjects/ChartObjectsLines.mqh

Используя эту библиотеку можно написать, например, так:

//+------------------------------------------------------------------+
//|                                                    TrendLine.mq4 |
//|                      Copyright 2021, Igor Ryabchikov (aka Rigal) |
//|                     /profile/109537-rigal/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, Igor Ryabchikov (aka Rigal)"
#property link      "/profile/109537-rigal/"
#property version   "1.00"
#property strict

input int RangePeriod = 12; //период на графике, на котором считаем High/Low
#include <ChartObjects/ChartObjectsLines.mqh>

CChartObjectTrend highLine, lowLine;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit() {
   //создаем линии 
   //время левой и правой точек выбираем, просто для примера, на три бара назад и текущее
   //цену задаем в ноль - "прячем" внизу до поры до времени (пока не понадобятся они нам)
   highLine.Create(0, "MyHighLine", 0, iTime(Symbol(), Period(), 3), 0.0, TimeCurrent(), 0.0);
   highLine.RayLeft(false);   //выключаем луч влево. Вправо - так же, только RayRight
   highLine.Color(clrRed);
   highLine.Width(2);         //чуть толще

   lowLine.Create(0, "MyLowLine", 0, iTime(Symbol(), Period(), 3), 0.0, TimeCurrent(), 0.0);
   lowLine.RayLeft(false); //выключаем луч влево. Вправо - так же, только RayRight
   lowLine.Color(clrBlue);
   lowLine.Width(2);         //чуть толще
   
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick() {
   int highestBarInRange = iHighest(Symbol(), Period(), MODE_HIGH, RangePeriod);
   datetime highestTime = iTime(Symbol(), Period(), highestBarInRange);
   double highestPrice = iHigh(Symbol(), Period(), highestBarInRange);
   //обновняем линию high
   highLine.Time(0, highestTime); //точка 0 (левая)
   highLine.Price(0, highestPrice);   
   highLine.Time(1, TimeCurrent()); //точка 1 (правая)
   highLine.Price(1, highestPrice);   
   
   //повторяем для Low
   int lowestBarInRange = iLowest(Symbol(), Period(), MODE_LOW, RangePeriod);
   datetime lowestTime = iTime(Symbol(), Period(), lowestBarInRange);
   double lowestPrice = iLow(Symbol(), Period(), lowestBarInRange);
   //обновняем линию high
   lowLine.Time(0, lowestTime); //точка 0 (левая)
   lowLine.Price(0, lowestPrice);   
   lowLine.Time(1, TimeCurrent()); //точка 1 (правая)
   lowLine.Price(1, lowestPrice);   
}
//+------------------------------------------------------------------+

Советник будет таскать линии за максимумом и минимумом заданного периода баров

Получится вот так:

  Показать контент

image.png.2d44b436955d531f3ae1b5b7173c75c9.png

 

Я, понятно, совершенно неоптимально считаю это все на каждом тике, ну и все такое, это просто пример.

Мне просто надо сделать так что бы я мог редактировать его потом. 

#6575
3 минуты назад, Гладиoлус сказал:

Мне просто надо сделать так что бы я мог редактировать его потом. 

А то я два раза кликнул на отрезок а он не выделился следовательно невозможно редактировать.

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

Перейти к списку тем
Форум · 2.0.20260627.0025