Местами резануло в коде.
//+------------------------------------------------------------------+ //| Returns the name timeframe | //+------------------------------------------------------------------+ string NameTimeframe(int timeframe=PERIOD_CURRENT) { if(timeframe==PERIOD_CURRENT) timeframe=Period(); switch(timeframe) { case 1 : return "M1"; case 2 : return "M2"; case 3 : return "M3"; case 4 : return "M4"; case 5 : return "M5"; case 6 : return "M6"; case 10 : return "M10"; case 12 : return "M12"; case 15 : return "M15"; case 20 : return "M20"; case 30 : return "M30"; case 16385 : return "H1"; case 16386 : return "H2"; case 16387 : return "H3"; case 16388 : return "H4"; case 16390 : return "H6"; case 16392 : return "H8"; case 16396 : return "H12"; case 16408 : return "D1"; case 32769 : return "W1"; case 49153 : return "MN1"; default : return (string)(int)Period(); } }
string NameTimeframe( const ENUM_TIMEFRAMES timeframe = PERIOD_CURRENT ) { return(StringSubstr(EnumToString(timeframe == PERIOD_CURRENT ? Period() : timeframe), 7)); }
//+------------------------------------------------------------------+ //| Заполняет массивы тикетов позиций | //+------------------------------------------------------------------+ void FillingListTickets(void) { list_tickets_buy.Clear(); list_tickets_sell.Clear(); total_volume_buy=0; total_volume_sell=0; //--- int total=PositionsTotal(); for(int i=total-1; i>=0; i--) { ulong ticket=PositionGetTicket(i); ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); if(PositionGetInteger(POSITION_MAGIC)!=InpMagic) continue; if(PositionGetString(POSITION_SYMBOL)!=symb) continue; double volume=PositionGetDouble(POSITION_VOLUME); if(type==POSITION_TYPE_BUY) { list_tickets_buy.Add(ticket); total_volume_buy+=volume; } else if(type==POSITION_TYPE_SELL) { list_tickets_sell.Add(ticket); total_volume_sell+=volume; } } }
Нет проверки PositionGetTicket.
"else if" может быть просто "else".
type берется не после continue.
В советнике нет отложенных ордеров, поэтому такое
double price=(order_type==ORDER_TYPE_BUY ? symbol_info.Ask() : symbol_info.Bid());
Такое условие корректно только для POSITION_TYPE_BUY.
В советнике нет отложенных ордеров, поэтому такое
Такое условие корректно только для POSITION_TYPE_BUY.
Почему?
Вызов этой функции присутствует в двух местах кода:
//--- Открытие позиций по сигналам if(open_long) { if(num_s>0) CloseSell(); if(num_b==0) { double sl=(InpStopLoss==0 ? 0 : CorrectStopLoss(ORDER_TYPE_BUY,InpStopLoss)); double tp=(InpTakeProfit==0 ? 0 : CorrectTakeProfit(ORDER_TYPE_BUY,InpTakeProfit)); double ll=trade.CheckVolume(symb,lot,symbol_info.Ask(),ORDER_TYPE_BUY); if(ll>0 && CheckLotForLimitAccount(POSITION_TYPE_BUY,ll)) { if(trade.Buy(ll,symb,0,sl,tp)) FillingListTickets(); } } } if(open_short) { if(num_b>0) CloseBuy(); if(num_s==0) { double sl=(InpStopLoss==0 ? 0 : CorrectStopLoss(ORDER_TYPE_SELL,InpStopLoss)); double tp=(InpTakeProfit==0 ? 0 : CorrectTakeProfit(ORDER_TYPE_SELL,InpTakeProfit)); double ll=trade.CheckVolume(symb,lot,symbol_info.Ask(),ORDER_TYPE_SELL); if(ll>0 && CheckLotForLimitAccount(POSITION_TYPE_SELL,ll)) { if(trade.Sell(ll,symb,0,sl,tp)) FillingListTickets(); } } }
Соответственно, если только сам программист, писавший этот код, сдуру отправит в функцию не тот тип ордера, то да, будет ошибка. В случае этого кода - её не будет.
Почему?
Вызов этой функции присутствует в двух местах кода:
Соответственно, если только сам программист, писавший этот код, сдуру отправит в функцию не тот тип ордера, то да, будет ошибка. В случае этого кода - её не будет.
Потому что может быть разный взгляд на КБ
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
МТ4 или МТ5. Какие преимущества и недостатки?
Renat Fatkhullin, 2018.01.31 14:28
- 4300 программ и 870 экспертов включительно, в исходниках, заведомо достаточно для обучения и развития собственных идей
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
МТ4 или МТ5. Какие преимущества и недостатки?
Renat Fatkhullin, 2018.01.31 15:53
Не шлак, а питательная среда для обучающихся.
Не утверждается, что в данном частном случае будет ошибка. Но функции мигрируют из одного кода в другой. Потенциальная ошибка в мигрирующей функции, как висящее ружье на стене.
Можно, конечно, сквозь пальцы это пропустить. Но мне видится здесь, что лучше предупредить.
Потому что может быть разный взгляд на КБ
Не утверждается, что в данном частном случае будет ошибка. Но функции мигрируют из одного кода в другой. Потенциальная ошибка в мигрирующей функции, как висящее ружье на стене.
Можно, конечно, сквозь пальцы это пропустить. Но мне видится здесь, что лучше предупредить.
Вы правы, предупредить - это верно.
Автор наверняка имел в виду убрать лишние ненужные проверки - в некоторых случаях универсальность - лишнее. Тут наверное вас сбило с толку перечисление ENUM_ORDER_TYPE. Если бы там было ENUM_POSITION_TYPE, то и вопросов бы не возникло.
Равно как и ваше предложение резать текст. Разве switch не быстрее?
Автор наверняка имел в виду убрать лишние ненужные проверки - в некоторых случаях универсальность - лишнее. Тут наверное вас сбило с толку перечисление ENUM_ORDER_TYPE. Если бы там было ENUM_POSITION_TYPE, то и вопросов бы не возникло.
Здесь и саму функцию и ее вызовы нужно было поправить. Автор еще с MT4 не осознал этого до конца.
Равно как и ваше предложение резать текст. Разве switch не быстрее?
А вот подобные switch-конструкции - это как раз то, как не нужно делать. Что касается скорости, то для этой функции она не нужна совсем. Но пример на самом деле получился показательным. И, как минимум, заинтересует.
Здесь и саму функцию и ее вызовы нужно было поправить. Автор еще с MT4 не осознал этого до конца.
А вот подобные switch-конструкции - это как раз то, как не нужно делать. Что касается скорости, то для этой функции она не нужна совсем. Но пример на самом деле получился показательным. И, как минимум, заинтересует.
Интересно. А в чём по вашему мнению не верность подхода к стандартному расчёту минимальной дистанции установки стоп-приказов?
//+------------------------------------------------------------------+ //| Возвращает корректный StopLoss относительно StopLevel | //+------------------------------------------------------------------+ double CorrectStopLoss(const ENUM_ORDER_TYPE order_type,const int stop_loss) { if(stop_loss==0) return 0; double pt=symbol_info.Point(); double price=(order_type==ORDER_TYPE_BUY ? symbol_info.Ask() : symbol_info.Bid()); int lv=StopLevel(),dg=symbol_info.Digits(); return (order_type==ORDER_TYPE_BUY ? NormalizeDouble(fmin(price-lv*pt,price-stop_loss*pt),dg) : NormalizeDouble(fmax(price+lv*pt,price+stop_loss*pt),dg) ); } //+------------------------------------------------------------------+
//+------------------------------------------------------------------+ //| Возвращает рассчитанный StopLevel | //+------------------------------------------------------------------+ int StopLevel(void) { int sp=symbol_info.Spread(); int lv=symbol_info.StopsLevel(); return(lv==0 ? sp*size_spread : lv); } //+------------------------------------------------------------------+
Я не вижу тут ошибок. Поясните. И в чём разница расчёта минимальной дистанции для MT4 и МТ5 ?
В коде на самом деле есть еще ошибки. Например, хорошо показано, что использовать CSymbolInfo лишь ради СБ-style - зло.
Закрывать позиции через ранее собранный список тикетов - зло. Это очень распространенная ошибка.
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
fxsaber, 2018.01.23 09:39
Это неправильная логика. После неудачного и удачного OrderSend должно быть заново полностью считано текущее торговое окружение. Это правило должно действовать всегда.
Насчет кодов возврата. В своих советниках никак не анализирую их. По-моему, торговая логика не должна от них зависеть.
Интересно. А в чём по вашему мнению не верность подхода к стандартному расчёту минимальной дистанции установки стоп-приказов?
Я не вижу тут ошибок. Поясните. И в чём разница расчёта минимальной дистанции для MT4 и МТ5 ?
Там ошибка в enum-входе и вызове, а не в мин. дистанции. Но и она рассчитывается неверно, потому что
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
fxsaber, 2018.02.01 21:38
хорошо показано, что использовать CSymbolInfo лишь ради СБ-style - зло.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Diff_TF_MA_EA:
Советник на основе индикатора Diff_TF_MA. В основе сигналов советника лежит обычное пересечение двух линий скользящих средних:
На одном сигнале открывается одна соответствующая позиция. Противоположная закрывается.
Сам индикатор для работы советника не требуется - все расчеты скользящих средних сделаны непосредственно в коде советника.
Советник позволяет реверсировать сигналы индикатора - открывать вместо покупок продажи, и наоборот. Так же можно задать стоп лосс и тейк профит в пунктах. При ошибочно заданных размерах стоп лосс или тейк профит советник их автоматически корректирует под минимальный размер StopLevel, установленный для символа.
Советник также скорректирует лот при неверно указанном значении. Если же лот слишком большой при открытии позиции, то советник выставит его таким, чтобы позицию можно было открыть. Если нет денег на открытие даже минимальным лотом, то сигнал будет пропущен.
Советник имеет девять настраиваемых параметров:
Для проверки стратегии был проведен тест с настройками по умолчанию на промежутке дат с 2017.01.02 по 2018.01.19. К сожалению, с настройками по умолчанию советник не показал никаких интересных результатов. Поэтому был проведен тест в режиме реверса сделок. Тут результаты были поинтереснее, и была проведена минимальная оптимизация всего одного параметра - Period of MA - в диапазоне от 1 до 20 с шагом 1. Лучшим вариантом при оптимизации на максимальный баланс оказался период 8.
Рис.1 Результат тестирования 2017.01.02 - 2018.01.19, период 8, реверс сделок включен
Рис.2 График тестирования 2017.01.02 - 2018.01.19, период 8, реверс сделок включен
Автор: Scriptor