- 2010.03.16
- Denis Zyatkevich
- www.mql5.com
Так вот видимо следует не пересчитывать индикаторы рассчитанные на предыдущих прогонах.
Если тормозит не тут , то укажите где. Вот только не надо советовать поменять стратегию - да пусть она "такая" специально, но настоящую не покажу. Но тестирует МЕДЛЕННО !!!! Надо срочно улучшать тестер. !
Если без торговых операций тоже тормозит, то нужно смотреть код индикатора
void OnTick() { // int copy; /*copy = */CopyBuffer ( i1,0,0,1,i1Buffer); /*copy = */CopyBuffer ( i2,0,0,1,i2Buffer); уберем все торговые операции // if ( i1Buffer[0] != 0 ) // Sell(); // if ( i2Buffer[0] != 0 ) // Buy(); }
Так вот видимо следует не пересчитывать индикаторы рассчитанные на предыдущих прогонах.
Если тормозит не тут , то укажите где. Вот только не надо советовать поменять стратегию - да пусть она "такая" специально, но настоящую не покажу. Но тестирует МЕДЛЕННО !!!! Надо срочно улучшать тестер. !
Если тормозит не тут , то укажите где. Вот только не надо советовать поменять стратегию - да пусть она "такая" специально, но настоящую не покажу. Но тестирует МЕДЛЕННО !!!! Надо срочно улучшать тестер. !
Указываем - индикаторы неэкономные.
Но Вы не предоставили их кода.
Возможность такой оптимизации в тестере, это частный случай торговой стратегии в целом. Поэтому навряд ли появится эта оптимизация.
Указываем - индикаторы неэкономные.
Но Вы не предоставили их кода.
ОК - я потрачу время, все равно надо вас убедить :)) И покажу что все-таки, господа надо "оптимизировать" работу тестера, а иначе результата не будет.
Вот тот же "эксперт" :fff.mq5
int i1; int i2; double i1Buffer[1]; double i2Buffer[1]; input int Par=15; int OnInit() { i1=iCustom(_Symbol,_Period,"i1",Par); if ( i1 == INVALID_HANDLE ) printf("ssss-> i1"); i2=iCustom(_Symbol,_Period,"i2",Par); return(0); } void OnDeinit(const int reason) { IndicatorRelease(i1); IndicatorRelease(i2); } int Magic=12345; void Buy(void) { MqlTradeRequest mrequest; MqlTradeResult mresult; MqlTick Tick; SymbolInfoTick(_Symbol,Tick); double Lot=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN); mrequest.action=TRADE_ACTION_DEAL; // немедленное исполнение mrequest.price=NormalizeDouble(Tick.ask,_Digits); // последняя цена ask mrequest.sl = 0;// NormalizeDouble(Tick.ask - StopLoss * _Point,_Digits); // Stop Loss mrequest.tp = 0;//NormalizeDouble(Tick.ask + TakeProfit* _Point,_Digits); // Take Profit mrequest.symbol= _Symbol; // символ mrequest.volume = Lot; // количество лотов для торговли mrequest.magic = Magic; // Magic Number mrequest.type = ORDER_TYPE_BUY; // ордер на покупку mrequest.type_filling = ORDER_FILLING_AON; // тип исполнения ордера - все или ничего mrequest.deviation=3; // проскальзывание от текущей цены OrderSend(mrequest,mresult); } void Sell(void) { MqlTradeRequest mrequest; MqlTradeResult mresult; MqlTick Tick; SymbolInfoTick(_Symbol,Tick); double Lot=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN); mrequest.action=TRADE_ACTION_DEAL; // немедленное исполнение mrequest.price=NormalizeDouble(Tick.bid,_Digits); // последняя цена ask mrequest.sl = 0;//NormalizeDouble(Tick.bid + StopLoss * _Point,_Digits); // Stop Loss mrequest.tp =0;// NormalizeDouble(Tick.bid - TakeProfit* _Point,_Digits); // Take Profit mrequest.symbol= _Symbol; // символ mrequest.volume = Lot; // количество лотов для торговли mrequest.magic = Magic; // Magic Number mrequest.type = ORDER_TYPE_SELL; // ордер на продажу mrequest.type_filling = ORDER_FILLING_AON; // тип исполнения ордера - все или ничего mrequest.deviation=3; // проскальзывание от текущей цены OrderSend(mrequest,mresult); } void OnTick() { // int copy; /*copy = */CopyBuffer ( i1,0,0,1,i1Buffer); /*copy = */CopyBuffer ( i2,0,0,1,i2Buffer); if ( i1Buffer[0] != 0 ) Sell(); if ( i2Buffer[0] != 0 ) Buy(); } //+------------------------------------------------------------------+
Вот индикаторы :
i1.mq5 ->
#property indicator_chart_window #property indicator_buffers 1 #property indicator_plots 1 #property indicator_label1 "i1" #property indicator_type1 DRAW_LINE #property indicator_color1 Red #property indicator_style1 STYLE_SOLID #property indicator_width1 1 input int Par=15; double Label1Buffer[]; int OnInit() { SetIndexBuffer(0,Label1Buffer,INDICATOR_DATA); return(0); } 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[]) { for ( int i=prev_calculated; i<rates_total; i++){ int sum=0; int e=i+Par; if ( e > rates_total ) e=rates_total; if ( (e-i)/3 != 0 ){ for ( int j=i; j<e; j++ ) sum += (int)(open[j]/_Point); sum = sum / ( (e-i)/3 ); if ( (sum % Par) == 0 ) Label1Buffer[i]=open[i]; } } return(rates_total); }
Вот i2.mq5->
#property indicator_chart_window #property indicator_buffers 1 #property indicator_plots 1 #property indicator_label1 "i2" #property indicator_type1 DRAW_LINE #property indicator_color1 Red #property indicator_style1 STYLE_SOLID #property indicator_width1 1 input int Par=15; double Label1Buffer[]; int OnInit() { SetIndexBuffer(0,Label1Buffer,INDICATOR_DATA); return(0); } 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[]) { for ( int i=prev_calculated; i<rates_total; i++){ int sum=0; int e=i+Par; if ( e > rates_total ) e=rates_total; if ( (e-i)/3 != 0 ){ for ( int j=i; j<e; j++ ) sum += (int)(open[j]/_Point); sum = sum / ( (e-i)/3 ); if ( (sum % (Par+Par/2)) == 0 ) Label1Buffer[i]=open[i]; } } return(rates_total); }
Не сказать что какой-то выдающийся код у индикаторов. Не сказать что перегруженный. Но зачем его вычислять сто-тыщь раз при оптимизации на одних и тех же данных не понятно.
Academic:
Представьте себе 2000 прогонов от начальной даты и до конечной - параметры не меняются => можно один раз индикатор просчитать и потом только выдавать расчетные. :) То есть если код експерта из трех строк, то тут уж по любому надо расчитывать индикатор один раз. Правда есть проблемы с нулевым баром. Так как там бар по которому расчитывается индикатор еще не сформирован. Но заниматься одинаковыми расчетами - глупо.
Такой подход годится только при режиме "по ценам открытия".
Как быть со значениями индикатора в процессе развития бара?
- www.mql5.com
Такой подход годится только при режиме "по ценам открытия".
Как быть со значениями индикатора в процессе развития бара?
Все просто - надо хранить результаты один раз просчитать и все - сохранить на диске и выдавать. Число тиков одинаково на каждый тик сохранил значение индикатора и потом только выдаешь - не считаешь. Иначе нафиг-нафиг такой оптимизатор. Вы же сами нагрузили тестер мультивалетностью, и хотите со старым подходом как в четверке? Вот поэтому и получается что медленно. И надо отработать компенсацию ( соптимизировать) по мультивалютной нагрузке.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования