동적 그리드 거래 전략

저자:차오장, 날짜: 2024-01-23 10:53:05
태그:

img

전반적인 설명

이 전략은 가격 범위 내에서 여러 개의 병렬 구매 및 판매 주문을 배치하여 그리드 거래를 구현합니다. 이윤을 얻기 위해 시장 변동에 따라 그리드 범위와 라인을 조정합니다.

전략 논리

  1. 최근 높은 가격과 낮은 가격에 따라 수동으로 구성하거나 자동으로 계산할 수 있는 그리드의 상부와 하부 경계를 설정합니다.
  2. 정해진 네트워크 라인 수에 따라 그리드 간격 너비를 계산합니다.
  3. 해당 양과 함께 그리드 라인 가격 배열을 생성합니다.
  4. 가격이 그리드 라인 아래로 떨어지면, 그 아래로 긴 오더를 열고, 가격이 그리드 라인 위로 올라가면 그 위로 짧은 오더를 닫습니다.
  5. 시장 변화에 전략을 조정하기 위해 제한, 간격 너비 및 그리드 라인 가격을 동적으로 조정합니다.

이점 분석

  1. 유동 시장에서 일정하게 수익을 올릴 수 있습니다.
  2. 강력한 적응력을 위해 수동 및 자동 매개 변수 설정을 지원합니다.
  3. 더 나은 보상을 위해 그리드 양, 간격 너비 및 주문 크기와 같은 최적화 가능한 매개 변수.
  4. 내장 위치 제어로 위험도 낮아집니다.
  5. 동적 그리드 범위 조절은 적응력을 향상시킵니다.

위험 분석

  1. 시장이 강세를 보이는 상황에서는 심각한 손실이 발생할 수 있습니다.
  2. 잘못된 격자량 및 위치 설정은 위험을 증폭시킬 수 있습니다.
  3. 자동으로 계산된 그리드 범위는 극심한 가격 변동에 실패할 수 있습니다.

위험 관리:

  1. 그리드 매개 변수를 최적화하고 전체 위치를 엄격히 제어합니다.
  2. 중요한 가격 움직임 전에 전략을 닫습니다.
  3. 트렌드 지표로 시장 상태를 판단하고 필요한 경우 전략을 세워야 합니다.

최적화 방향

  1. 시장 특성과 자본 규모에 따라 최적의 네트워크 양을 선택합니다.
  2. 오토 매개 변수를 최적화하기 위해 다양한 기간을 테스트합니다.
  3. 더 안정적인 보상을 위해 주문 크기의 계산을 최적화하십시오.
  4. 트렌드 식별 및 전략 폐쇄 조건에 대한 지표를 추가합니다.

요약

동적 그리드 거래 전략은 그리드 매개 변수를 조정함으로써 시장에 적응합니다. 범위와 변동성 시장에서 이익을 얻습니다. 적절한 위치 제어로 위험은 완화됩니다. 그리드 설정을 최적화하고 트렌드 판단 지표를 통합하면 전략의 안정성을 더욱 향상시킬 수 있습니다.


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

//@version=4
strategy("sarasa srinivasa kumar", 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="(Auto) 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="(Auto) 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)



더 많은