Двунаправленная торговая стратегия Momentum Breakout


Дата создания: 2023-10-27 17:04:48 Последнее изменение: 2023-10-27 17:04:48
Копировать: 0 Количество просмотров: 655
1
Подписаться
1617
Подписчики

Двунаправленная торговая стратегия Momentum Breakout

Обзор

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

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

Эта стратегия использует ВВМА для определения направления рыночной тенденции. Когда ВВМА повышается, делайте больше; когда ВВМА падает, делайте меньше.

В частности, стратегия сначала рассчитывает VWMA определенного цикла, а затем определяет, выросла ли VWMA более чем на 5 дней, и если да, то открывает позицию; если VWMA снизилась более чем на 5 дней, то открывает позицию и делает ее пустой. Условие для закрытия позиции заключается в том, что VWMA поворачивается в обратном направлении более чем через 5 дней.

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

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

Эта стратегия имеет следующие преимущества:

  1. Используя VWMA для определения тенденций, можно эффективно отфильтровывать рыночный шум и улавливать основные тенденции.

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

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

  4. Записывайте ежемесячные и годовые доходы, чтобы оценить эффективность стратегии.

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

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

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

  1. Используя VWMA, можно определить, что тренд задерживается, и, возможно, пропустить начальный этап.

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

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

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

  5. В результате, потери могут увеличиваться.

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

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

  1. Оптимизация параметров циклов VWMA для улучшения оценки тенденций.

  2. Изменение числа дней подтверждения тенденции, улучшение времени входа и выхода в игру.

  3. Добавление стратегии стоп-лосса для контроля одиночных убытков

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

  5. Оптимизация управления позициями, корректировка позиций в соответствии с рыночными условиями.

  6. Учитывайте стоимость сделки и установите минимальную прибыль.

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

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

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

//@version=4
strategy(title="Monthly Returns in Strategies with Market Benchmark", shorttitle="Monthly P&L With Market", initial_capital= 1000, overlay=true,default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, commission_value = 0.1)
maLength= input(400)

wma= vwma(hl2,maLength)
uptrend= rising(wma, 5)
downtrend= falling(wma,5)

plot(wma)

if uptrend
    strategy.entry("Buy", strategy.long)
else
    strategy.close("Buy")//

///////////////////
// MONTHLY TABLE //

new_month = month(time) != month(time[1])
new_year  = year(time)  != year(time[1])

eq = strategy.equity

bar_pnl = eq / eq[1] - 1
bar_bh = (close-close[1])/close[1]

cur_month_pnl = 0.0
cur_year_pnl  = 0.0
cur_month_bh = 0.0
cur_year_bh  = 0.0

// Current Monthly P&L
cur_month_pnl := new_month ? 0.0 : 
                 (1 + cur_month_pnl[1]) * (1 + bar_pnl) - 1 
cur_month_bh := new_month ? 0.0 : 
                 (1 + cur_month_bh[1]) * (1 + bar_bh) - 1

// Current Yearly P&L
cur_year_pnl := new_year ? 0.0 : 
                 (1 + cur_year_pnl[1]) * (1 + bar_pnl) - 1
cur_year_bh := new_year ? 0.0 : 
                 (1 + cur_year_bh[1]) * (1 + bar_bh) - 1

// Arrays to store Yearly and Monthly P&Ls
var month_pnl  = array.new_float(0)
var month_time = array.new_int(0)
var month_bh  = array.new_float(0)

var year_pnl  = array.new_float(0)
var year_time = array.new_int(0)
var year_bh  = array.new_float(0)

last_computed = false

if (not na(cur_month_pnl[1]) and (new_month or time_close + (time_close - time_close[1]) > timenow or barstate.islastconfirmedhistory))
    if (last_computed[1])
        array.pop(month_pnl)
        array.pop(month_time)
        
    array.push(month_pnl , cur_month_pnl[1])
    array.push(month_time, time[1])
    array.push(month_bh , cur_month_bh[1])

if (not na(cur_year_pnl[1]) and (new_year or time_close + (time_close - time_close[1]) > timenow or barstate.islastconfirmedhistory))
    if (last_computed[1])
        array.pop(year_pnl)
        array.pop(year_time)
        
    array.push(year_pnl , cur_year_pnl[1])
    array.push(year_time, time[1])
    array.push(year_bh , cur_year_bh[1])

last_computed := (time_close + (time_close - time_close[1]) > timenow or barstate.islastconfirmedhistory) ? true : nz(last_computed[1])

// Monthly P&L Table    
var monthly_table = table(na)

getCellColor(pnl, bh)  => 
    if pnl > 0
        if bh < 0 or pnl > 2 * bh
            color.new(color.green, transp = 20)
        else if pnl > bh
            color.new(color.green, transp = 50)
        else
            color.new(color.green, transp = 80)
    else
        if bh > 0
            color.new(color.red, transp = 20)
        else if pnl < bh
            color.new(color.red, transp = 50)
        else
            color.new(color.red, transp = 80)

if last_computed
    monthly_table := table.new(position.bottom_right, columns = 14, rows = array.size(year_pnl) + 1, border_width = 1)

    table.cell(monthly_table, 0,  0, "",     bgcolor = #cccccc)
    table.cell(monthly_table, 1,  0, "Jan",  bgcolor = #cccccc)
    table.cell(monthly_table, 2,  0, "Feb",  bgcolor = #cccccc)
    table.cell(monthly_table, 3,  0, "Mar",  bgcolor = #cccccc)
    table.cell(monthly_table, 4,  0, "Apr",  bgcolor = #cccccc)
    table.cell(monthly_table, 5,  0, "May",  bgcolor = #cccccc)
    table.cell(monthly_table, 6,  0, "Jun",  bgcolor = #cccccc)
    table.cell(monthly_table, 7,  0, "Jul",  bgcolor = #cccccc)
    table.cell(monthly_table, 8,  0, "Aug",  bgcolor = #cccccc)
    table.cell(monthly_table, 9,  0, "Sep",  bgcolor = #cccccc)
    table.cell(monthly_table, 10, 0, "Oct",  bgcolor = #cccccc)
    table.cell(monthly_table, 11, 0, "Nov",  bgcolor = #cccccc)
    table.cell(monthly_table, 12, 0, "Dec",  bgcolor = #cccccc)
    table.cell(monthly_table, 13, 0, "Year", bgcolor = #999999)


    for yi = 0 to array.size(year_pnl) - 1
        table.cell(monthly_table, 0,  yi + 1, tostring(year(array.get(year_time, yi))), bgcolor = #cccccc)
        
        y_color = getCellColor(array.get(year_pnl, yi), array.get(year_bh, yi))
        table.cell(monthly_table, 13, yi + 1, tostring(round(array.get(year_pnl, yi) * 100)) + " (" + tostring(round(array.get(year_bh, yi) * 100)) + ")", bgcolor = y_color)
        
    for mi = 0 to array.size(month_time) - 1
        m_row   = year(array.get(month_time, mi))  - year(array.get(year_time, 0)) + 1
        m_col   = month(array.get(month_time, mi)) 
        m_color = getCellColor(array.get(month_pnl, mi), array.get(month_bh, mi))
        
        table.cell(monthly_table, m_col, m_row, tostring(round(array.get(month_pnl, mi) * 100)) + " (" + tostring(round(array.get(month_bh, mi) * 100)) +")", bgcolor = m_color)