Количественная стратегия, основанная на индикаторе супертренда и торговле кривой капитала


Дата создания: 2024-01-15 11:41:53 Последнее изменение: 2024-01-15 11:41:53
Копировать: 1 Количество просмотров: 601
1
Подписаться
1617
Подписчики

Количественная стратегия, основанная на индикаторе супертренда и торговле кривой капитала

Обзор

Основная идея этой стратегии заключается в том, чтобы объединить сверхтрендовый индикатор с торговлей по кривой чистой стоимости. Когда сверхтрендовый индикатор посылает сигнал о покупке или продаже, мы не выполняем сделку напрямую, а судим, ниже ли текущая кривая чистой стоимости, чем ее движущаяся средняя. Мы открываем позицию только тогда, когда кривая чистой стоимости выше, чем движущаяся средняя.

Стратегический принцип

Стратегия состоит из двух основных частей:

  1. Показатель сверхтенденции
  2. Торговля по кривой

Формула расчета сверхтенденционного показателя следующая:

Поездка на рельсы = цена - ATR умноженный на ATR Нижняя линия = цена + ATR умноженное на ATR

ATR представляет собой среднюю истинную волну. Супертенденционный индикатор использует ATR для установки наверх и вниз, чтобы продать сигнал, когда цена прорывается вверх, и купить сигнал, когда цена прорывается вниз.

Идея торговли по кривой нетто состоит в том, что мы принимаем подвижное среднее по кривой нетто стратегии, приостанавливаем торговлю по текущей стратегии, когда кривая нетто ниже, и открываем торговлю снова, когда кривая нетто поднимается выше.

Эта стратегия объединяет эти два, после того, как сверхтенденциальный индикатор создает торговый сигнал, мы не торгуем напрямую, а судим, выше ли текущая кривая чистой стоимости, чем движущаяся средняя. Только если оба условия будут удовлетворены одновременно, мы откроем позицию. Это позволяет эффективно избежать риска самого сверхтенденциального индикатора и предотвратить чрезмерные потери.

Анализ преимуществ

Основные преимущества этой стратегии:

  1. Риск от сверхтенденциальных показателей может быть эффективно предотвращен. Сами сверхтенденциальные показатели не могут эффективно избежать убытков, и торговля кривой чистой стоимости может восполнить этот недостаток.

  2. При неблагоприятных условиях можно приостановить стратегию торговли, чтобы избежать чрезмерных потерь.

  3. Позиции могут автоматически управляться без какого-либо вмешательства человека. Они автоматически приостанавливаются, когда кривая чистой стоимости ниже скользящей средней, и автоматически открываются, когда она выше.

Анализ рисков

Однако есть и риски:

  1. Ошибки в параметрах могут привести к неэффективному использованию кривой чистой стоимости. Необходимо выбрать подходящий цикл скользящих средних.

  2. Когда рыночная тенденция меняется, возможно, не удастся своевременно скорректировать позиции. Это может привести к определенным потерям.

  3. Поскольку нужно ждать, пока кривая стоимости акций вернется вверх, возможно, вы пропустите лучший момент для вступления в компанию.

Ответ:

  1. Оптимизация параметров, выбор оптимального цикла скользящих средних.

  2. Вместе с другими показателями, чтобы оценить тенденции, своевременно корректировать позиции.

  3. Сокращение сроков приостановки торгов, чтобы снизить вероятность пропущенного входа.

Направление оптимизации

Эта стратегия может быть оптимизирована в следующих аспектах:

  1. Тестируйте различные комбинации параметров, чтобы найти оптимальные ATR-циклы и ATR-множества.

  2. Попробуйте использовать другие типы скользящих средних, такие как индексные скользящие средние, Hull скользящие средние и т.д.

  3. Добавить другие показатели, чтобы оценить тенденцию, и своевременно корректировать позиции при изменении тенденции.

  4. Оптимизируйте циклы скользящих средних и найдите оптимальную точку равновесия. Слишком длинные циклы могут привести к упущенным возможностям, а слишком короткие часто приостанавливаются.

  5. Оптимизация условий приостановки торговли, например, установка линий стоп-лосса, приостановка торговли только после достижения определенного уровня убытков.

Подвести итог

Эта стратегия хитро сочетает в себе сверхтрендовый индикатор и торговлю по кривой чистой стоимости. Она сохраняет преимущества, связанные с определением тенденции сверхтрендовым индикатором, и эффективно контролирует риск через торговлю по кривой чистой стоимости. Результаты тестирования показывают, что в большинстве случаев торговля по кривой чистой стоимости приводит к снижению уровня прибыли.

Исходный код стратегии
/*backtest
start: 2023-01-14 00:00:00
end: 2024-01-14 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
strategy('Supertrend & Equity curve with EMA', overlay=false, format=format.price, precision=2, initial_capital=100000)

eqlen = input.int(25, "EQ EMA len", group = "New Equity Curve Settings")
shEQandMA = input.bool(true, "Show Original Equity Curve and MA")
shEQfilt = input.bool(true, "Show Filtered Equity Curve by MA")

Periods = input(title='ATR Period', defval=10, group = "SuperTrend Settings")
src = input(hl2, title='Source', group = "SuperTrend Settings")
Multiplier = input.float(title='ATR Multiplier', step=0.1, defval=3.0, group = "SuperTrend Settings")
changeATR = input(title='Change ATR Calculation Method ?', defval=true, group = "SuperTrend Settings")

//SuperTrend Code
atr2 = ta.sma(ta.tr, Periods)
atr = changeATR ? ta.atr(Periods) : atr2
up = src - Multiplier * atr
up1 = nz(up[1], up)
up := close[1] > up1 ? math.max(up, up1) : up
dn = src + Multiplier * atr
dn1 = nz(dn[1], dn)
dn := close[1] < dn1 ? math.min(dn, dn1) : dn
trend = 1
trend := nz(trend[1], trend)
trend := trend == -1 and close > dn1 ? 1 : trend == 1 and close < up1 ? -1 : trend

// Strategy main code
buySignal = trend == 1 and trend[1] == -1
sellSignal = trend == -1 and trend[1] == 1
if buySignal
    strategy.entry('Long', strategy.long)
if sellSignal
    strategy.entry('Short', strategy.short)



//Equity Curve calcs
eq = strategy.netprofit
ch = ta.change(eq)
neq = ch != 0 ? eq : na
mova = ta.ema(neq,eqlen)

// New Equity Curve
var float neweq = 0
var int ttrades = 0
var int wintrades = 0
var int losetrades = 0

switch
    strategy.netprofit == strategy.netprofit[1]  => na
    strategy.netprofit < mova and strategy.netprofit[1] > mova  => neweq := neweq + ch
    strategy.netprofit < mova and strategy.netprofit[1] < mova => na
    strategy.netprofit > mova and strategy.netprofit[1] > mova => neweq := neweq + ch

newch = ta.change(neweq)
switch
    newch == 0 => na
    newch > 0 => 
        wintrades := wintrades +1
        ttrades := ttrades +1
    newch < 0 =>
        losetrades := losetrades +1
        ttrades := ttrades +1

//plot(eq, linewidth = 2)
//plot(mova, color=color.red)
//plot(neweq, color= color.green, linewidth = 3)


//Table 
var testTable = table.new(position = position.top_right, columns = 5, rows = 10, bgcolor = color.green, border_width = 1)
table.cell(table_id = testTable, column = 0, row = 0, text = "Strategy: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 1, row = 0, text = "Original: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 2, row = 0, text = "Equity Curve EMA: ", bgcolor=color.white)     

table.cell(table_id = testTable, column = 0, row = 1, text = "Total Trades: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 0, row = 2, text = "Win Trades: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 0, row = 3, text = "Lose Trades: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 0, row = 4, text = "Win Rate: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 0, row = 5, text = "Net Profit: ", bgcolor=color.white)     

//Equity Curve EMA stat
table.cell(table_id = testTable, column = 2, row = 1, text = str.tostring(ttrades), bgcolor=color.white)     
table.cell(table_id = testTable, column = 2, row = 2, text = str.tostring(wintrades), bgcolor=color.white)
table.cell(table_id = testTable, column = 2, row = 3, text = str.tostring(losetrades), bgcolor=color.white)
table.cell(table_id = testTable, column = 2, row = 4, text = str.tostring(math.round(100*wintrades/ttrades,2)), bgcolor=color.white)
table.cell(table_id = testTable, column = 2, row = 5, text = str.tostring(math.round(neweq)), bgcolor=color.white)

//Original Strategy stat
// table.cell(table_id = testTable, column = 1, row = 1, text = str.tostring(strategy.closedtrades), bgcolor=color.white)     
// table.cell(table_id = testTable, column = 1, row = 2, text = str.tostring(strategy.wintrades), bgcolor=color.white)
// table.cell(table_id = testTable, column = 1, row = 3, text = str.tostring(strategy.losstrades), bgcolor=color.white)
// table.cell(table_id = testTable, column = 1, row = 4, text = str.tostring(math.round(100*strategy.wintrades/strategy.closedtrades,2)), bgcolor=color.white)
// table.cell(table_id = testTable, column = 1, row = 5, text = str.tostring(math.round(strategy.netprofit)), bgcolor=color.white)




//New Equity curve
var newcurve = array.new_float(0)
var int ida = 0
var bool printEQ = false
if newch !=0 
    array.push(newcurve, neweq)
if bar_index > last_bar_index - array.size(newcurve) - 1 - 20  and array.size(newcurve) > 20 
    printEQ := true
else
    printEQ := false

plot(printEQ and ida < strategy.closedtrades and shEQfilt ? array.get(newcurve, ida) : na, color=color.green, linewidth = 2)

if printEQ
    ida := ida + 1
if ida >= array.size(newcurve) and printEQ
    ida := array.size(newcurve) -1



//Original Equity curve
var newcurve2 = array.new_float(0)
var int ida2 = 0
var bool printEQ2 = false
if ch !=0 
    array.push(newcurve2, eq)
if bar_index > last_bar_index - array.size(newcurve2) - 1 - 20  and array.size(newcurve2) > 20 
    printEQ2 := true
else
    printEQ2 := false

plot(printEQ2 and ida2 < strategy.closedtrades and shEQandMA  ? array.get(newcurve2, ida2) : na, color=color.blue, linewidth = 2)

if printEQ2
    ida2 := ida2 + 1
if ida2 >= array.size(newcurve2) and printEQ2
    ida2 := array.size(newcurve2) -1



//Moving Average Array
var marray = array.new_float(0)
if ch
    array.push(marray, mova)

plot(printEQ2 and  array.size(marray) > 40 and shEQandMA ? array.get(marray, ida2-1) : na, color=color.red, linewidth = 1)

hline(0,"0 line", color=color.black, linestyle = hline.style_dotted)


if (last_bar_index-1) and array.size(newcurve2) > 20 and array.size(newcurve) > 20
    l = label.new(bar_index+2, array.get(newcurve2, array.size(newcurve2)-1), "Original Equity Curve", color=color.rgb(33, 149, 243, 85), textcolor = color.black, style = label.style_label_left)
    label.delete(l[1])
    f = label.new(bar_index+2, array.get(newcurve, array.size(newcurve)-1), "Filtered Equity Curve", color=color.rgb(69, 238, 97, 85), textcolor = color.black, style = label.style_label_left)
    label.delete(f[1])