Господа, есть советник, которого пытаюсь тестировать на сервере с демо-счётом, но он работает не совсем корректно. Суть его работы основана на мартингейле, когда он доходит до лота, который больше максимального, он не берёт максимально возможный (как это прописано в коде), а пытается отправить торговый запрос брокеру, и получает ошибку "broker comment: no money".
Подскажите пожалуйста, как изменить в коде проверку максимального лота, чтобы такой ошибки не возникало.
Или кто-то опытный может прописать этот код, по сути не займёт времени больше 5 минут, и если советник вас заинтересует - оставите себе исправленную версию.
Читайте статью "Какие проверки должен пройти советник перед публикацией в маркете".
- www.mql5.com
//+------------------------------------------------------------------+ //| Refreshes the symbol quotes data | //+------------------------------------------------------------------+ bool RefreshRates() { //--- refresh rates if(!m_symbol.RefreshRates()) { Print("RefreshRates error"); return(false); } //--- protection against the return value of "zero" if(m_symbol.Ask()==0 || m_symbol.Bid()==0) return(false); //--- return(true); } //+------------------------------------------------------------------+ //| Check the correctness of the order volume | //+------------------------------------------------------------------+ bool CheckVolumeValue(double volume,string &error_description) { //--- minimal allowed volume for trade operations double min_volume=m_symbol.LotsMin(); if(volume<min_volume) { error_description=StringFormat("Volume is less than the minimal allowed SYMBOL_VOLUME_MIN=%.2f",min_volume); return(false); } //--- maximal allowed volume of trade operations double max_volume=m_symbol.LotsMax(); if(volume>max_volume) { error_description=StringFormat("Volume is greater than the maximal allowed SYMBOL_VOLUME_MAX=%.2f",max_volume); return(true); } //--- get minimal step of volume changing double volume_step=m_symbol.LotsStep(); int ratio=(int)MathRound(volume/volume_step); if(MathAbs(ratio*volume_step-volume)>0.0000001) { error_description=StringFormat("Volume is not a multiple of the minimal step SYMBOL_VOLUME_STEP=%.2f, the closest correct volume is %.2f", volume_step,ratio*volume_step); return(false); } error_description="Correct volume value"; return(true); } //+------------------------------------------------------------------+ //| Checks if the specified filling mode is allowed | //+------------------------------------------------------------------+ bool IsFillingTypeAllowed(int fill_type) { //--- Obtain the value of the property that describes allowed filling modes int filling=m_symbol.TradeFillFlags(); //--- Return true, if mode fill_type is allowed return((filling & fill_type)==fill_type); } //+------------------------------------------------------------------+ //| Lot Check | //+------------------------------------------------------------------+ double LotCheck(double lots) { //--- calculate maximum volume double volume=NormalizeDouble(lots,2); double stepvol=m_symbol.LotsStep(); if(stepvol>0.0) volume=stepvol*MathFloor(volume/stepvol); //--- double minvol=m_symbol.LotsMin(); if(volume<minvol) volume=0.0; //--- double maxvol=m_symbol.LotsMax(); if(volume>maxvol) volume=maxvol; return(volume); }
выложил код проверки объёма
Только последняя функция считает проверяет объем.
в этой функции вы сразу нормализуете объем. Потом его пересчитываете и сравниваете с мин и макс. объемом. Надо наоборот. Сначала производим действие, потом нормализуем.
bool CheckVolumeValue(double volume,string &error_description)
В этой функции если объем меньше мин объема - то
функция возвращает false. Это правильно.
А вот если объем больше допустимого то функция вернет true. Если в дальнейшем будете пересчет то правильно. Если это конечная проверка -
то ошибка.
Только последняя функция считает проверяет объем.
в этой функции вы сразу нормализуете объем. Потом его пересчитываете и сравниваете с мин и макс. объемом. Надо наоборот. Сначала производим действие, потом нормализуем.
В этой функции если объем меньше мин объема -
то функция возвращает false. Это правильно.
А вот если объем больше допустимого то функция вернет true. Если в дальнейшем будете пересчет то правильно. Если это конечная
проверка - то ошибка.
Спасибо за наводящие мысли, общую идею я понял, но пока не сообразил, как реализовывается сразу пересчитать, и потом нормализовать.
Спасибо за наводящие мысли, общую идею я понял, но пока не сообразил, как реализовывается сразу пересчитать, и потом нормализовать.
double volume=NormalizeDouble(lots,2);
вот эту строчку убираем в начале и ставим перед return.
НУ естественно объявляем в начале volume и в конце получится
volume=NormalizeDouble(lots,2); return volume;
вот эту строчку убираем в начале и ставим перед return.
НУ естественно объявляем в начале volume и в конце получится
Спасибо большое, буду пробовать тестировать.
вот эту строчку убираем в начале и ставим перед return.
НУ естественно объявляем в начале volume и в конце получится
Всё равно он доходит до лота больше возможного, но не обновляет цикл, а выдаёт ошибку "not enought money", как я понимаю, это прописано у него прямо в коде? прикрепляю ниже
//--- check volume before OrderSend to avoid "not enough money" error (CTrade) double check_volume_lot=m_trade.CheckVolume(m_symbol.Name(),ExtLot,m_symbol.Ask(),ORDER_TYPE_BUY); if(check_volume_lot!=0.0) if(check_volume_lot>=ExtLot) { if(m_trade.Buy(ExtLot,m_symbol.Name(),m_symbol.Ask(),sl,tp)) { if(m_trade.ResultDeal()==0) { Print("#1 Buy -> false. Result Retcode: ",m_trade.ResultRetcode(), ", description of result: ",m_trade.ResultRetcodeDescription()); PrintResult(m_trade,m_symbol); } else { Print("#2 Buy -> true. Result Retcode: ",m_trade.ResultRetcode(), ", description of result: ",m_trade.ResultRetcodeDescription()); PrintResult(m_trade,m_symbol); } } else { Print("#3 Buy -> false. Result Retcode: ",m_trade.ResultRetcode(), ", description of result: ",m_trade.ResultRetcodeDescription()); PrintResult(m_trade,m_symbol); } return; } ExtLot=InpLots; //---
Извините, что отнимаю время, но не могли бы вы пояснить, как решить эту проблему, и прописать, чтобы робот доходя до лота больше максимального не останавливался, а использовал максимально возможный и заканчивал свой цикл?
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Господа, есть советник, которого пытаюсь тестировать на сервере с демо-счётом, но он работает не совсем корректно. Суть его работы основана на мартингейле, когда он доходит до лота, который больше максимального, он не берёт максимально возможный (как это прописано в коде), а пытается отправить торговый запрос брокеру, и получает ошибку "broker comment: no money".
Подскажите пожалуйста, как изменить в коде проверку максимального лота, чтобы такой ошибки не возникало.
Или кто-то опытный может прописать этот код, по сути не займёт времени больше 5 минут, и если советник вас заинтересует - оставите себе исправленную версию.