К сожалению, заявление голословно:
1) нет кода
2) нет точного описания условий тестирования
3) нет логов и отчетов
Большая разница просто по готовым барам пробежаться против даже минимального моделирования OHLC и рыночных условий.
//+------------------------------------------------------------------+ //| ProjectName | //| Copyright 2020, CompanyName | //| http://www.companyname.net | //+------------------------------------------------------------------+ #include <Trade\Trade.mqh> CTrade trade; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ input int periodLongI=10;//Период длинной скользящей input int periodMiddleI=6;//Период средней скользящей input ENUM_TIMEFRAMES timeframesI = PERIOD_M1;//Временной период таймфрейм input double sharesBuyI=1;//Объем позиции лонга input double sharesSellI=1;//Объем позиции шорта //input ENUM_MA_METHOD typeSmoothingI = MODE_EMA;//Тип скользящей средней //input ENUM_APPLIED_PRICE typePriceI = PRICE_CLOSE;//Используемая цена скользящей средней По закрытию double sharesBuy=sharesBuyI; double sharesSell=sharesSellI; int barWait; //Algorithm bool signalBuy; bool signalShort; //Indicator int handleLong; int handleMiddle; //DATA double listLong[]; double listMiddle[]; int barsCount; double price; MqlTick tick; //+------------------------------------------------------------------+ int OnInit() { IndicatorReturn(); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { int iMax=ChartIndicatorsTotal(0,0); for(int i = 0 ; i<iMax; i++) { ChartIndicatorDelete(0,0,ChartIndicatorName(0,0,i)); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnTick() { DataReturn(); if(barWait==barsCount) { return; } barWait=barsCount; signalBuy = listMiddle[barsCount-2]> listLong[barsCount-2]; signalShort = listMiddle[barsCount-2]<listLong[barsCount-2]; if(PositionsTotal()<1) { if(signalBuy) { if( trade.PositionOpen(_Symbol,ORDER_TYPE_BUY,1,SymbolInfoDouble(_Symbol,SYMBOL_ASK),0,0)) { } } else if(signalShort) { if( trade.PositionOpen(_Symbol,ORDER_TYPE_SELL,1,SymbolInfoDouble(_Symbol,SYMBOL_BID),0,0)) { } } } else { if(PositionSelect(_Symbol)) { if((((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) && signalShort) || ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL && signalBuy)) { if(trade.PositionClose(_Symbol)) { } } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool IndicatorReturn() { handleLong=iMA(_Symbol,timeframesI,periodLongI,0,MODE_EMA,PRICE_CLOSE); handleMiddle=iMA(_Symbol,timeframesI,periodMiddleI,0,MODE_EMA,PRICE_CLOSE); ChartIndicatorAdd(0,0,handleLong); ChartIndicatorAdd(0,0,handleMiddle); return true; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool DataReturn() { barsCount=SeriesInfoInteger(_Symbol,timeframesI,SERIES_BARS_COUNT); CopyBuffer(handleLong,0,0,barsCount,listLong); CopyBuffer(handleMiddle,0,0,barsCount,listMiddle); SymbolInfoTick(_Symbol,tick); if(tick.last==0) { price=tick.bid; } else { price=tick.last; } return true; }
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel.Design; using System.IO.IsolatedStorage; using System.Linq; using System.Text; using TSLab.DataSource; using TSLab.Script; using TSLab.Script.GraphPane; using TSLab.Script.Handlers; using TSLab.Script.Helpers; using TSLab.Script.Optimization; using TSLab.Utils; namespace ClassLibrary1 { public class TestSpeed : IExternalScript { public OptimProperty smaDlin = new OptimProperty(500, 1, 1000, 1); public OptimProperty smaKor = new OptimProperty(200, 1, 1000, 1); public static Color _ColorGreen = new Color(21, 212, 11); public static Color _ColorBlack = new Color(0, 0, 0); public static Color _ColorRed = new Color(247, 59, 69); public void Execute(IContext c, ISecurity s) { c.ScriptResults["EMAdlin"] = smaDlin; c.ScriptResults["EMAkor"] = smaKor; IList<double> _smaDlin = Series.EMA(s.ClosePrices, smaDlin); IList<double> _smaKor = Series.EMA(s.ClosePrices, smaKor); //Графическое отображение if (!c.IsOptimization) { IGraphPane panel1 = c.CreateGraphPane("Pr", "Price"); IGraphList price = panel1.AddList("Pri", s, CandleStyles.BAR_CANDLE, _ColorGreen, PaneSides.RIGHT); price.AlternativeColor = _ColorRed; if (true) { panel1.AddList("Dlin", _smaDlin, ListStyles.LINE, _ColorGreen, LineStyles.SOLID, PaneSides.RIGHT); panel1.AddList("Kor", _smaKor, ListStyles.LINE, _ColorBlack, LineStyles.SOLID, PaneSides.RIGHT); } } //Конец Графическое отображение int nachBar = smaDlin; bool signalBuy = false; bool signalSell = false; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// for (int bar = nachBar; bar < s.Bars.Count; bar++) { signalBuy = _smaKor[bar] > _smaDlin[bar]; signalSell = _smaKor[bar] < _smaDlin[bar]; if (s.Positions.GetLastPositionActive(bar) == null) { if (signalBuy) { s.Positions.BuyAtMarket(bar + 1, 1, "Buy"); } if (signalSell) { s.Positions.SellAtMarket(bar + 1, 1, "Short"); } } IPosition posL = s.Positions.GetLastLongPositionActive(bar); if (posL != null) { if (signalSell) { posL.CloseAtMarket(bar + 1, "Buy"); s.Positions.SellAtMarket(bar + 1, 1, "Short"); } } IPosition posS = s.Positions.GetLastShortPositionActive(bar); if (posS != null) { if (signalBuy) { posS.CloseAtMarket(bar + 1, "Short"); s.Positions.BuyAtMarket(bar + 1, 1, "Buy"); } } } } } }
Вот два кода. Проверяйте сами. Два теста сделал. Уже выложил, но увидел. Что котировке не было данных, поэтому 2 сделки всего было. Но при этом 7 минут и 29 секунд там что то крутилось. Второй тест уже не хочу ждать. В тслабе крутил 30 дней за 22 секунды, в метатрейдере 20 и оценка 20 минут. Бред какой то. Тестер в моих руках не работает.
Вот два кода. Проверяйте сами. Два теста сделал. Уже выложил, но увидел. Что котировке не было данных, поэтому 2 сделки всего было. Но при этом 7 минут и 29 секунд там что то крутилось. Второй тест уже не хочу ждать. В тслабе крутил 30 дней за 22 секунды, в метатрейдере 20 и оценка 20 минут. Бред какой то. Тестер в моих руках не работает.
На каждом тике копировать весь M1 буфер, который может достигать 100 MB при UNLIMITED bars. Причем два раза. Вместо того, чтобы скопировать только недостоющие с последнего раза бары (как правило - один)
input ENUM_TIMEFRAMES timeframesI = PERIOD_M1;//Временной период таймфрейм ... void OnTick() { DataReturn(); ... bool DataReturn() { barsCount=SeriesInfoInteger(_Symbol,timeframesI,SERIES_BARS_COUNT); CopyBuffer(handleLong,0,0,barsCount,listLong); CopyBuffer(handleMiddle,0,0,barsCount,listMiddle);
Улыбнуло.
Короче, как обычно: чем меньше понимания, тем больше претензий.На каждом тике копировать весь M1 буфер, который может достигать 100 MB при UNLIMITED bars. Причем два раза. Вместо того, чтобы скопировать только недостоющие с последнего раза бары (как правило - один)
Улыбнуло.
Короче, как обычно: чем меньше понимания, тем больше претензий.Да, увидел. Все равно раза от 7 раз тслаб быстрее
Расходимся.
Это очередной писатель цикла for на готовых барах:
for (int bar = nachBar; bar < s.Bars.Count; bar++)
Такие системы я в 1999 году писал. Даже в первом MQL в 2001 году было простейшее моделирование тиков, а не чистый цикл по сформировавшимся барам.
Сейчас требования к сложности и точности моделирования на пару порядков выше.
Ознакомьтесь со следующими статьями, которые раскрывают важность потикового моделирования, включая точное мультивалютное и учет проскальзывания при исполнении:
- www.mql5.com
Расходимся.
Это очередной писатель цикла for на готовых барах:
Такие системы я в 1999 году писал. Даже в первом MQL в 2001 году было простейшее моделирование тиков, а не чистый цикл по сформировавшимся барам.
Сейчас требования к сложности и точности моделирования на пару порядков выше.
Ознакомьтесь со следующими статьями, которые раскрывают важность потикового моделирования, включая точное мультивалютное и учет проскальзывания при исполнении:
И много вам дало моделирование тиков? На рынке итак полно случайностей. Так вы её ещё моделируете!
В проскальзывание я верю только реальное. Тупо запустите сканер стакана и тогда уже моделируйте случайных вход и выход. За несколько дней вы соберете реальное проскальзывание для вашего объема и котировки для любой стратегии.
Корректно сравнивать безындикаторные советники, чтобы избежать случаев плохого кода, включая получение баров.
Идеально - на каждом входе берется только новый тик и больше ничего.
MT5-тестер имеет производительность в несколько миллионов тиков в секунду на одно ядро. Оптимизатор задействует много ядер. Поэтому во время оптимизации молотится по несколько десятков миллионов тиков в секунду. TSLab ни при каких раскладах не сможет обеспечивать (как заявляется в ветке) около миллиарда тиков в секунду. Это технически почти невозможно.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Переписал алгоритм с tslab. Запустил тестер - и ужаснулся. То, что у меня занимало там меньше 30 секунд, здесь 7 минут. Переписал код с использование Trade библиотеки. Убрал все, тоже условие - вход один раз на баре. И ничего более. Еще хуже стало, в два раза. Т.е. мои виртуальные позиции еще улучшают скорость теста. Может, что то не то делаю?
Опишите, как настроить под оптимизацию? Или бесполезно?