Самоадаптивная стратегия торговли квантовыми сетями

Автор:Чао Чжан, Дата: 2024-02-02 18:08:22
Тэги:

img

Обзор

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

Логика стратегии

  1. Вычислить границы сети и ценовой массив сети на основе входных параметров.

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

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

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

  1. Долгие/короткие позиции создаются и закрываются в партии на разных уровнях цен для достижения общей прибыли.

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

  3. Максимальная потеря ограничена ограничением максимального количества линий сети.

  4. Настройка расстояния между сетками для корректировки прибыли/убытка на одну сделку.

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

  1. Риск попасть в ловушку. Частые колебания цен в пределах сетевого диапазона могут привести к потерям.

  2. Недостаточное финансирование не может обеспечить достаточное количество линий сети.

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

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

Оптимизация

  1. Внедрить логику стоп-лосса, такую как стоп-лосс, чтобы еще больше ограничить риск снижения по направлению.

  2. Оптимизировать параметры сетки с помощью машинного обучения. Испытать различные параметры в рыночных условиях и обучить модели ML для получения оптимальных адаптивных параметров.

  3. Оцените силу текущего тренда с помощью таких индикаторов, как MACD и RSI, чтобы направлять количество сетки и настройку параметров.

  4. Улучшить контроль рисков путем установления максимально допустимого процента привлечения.

Заключение

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


/*backtest
start: 2024-01-02 00:00:00
end: 2024-02-01 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@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)



Больше