• Тинькофф Банк-лучшие банковские продукты еще выгоднее
    Выбирайте продукт от банка Тинькофф
  • Уважаемые форумчане, друзья и посетители!
    Поступило предложение ( ссылка на обсуждение ) на сбор средств поддержания форума в рабочем состоянии с 1 июня ( оплата хостинга, бэкап ежедневный на другой хостинг и тд), отчетность будет предоставляться ежемесячно. Пока на ЮMoney ( яндекс деньги), доступно картой перевод, далее добавлю другие способы. Сумму перевода указывайте на ваш выбор исходя из своих возможностей.
    Форум продолжает свою работу благодаря Вашим пожертвованиям.

Программирование Обойти неточность бэктеста

NoName

Member
NinjaTrader
Здравствуйте! Проводя бэктесты стратегии наткнулся на погрешность алгоритма бэктестинга, которая заключается в срабатывании Profit target там, где он сработать не должен, так как выставлялся после срабатывания Sell limit. (см. рисунок) Таким образом, данная неточность алгоритма вносит большую погрешность в оценку работы стратегии.

Я знаю что можно создать пользовательский алгоритм бэктеста (Fill type). Кто-либо сталкивался с данной проблемой, существуют ли решения или же какие-то идеи?
8Z9Mhww.png
 
Это фундаментальный недостаток бэктеста у NT7. Адекватно обойти его невозможно, т.к. кроме данных OHLC ничего нет.

Как вариант - использовать Market Replay.
 
Тестирование на тиках теоретически дает возможность "нормального" бэктестинга, но практически имеет ряд критических недостатков.
 
Тестирование на тиках теоретически дает возможность "нормального" бэктестинга, но практически имеет ряд критических недостатков.
Вижу статья есть на вашем сайте по теме, правда на английском.
ps/ онлайн переводчик нормально переводит.
 
Проблему решили доработкой FillType, а именно переделали обработку лимитника. (Не знаю насколько точно решили проблему, но разбирающийся человек в ценообразовании да и торговле в целом сказал что бэктест работает именно так, как ведет себя рынок, т.е. как надо)) )
 
Было бы интересно узнать подробности. Очевидно, что в случае OHLC (баров) ничто не в силах спасти ситуацию, т.к. нет никакой информации о движении цены внутри бара. Следовательно, должны использоваться тиковые данные. Но тогда возникает ряд сложностей. Здесь уже надо смотреть нюансы: в некоторых случаях эти сложности можно будет обойти, в некоторых это будет сделать нетривиально, в некоторых и вовсе невозможно.

Есть возможность увидеть код?
 
Или хотя бы словесное описание. Более подробно, т.к. тоже считаю что обойти это ограничение корректно возможно только с использованием тиковых данных ( и то не всегда). А изменять логику работы лимитника ... это можно на такие грабли наступить, что мама не горюй...
Вот один из примеров
http://ninjafutures.ru/threads/voprosy-programmirovanija.505/page-4#post-6731
 
Последнее редактирование:
Ничего сверхъестественного не делали, всё банально до безобразия, добавили лишь обработку лимитника Profit target. К сожалению, подробных комментариев дать не могу, ибо обладаю недостаточной информацией на этот счёт, не разбираюсь в этих лимитниках, ценообразовании, да и в целом с торговлей знаком совсем недавно. Могу ток сказать что глядя в код видно, что лимитник выставляется на следующем баре.
Не могу утверждать что 100% правильная реализация, но мне сказали "работает как надо", а я только рад этому:smile: (если конечно это действительно так).
Кстати, если даже этот вариант в целом не верный (а исходя из ваших рассуждений думаю это так), в нашем случае он "сгладил" красивый результат бэктеста, и приблизил результаты к реальным, даже с небольшим запасом прочности, т.е. резалты показываются немного в худшую сторону.
P.S. немного тяжело было слышать, что результат, полученный на дефолтном филлтайпе, был не верным.. А там так всё красиво было..))
Код:
else if (order.OrderType == OrderType.Limit)
            {
                // Profit Target
                 if(order.Name == "Profit target")
                {
                    if(Strategy.Bars.CurrentBar >= BAR_INDEX + 1)
                    {
                        double nextLow    = NextLow;
                        double nextHigh = NextHigh;
                        if ((order.OrderAction == Cbi.OrderAction.Buy                    && order.LimitPrice > nextLow + epsilon)
                                || (order.OrderAction == Cbi.OrderAction.BuyToCover    && order.LimitPrice > nextLow + epsilon)
                                || (order.OrderAction == Cbi.OrderAction.Sell            && order.LimitPrice < nextHigh - epsilon)
                                || (order.OrderAction == Cbi.OrderAction.SellShort    && order.LimitPrice < nextHigh - epsilon))
                            {
                                FillPrice = order.LimitPrice;                                                // set fill price
                            }
                    }
                                         
                }
             
                else
                {
                    // Orders are filled when traded through the limit price not at the limit price
                    double nextLow    = NextLow;
                    double nextHigh = NextHigh;
                    if ((order.OrderAction == Cbi.OrderAction.Buy                    && order.LimitPrice > nextLow + epsilon)
                            || (order.OrderAction == Cbi.OrderAction.BuyToCover    && order.LimitPrice > nextLow + epsilon)
                            || (order.OrderAction == Cbi.OrderAction.Sell            && order.LimitPrice < nextHigh - epsilon)
                            || (order.OrderAction == Cbi.OrderAction.SellShort    && order.LimitPrice < nextHigh - epsilon))
                        {
                            FillPrice = order.LimitPrice;                                                // set fill price
                            BAR_INDEX = Strategy.Bars.CurrentBar;
                        }
                }
            }
 
Назад
Верх Низ