АвторСообщение





Сообщение: 122
Зарегистрирован: 05.03.13
Репутация: 1
ссылка на сообщение  Отправлено: 14.04.14 09:56. Заголовок: Я в шоке! Подскажите.


Всем привет!
Я в шоке! Выпал из рынка на 3,5 месяца, а тут такие перемены. Игорь подскажи, где можно ознакомиться с изменениями в MQL4?
Хотел перенести все данные на новый комп, но некоторые индикаторы после компиляции перестают работать. Вот один из них.
http://gfile.ru/a8cCP
Хотя не перекомпилированные файлы работают.
Компиляция ошибок в коде не выявляет. Но при отладке выдается ошибка формирования массива стр.67. Но в чем ошибка не пойму.
Буду благодарен, если найдешь время исправить.



Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 203 , стр: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 All [только новые]







Сообщение: 558
Зарегистрирован: 05.03.13
Репутация: 1
ссылка на сообщение  Отправлено: 24.01.18 14:31. Заголовок: Игорь, Привет! Я реш..


Игорь, Привет!
Я решил попробовать MQL5. Начал с простого. Попробовал раскрасить OsMA используя вызов стандартного индикатора.
Привожу код полностью
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots 2
#property indicator_type1 DRAW_HISTOGRAM
#property indicator_color1 clrGreen
#property indicator_width1 2
#property indicator_type2 DRAW_HISTOGRAM
#property indicator_color2 clrRed
#property indicator_width2 2
#property indicator_level1 0
input int ShowBars = 300;
input int FastEMA = 34;
input int SlowEMA = 72;
input int SignalSMA = 9;
input ENUM_APPLIED_PRICE applied_price = PRICE_CLOSE;
//--- indicator buffers
double Up_OsMA_Buffer[];
double Dn_OsMA_Buffer[];
double OsMA_Buffer[];
//--- OsMA handles
int OsMA_Handle;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,Up_OsMA_Buffer,INDICATOR_DATA);
SetIndexBuffer(1,Dn_OsMA_Buffer,INDICATOR_DATA);
SetIndexBuffer(2,OsMA_Buffer,INDICATOR_CALCULATIONS);

IndicatorSetInteger(INDICATOR_DIGITS,_Digits+3);

PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,SlowEMA+SignalSMA-2);
PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,SlowEMA+SignalSMA-2);

IndicatorSetString(INDICATOR_SHORTNAME,"FW-OsMA("+string(FastEMA)+","+string(SlowEMA)+","+string(SignalSMA)+")");

PlotIndexSetString(0,PLOT_LABEL,"UpOsMA");
PlotIndexSetString(1,PLOT_LABEL,"DnOsMA");

OsMA_Handle = iOsMA(NULL,PERIOD_CURRENT ,FastEMA,SlowEMA,SignalSMA,applied_price);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Функция деинициализации |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
IndicatorRelease(OsMA_Handle); // удаляет хэндл индикатора и освобождает память занимаемую им
ArrayFree(Up_OsMA_Buffer); // освобождаем динамический массив от данных
ArrayFree(Dn_OsMA_Buffer);
ArrayFree(OsMA_Buffer);
}
//====================================================================
//+------------------------------------------------------------------+
//| 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 calculated=BarsCalculated(OsMA_Handle);
if(calculated<rates_total)
{
Alert("Not all data of OsMA_Handle is calculated (",calculated,"bars ). Error",GetLastError());
return(0);
}

//--- we can copy not all data
int to_copy;
if(prev_calculated>rates_total || prev_calculated<0) to_copy=rates_total;
else
{
to_copy=rates_total-prev_calculated;
to_copy++;
}
//--- get OsMA_Buffer buffer
if(IsStopped()) return(0); //Checking for stop flag
if(CopyBuffer(OsMA_Handle,0,0,to_copy,OsMA_Buffer)<=0)
{
Print("Getting OsMA_Buffer is failed! Error",GetLastError());
return(0);
}

//---
int k,limit;
if(prev_calculated==0)
limit=0;
else limit=prev_calculated-1;
//--- the main loop of calculations
for(k=limit;k<rates_total;k++)
{
//Dn_OsMA_Buffer[k]=0.0; Up_OsMA_Buffer[k]=0.0;
//--- calculate OsMA
//if(OsMA_Buffer[k]>OsMA_Buffer[k+1])
//Up_OsMA_Buffer[k]=OsMA_Buffer[k];
//else Dn_OsMA_Buffer[k]=OsMA_Buffer[k];


Если вместо выше выделенного текста подставить нижнюю строку и (#property indicator_plots 1), то все работает, но в одном цвете.
А так, нет. Отображается абра-кадабра какая-то.

Up_OsMA_Buffer[k]=OsMA_Buffer[k];
}

//--- return value of prev_calculated for next call
return(rates_total);
}
//====================================================================

Что не правильно в выделенном тексте?
А если задать ArraySetAsSeries(OsMA_Buffer,true); , то и этот вариант не работает.



С уважением! Спасибо: 0 
ПрофильЦитата Ответить





Сообщение: 2572
Зарегистрирован: 03.03.13
Откуда: Украина, Каменское (Днепродзержинск)
Репутация: 3
ссылка на сообщение  Отправлено: 25.01.18 22:45. Заголовок: Sergey пишет: Что н..


Sergey пишет:

 цитата:
Что не правильно в выделенном тексте?
А если задать ArraySetAsSeries(OsMA_Buffer,true); , то и этот вариант не работает.


Дело в том, что без ArraySetAsSeries нумерация баров в таймсериях ведется слева направо по графику. То есть бар с индексом 0 - где-то глубоко в истории, а текущий бар - это rates_total - 1.
Поэтому для такой нумерации нужно:
  • Начинать перебор баров не с бара 0, а с бара 1, т. к. нам нужно взять высоты гистограммы предыдущего бара, которого для бара 0 нет. То есть limit ставится не на 0, а на 1.
  • Понять, что предыдущий бар, это не k + 1, а k - 1.

    Получаем такой вот работающий код:

     цитата:
    #property indicator_separate_window
    #property indicator_buffers 3
    #property indicator_plots 2
    #property indicator_type1 DRAW_HISTOGRAM
    #property indicator_color1 clrGreen
    #property indicator_width1 2
    #property indicator_type2 DRAW_HISTOGRAM
    #property indicator_color2 clrRed
    #property indicator_width2 2
    #property indicator_level1 0
    input int ShowBars= 300;
    input int FastEMA = 34;
    input int SlowEMA = 72;
    input int SignalSMA=9;
    input ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE;
    //--- indicator buffers
    double Up_OsMA_Buffer[];
    double Dn_OsMA_Buffer[];
    double OsMA_Buffer[];
    //--- OsMA handles
    int OsMA_Handle;
    //+------------------------------------------------------------------+
    //| Custom indicator initialization function |
    //+------------------------------------------------------------------+
    int OnInit()
    {
    //--- indicator buffers mapping
    SetIndexBuffer(0,Up_OsMA_Buffer,INDICATOR_DATA);
    SetIndexBuffer(1,Dn_OsMA_Buffer,INDICATOR_DATA);
    SetIndexBuffer(2,OsMA_Buffer,INDICATOR_CALCULATIONS);

    IndicatorSetInteger(INDICATOR_DIGITS,_Digits+3);

    PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,SlowEMA+SignalSMA-2);
    PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,SlowEMA+SignalSMA-2);

    IndicatorSetString(INDICATOR_SHORTNAME,"FW-OsMA("+string(FastEMA)+","+string(SlowEMA)+","+string(SignalSMA)+")");

    PlotIndexSetString(0,PLOT_LABEL,"UpOsMA");
    PlotIndexSetString(1,PLOT_LABEL,"DnOsMA");

    OsMA_Handle=iOsMA(NULL,PERIOD_CURRENT,FastEMA,SlowEMA,SignalSMA,applied_price);
    //---
    return(INIT_SUCCEEDED);
    }
    //+------------------------------------------------------------------+
    //| Функция деинициализации |
    //+------------------------------------------------------------------+
    void OnDeinit(const int reason)
    {
    IndicatorRelease(OsMA_Handle); // удаляет хэндл индикатора и освобождает память занимаемую им
    ArrayFree(Up_OsMA_Buffer); // освобождаем динамический массив от данных
    ArrayFree(Dn_OsMA_Buffer);
    ArrayFree(OsMA_Buffer);
    }
    //====================================================================
    //+------------------------------------------------------------------+
    //| 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 calculated=BarsCalculated(OsMA_Handle);
    if(calculated<rates_total)
    {
    Alert("Not all data of OsMA_Handle is calculated (",calculated,"bars ). Error",GetLastError());
    return(0);
    }

    //--- we can copy not all data
    int to_copy;
    if(prev_calculated>rates_total || prev_calculated<0) to_copy=rates_total;
    else
    {
    to_copy=rates_total-prev_calculated;
    to_copy++;
    }
    //--- get OsMA_Buffer buffer
    if(IsStopped()) return(0); //Checking for stop flag
    if(CopyBuffer(OsMA_Handle,0,0,to_copy,OsMA_Buffer)<=0)
    {
    Print("Getting OsMA_Buffer is failed! Error",GetLastError());
    return(0);
    }

    //---
    int k,limit;
    if(prev_calculated==0)
    limit=1;
    else limit=prev_calculated-1;
    //--- the main loop of calculations
    for(k=limit;k<rates_total;k++)
    {
    Dn_OsMA_Buffer[k]=0.0; Up_OsMA_Buffer[k]=0.0;
    //-- calculate OsMA
    if(OsMA_Buffer[k]>OsMA_Buffer[k-1])
    Up_OsMA_Buffer[k]=OsMA_Buffer[k];
    else
    Dn_OsMA_Buffer[k]=OsMA_Buffer[k];
    }

    //--- return value of prev_calculated for next call
    return(rates_total);
    }





  • Спасибо: 0 
    ПрофильЦитата Ответить





    Сообщение: 559
    Зарегистрирован: 05.03.13
    Репутация: 1
    ссылка на сообщение  Отправлено: 26.01.18 07:35. Заголовок: Спасибо! Но хотелось..


    Спасибо! Но хотелось бы разобраться до конца.
    Как изменить код с использованием ArraySetAsSeries(OsMA_Buffer,true);
    Поскольку именно этот вариант в дальнейшем будет использован в советниках и рекомендован во всех статьях, а у меня не вышел.

    С уважением! Спасибо: 0 
    ПрофильЦитата Ответить





    Сообщение: 2573
    Зарегистрирован: 03.03.13
    Откуда: Украина, Каменское (Днепродзержинск)
    Репутация: 3
    ссылка на сообщение  Отправлено: 26.01.18 17:44. Заголовок: Тогда нужно всю инде..


    Тогда нужно всю индексацию развернуть, а не просто использовать ArraySetAsSeries.
    Т. к. цикл расчета данных для каждого бара в "правильном" индикаторе должен следовать слева направо по графику, то нужно идти от rates_total (limit поддерживать) до 0 с декрементом.

    Спасибо: 0 
    ПрофильЦитата Ответить





    Сообщение: 560
    Зарегистрирован: 05.03.13
    Репутация: 1
    ссылка на сообщение  Отправлено: 27.01.18 10:00. Заголовок: Scriptong пишет: То..


    Scriptong пишет:

     цитата:
    Тогда нужно всю индексацию развернуть, а не просто использовать ArraySetAsSeries.
    Т. к. цикл расчета данных для каждого бара в "правильном" индикаторе должен следовать слева направо по графику, то нужно идти от rates_total (limit поддерживать) до 0 с декрементом.



    На словах я это понимаю, с практикой туго.
    Устанавливаем порядок индексации массива как в таймсерии
    if(CopyBuffer(OsMA_Handle,0,0,to_copy,OsMA_Buffer)<=0)
    {
    Print("Getting OsMA_Buffer is failed! Error",GetLastError());
    return(0);
    }
    ArraySetAsSeries(OsMA_Buffer,true);

    Отобразим первые 200 баров

    for(int k=200;k>=0;k--)
    {
    Dn_OsMA_Buffer[k]=0.0; Up_OsMA_Buffer[k]=0.0;
    //-- calculate OsMA
    if(OsMA_Buffer[k]>OsMA_Buffer[k+1])
    Up_OsMA_Buffer[k]=OsMA_Buffer[k];
    else
    Dn_OsMA_Buffer[k]=OsMA_Buffer[k];
    }

    Как не пересчитываю слева-направо или наоборот, получается фигня.
    В чем не прав не знаю. Я это смогу понять, лишь проанализировав правильный код. Не зачти за лишний труд. Плиз!

    С уважением! Спасибо: 0 
    ПрофильЦитата Ответить





    Сообщение: 2574
    Зарегистрирован: 03.03.13
    Откуда: Украина, Каменское (Днепродзержинск)
    Репутация: 3
    ссылка на сообщение  Отправлено: 28.01.18 17:10. Заголовок: Sergey пишет: Как н..


    Sergey пишет:

     цитата:
    Как не пересчитываю слева-направо или наоборот, получается фигня.
    В чем не прав не знаю. Я это смогу понять, лишь проанализировав правильный код. Не зачти за лишний труд. Плиз!


    Установка признака таймсерии делается один раз, а не на каждом тике. И не для одного буфера, а для всех. Поэтому и проблема:

     цитата:

    #property indicator_separate_window
    #property indicator_buffers 3
    #property indicator_plots 2
    #property indicator_type1 DRAW_HISTOGRAM
    #property indicator_color1 clrGreen
    #property indicator_width1 2
    #property indicator_type2 DRAW_HISTOGRAM
    #property indicator_color2 clrRed
    #property indicator_width2 2
    #property indicator_level1 0
    input int ShowBars= 300;
    input int FastEMA = 34;
    input int SlowEMA = 72;
    input int SignalSMA=9;
    input ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE;
    //--- indicator buffers
    double Up_OsMA_Buffer[];
    double Dn_OsMA_Buffer[];
    double OsMA_Buffer[];
    //--- OsMA handles
    int OsMA_Handle;
    //+------------------------------------------------------------------+
    //| Custom indicator initialization function |
    //+------------------------------------------------------------------+
    int OnInit()
    {
    //--- indicator buffers mapping
    SetIndexBuffer(0,Up_OsMA_Buffer,INDICATOR_DATA);
    SetIndexBuffer(1,Dn_OsMA_Buffer,INDICATOR_DATA);
    SetIndexBuffer(2,OsMA_Buffer,INDICATOR_CALCULATIONS);

    ArraySetAsSeries(Up_OsMA_Buffer, true);
    ArraySetAsSeries(Dn_OsMA_Buffer, true);
    ArraySetAsSeries(OsMA_Buffer, true);

    IndicatorSetInteger(INDICATOR_DIGITS,_Digits+3);

    PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,SlowEMA+SignalSMA-2);
    PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,SlowEMA+SignalSMA-2);

    IndicatorSetString(INDICATOR_SHORTNAME,"FW-OsMA("+string(FastEMA)+","+string(SlowEMA)+","+string(SignalSMA)+")");

    PlotIndexSetString(0,PLOT_LABEL,"UpOsMA");
    PlotIndexSetString(1,PLOT_LABEL,"DnOsMA");

    OsMA_Handle=iOsMA(NULL,PERIOD_CURRENT,FastEMA,SlowEMA,SignalSMA,applied_price);
    //---
    return(INIT_SUCCEEDED);
    }
    //+------------------------------------------------------------------+
    //| Функция деинициализации |
    //+------------------------------------------------------------------+
    void OnDeinit(const int reason)
    {
    IndicatorRelease(OsMA_Handle); // удаляет хэндл индикатора и освобождает память занимаемую им
    ArrayFree(Up_OsMA_Buffer); // освобождаем динамический массив от данных
    ArrayFree(Dn_OsMA_Buffer);
    ArrayFree(OsMA_Buffer);
    }
    //====================================================================
    //+------------------------------------------------------------------+
    //| 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 calculated = BarsCalculated(OsMA_Handle);
    if(calculated < rates_total)
    {
    Alert("Not all data of OsMA_Handle is calculated (", calculated, "bars ). Error", GetLastError());
    return(0);
    }

    //--- we can copy not all data
    int to_copy;
    if(prev_calculated>rates_total || prev_calculated<0)
    to_copy = rates_total;
    else
    {
    to_copy = rates_total-prev_calculated;
    to_copy++;
    }
    //--- get OsMA_Buffer buffer
    if(CopyBuffer(OsMA_Handle, 0, 0, to_copy, OsMA_Buffer)<=0)
    {
    Print("Getting OsMA_Buffer is failed! Error", GetLastError());
    return(0);
    }

    //---
    int k,limit;
    if(prev_calculated == 0)
    limit = rates_total - 2;
    else
    limit = fmin(rates_total - prev_calculated, rates_total - 2);
    //--- the main loop of calculations
    for(k = limit; k >= 0; --k)
    {
    Dn_OsMA_Buffer[k] = 0.0;
    Up_OsMA_Buffer[k] = 0.0;

    //-- calculate OsMA
    if (OsMA_Buffer[k] > OsMA_Buffer[k + 1])
    Up_OsMA_Buffer[k] = OsMA_Buffer[k];
    else
    Dn_OsMA_Buffer[k] = OsMA_Buffer[k];
    }

    //--- return value of prev_calculated for next call
    return(rates_total);
    }



    Спасибо: 0 
    ПрофильЦитата Ответить





    Сообщение: 561
    Зарегистрирован: 05.03.13
    Репутация: 1
    ссылка на сообщение  Отправлено: 28.01.18 20:03. Заголовок: Scriptong пишет: Ус..


    Scriptong пишет:

     цитата:
    Установка признака таймсерии делается один раз, а не на каждом тике. И не для одного буфера, а для всех. Поэтому и проблема:



    Все точно! В этом проблема. А что с советниками? Вот пример на сайте mql5.com
    /---- indicator buffers
    double MA[]; // массив для индикатора iMA
    //---- handles for indicators
    int MA_handle; // указатель на индикатор iMA
    //+------------------------------------------------------------------+
    //| Expert initialization function |
    //+------------------------------------------------------------------+
    int OnInit()
    {
    //--- создание указателя на объект - индикатор iMA
    MA_handle=iMA(NULL,0,21,0,MODE_EMA,PRICE_CLOSE);
    return(0);
    }
    //+------------------------------------------------------------------+
    //| Expert tick function |
    //+------------------------------------------------------------------+
    void OnTick()
    {
    //--- заполнение массива MA[] текущими значениями индикатора iMA
    //--- в массив будет записано 100 элементов
    CopyBuffer(MA_handle,0,0,100,MA);
    //--- задаём порядок индексации массива MA[] как в MQL4
    ArraySetAsSeries(MA,true);
    //--- а дальше делайте с этими данными всё что угодно, например:
    if(MA[0]>MA[1])
    {
    //--- выполнение каких-то операций
    }
    }

    1. Почему в советниках порядок индексации делается на каждом тике?
    2. Есть ли возможность в советниках обновлять последние бары как в индикаторах, если для анализа нужно большое их количество.
    3. И стоит ли использовать динамический массив, если для анализа брать 2 последних бара.


    Можно ли написать так:

    double MA[2]; // массив для индикатора iMA
    //---- handles for indicators
    int MA_handle; // указатель на индикатор iMA
    //+------------------------------------------------------------------+
    //| Expert initialization function |
    //+------------------------------------------------------------------+
    int OnInit()
    {
    //--- создание указателя на объект - индикатор iMA
    MA_handle=iMA(NULL,0,21,0,MODE_EMA,PRICE_CLOSE);
    //--- задаём порядок индексации массива MA[] как в MQL4
    ArraySetAsSeries(MA,true);
    return(0);
    }
    //+------------------------------------------------------------------+
    //| Expert tick function |
    //+------------------------------------------------------------------+
    void OnTick()
    {
    //--- заполнение массива MA[] текущими значениями индикатора iMA
    //--- в массив будет записано 2 элементов
    CopyBuffer(MA_handle,0,0,2,MA);

    //--- а дальше делайте с этими данными всё что угодно, например:
    if(MA[0]>MA[1])
    {
    //--- выполнение каких-то операций
    }
    }

    С уважением! Спасибо: 0 
    ПрофильЦитата Ответить





    Сообщение: 2575
    Зарегистрирован: 03.03.13
    Откуда: Украина, Каменское (Днепродзержинск)
    Репутация: 3
    ссылка на сообщение  Отправлено: 29.01.18 16:01. Заголовок: Sergey пишет: Можно..


    Sergey пишет:

     цитата:
    Можно ли написать так:


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

     цитата:
    double MA[];
    int MA_handle;
    void OnInit()
    {
    MA_handle = iMA(NULL, 0, 21, 0, MODE_EMA, PRICE_CLOSE);
    ArraySetAsSeries(MA, true);
    }

    void OnTick()
    {
    if (!IsNewBar())
    return;

    if (CopyBuffer(MA_handle, 0, 0, 2, MA) != 2)
    {
    Print("Receiving MA values error N", GetLastError());
    return;
    }

    if (MA[0] > MA[1])
    {
    Print("MA[0] (", MA[0], ") greater than MA[1] (", MA[1], ")");
    }
    else
    Print("MA[0] (", MA[0], ") less than MA[1] (", MA[1], ")");
    }

    bool IsNewBar()
    {
    static datetime dtLastTime = 0;
    datetime arrdtTime[1];

    if (CopyTime(Symbol(), PERIOD_CURRENT, 0, 1, arrdtTime) != 1)
    {
    Print("Receiving Time value error N", GetLastError());
    return false;
    }

    bool bResult = (arrdtTime[0] != dtLastTime);
    dtLastTime = arrdtTime[0];
    return bResult;
    }



    Спасибо: 0 
    ПрофильЦитата Ответить





    Сообщение: 562
    Зарегистрирован: 05.03.13
    Репутация: 1
    ссылка на сообщение  Отправлено: 29.01.18 17:37. Заголовок: Игорь, огромное спас..


    Игорь, огромное спасибо!
    Ситуацию по обращению к индикаторам прояснил.

    С уважением! Спасибо: 0 
    ПрофильЦитата Ответить





    Сообщение: 563
    Зарегистрирован: 05.03.13
    Репутация: 1
    ссылка на сообщение  Отправлено: 18.02.18 09:47. Заголовок: Столкнулся с не пони..


    Столкнулся с не пониманием обращения к функции... в mql4.
    //+------------------------------------------------------------------+
    //| Проверяет объем ордера на корректность |
    //+------------------------------------------------------------------+
    bool CheckVolumeValueStart(double volume,string &description)
    {
    //--- минимально допустимый объем для торговых операций
    double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
    if(volume<min_volume)
    {
    description=StringFormat("Объем меньше минимально допустимого SYMBOL_VOLUME_MIN=%.2f",min_volume);
    return(false);
    }

    //--- максимально допустимый объем для торговых операций
    double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
    if(volume>max_volume)
    {
    description=StringFormat("Объем больше максимально допустимого SYMBOL_VOLUME_MAX=%.2f",max_volume);
    return(false);
    }

    //--- получим минимальную градацию объема
    double volume_step=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP);

    int ratio=(int)MathRound(volume/volume_step);
    if(MathAbs(ratio*volume_step-volume)>0.0000001)
    {
    description=StringFormat("Объем не является кратным минимальной градации SYMBOL_VOLUME_STEP=%.2f, ближайший корректный объем %.2f",
    volume_step,ratio*volume_step);
    return(false);
    }
    description="Корректное значение объема";
    return(true);
    }
    //=============================================================================
    Что делать с &description?
    if (!CheckVolumeValueStart(Lot,................)) return;
    Конечно, можно его убрать из функции, а в тексте заменить на Print. Но хотелось бы разобраться, что это значит и как правильно применить.
    Спасибо!


    С уважением! Спасибо: 0 
    ПрофильЦитата Ответить



    Сообщение: 52
    Зарегистрирован: 03.03.13
    Репутация: 0
    ссылка на сообщение  Отправлено: 18.02.18 16:55. Заголовок: Sergey пишет: Что д..


    Sergey пишет:

     цитата:
    Что делать с &description?
    if (!CheckVolumeValueStart(Lot,................)) return;
    Конечно, можно его убрать из функции, а в тексте заменить на Print. Но хотелось бы разобраться, что это значит и как правильно применить.


    Этот аргумент функции нужно рассматривать как сообщение об ошибке. Пользоваться так:

     цитата:

    string description = "";
    if (!CheckVolumeValueStart(Lot, description))
    {
    Print(description);
    return;
    }


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

    Спасибо: 0 
    ПрофильЦитата Ответить





    Сообщение: 564
    Зарегистрирован: 05.03.13
    Репутация: 1
    ссылка на сообщение  Отправлено: 18.02.18 19:03. Заголовок: Admin пишет: Могу с..


    Admin пишет:

     цитата:
    string description = "";


    А вот это я и пропустил. Забыл объявить. Спасибо Игорь!
    Admin пишет:

     цитата:
    Могу согласиться с тем, что в качестве примера такой прием вызывает недоумение. Скорее всего взято из какого-то готового проекта и вставлено как есть.


    В маркете на mql5.com при валидации (автоматической проверки на наличие ошибок) это выдано в качестве примера. Авто контроль проверяет каждую из позиций: минимальный и максимальный лот, кратность шагу и достаточность свободных средств для стартового лота в советнике. Причем ошибка обязательно должна быть выведена в журнал (Print) иначе проверку сова на проходит. Пришлось сделать отдельную объединенную функцию на будущее. Замучился, пока понял, что ошибка неправильные объемы относятся к стартовому лоту.

    С уважением! Спасибо: 0 
    ПрофильЦитата Ответить





    Сообщение: 565
    Зарегистрирован: 05.03.13
    Репутация: 1
    ссылка на сообщение  Отправлено: 19.02.18 12:12. Заголовок: Сейчас другая пробле..


    Сейчас другая проблема:"Необходимо добавить возможность проверки торговых функций программы на наличие ошибок в Тестере стратегий." В советнике заложен вывод (Alert), если ордер не установлен, при условии, что все параметры заданы правильно. Что еще нужно не пойму. Ведь Alert в журнал тоже выводится. Может кто подскажет, что означает выше указанная ошибка.....
    И вот это:
    TickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
    double Lot = CalculatedProfit/TickValue/TakeProfit;

    TickValue почему-то именно для золота равно 0. Валютные пары тестирование проходят. Бред какой-то. Как обойти не знаю. В тестере ошибок нет.

    С уважением! Спасибо: 0 
    ПрофильЦитата Ответить





    Сообщение: 2581
    Зарегистрирован: 03.03.13
    Откуда: Украина, Каменское (Днепродзержинск)
    Репутация: 3
    ссылка на сообщение  Отправлено: 19.02.18 18:14. Заголовок: Sergey пишет: Сейча..


    Sergey пишет:

     цитата:
    Сейчас другая проблема:"Необходимо добавить возможность проверки торговых функций программы на наличие ошибок в Тестере стратегий." В советнике заложен вывод (Alert), если ордер не установлен, при условии, что все параметры заданы правильно. Что еще нужно не пойму. Ведь Alert в журнал тоже выводится. Может кто подскажет, что означает выше указанная ошибка.....


    Alert при тестировании выводится в журнал тестера по аналогии с функцией Print. Само окно и звуковой сигнал, конечно же, не отображается ни в одном из режимов тестирования.

    Sergey пишет:

     цитата:
    И вот это:
    TickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
    double Lot = CalculatedProfit/TickValue/TakeProfit;

    TickValue почему-то именно для золота равно 0. Валютные пары тестирование проходят. Бред какой-то. Как обойти не знаю. В тестере ошибок нет.


    Проверил для золота на Альпари. Есть значение.
    А в онлайн что показывает?
    Еще можно попробовать заменить на более современную форму:

     цитата:

    SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE);





    Спасибо: 0 
    ПрофильЦитата Ответить





    Сообщение: 566
    Зарегистрирован: 05.03.13
    Репутация: 1
    ссылка на сообщение  Отправлено: 19.02.18 21:40. Заголовок: Scriptong пишет: ще..


    Scriptong пишет:

     цитата:
    ще можно попробовать заменить на более современную форму:


    За эту подсказку спасибо. Что современнее , то и надо применять.
    Scriptong пишет:

     цитата:
    А в онлайн что показывает?


    Значения есть. Мне видится дело не в этом, а в настойках стартового лота. Проблему решил так: Установил в стартовых настройках вместо расчетного постоянный лот. Таким образом строка в авто проверку не попала. Теперь жду замечания от модератора.....

    С уважением! Спасибо: 0 
    ПрофильЦитата Ответить
    Ответов - 203 , стр: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 All [только новые]
    Ответ:
    1 2 3 4 5 6 7 8 9
    большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

    показывать это сообщение только модераторам
    не делать ссылки активными
    Имя, пароль:      зарегистрироваться    
    Тему читают:
    - участник сейчас на форуме
    - участник вне форума
    Все даты в формате GMT  2 час. Хитов сегодня: 0
    Права: смайлы да, картинки да, шрифты да, голосования нет
    аватары да, автозамена ссылок вкл, премодерация откл, правка нет