Долгосрочная адаптивная стратегия динамической сетки на основе

Автор:Чао Чжан, Дата: 2024-03-19 14:19:12
Тэги:

img

Обзор

Это долго-короткая адаптивная динамическая стратегия торговли сеткой, основанная на Pine Script. Основная идея этой стратегии заключается в автоматическом вычислении верхних и нижних границ сетки на основе недавних максимумов и минимумов цен или простой скользящей средней, а затем равномерно разделить этот диапазон на несколько линий сетки. Когда цена достигает определенной линии сетки, она открывает длинную позицию или закрывает позицию на этом уровне. Таким образом, стратегия может непрерывно открывать и закрывать позиции на рынке диапазона для захвата ценового спрэда. В то же время, динамически регулируя границы сетки, она также может адаптироваться к различным рыночным тенденциям.

Принципы стратегии

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

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

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

  4. Выход / Уменьшение позиции. Пересечь линии сетки сверху вниз. Если текущая цена закрытия больше, чем цена сетки, и есть позиция на линии сетки ниже, то закрыть длинную позицию на нижней линии сетки. Таким образом, когда цена падает назад, он будет продолжать снижать позиции.

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

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

  1. Сильная адаптивность. Сетевая стратегия торговли может адаптироваться как к рынкам с ограниченным диапазоном, так и к рынкам с тенденциями. На рынке с ограниченным диапазоном сетевая стратегия может непрерывно открывать и закрывать позиции, чтобы заработать спред цены; на рынке с тенденциями, поскольку сеть следует за движением цен, она также может поддерживать определенную позицию, чтобы получить прибыль от тренда.

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

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

  4. Гибкие параметры. Пользователи могут гибко устанавливать количество линий сети, динамические параметры сети и т. д. в соответствии с характеристиками рынка для оптимизации эффективности стратегии.

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

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

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

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

Руководство по оптимизации

  1. Добавьте трендовый фильтр. Стратегии сетки не работают хорошо на односторонних трендовых рынках. Индикаторы тренда могут быть добавлены в качестве фильтра, например, разрешать сетку только тогда, когда ADX ниже порога, и закрывать сетку, когда тенденция очевидна, держать только односторонние позиции.

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

  3. Управление позицией. В настоящее время положение каждой сетки в стратегии фиксировано. Его можно настроить, чтобы должным образом уменьшить положение каждой сетки, когда цена далека от средней рыночной цены, и увеличить положение, когда оно близко к средней рыночной цене, чтобы повысить эффективность использования капитала.

  4. Динамическая настройка плотности сети в зависимости от волатильности цены. При высокой волатильности количество сетей может быть увеличено; при низкой волатильности количество сетей может быть уменьшено. Это может оптимизировать ширину сети и улучшить использование капитала.

Резюме

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


// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © jcloyd

//@version=4
strategy("(IK) Grid Script", overlay=true, pyramiding=14, close_entries_rule="ANY", default_qty_type=strategy.cash, initial_capital=100.0, currency="USD", commission_type=strategy.commission.percent, commission_value=0.1)
i_autoBounds    = input(group="Grid Bounds", title="Use Auto Bounds?", defval=true, type=input.bool)                             // calculate upper and lower bound of the grid automatically? This will theorhetically be less profitable, but will certainly require less attention
i_boundSrc      = input(group="Grid Bounds", title="(Auto) Bound Source", defval="Hi & Low", options=["Hi & Low", "Average"])     // should bounds of the auto grid be calculated from recent High & Low, or from a Simple Moving Average
i_boundLookback = input(group="Grid Bounds", title="(Auto) Bound Lookback", defval=250, type=input.integer, maxval=500, minval=0) // when calculating auto grid bounds, how far back should we look for a High & Low, or what should the length be of our sma
i_boundDev      = input(group="Grid Bounds", title="(Auto) Bound Deviation", defval=0.10, type=input.float, maxval=1, minval=-1)  // if sourcing auto bounds from High & Low, this percentage will (positive) widen or (negative) narrow the bound limits. If sourcing from Average, this is the deviation (up and down) from the sma, and CANNOT be negative.
i_upperBound    = input(group="Grid Bounds", title="(Manual) Upper Boundry", defval=0.285, type=input.float)                      // for manual grid bounds only. The upperbound price of your grid
i_lowerBound    = input(group="Grid Bounds", title="(Manual) Lower Boundry", defval=0.225, type=input.float)                      // for manual grid bounds only. The lowerbound price of your grid.
i_gridQty       = input(group="Grid Lines",  title="Grid Line Quantity", defval=8, maxval=15, minval=3, type=input.integer)       // how many grid lines are in your grid

f_getGridBounds(_bs, _bl, _bd, _up) =>
    if _bs == "Hi & Low"
        _up ? highest(close, _bl) * (1 + _bd) : lowest(close, _bl)  * (1 - _bd)
    else
        avg = sma(close, _bl)
        _up ? avg * (1 + _bd) : avg * (1 - _bd)

f_buildGrid(_lb, _gw, _gq) =>
    gridArr = array.new_float(0)
    for i=0 to _gq-1
        array.push(gridArr, _lb+(_gw*i))
    gridArr

f_getNearGridLines(_gridArr, _price) =>
    arr = array.new_int(3)
    for i = 0 to array.size(_gridArr)-1
        if array.get(_gridArr, i) > _price
            array.set(arr, 0, i == array.size(_gridArr)-1 ? i : i+1)
            array.set(arr, 1, i == 0 ? i : i-1)
            break
    arr

var upperBound      = i_autoBounds ? f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, true) : i_upperBound  // upperbound of our grid
var lowerBound      = i_autoBounds ? f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, false) : i_lowerBound // lowerbound of our grid
var gridWidth       = (upperBound - lowerBound)/(i_gridQty-1)                                                       // space between lines in our grid
var gridLineArr     = f_buildGrid(lowerBound, gridWidth, i_gridQty)                                                 // an array of prices that correspond to our grid lines
var orderArr        = array.new_bool(i_gridQty, false)                                                              // a boolean array that indicates if there is an open order corresponding to each grid line

var closeLineArr    = f_getNearGridLines(gridLineArr, close)                                                        // for plotting purposes - an array of 2 indices that correspond to grid lines near price
var nearTopGridLine = array.get(closeLineArr, 0)                                                                    // for plotting purposes - the index (in our grid line array) of the closest grid line above current price
var nearBotGridLine = array.get(closeLineArr, 1)                                                                    // for plotting purposes - the index (in our grid line array) of the closest grid line below current price
strategy.initial_capital = 50000
for i = 0 to (array.size(gridLineArr) - 1)
    if close < array.get(gridLineArr, i) and not array.get(orderArr, i) and i < (array.size(gridLineArr) - 1)
        buyId = i
        array.set(orderArr, buyId, true)
        strategy.entry(id=tostring(buyId), long=true, qty=(strategy.initial_capital/(i_gridQty-1))/close, comment="#"+tostring(buyId))
    if close > array.get(gridLineArr, i) and i != 0
        if array.get(orderArr, i-1)
            sellId = i-1
            array.set(orderArr, sellId, false)
            strategy.close(id=tostring(sellId), comment="#"+tostring(sellId))

if i_autoBounds
    upperBound  := f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, true)
    lowerBound  := f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, false)
    gridWidth   := (upperBound - lowerBound)/(i_gridQty-1)
    gridLineArr := f_buildGrid(lowerBound, gridWidth, i_gridQty)

closeLineArr    := f_getNearGridLines(gridLineArr, close)
nearTopGridLine := array.get(closeLineArr, 0)
nearBotGridLine := array.get(closeLineArr, 1)

Больше