• Demo счет NinjaTrader, регистрируется в брокерской компании NinjaTrader Brokerage . NinjaTrader™, LLC
    Ссылка на демо счет NinjaTrader
    Фид на соединении Continuum/CQG.
    Для справки: Continuum - это брэнд CQG, и ни чем они не отличаются друг от друга.
  • Сколько я реально плачу комиссии?
    Подробнее по ссылке

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

NoName

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

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

Как вариант - использовать Market Replay.
 
#4
Тестирование на тиках теоретически дает возможность "нормального" бэктестинга, но практически имеет ряд критических недостатков.
 

Alexander

Administrator
Член команды
Помогли тебе - помоги другим!
#5
Тестирование на тиках теоретически дает возможность "нормального" бэктестинга, но практически имеет ряд критических недостатков.
Вижу статья есть на вашем сайте по теме, правда на английском.
ps/ онлайн переводчик нормально переводит.
 

NoName

Member
NinjaTrader
#6
Проблему решили доработкой FillType, а именно переделали обработку лимитника. (Не знаю насколько точно решили проблему, но разбирающийся человек в ценообразовании да и торговле в целом сказал что бэктест работает именно так, как ведет себя рынок, т.е. как надо)) )
 
#7
Было бы интересно узнать подробности. Очевидно, что в случае OHLC (баров) ничто не в силах спасти ситуацию, т.к. нет никакой информации о движении цены внутри бара. Следовательно, должны использоваться тиковые данные. Но тогда возникает ряд сложностей. Здесь уже надо смотреть нюансы: в некоторых случаях эти сложности можно будет обойти, в некоторых это будет сделать нетривиально, в некоторых и вовсе невозможно.

Есть возможность увидеть код?
 

Привал

Well-Known Member
NinjaTrader
#8
Или хотя бы словесное описание. Более подробно, т.к. тоже считаю что обойти это ограничение корректно возможно только с использованием тиковых данных ( и то не всегда). А изменять логику работы лимитника ... это можно на такие грабли наступить, что мама не горюй...
Вот один из примеров
http://ninjafutures.ru/threads/voprosy-programmirovanija.505/page-4#post-6731
 
Последнее редактирование:

NoName

Member
NinjaTrader
#9
Ничего сверхъестественного не делали, всё банально до безобразия, добавили лишь обработку лимитника 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;
                        }
                }
            }