Каждый трейдер по мере своего развития в торговле формирует свою торговую систему — набор правил, согласно которым он действует. Чтобы проверить свою торговую систему по истории графика используют бэктест. В бэктесте задается большое количество параметров: условие входа и выхода, объем входа и выхода, комиссия сделки, тейк профит и стоп лос сделки и так далее. По полученным данным, таким как, доходность в процентах или в валюте, количеству закрывшихся сделок по стопу или по тейк профиту, можно судить об эффективности стратегии на заданном временном промежутке истории графика.
Выбирая для бэктеста различные по типу активы и находящиеся в разной фазе инструменты, можно понять насколько ваша торговая система применима к ним.
Я тестирую свои торговые системы или индикаторы на языке программирования Pine Script в социальной сети для трейдеров Trading View. На этом языке есть встроенные функции для бэктеста, но мне было удобней написать свои и гибко менять настройки так как мне надо.
Ниже представлен код двух способов построения дивергенции. Один с помощью функции корреляции, другой с помощью функции пивот.
ta.correlation() — Коэффициент корреляции. Описывает степень, на которую две серии стремятся отклониться от своих ta.sma значений.
7 — передаем значение встроенной функции ta.rsi в переменную rsi
8 — задаем коэффициент корреляции, на который будет реагировать индикатор
9 - задаем расчетный период корреляции
11 — переносим значение встроенной функции корреляции ta.correlation в переменную correlation
14 — задаем цвет направления корреляции, изначально бесцветный
15 — с помощью тернарного оператора задаем два условия дивергенции типа Strong. Первое условие медвежьей дивергенции, цвет будет красный, второе — бычьей и цвет зеленый. В случае не выполнения обоих условий цвет будет серый.
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // This strategy has been created for illustration purposes only and should not be relied upon as a basis for buying, selling, or holding any asset or security. // © Diamond //@version=5 strategy('SMA Golden Short Strategy', overlay=true, calc_on_every_tick=false, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_value=0.04, commission_type=strategy.commission.percent) //Inputs smaFast = input.int(title='Fast SMA', defval=50, minval=1) smaSlow = input.int(title='Slow SMA', defval=200, minval=1)
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // This strategy has been created for illustration purposes only and should not be relied upon as a basis for buying, selling, or holding any asset or security. // © Diamond //@version=4 strategy("SMA Golden Cross Strategy", overlay = true, calc_on_every_tick = true, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_value = 0.04, commission_type = strategy.commission.percent)Доступно редактирование 4 переменных: период быстрой средней, период медленной средней, даты начала и конца бэктеста:
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ //@version=4 study("Historical Volatility") // Настройки окон HVPeriod1 = input(17, minval=1, title="Окно 1") HVPeriod2 = input(34, minval=1, title="Окно 2") HVPeriod3 = input(51, minval=1, title="Окно 3") HVPeriod4 = input(85, minval=1, title="Окно 4") // Настройка периода для сглаживания EMAPeriod = input(17, minval=2, title="Период сглаживания") // Собственно индикатор // мультипликатор, для нормирования к году mul = 252 * 1210 / timeframe.multiplier //приращение за бар ch = log(close) - log(close[1]) // Историческая волатильность в окнах HV1 = ema(sqrt(sum(ch * ch, HVPeriod1) * mul / HVPeriod1) * 100, EMAPeriod) HV2 = ema(sqrt(sum(ch * ch, HVPeriod2) * mul / HVPeriod2) * 100, EMAPeriod) HV3 = ema(sqrt(sum(ch * ch, HVPeriod3) * mul / HVPeriod3) * 100, EMAPeriod) HV4 = ema(sqrt(sum(ch * ch, HVPeriod4) * mul / HVPeriod4) * 100, EMAPeriod) // Рисуем красивое plot(HV1, color=#cccccc) plot(HV2, color=#ffcccc) plot(HV3, color=#ff9999) plot(HV4, color=#ff0000)Чтобы использовать, копируем, в TradingView открываем Редактор Pine, создаем там новый индикатор (Открыть -> Новый индикатор), удаляем все что там в скрипте по умолчанию и вставляем этот код. Жмем Сохранить. Дальше скрипт будет доступен в выпадающем списке над графиком под кнопкой Индикаторы во вкладке Мои скрипты. Модно, быстро и удобно )
Я столкнулся с необходимостью загрузить на график трейдингвью сигналы покупки/продажи робота и бактеста для их графической проверки на истории. В итоге сделал расширение для гугл хрома, цикл загрузки выглядит примерно так (тестовые данные):
Чуть подробней и как попробовать ниже.
В сообществе рекомендуют автоматически формировать Pinescript с условиями времени на каждое событие. Но это крайне неудобно и лимит 900 строк, а значит 900 сигналов.
Эту задачу можно решить лучше и проще, передать сигналы в индикатор как строки со штампом времени и проверять на их совпадение с текущим временем бара. Ограничение только в точности совпадения штампов времени. Есть ещё на лимиты в длине строке параметров и времени вычислений, но на тестовых 5000 сигналов я не столкнулся и ни с тем, ни с другим.
// 1-st version if ( true ) strategy.entry( "long", strategy.long, when = close >= long_condition ) strategy.entry( "short", strategy.short, when = close <= short_condition ) // 2-nd version if ( true ) strategy.entry( "long", strategy.long, stop = long_condition ) strategy.entry( "short", strategy.short, stop = short_condition )
Примечания:
согласно справочнику
— стоп ордер на покупку исполняется, когда цена станет такой же или хуже уровня указанного в ордере (то есть цена равна или больше уровня)
— на продажу аналогично (то есть равна или меньше)
//@version=4 study("Color Resolution", overlay=true) resolution = input(title="Resolution", type=input.resolution, defval="D") resolution_open = security(syminfo.tickerid, resolution, open, barmerge.gaps_off, barmerge.lookahead_on) resolution_close = security(syminfo.tickerid, resolution, close, barmerge.gaps_off, barmerge.lookahead_on) p_open = plot(resolution_open, color=#00000080, display=display.all, style=plot.style_stepline) p_close = plot(resolution_close, color=#00000080, display=display.all, style=plot.style_stepline) fill(p_open, p_close, resolution_close >= resolution_open ? color.green : color.red, 75)
//@version=4 study("Color Resolution Vinni", overlay=true) rsl = input(title="Resolution", type=input.resolution, defval="D" ) resolution = timeframe.isweekly? "M": rsl resolution_high = security(syminfo.tickerid, resolution, high, barmerge.gaps_off, barmerge.lookahead_on) resolution_low = security(syminfo.tickerid, resolution, low, barmerge.gaps_off, barmerge.lookahead_on) p_high = plot(resolution_high, color=#000000, display=display.all, style=plot.style_stepline, transp = 100, title="High") p_low = plot(resolution_low, color=#000000, display=display.all, style=plot.style_stepline, transp = 100, title="Low") fill(p_high, p_low, color = #131722, transp = 80, title="Fill_High_low") resolution_open = security(syminfo.tickerid, resolution, open, barmerge.gaps_off, barmerge.lookahead_on) resolution_close = security(syminfo.tickerid, resolution, close, barmerge.gaps_off, barmerge.lookahead_on) p_open = plot(resolution_open, color=#000000, display=display.all, style=plot.style_stepline, transp = 100, title="Open") p_close = plot(resolution_close, color=#000000, display=display.all, style=plot.style_stepline, transp = 100, title="Close") fill(p_open, p_close, resolution_close >= resolution_open? #0cf8c4: #e91e63, transp = 90, title="Fill_Open_Close")