
Strategi ini mewujudkan keuntungan yang stabil dalam keadaan turun naik dengan membina grid perdagangan yang disesuaikan secara dinamik. Strategi ini akan mengira jarak grid dan harga bawah dan atas secara automatik berdasarkan jumlah grid yang ditetapkan. Apabila harga menembusi setiap garisan grid, ia akan membuat lebih banyak atau kosong.
Array harga garisan garisan dan garisan garisan dikira berdasarkan parameter input.
Apabila harga lebih rendah daripada satu garisan grid dan garisan grid itu tidak mempunyai pesanan yang sesuai, buatlah banyak pesanan di titik harga garisan grid itu; apabila harga lebih tinggi daripada garisan grid sebelumnya (kecuali yang pertama) dan garisan grid sebelumnya ada pesanan simpanan yang sesuai, buatlah banyak pesanan yang sesuai di garisan grid sebelumnya.
Jika parameter grid penyesuaian automatik diaktifkan, harga, jarak grid, dan array grid akan dikira semula secara berkala berdasarkan jumlah data K-line terkini.
Mencapai matlamat untuk mendapat keuntungan dalam keadaan turun naik. Dalam keadaan turun naik, dapat membuat pegangan dan penutupan pegangan pada pelbagai titik harga, sehingga dapat memperoleh keuntungan secara keseluruhan.
Anda boleh memilih untuk menyesuaikan parameter grid secara manual atau automatik. Penyesuaian manual memerlukan campur tangan manusia, tetapi lebih terkawal. Penyesuaian automatik mengurangkan beban kerja operasi dan membolehkan strategi menyesuaikan diri dengan perubahan keadaan pasaran.
Dengan mengehadkan bilangan grid maksimum, risiko unilateral dapat dikawal. Risiko dalam arah ini dapat dikawal apabila harga menembusi semua garisan grid.
Anda boleh mengawal kerugian setiap unit dengan menyesuaikan jarak grid. Mengurangkan jarak grid dapat mengurangkan kerugian tunggal.
Terdapat risiko untuk melakukan penipuan jika harga bergelombang dengan cepat di antara beberapa grid.
Perlu menetapkan jumlah modal awal yang munasabah. Jika modal awal tidak mencukupi, tidak dapat menyokong jumlah garisan yang mencukupi.
Jumlah grid yang terlalu besar atau terlalu kecil tidak baik untuk keuntungan strategi. Jumlah grid yang terlalu sedikit tidak dapat memanfaatkan fluktuasi sepenuhnya; terlalu banyak adalah kerugian tunggal yang terlalu kecil. Ujian diperlukan untuk menentukan parameter terbaik.
Terdapat risiko bahawa parameter grid yang disesuaikan secara automatik dapat dimanipulasi. Pengiraan parameter grid bergantung pada jumlah K yang tertentu dan mungkin dipengaruhi oleh operasi jangka pendek.
Tambah logik hentian kerugian, seperti menetapkan hentian terapung atau hentian pengesanan, untuk mengawal risiko kerugian unilateral.
Menggabungkan algoritma untuk mengoptimumkan parameter grid. Anda boleh menguji tetapan parameter pada peringkat pasaran yang berbeza, dan kemudian melatih model dengan kaedah pembelajaran mesin untuk mengoptimumkan parameter secara automatik.
Menggabungkan lebih banyak indikator untuk menilai keadaan. Seperti MACD, KD dan lain-lain untuk menentukan sama ada trend naik atau turun, untuk menyesuaikan bilangan grid atau parameter.
Mengoptimumkan kawalan penarikan balik, seperti menetapkan peratusan penarikan balik maksimum, dan menutup strategi apabila paras paras terhad dicapai, untuk mengelakkan kerugian daripada berkembang lebih jauh.
Strategi ini memanfaatkan sepenuhnya ciri-ciri keadaan turun naik, mencapai matlamat keuntungan yang stabil melalui perdagangan grid dinamik. Strategi ini mempertimbangkan fleksibiliti pengaturan parameter dan mengurangkan intensiti kerja operasi.
/*backtest
start: 2024-01-02 00:00:00
end: 2024-02-01 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
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)