Оптимизация - страница 2

 
Vladimir Karputov:
Пожалуйста 🙂. Как видите ничего сложного в MQL5 нет.

К сожалению, все равно, около 500-го прохода начинает ОООЧЕНЬ тормозить оптимизация. Возможно, есть еще какие-то моменты, которые я не учел при написании. Я уже взял период оптимизации 1 день(!!!), на котором очень заметно понижение темпа оптимизации.  Скидываю весь код:

//+------------------------------------------------------------------+
//|                                                          123.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"



string symb=Symbol();

double High[], Low[];
int barscount;


input int BBshift=1;
input double BBdeviation=1.0;
input int numberbarBB=1;
input int countofbars=1;
input int pointBB=20;
input int enterpoint=20;
input int stop=10;
input int take=20;
input int periodBB=20;








//---------- indicators ------------+
int handle_iBands;

int OnInit()
{
handle_iBands=iBands(Symbol(),Period(),periodBB,BBshift,BBdeviation,PRICE_CLOSE);

   if(handle_iBands==INVALID_HANDLE)
     {
    
      PrintFormat("Failed to create handle of the iBands indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      
      return(INIT_FAILED);
     }


   return(INIT_SUCCEEDED);


}


void OnTick()
{



double _bollmiddle=iBandsGet(BASE_LINE,numberbarBB);
double _bolllow=iBandsGet(LOWER_BAND,numberbarBB);
double _bollhigh=iBandsGet(UPPER_BAND,numberbarBB);












if((_bollhigh-_bolllow)/_Point<pointBB&&OrdersTotal()==0&&PositionsTotal()==0) //Если верхней линией индикатора и нижней меньше определенного значения
{
if(iHigh(symb,0,numberbarBB)<_bollhigh) //Если Хай
{

MqlTradeRequest requestbuy={0};
   MqlTradeResult  resultbuy={0};
//--- параметры запроса
   requestbuy.action   =TRADE_ACTION_PENDING;                     // тип торговой операции
   requestbuy.symbol   =symb;                              // символ
   requestbuy.volume   =0.1;                                 // объем в 0.1 лот
   requestbuy.type     =ORDER_TYPE_BUY_STOP;                        // тип ордера
   requestbuy.price    =_bollhigh+enterpoint*_Point; // цена для открытия
   requestbuy.deviation=3;                                     // допустимое отклонение от цены
   requestbuy.magic    =0;                          // MagicNumber ордера
   requestbuy.sl       =_bolllow-stop*_Point;
   requestbuy.tp       =_bollhigh+take*_Point;
  

//Alert(_bollh[1]+10*_Point);
OrderSend(requestbuy,resultbuy);
}

if(iLow(symb,0,numberbarBB)>_bolllow)
{

MqlTradeRequest requestsell={0};
   MqlTradeResult  resultsell={0};
//--- параметры запроса
   requestsell.action   =TRADE_ACTION_PENDING;                     // тип торговой операции
   requestsell.symbol   =symb;                              // символ
   requestsell.volume   =0.1;                                  // объем в 0.1 лот
   requestsell.type     =ORDER_TYPE_SELL_STOP;                        // тип ордера
   requestsell.price    =_bolllow-enterpoint*_Point; // цена для открытия
   requestsell.deviation=3;                                     // допустимое отклонение от цены
   requestsell.magic    =0;                          // MagicNumber ордера
   requestsell.sl       =_bollhigh+stop*_Point;
   requestsell.tp       =_bolllow-take*_Point;

//Alert(_bollh[1]+10*_Point);
OrderSend(requestsell,resultsell);


}



barscount=Bars(symb,0);



}



  if(Bars(symb,0)==barscount+countofbars)
  {
     MqlTradeRequest request={0};
   MqlTradeResult  result={0};
   int total=OrdersTotal(); // количество установленных отложенных ордеров
//--- перебор всех установленных отложенных ордеров
   for(int i=total-1; i>=0; i--)
     {
      ulong  order_ticket=OrderGetTicket(i);                   // тикет ордера
      //--- если MagicNumber совпадает
      if(Symbol()==symb)
        {
         //--- обнуление значений запроса и результата
         ZeroMemory(request);
         ZeroMemory(result);
         //--- установка параметров операции    
         request.action=TRADE_ACTION_REMOVE;                   // тип торговой операции
         request.order = order_ticket;                         // тикет ордера
         //--- отправка запроса
         if(!OrderSend(request,result))
            PrintFormat("OrderSend error %d",GetLastError());  // если отправить запрос не удалось, вывести код ошибки
         //--- информация об операции  
         PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
        }
     }
  }


}








double iHigh(string symbol,ENUM_TIMEFRAMES timeframe,int index)
  {
   double high=0;
   ArraySetAsSeries(High,true);
   int copied=CopyHigh(symbol,timeframe,0,Bars(symbol,timeframe),High);
   if(copied>0 && index<copied) high=High[index];
   return(high);
  }
  
  
  
  
  double iLow(string symbol,ENUM_TIMEFRAMES timeframe,int index)
  {
   double low=0;
   ArraySetAsSeries(Low,true);
   int copied=CopyLow(symbol,timeframe,0,Bars(symbol,timeframe),Low);
   if(copied>0 && index<copied) low=Low[index];
   return(low);
  }
  
  


  
  
  double iBandsGet(const int buffer,const int index)
  {
   double Bands[];
   ArraySetAsSeries(Bands,true);

   ResetLastError();

   if(CopyBuffer(handle_iBands,buffer,0,index+1,Bands)<0)
     {

      PrintFormat("Failed to copy data from the iBands indicator, error code %d",GetLastError());

      return(0.0);
     }
   return(Bands[index]);
  }
 

Поправил обращение к массивам.

Как оптимизируете (вставьте в сообщение скриншот вкладок тестера "Настройки" и "Параметры").

 

Добавлено: а также укажите тип торгового счёта - неттинг или хедж. 

 

Добавлено, добавлено: а Вам точно нужно на каждом тике работать? Не легче проверять условие один раз - на открытии бара?

 

Добавлено, добавлено, добавлено: у вас ошибка - Вы не тюнингуете размер стопа и тейкпрофита в зависимости от "пяти" или "четырехзнака". В итоге ВЫ пытаетесь выставлять нереально близко стоп и тейк - в районе 1 и 2 пунктов по "четырёхзнаку". Возьмите любой мой последний код из кодобазы - там это есть.

Файлы:
123.mq5  14 kb
 
Vladimir Karputov:

Поправил обращение к массивам.

Как оптимизируете (вставьте в сообщение скриншот вкладок тестера "Настройки" и "Параметры").

Добавлено: а также укажите тип торгового счёта - неттинг или хедж. 

Сейчас все хорошо. Во всяком случае, уже не происходит торможения на 400-500 проходах. Вы решили проблему. Спасибо.

 

 

Тип счета: хедж. 

 

Добавлено, добавлено, добавлено: у вас ошибка - Вы не тюнингуете размер стопа и тейкпрофита в зависимости от "пяти" или "четырехзнака". В итоге ВЫ пытаетесь выставлять нереально близко стоп и тейк - в районе 1 и 2 пунктов по "четырёхзнаку". Возьмите любой мой последний код из кодобазы - там это есть.

 

Остальные вопросы не раньше вечера. 

 
Vladimir Karputov:

Добавлено, добавлено, добавлено: у вас ошибка - Вы не тюнингуете размер стопа и тейкпрофита в зависимости от "пяти" или "четырехзнака". В итоге ВЫ пытаетесь выставлять нереально близко стоп и тейк - в районе 1 и 2 пунктов по "четырёхзнаку". Возьмите любой мой последний код из кодобазы - там это есть.

 

Остальные вопросы не раньше вечера. 

Я Вас понял. Спасибо.
 
Как успехи?
 
Vladimir Karputov:
Как успехи?
Все отлично оптимизировалось! А у Вас, случайно, нет функции, которая расчитывает  размер лота в зависимости от риска(в процентах) на сделку? 
 
Igor Knyazkov:
Все отлично оптимизировалось! А у Вас, случайно, нет функции, которая расчитывает  размер лота в зависимости от риска(в процентах) на сделку? 
Отдельно нет - так как я генерирую советники при помощи Мастера MQL5 (сначала создаю индикатор, потом на его базе создаю модуль сигналов) - и там-же выбираю модуль управления капиталом: Управление капиталом.
 
Igor Knyazkov:
Все отлично оптимизировалось! А у Вас, случайно, нет функции, которая расчитывает  размер лота в зависимости от риска(в процентах) на сделку? 

На базе класса

CMoneyFixedRisk

Класс CMoneyFixedRisk Класс CMoneyFixedRisk является классом для реализации алгоритма торговли с фиксированным уровнем риска. Описание Класс CMoneyFixedRisk реализует алгоритм для входа в рынок фиксированным уровнем риска, заданным при настройке. Декларация class CMoneyFixedRisk: public CExpertMoney Заголовок #include <Expert\Money\MoneyFixedRisk.mqh> Методы класса по группам Методы управления капиталом и рисками virtual CheckOpenLong Определяет объем для открытия длинной позиции virtual CheckOpenShort Определяет объем для открытия короткой позиции

- данный класс рассчитаем размер лота в зависимости от процента риска. Расчёт ведётся от размера баланса!

И проверочный пример (в данном примере, как и во всех экспертах на базе CExpert) двухуровневая проверка:

  1. уровень #1 - запрос размера лота у класса CMoneyFixedRisk (помним, что расчёт ведётся от размера баланса, при этом просадка по средствам не берётся в расчёт)
          //--- getting lot size for open long position (CMoneyFixedRisk)
          double check_open_long_lot=m_money.CheckOpenLong(m_symbol.Ask(),m_symbol.Bid()-ExtStopLoss);
  2. если размер лота не равен "0", то уровень #2 - запрос размера лота у класса CTrade - дабы избежать ошибки "not enough money" (здесь проводится расчёт лота в зависимости от средств)
          if(check_open_long_lot==0.0)
             return;

          //--- check volume before OrderSend to avoid "not enough money" error (CTrade)
          double chek_volime_lot=m_trade.CheckVolume(m_symbol.Name(),check_open_long_lot,m_symbol.Ask(),ORDER_TYPE_BUY);
  3. последняя проверка от меня: если класс CTrade выдал размер лота меньше, чем выдал класс CMoneyFixedRisk - значит позицию не открываем:
          if(chek_volime_lot!=0.0)
             if(chek_volime_lot>=check_open_long_lot)
                m_trade.Buy(chek_volime_lot,NULL,m_symbol.Ask(),m_symbol.Bid()-ExtStopLoss,m_symbol.Bid()+ExtStopLoss);
          else
             Print("CMoneyFixedRisk lot = ",DoubleToString(check_open_long_lot,2),
                   ", CTrade lot = ",DoubleToString(chek_volime_lot,2));

Весь код:

//+------------------------------------------------------------------+
//|                                          TestCMoneyFixedRisk.mq5 |
//|                              Copyright © 2016, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>  
#include <Trade\AccountInfo.mqh>
#include <Expert\Money\MoneyFixedRisk.mqh>
CTrade         m_trade;                      // trading object
CSymbolInfo    m_symbol;                     // symbol info object
CAccountInfo   m_account;                    // account info wrapper
CMoneyFixedRisk m_money;
//---
input ushort   InpStopLoss=25;
//---
double ExtStopLoss=0.0;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   m_symbol.Name(Symbol());
   m_symbol.Refresh();
   if(!RefreshRates())
     {
      Print("Error RefreshRates. Bid=",DoubleToString(m_symbol.Bid(),Digits()),
            ", Ask=",DoubleToString(m_symbol.Ask(),Digits()));
      return(INIT_FAILED);
     }
//--- tuning for 3 or 5 digits
   int digits_adjust=1;
   if(m_symbol.Digits()==3 || m_symbol.Digits()==5)
      digits_adjust=10;
   ExtStopLoss=InpStopLoss*m_symbol.Point()*digits_adjust;
//---
   if(!m_money.Init(GetPointer(m_symbol),Period(),m_symbol.Point()*digits_adjust))
      return(INIT_FAILED);
   m_money.Percent(10); // 10% risk
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   if(!RefreshRates())
      return;

   static long count=0;
   if(count%980==0) // we pass 980 tics
     {
      //--- getting lot size for open long position (CMoneyFixedRisk)
      double check_open_long_lot=m_money.CheckOpenLong(m_symbol.Ask(),m_symbol.Bid()-ExtStopLoss);
      Print("CheckOpenLong: ",DoubleToString(check_open_long_lot,2),
            ", Balance: ",    DoubleToString(m_account.Balance(),2),
            ", Equity: ",     DoubleToString(m_account.Equity(),2),
            ", FreeMargin: ", DoubleToString(m_account.FreeMargin(),2));
      if(check_open_long_lot==0.0)
         return;

      //--- check volume before OrderSend to avoid "not enough money" error (CTrade)
      double chek_volime_lot=m_trade.CheckVolume(m_symbol.Name(),check_open_long_lot,m_symbol.Ask(),ORDER_TYPE_BUY);

      if(chek_volime_lot!=0.0)
         if(chek_volime_lot>=check_open_long_lot)
            m_trade.Buy(chek_volime_lot,NULL,m_symbol.Ask(),m_symbol.Bid()-ExtStopLoss,m_symbol.Bid()+ExtStopLoss);
      else
         Print("CMoneyFixedRisk lot = ",DoubleToString(check_open_long_lot,2),
               ", CTrade lot = ",DoubleToString(chek_volime_lot,2));
      //---
     }
   count++;
  }
//+------------------------------------------------------------------+
//| Refreshes the symbol quotes data                                 |
//+------------------------------------------------------------------+
bool RefreshRates()
  {
//--- refresh rates
   if(!m_symbol.RefreshRates())
      return(false);
//--- protection against the return value of "zero"
   if(m_symbol.Ask()==0 || m_symbol.Bid()==0)
      return(false);
//---
   return(true);
  }
//+------------------------------------------------------------------+


Таким образом этот код будет открывать позицию с фиксированным размером риска от баланса в 10%.

Файлы:
 
Vladimir Karputov:

На базе класса

- данный класс рассчитаем размер лота в зависимости от процента риска. Расчёт ведётся от размера баланса!

И проверочный пример (в данном примере, как и во всех экспертах на базе CExpert) двухуровневая проверка:

  1. уровень #1 - запрос размера лота у класса CMoneyFixedRisk (помним, что расчёт ведётся от размера баланса, при этом просадка по средствам не берётся в расчёт)
          //--- getting lot size for open long position (CMoneyFixedRisk)
          double check_open_long_lot=m_money.CheckOpenLong(m_symbol.Ask(),m_symbol.Bid()-ExtStopLoss);
  2. если размер лота не равен "0", то уровень #2 - запрос размера лота у класса CTrade - дабы избежать ошибки "not enough money" (здесь проводится расчёт лота в зависимости от средств)
          if(check_open_long_lot==0.0)
             return;

          //--- check volume before OrderSend to avoid "not enough money" error (CTrade)
          double chek_volime_lot=m_trade.CheckVolume(m_symbol.Name(),check_open_long_lot,m_symbol.Ask(),ORDER_TYPE_BUY);
  3. последняя проверка от меня: если класс CTrade выдал размер лота меньше, чем выдал класс CMoneyFixedRisk - значит позицию не открываем:
          if(chek_volime_lot!=0.0)
             if(chek_volime_lot>=check_open_long_lot)
                m_trade.Buy(chek_volime_lot,NULL,m_symbol.Ask(),m_symbol.Bid()-ExtStopLoss,m_symbol.Bid()+ExtStopLoss);
          else
             Print("CMoneyFixedRisk lot = ",DoubleToString(check_open_long_lot,2),
                   ", CTrade lot = ",DoubleToString(chek_volime_lot,2));

Весь код:

//+------------------------------------------------------------------+
//|                                          TestCMoneyFixedRisk.mq5 |
//|                              Copyright © 2016, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>  
#include <Trade\AccountInfo.mqh>
#include <Expert\Money\MoneyFixedRisk.mqh>
CTrade         m_trade;                      // trading object
CSymbolInfo    m_symbol;                     // symbol info object
CAccountInfo   m_account;                    // account info wrapper
CMoneyFixedRisk m_money;
//---
input ushort   InpStopLoss=25;
//---
double ExtStopLoss=0.0;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   m_symbol.Name(Symbol());
   m_symbol.Refresh();
   if(!RefreshRates())
     {
      Print("Error RefreshRates. Bid=",DoubleToString(m_symbol.Bid(),Digits()),
            ", Ask=",DoubleToString(m_symbol.Ask(),Digits()));
      return(INIT_FAILED);
     }
//--- tuning for 3 or 5 digits
   int digits_adjust=1;
   if(m_symbol.Digits()==3 || m_symbol.Digits()==5)
      digits_adjust=10;
   ExtStopLoss=InpStopLoss*m_symbol.Point()*digits_adjust;
//---
   if(!m_money.Init(GetPointer(m_symbol),Period(),m_symbol.Point()*digits_adjust))
      return(INIT_FAILED);
   m_money.Percent(10); // 10% risk
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   if(!RefreshRates())
      return;

   static long count=0;
   if(count%980==0) // we pass 980 tics
     {
      //--- getting lot size for open long position (CMoneyFixedRisk)
      double check_open_long_lot=m_money.CheckOpenLong(m_symbol.Ask(),m_symbol.Bid()-ExtStopLoss);
      Print("CheckOpenLong: ",DoubleToString(check_open_long_lot,2),
            ", Balance: ",    DoubleToString(m_account.Balance(),2),
            ", Equity: ",     DoubleToString(m_account.Equity(),2),
            ", FreeMargin: ", DoubleToString(m_account.FreeMargin(),2));
      if(check_open_long_lot==0.0)
         return;

      //--- check volume before OrderSend to avoid "not enough money" error (CTrade)
      double chek_volime_lot=m_trade.CheckVolume(m_symbol.Name(),check_open_long_lot,m_symbol.Ask(),ORDER_TYPE_BUY);

      if(chek_volime_lot!=0.0)
         if(chek_volime_lot>=check_open_long_lot)
            m_trade.Buy(chek_volime_lot,NULL,m_symbol.Ask(),m_symbol.Bid()-ExtStopLoss,m_symbol.Bid()+ExtStopLoss);
      else
         Print("CMoneyFixedRisk lot = ",DoubleToString(check_open_long_lot,2),
               ", CTrade lot = ",DoubleToString(chek_volime_lot,2));
      //---
     }
   count++;
  }
//+------------------------------------------------------------------+
//| Refreshes the symbol quotes data                                 |
//+------------------------------------------------------------------+
bool RefreshRates()
  {
//--- refresh rates
   if(!m_symbol.RefreshRates())
      return(false);
//--- protection against the return value of "zero"
   if(m_symbol.Ask()==0 || m_symbol.Bid()==0)
      return(false);
//---
   return(true);
  }
//+------------------------------------------------------------------+


Таким образом этот код будет открывать позицию с фиксированным размером риска от баланса в 10%.

Спасибо. Это, что надо!)
Скажите, я правильно понимаю, что если не вызывать индикатор в коде советника, а написать логику индикатора в самом советнике, а потом оперировать показаниями на определенном баре, то можно ускорить оптимизацию
Причина обращения: