해양 이론 그리드 거래 전략


생성 날짜: 2023-10-13 17:07:39 마지막으로 수정됨: 2023-10-13 17:07:39
복사: 0 클릭수: 787
avatar of ChaoZhang ChaoZhang
1
집중하다
1617
수행원

개요

이 전략은 해양 이론의 격자 거래 방법을 적용하여 설정된 가격 범위 내에서 균등하게 분산된 격자 라인을 사용하여 가격과 격자 라인과의 관계에 따라 구매 및 판매 작업을 수행한다. 이 전략은 자동으로 격자 가격 범위를 계산하고 균등하게 분산된 격자 라인 등의 특징을 가지고 있어 위험을 효과적으로 제어할 수 있다.

전략 원칙

이 전략은 우선 사용자 선택 또는 기본 설정에 따라 가격 격자의 상하를 계산한다. 그 격자의 최고 가격과 최저 가격이다. 계산 방법은 두 가지로, 하나는 재측정 주기 내의 최고 가격과 최저 가격을 찾는 것, 두 번째는 일정 주기 동안의 평균선을 계산하는 것이다.

거래 신호의 발생은 가격과 격자선과의 관계에 의존한다. 가격이 아래의 격자선보다 낮을 때, 그 격자선에서 일정한 수량으로 더 많은 입장을 취한다. 가격이 위의 격자선보다 높을 때, 그 격자선에서 일정한 수량으로 더 적은 입장을 취한다. 이렇게 가격의 변동과 함께, 입장은 또한 격자 내에서 변동하여 이익을 얻는다.

구체적으로, 전략은 각 격자 라인마다 상권이 있는지 여부를 나타내는 격자 라인 가격 배열과 bool 배열을 유지한다. 어떤 격자 라인보다 가격이 낮고 그 라인에는 상권이 없는 경우, 그 라인에서 더 많은 가격을 매긴다. 어떤 격자 라인보다 가격이 높고 그 아래에 있는 격자 라인에는 상권이 있는 경우, 그 아래에 있는 격자 라인에서 평점을 한다.

전략적 이점

  1. 그리드 구간을 자동으로 계산하여 수동 설정의 어려움을 피할 수 있습니다. 다른 계산 방법을 선택할 수 있습니다.

  2. 균일하게 배포된 그리드 라인, 그리드 밀도가 과도한 거래로 이어지는 것을 방지한다. 그리드 라인의 수는 조정할 수 있다.

  3. 격자 거래 방식을 사용하면 위험을 효과적으로 제어 할 수 있으며 격자 내에서 가격 변동은 항상 수익을 얻을 수 있습니다.

  4. 가격에 대한 방향성이 예상되지 않고, 충격적인 상황에 적용된다.

  5. 수요율과 포지션 수를 사용자 정의 할 수 있으며, 다양한 거래 유형에 적합합니다.

  6. 그레드 라인을 시각적으로 보여 주고 거래 상황을 파악할 수 있다.

전략적 위험

  1. 그리드 상부 하위 경계를 넘으면 손실이 커질 수 있다.

  2. 그리드 간격이 너무 넓으면 수익이 떨어지지만 그리드 간격이 너무 좁으면 수수료가 증가합니다. 균형이 필요합니다.

  3. 지분 기간이 너무 길다는 위험. 지분 기간이 너무 길다는 것은 수익을 내기 어렵고, 수수료 손실을 증가시킬 수 있다.

  4. 매개 변수 설정이 잘못되면 위험하다. 회수주기나 평균선주기 같은 매개 변수 설정이 잘못되면 격자 간격 계산에 영향을 줄 수 있다.

  5. 시장의 체계적 위험. 이 전략은 장기적인 일방적인 행위에 적합하지 않고, 충격적인 행위에 더 적합하다.

전략 최적화

  1. 최적화 그리드 파라미터 설정 ᆞ 종합적으로 시장 특성, 거래 비용 등의 요인을 고려하고, 최적화 그리드 수, 재검사 주기 등의 파라미터 ᆞ

  2. 격자 구간 동적 조정. 시장이 큰 변화가 있을 때 격자 구간 동적 조정 메커니즘을 도입할 수 있다.

  3. 스포드 메커니즘에 가입하십시오. 합리적인 스포드 라인을 설정하여 과도한 손실을 피하십시오. 스포드 라인은 또한 동적으로 조정할 수 있습니다.

  4. 부린라인, 트렌드 지표 등과 같은 다른 지표와 함께 거래를 필터링하십시오. 부적절한 거래를 피하십시오.

  5. 자본 사용 효율을 최적화한다. 냉열 분석을 추가하고, 변동이 적을 때 거래를 줄인다.

요약하다

이 전략은 격자 거래 원리를 활용하여 위험을 제어할 수 있는 격자 거래를 구현한다. 이 전략은 자동 계산 격자, 균등 분배 격자 등의 장점을 가지고 있으며, 매개 변수를 조정하여 서로 다른 시장 환경에 적응할 수 있다. 위험은 제어할 수 있고 작동하기 쉽다. 그러나 전략에는 시장 변화에 적응하기 위해 지속적인 최적화가 필요한 한계가 있다. 전반적으로 이 전략은 격자 거래에 대해 표준화되고 변수화 가능한 구현 방법을 제공한다.

전략 소스 코드
/*backtest
start: 2023-09-12 00:00:00
end: 2023-10-12 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
strategy.initial_capital = 50000
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

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)