그리드 트레이딩 리스크 헤지링 전략 (Grid Trading Risk Hedging Strategy) 은 리스크 헤지링의 개념과 결합된 그리드 트레이딩의 개념을 기반으로 한 양적 거래 전략이다. 이 전략은 가격 변동으로부터 이익을 얻기 위해 미리 정의된 가격 범위 내에서 여러 구매 및 판매 주문을 설정한다. 동시에, 전략은 시장 환경의 변화에 적응하고 전략 위험을 줄이기 위해 그리드 경계를 동적으로 조정하는 리스크 헤지링 메커니즘을 도입한다.
이 전략의 핵심 원칙은 그리드 트레이딩이다. 먼저, 사용자에 의해 설정된 매개 변수에 기초하여 그리드의 상부와 하부 경계와 그리드 라인의 수를 결정한다. 그 다음, 매입 및 판매 주문은 그리드 라인에 배치된다: 가격이 그리드 라인을 만지면, 그 그리드 라인에 이전에 주문이 없었다면, 포지션이 열린다; 이전에 주문이 있었다면, 포지션이 닫힌다. 이 방법으로, 전략은 수익을 창출하기 위해 가격 변동에서 지속적으로 포지션을 열고 닫을 수 있다.
동시에 위험을 줄이기 위해 전략은 동적 격자 경계 조정 메커니즘을 도입한다. 사용자의 선택에 따라, 격자 상부와 하부 경계는 최근 기간의 가장 높고 가장 낮은 가격에 기초하여 사용자에 의해 설정된 오차를 고려하여 자동으로 조정될 수 있다.
또한, 포지션을 열 때, 전략은 총 자금을 N 개의 동등한 부분으로 나누고, 포지션을 열 때마다 동일한 자금을 사용합니다. 이는 단일 거래의 위험을 줄일 수 있습니다.
강력한 적응력: 네트워크 경계를 동적으로 조정함으로써 전략은 다른 시장 환경에 적응 할 수 있습니다. 추세 또는 변동적인 시장에서 더 나은 수익을 얻기 위해 자동으로 조정 할 수 있습니다.
통제 가능한 위험: 전략은 포지션을 열 때 동일한 금액의 자금을 사용하므로 단일 거래의 위험이 작습니다. 동시에 동적 그리드 경계 조정 메커니즘은 가격 경계를 넘을 위험을 줄일 수 있습니다.
높은 거래 빈도: 그리드는 일반적으로 많은 주문을 가지고 있기 때문에 거래 빈도는 높으며 변동적인 시장에서 수익을 더 쉽게 만듭니다.
유연한 매개 변수: 사용자는 자신의 선호도에 따라 격자 수, 상부 및 하부 경계, 동적 조정 매개 변수 등을 설정하여 다른 거래 스타일에 적응할 수 있습니다.
트렌드 시장에서 낮은 성과: 가격이 일방적으로 상승하거나 하락하여 그리드 경계를 뚫고 계속되고 동적 조정이 가격 변화 속도를 따라잡을 수 없다면 전략은 더 큰 위험에 직면 할 수 있습니다.
거래 수수료: 전략이 거래 빈도가 높기 때문에 거래 수수료는 수익에 어느 정도 영향을 줄 수 있습니다.
부적절한 매개 변수 설정: 너무 많은 그리드 라인이나 부적절한 그리드 경계 설정과 같은 매개 변수가 부적절하게 설정되면 전략 성능이 떨어질 수 있습니다.
솔루션: 1) 트렌드 시장에서 그리드 경계의 조정 범위를 늘리거나 트렌드 전략과 결합하는 것을 고려하십시오. 2) 낮은 거래 수수료가있는 거래소와 통화를 선택하십시오. 3) 실제 운영 전에 매개 변수는 완전히 백테스트되고 최적화되어야합니다.
다른 전략과 결합: 전략의 적응력과 안정성을 향상시키기 위해 트렌드 전략, 평균 반전 전략 등 다른 유형의 전략과 그리드 거래 전략을 결합하는 것을 고려하십시오.
동적 조정 메커니즘을 개선: 전략의 현재 동적 조정 메커니즘은 상대적으로 간단하며 더 많은 요인 (거래량, 변동성 등) 을 고려하고 더 고급 알고리즘 (응용 알고리즘, 기계 학습 알고리즘 등) 을 채택하는 등 추가로 최적화 할 수 있습니다.
펀드 관리를 최적화: 현재 전략은 동등한 펀드 관리를 채택하고 있습니다. 우리는 켈리 기준, 최적화 방법 등과 같은 더 진보된 펀드 관리 방법을 도입하는 것을 고려할 수 있습니다.
이윤을 취하고 손실을 중지: 그리드 거래의 기초에 따라 전략 위험을 더욱 줄이기 위해 수익을 취하고 손실을 중지하는 로직을 도입 할 수 있습니다. 예를 들어, 이동이 수익을 취하고 손실을 중지합니다. 변동성이 수익을 취하고 손실을 중지합니다.
그리드 트레이딩 리스크 헤지 전략 (Grid Trading Risk Hedging Strategy) 은 고도로 자동화되고 적응 가능하며 위험 조절 가능한 양적 거래 전략이다. 그리드 트레이딩과 동적 그리드 조정을 통해 전략은 위험을 제어하면서 다양한 시장 조건에서 이익을 얻을 수 있다. 그러나 전략은 트렌드 시장에서 성능이 떨어질 수 있으며 거래 수수료는 수익에 영향을 미칠 수 있다. 따라서 실질적인 응용 분야에서 추가 최적화와 개선이 필요하다. 일반적으로 전략은 비교적 성숙한 양적 거래 아이디어를 제공하며 추가 연구와 응용에 가치가 있다.
/*backtest start: 2024-03-19 00:00:00 end: 2024-03-23 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)