
이 전략은 격자 거래의 개념에 기반한 자기 적응 암호화폐 중매 전략이다. 그것은 시장의 변동에 따라 자동으로 격자 거래의 가격 범위를 조정하고 그 가격 범위에 효율적으로 중매 거래를 할 수 있다.
이 전략의 핵심은 다음과 같습니다.
역동적으로 거래망의 가격 범위를 계산하여 역사적 가격의 높고 낮은 점에 따라 계산합니다.
이 가격 범위에서, 같은 간격으로 N개의 거래 격자선을 설정한다.
가격이 각 격자선을 뚫을 때, 고정된 수량에 따라 포지션을 상장하거나 상장한다.
인접한 그리드 라인 사이에 경매를 하고, 이윤을 얻은 후 평축한다.
가격이 격자 범위에 다시 들어갔을 때, 격자 선의 경계 비용 가격으로 포지션을 계속 개설하십시오.
이런 식으로 순환을 거듭하며, 격자 가격 범위 내에서 고주파수 중개 거래가 진행된다.
구체적으로, 전략은 먼저 구성된 돌아보기 창 ((i_boundLookback) 과 변동 영역 ((i_boundDev) 의 파라미터를 기반으로, 실시간으로 격자의 가격 상하를 계산한다.
그리고 상하한계들 사이에 모두 N개의 그리드 라인을 나눕니다. 이 그리드 라인의 가격은 gridLineArr 배열에 저장됩니다.
가격이 어떤 격자선을 돌파할 때, 고정된 수에 따라 (전략의 자본을 격자 수로 나눈다) 포지션을 상장하거나 상장한다. 주문은 orderArr 배열에 기록된다.
가격이 다시 인접한 격자선을 돌파할 때, 이전 주문과 일치하는 수익을 얻을 수 있습니다.
이런 식으로 순환해서 가격 변동의 범위 내에서 고주파수 중매를 한다.
전통적인 격자 전략에 비해, 이 전략의 가장 큰 장점은 격자 범위가 자동으로 조정되고, 시장의 변동에 따라 적응할 수 있다는 것이다. 다음과 같은 특징이 있다:
자동 조정, 인적 개입 없이
가격 동향을 포착하고 동향 방향으로 거래할 수 있다.
“위험은 통제할 수 있고, 일방적인 공격은 피할 수 있다”.
거래 빈도가 높고, 수익률도 높습니다.
이해하기 쉽고, 구성도 간단하다.
이 프로젝트의 경우, 이 프로젝트의 투자율은 높은데,
로봇 거래에 적합한 시장 변화를 실시간으로 반영합니다.
이 전략은 장점이 많지만, 다음과 같은 위험도 있습니다.
가격의 급격한 변동으로 인해 큰 손실이 발생할 수 있습니다.
적당한 지분 보유 기간과 거래 쌍이 필요하여 수익을 창출합니다.
자금 규모와 변동 범위의 일치성은 신중하게 평가해야 합니다.
정상 작동을 보장하기 위해 매개 변수를 정기적으로 모니터링하고 최적화해야 할 수 있습니다.
대응책은 다음과 같습니다:
그리드 간격을 늘리고, 그리드 범위를 넓혀라.
변동이 평평한 거래 쌍을 선택하십시오.
충분한 유동성을 보장하기 위해 자금 규모를 조정하십시오.
자동 감시 및 경보 시스템을 구축하십시오.
이 전략은 다음과 같은 부분에서 최적화될 수 있습니다.
동적 격자: 거래 쌍의 변동성에 따라 그리드 매개 변수를 자동으로 조정할 수 있다.
손해 방지 장치이 경우, 상자 상점의 경우, 상자 상점의 경우, 상자 상점의 경우, 상자 상점의 경우,
복합 격자: 시간 복제를 구현하기 위해 다른 시간 동안 다른 매개 변수를 사용하는 격자 조합.
기계 학습: 신경망과 같은 대안 규칙을 사용하여, 매개 변수의 자동 최적화를 구현한다.
크로스마켓 차익거래이 거래소에서는 거래소와 거래소 간의 거래가 가능하며, 거래소와 거래소 간의 거래가 가능합니다.
이 전략은 전체적으로 매우 실용적인 자기 적응 암호화폐 격자 조정 전략이다. 전통적인 격자 전략에 비해, 그 가장 큰 특징은 격자 범위가 자동으로 조정되며, 시장 변화에 따라 자신의 거래 범위를 구성 할 수 있다는 것이다. 전략 아이디어는 명확하고, 이해하기 쉽고, 구성, 기본이있는 개인 투자자가 사용할 수 있으며, 거래 로봇으로 사용할 수 있는 전략 템플릿이다.
/*backtest
start: 2024-01-11 00:00:00
end: 2024-01-18 00:00:00
period: 1m
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)