Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Пожалуйста 🙂. Как видите ничего сложного в 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 пунктов по "четырёхзнаку". Возьмите любой мой последний код из кодобазы - там это есть.
Поправил обращение к массивам.
Как оптимизируете (вставьте в сообщение скриншот вкладок тестера "Настройки" и "Параметры").
Добавлено: а также укажите тип торгового счёта - неттинг или хедж.
Сейчас все хорошо. Во всяком случае, уже не происходит торможения на 400-500 проходах. Вы решили проблему. Спасибо.
Тип счета: хедж.
Добавлено, добавлено, добавлено: у вас ошибка - Вы не тюнингуете размер стопа и тейкпрофита в зависимости от "пяти" или "четырехзнака". В итоге ВЫ пытаетесь выставлять нереально близко стоп и тейк - в районе 1 и 2 пунктов по "четырёхзнаку". Возьмите любой мой последний код из кодобазы - там это есть.
Остальные вопросы не раньше вечера.
Добавлено, добавлено, добавлено: у вас ошибка - Вы не тюнингуете размер стопа и тейкпрофита в зависимости от "пяти" или "четырехзнака". В итоге ВЫ пытаетесь выставлять нереально близко стоп и тейк - в районе 1 и 2 пунктов по "четырёхзнаку". Возьмите любой мой последний код из кодобазы - там это есть.
Остальные вопросы не раньше вечера.
Как успехи?
Все отлично оптимизировалось! А у Вас, случайно, нет функции, которая расчитывает размер лота в зависимости от риска(в процентах) на сделку?
Все отлично оптимизировалось! А у Вас, случайно, нет функции, которая расчитывает размер лота в зависимости от риска(в процентах) на сделку?
На базе класса
CMoneyFixedRisk
- данный класс рассчитаем размер лота в зависимости от процента риска. Расчёт ведётся от размера баланса!
И проверочный пример (в данном примере, как и во всех экспертах на базе CExpert) двухуровневая проверка:
double check_open_long_lot=m_money.CheckOpenLong(m_symbol.Ask(),m_symbol.Bid()-ExtStopLoss);
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>=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%.
На базе класса
- данный класс рассчитаем размер лота в зависимости от процента риска. Расчёт ведётся от размера баланса!
И проверочный пример (в данном примере, как и во всех экспертах на базе CExpert) двухуровневая проверка:
double check_open_long_lot=m_money.CheckOpenLong(m_symbol.Ask(),m_symbol.Bid()-ExtStopLoss);
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>=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%.
Скажите, я правильно понимаю, что если не вызывать индикатор в коде советника, а написать логику индикатора в самом советнике, а потом оперировать показаниями на определенном баре, то можно ускорить оптимизацию?