적응형 지능형 네트워크 거래 전략

저자:차오장, 날짜: 2024-01-16 14:51:48
태그:

img

전반적인 설명

이 전략은 파인 스크립트 v4로 작성된 트레이딩뷰 플랫폼을 기반으로 한 적응형 지능형 그리드 거래 전략입니다. 가격 차트에 덮여서 구매 및 판매 신호를 생성하기 위해 지정된 경계 내에서 그리드를 만듭니다.

전략 논리

주요 특징

  1. 피라미드 제작 및 돈 관리:

    • 같은 방향으로 최대 14개의 추가를 허용합니다 (피라미드 모양)
    • 현금 기반의 전략을 사용하여 포지션 크기를 관리합니다.
    • 시뮬레이션 목적으로 초기 자본은 100 USD로 설정됩니다.
    • 0.1%의 작은 수수료가 각 거래에 부과됩니다.
  2. 그리드 경계:

    • 사용자는 자동으로 계산된 경계를 사용하거나 그리드의 상부와 하부 경계를 수동으로 설정할 수 있습니다.
    • 자동 경계는 가격의 최근 최고 & 낮은 또는 간단한 이동 평균 (SMA) 에서 도출 될 수 있습니다.
    • 사용자들은 한계 계산을 위한 룩백 기간을 정의하고, 한계를 넓히거나 좁히기 위해 오차를 조정할 수 있습니다.
  3. 그리드 라인:

    • 이 전략은 경계선 내에서 사용자 정의 가능한 네트워크 라인 수를 허용하며 권장 범위는 3에서 15 사이입니다.
    • 그리드 라인은 상부와 하부 경계 사이에 균등하게 떨어져 있습니다.

전략 논리

  • 입력:

    • 스크립트는 가격이 그리드 라인 아래로 떨어지고 그 그리드 라인과 관련된 기존 오더가 없을 때 구매 주문을 합니다.
    • 각 구매 주문 양은 초기 자본을 현재 가격에 조정된 네트워크 라인 수로 나누어서 계산됩니다.
  • 출구:

    • 매각 주문은 가격이 그리드 라인을 넘어서면 시작됩니다. 그 다음 아래 그리드 라인에 해당하는 오픈 오더가 있는 경우에요.
  • 적응 격자:

    • 자동 한계로 설정되면, 그리드는 상부와 하부 한계를 재 계산하고 그대로 그리드를 조정함으로써 변화하는 시장 조건에 적응합니다.

이점 분석

이 전략은 그리드 거래의 체계적인 성격과 효율적인 실행을 통합합니다. 피라미딩을 허용하고 돈 관리를 사용하여 위험을 효과적으로 제어 할 수 있습니다. 자동 적응 그리드는 다른 시장 조건에 적합합니다. 조정 가능한 매개 변수는 다른 거래 스타일에 적합합니다.

위험 분석

네트워크 한계를 넘어가는 가격 파업은 심각한 손실을 초래할 수 있습니다. 매개 변수는 적절히 조정되거나 위험을 제어하기 위해 스톱 로스로 결합해야합니다. 또한 과도한 거래는 거래 비용을 증가시킵니다.

최적화 방향

트렌드 필터와 결합하거나 그리드 매개 변수를 최적화하는 것을 고려하십시오. 스톱 로스는 극단적인 시장 움직임의 위험을 예방하는 데 도움이 될 수 있습니다.

결론

이 전략은 포지션을 관리하는 동안 체계적으로 입출구를 생성합니다. 매개 변수 조정을 통해 다른 선호도에 적응합니다. 그리드 거래의 규칙 기반 성격과 트렌드 거래의 유연성을 결합하여 안정성을 유지하면서 운영 복잡성을 완화합니다.


/*backtest
start: 2024-01-08 00:00:00
end: 2024-01-15 00:00:00
period: 5m
basePeriod: 1m
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)

더 많은